Merge remote-tracking branch 'origin/MV5' into revamp-config

# Conflicts:
#	build.gradle
#	src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
#	src/main/java/com/onarandombox/MultiverseCore/MultiverseCoreConfiguration.java
#	src/main/java/com/onarandombox/MultiverseCore/api/MVConfig.java
#	src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandCompletions.java
#	src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandContexts.java
#	src/main/java/com/onarandombox/MultiverseCore/listeners/MVChatListener.java
#	src/main/java/com/onarandombox/MultiverseCore/listeners/MVEntityListener.java
#	src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java
#	src/main/java/com/onarandombox/MultiverseCore/world/SimpleMVWorld.java
#	src/main/java/com/onarandombox/MultiverseCore/world/SimpleMVWorldManager.java
This commit is contained in:
Jeremy Wood 2023-03-26 19:09:37 -04:00
commit a45e95c7fd
No known key found for this signature in database
GPG Key ID: C5BAD04C77B91B4B
85 changed files with 1758 additions and 940 deletions

View File

@ -40,7 +40,7 @@ jobs:
- uses: actions/setup-java@v3
with:
java-version: '11'
java-version: '17'
distribution: 'adopt'
cache: gradle

View File

@ -12,7 +12,7 @@ jobs:
- uses: actions/setup-java@v3
with:
java-version: '11'
java-version: '17'
distribution: 'adopt'
cache: gradle

View File

@ -14,7 +14,7 @@ jobs:
- uses: actions/setup-java@v3
with:
java-version: '11'
java-version: '17'
distribution: 'adopt'
cache: gradle
@ -24,7 +24,7 @@ jobs:
- name: Run unit tests
uses: gradle/gradle-build-action@v2
with:
arguments: build
arguments: build -x checkstyleMain -x checkstyleTest -x javadoc
env:
GITHUB_VERSION: pr${{ github.event.pull_request.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -64,6 +64,13 @@ repositories {
configurations {
oldTestImplementation.extendsFrom implementation
oldTestRuntime.extendsFrom runtime
relocatedApi
compileClasspath.extendsFrom relocatedApi
runtimeClasspath.extendsFrom relocatedApi
testCompileClasspath.extendsFrom relocatedApi
testRuntimeClasspath.extendsFrom relocatedApi
oldTestCompileClasspath.extendsFrom relocatedApi
oldTestRuntimeClasspath.extendsFrom relocatedApi
}
dependencies {
@ -75,27 +82,29 @@ dependencies {
}
// PlaceholderAPI
compileOnly 'me.clip:placeholderapi:2.11.2'
implementation 'me.clip:placeholderapi:2.11.2'
// Command Framework
api 'co.aikar:acf-paper:0.5.1-SNAPSHOT'
relocatedApi 'co.aikar:acf-paper:0.5.1-SNAPSHOT'
// Config
api('me.main__.util:SerializationConfig:1.7') {
relocatedApi('me.main__.util:SerializationConfig:1.7') {
exclude group: 'org.bukkit', module: 'bukkit'
}
api('io.github.townyadvanced.commentedconfiguration:CommentedConfiguration:1.0.1') {
relocatedApi('io.github.townyadvanced.commentedconfiguration:CommentedConfiguration:1.0.1') {
exclude group: 'org.spigotmc', module: 'spigot-api'
}
// Utils
api('com.dumptruckman.minecraft:Logging:1.1.1') {
relocatedApi 'io.vavr:vavr:0.10.4'
relocatedApi 'org.glassfish.hk2:hk2-locator:3.0.3'
relocatedApi('com.dumptruckman.minecraft:Logging:1.1.1') {
exclude group: 'junit', module: 'junit'
}
api 'de.themoep.idconverter:mappings:1.2-SNAPSHOT'
api 'org.bstats:bstats-bukkit:2.2.1'
api 'net.minidev:json-smart:2.4.8'
api 'org.jetbrains:annotations:22.0.0'
relocatedApi 'de.themoep.idconverter:mappings:1.2-SNAPSHOT'
relocatedApi 'org.bstats:bstats-bukkit:2.2.1'
relocatedApi 'net.minidev:json-smart:2.4.8'
relocatedApi 'org.jetbrains:annotations:22.0.0'
// Tests
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10'
@ -104,6 +113,7 @@ dependencies {
exclude group: 'junit', module: 'junit'
}
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'com.natpryce:hamkrest:1.8.0.1'
// Old Tests
oldTestImplementation 'org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT'
@ -113,6 +123,10 @@ dependencies {
oldTestImplementation 'junit:junit:4.13.1'
oldTestImplementation 'org.mockito:mockito-core:3.11.2'
oldTestImplementation 'commons-io:commons-io:2.7'
// Annotation Processors
annotationProcessor 'org.glassfish.hk2:hk2-metadata-generator:3.0.3'
testAnnotationProcessor 'org.glassfish.hk2:hk2-metadata-generator:3.0.3'
}
@ -183,18 +197,18 @@ task prepareSource(type: Sync) {
compileJava {
source = prepareSource.outputs
}
tasks.withType(JavaCompile) {
configure(options) {
options.compilerArgs << '-Aorg.glassfish.hk2.metadata.location=META-INF/hk2-locator/Multiverse-Core'
}
}
compileKotlin {
// We're not using Kotlin in the plugin itself, just tests!
enabled = false
}
configurations {
compileOnly {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
runtimeOnly {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
configurations.findAll { !it.name.startsWith('test') }.each {
it.exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
processResources {
@ -227,15 +241,26 @@ javadoc {
project.configurations.api.canBeResolved = true
shadowJar {
relocate 'co.alkar.commands', 'com.onarandombox.acf'
relocate 'co.aikar', 'com.onarandombox.acf'
relocate 'com.dumptruckman.minecraft.util.Logging', 'com.onarandombox.MultiverseCore.utils.CoreLogging'
relocate 'com.dumptruckman.minecraft.util.DebugLog', 'com.onarandombox.MultiverseCore.utils.DebugFileLogger'
relocate 'de.themoep.idconverter', 'com.onarandombox.idconverter'
relocate 'io.github.townyadvanced.commentedconfiguration', 'com.onarandombox.commentedconfiguration'
relocate 'me.main__.util', 'com.onarandombox.serializationconfig'
relocate 'org.bstats', 'com.onarandombox.bstats'
relocate 'com.sun', 'com.onarandombox.sun'
relocate 'net.minidev', 'com.onarandombox.minidev'
relocate 'org.objectweb', 'com.onarandombox.objectweb'
relocate 'io.vavr', 'com.onarandombox.vavr'
relocate 'jakarta', 'com.onarandombox.jakarta'
relocate 'javassist', 'com.onarandombox.javassist'
relocate 'org.aopalliance', 'com.onarandombox.aopalliance'
relocate 'org.glassfish', 'com.onarandombox.glassfish'
relocate 'org.jvnet', 'com.onarandombox.jvnet'
relocate 'org.intellij', 'com.onarandombox.intellij'
relocate 'org.jetbrains', 'com.onarandombox.jetbrains'
configurations = [project.configurations.api]
configurations = [project.configurations.api, project.configurations.relocatedApi]
archiveFileName = "$baseName-$version.$extension"
@ -251,4 +276,8 @@ jar.enabled = false
test {
useJUnitPlatform()
testLogging {
exceptionFormat = 'full'
}
}

View File

@ -8,100 +8,68 @@
package com.onarandombox.MultiverseCore;
import java.io.File;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.anchor.AnchorManager;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVConfig;
import com.onarandombox.MultiverseCore.api.Destination;
import com.onarandombox.MultiverseCore.api.MVCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.commands.CheckCommand;
import com.onarandombox.MultiverseCore.commands.CloneCommand;
import com.onarandombox.MultiverseCore.commands.ConfigCommand;
import com.onarandombox.MultiverseCore.commands.ConfirmCommand;
import com.onarandombox.MultiverseCore.commands.CreateCommand;
import com.onarandombox.MultiverseCore.commands.DebugCommand;
import com.onarandombox.MultiverseCore.commands.DeleteCommand;
import com.onarandombox.MultiverseCore.commands.GameruleCommand;
import com.onarandombox.MultiverseCore.commands.ImportCommand;
import com.onarandombox.MultiverseCore.commands.LoadCommand;
import com.onarandombox.MultiverseCore.commands.RegenCommand;
import com.onarandombox.MultiverseCore.commands.ReloadCommand;
import com.onarandombox.MultiverseCore.commands.RemoveCommand;
import com.onarandombox.MultiverseCore.commands.RootCommand;
import com.onarandombox.MultiverseCore.commands.TeleportCommand;
import com.onarandombox.MultiverseCore.commands.UnloadCommand;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import com.onarandombox.MultiverseCore.configuration.DefaultMVConfig;
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
import com.onarandombox.MultiverseCore.destination.core.AnchorDestination;
import com.onarandombox.MultiverseCore.destination.core.BedDestination;
import com.onarandombox.MultiverseCore.destination.core.CannonDestination;
import com.onarandombox.MultiverseCore.destination.core.ExactDestination;
import com.onarandombox.MultiverseCore.destination.core.PlayerDestination;
import com.onarandombox.MultiverseCore.destination.core.WorldDestination;
import com.onarandombox.MultiverseCore.economy.MVEconomist;
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
import com.onarandombox.MultiverseCore.listeners.MVChatListener;
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVPortalListener;
import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
import com.onarandombox.MultiverseCore.listeners.MVWorldInitListener;
import com.onarandombox.MultiverseCore.listeners.MVWorldListener;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import com.onarandombox.MultiverseCore.inject.PluginInjection;
import com.onarandombox.MultiverseCore.placeholders.MultiverseCorePlaceholders;
import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety;
import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.teleportation.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
import com.onarandombox.MultiverseCore.utils.TestingMode;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator;
import com.onarandombox.MultiverseCore.world.SimpleMVWorldManager;
import com.onarandombox.MultiverseCore.world.WorldProperties;
import io.vavr.control.Try;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import me.main__.util.SerializationConfig.SerializationConfig;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import org.glassfish.hk2.api.MultiException;
import org.glassfish.hk2.api.ServiceHandle;
import org.glassfish.hk2.api.ServiceLocator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
/**
* The implementation of the Multiverse-{@link MVCore}.
*/
@Service
public class MultiverseCore extends JavaPlugin implements MVCore {
private static final int PROTOCOL = 50;
// Setup various managers
private final AnchorManager anchorManager = new AnchorManager(this);
private BlockSafety blockSafety = new SimpleBlockSafety(this);
private MVCommandManager commandManager;
private DestinationsProvider destinationsProvider;
private MVEconomist economist;
private LocationManipulation locationManipulation = new SimpleLocationManipulation();
private final MVPermissions mvPermissions = new MVPermissions(this);
private SafeTTeleporter safeTTeleporter = new SimpleSafeTTeleporter(this);
private final UnsafeCallWrapper unsafeCallWrapper = new UnsafeCallWrapper(this);
private final MVWorldManager worldManager = new SimpleMVWorldManager(this);
// Configurations
private MVConfig config;
// Listeners
private MVChatListener chatListener;
private final MVEntityListener entityListener = new MVEntityListener(this);
private final MVPlayerListener playerListener = new MVPlayerListener(this);
private final MVPortalListener portalListener = new MVPortalListener(this);
private final MVWeatherListener weatherListener = new MVWeatherListener(this);
private final MVWorldListener worldListener = new MVWorldListener(this);
private final MVWorldInitListener worldInitListener = new MVWorldInitListener(this);
private ServiceLocator serviceLocator;
@Inject
private MVCoreConfigProvider configProvider;
@Inject
private Provider<MVWorldManager> worldManagerProvider;
@Inject
private Provider<AnchorManager> anchorManagerProvider;
@Inject
private Provider<MVCommandManager> commandManagerProvider;
@Inject
private Provider<DestinationsProvider> destinationsProviderProvider;
@Inject
private Provider<MetricsConfigurator> metricsConfiguratorProvider;
@Inject
private Provider<MVEconomist> economistProvider;
// Counter for the number of plugins that have registered with us
private int pluginCount;
@ -131,39 +99,43 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
*/
@Override
public void onEnable() {
initializeDependencyInjection();
// Load our configs first as we need them for everything else.
this.loadConfigs();
if (this.config == null) {
if (!getConfigProvider().isConfigLoaded()) {
Logging.severe("Your configs were not loaded.");
Logging.severe("Please check your configs and restart the server.");
this.getServer().getPluginManager().disablePlugin(this);
return;
}
Logging.setShowingConfig(!getMVConfig().getSilentStart());
Logging.setShowingConfig(shouldShowConfig());
this.worldManager.getDefaultWorldGenerators();
this.worldManager.loadDefaultWorlds();
this.worldManager.loadWorlds(true);
var worldManager = worldManagerProvider.get();
worldManager.getDefaultWorldGenerators();
worldManager.loadDefaultWorlds();
worldManager.loadWorlds(true);
// Now set the firstspawnworld (after the worlds are loaded):
this.worldManager.setFirstSpawnWorld(getMVConfig().getFirstSpawnLocation());
MVWorld firstSpawnWorld = this.worldManager.getFirstSpawnWorld();
worldManager.setFirstSpawnWorld(getConfigProvider().getConfig().getFirstSpawnLocation());
MVWorld firstSpawnWorld = worldManager.getFirstSpawnWorld();
if (firstSpawnWorld != null) {
getMVConfig().setFirstSpawnLocation(firstSpawnWorld.getName());
getConfigProvider().getConfig().setFirstSpawnLocation(firstSpawnWorld.getName());
}
//Setup economy here so vault is loaded
this.economist = new MVEconomist(this);
this.loadEconomist();
// Init all the other stuff
this.anchorManager.loadAnchors();
this.loadAnchors();
this.registerEvents();
this.registerCommands();
this.setUpLocales();
this.registerDestinations();
this.setupMetrics();
this.setupPlaceholderAPI();
this.loadPlaceholderAPIIntegration();
this.saveMVConfig();
this.logEnableMessage();
}
@ -174,67 +146,92 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
@Override
public void onDisable() {
this.saveAllConfigs();
shutdownDependencyInjection();
Logging.shutdown();
}
private void initializeDependencyInjection() {
serviceLocator = PluginInjection.createServiceLocator(new MultiverseCorePluginBinder(this))
.andThenTry(locator -> {
PluginInjection.enable(this, locator);
})
.getOrElseThrow(exception -> {
Logging.severe("Failed to initialize dependency injection");
getServer().getPluginManager().disablePlugin(this);
return new RuntimeException(exception);
});
}
private void shutdownDependencyInjection() {
if (serviceLocator != null) {
PluginInjection.disable(this, serviceLocator);
serviceLocator = null;
}
}
private boolean shouldShowConfig() {
return !getConfigProvider().getConfig().getSilentStart();
}
private void loadEconomist() {
Try.run(() -> economistProvider.get())
.onFailure(e -> Logging.severe("Failed to load economy integration", e));
}
private void loadAnchors() {
Try.of(() -> anchorManagerProvider.get())
.onSuccess(AnchorManager::loadAnchors)
.onFailure(e -> Logging.severe("Failed to load anchors", e));
}
/**
* Function to Register all the Events needed.
*/
private void registerEvents() {
PluginManager pluginManager = getServer().getPluginManager();
this.chatListener = new MVChatListener(this, this.playerListener);
pluginManager.registerEvents(this.chatListener, this);
pluginManager.registerEvents(this.entityListener, this);
pluginManager.registerEvents(this.playerListener, this);
pluginManager.registerEvents(this.portalListener, this);
pluginManager.registerEvents(this.weatherListener, this);
pluginManager.registerEvents(this.worldListener, this);
pluginManager.registerEvents(this.worldInitListener, this);
var pluginManager = getServer().getPluginManager();
Try.run(() -> serviceLocator.getAllServices(InjectableListener.class)
.forEach(listener -> pluginManager.registerEvents(listener, this)))
.onFailure(e -> {
throw new RuntimeException("Failed to register listeners. Terminating...", e);
});
}
/**
* Register Multiverse-Core commands to Command Manager.
*/
private void registerCommands() {
this.commandManager = new MVCommandManager(this);
this.commandManager.registerCommand(new CheckCommand(this));
this.commandManager.registerCommand(new CloneCommand(this));
this.commandManager.registerCommand(new ConfigCommand(this));
this.commandManager.registerCommand(new ConfirmCommand(this));
this.commandManager.registerCommand(new CreateCommand(this));
this.commandManager.registerCommand(new DebugCommand(this));
this.commandManager.registerCommand(new DeleteCommand(this));
this.commandManager.registerCommand(new ImportCommand(this));
this.commandManager.registerCommand(new GameruleCommand(this));
this.commandManager.registerCommand(new LoadCommand(this));
this.commandManager.registerCommand(new RegenCommand(this));
this.commandManager.registerCommand(new ReloadCommand(this));
this.commandManager.registerCommand(new RemoveCommand(this));
this.commandManager.registerCommand(new RootCommand(this));
this.commandManager.registerCommand(new TeleportCommand(this));
this.commandManager.registerCommand(new UnloadCommand(this));
Try.of(() -> commandManagerProvider.get())
.andThenTry(commandManager -> {
serviceLocator.getAllServices(MultiverseCommand.class)
.forEach(commandManager::registerCommand);
})
.onFailure(e -> Logging.severe("Failed to register commands", e));
}
/**
* Register locales
*/
private void setUpLocales() {
this.commandManager.usePerIssuerLocale(true, true);
this.commandManager.getLocales().addFileResClassLoader(this);
this.commandManager.getLocales().addMessageBundles("multiverse-core");
Try.of(() -> commandManagerProvider.get())
.andThenTry(commandManager -> {
commandManager.usePerIssuerLocale(true, true);
commandManager.getLocales().addFileResClassLoader(this);
commandManager.getLocales().addMessageBundles("multiverse-core");
})
.onFailure(e -> Logging.severe("Failed to register locales", e));
}
/**
* Register all the destinations.
*/
private void registerDestinations() {
this.destinationsProvider = new DestinationsProvider(this);
this.destinationsProvider.registerDestination(new AnchorDestination(this));
this.destinationsProvider.registerDestination(new BedDestination());
this.destinationsProvider.registerDestination(new CannonDestination(this));
this.destinationsProvider.registerDestination(new ExactDestination(this));
this.destinationsProvider.registerDestination(new PlayerDestination());
this.destinationsProvider.registerDestination(new WorldDestination(this));
Try.of(() -> destinationsProviderProvider.get())
.andThenTry(destinationsProvider -> {
serviceLocator.getAllServices(Destination.class)
.forEach(destinationsProvider::registerDestination);
})
.onFailure(e -> Logging.severe("Failed to register destinations", e));
}
/**
@ -242,7 +239,11 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
*/
private void setupMetrics() {
if (TestingMode.isDisabled()) {
MetricsConfigurator.configureMetrics(this);
// Load metrics
Try.of(() -> metricsConfiguratorProvider.get())
.onFailure(e -> Logging.severe("Failed to setup metrics", e));
} else {
Logging.info("Metrics are disabled in testing mode.");
}
}
@ -251,19 +252,25 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
*/
private void logEnableMessage() {
Logging.config("Version %s (API v%s) Enabled - By %s", this.getDescription().getVersion(), PROTOCOL, getAuthors());
if (getMVConfig().isShowingDonateMessage()) {
if (getConfigProvider().getConfig().isShowingDonateMessage()) {
Logging.config("Help dumptruckman keep this project alive. Become a patron! https://www.patreon.com/dumptruckman");
Logging.config("One time donations are also appreciated: https://www.paypal.me/dumptruckman");
}
}
private void setupPlaceholderAPI() {
if(config.isRegisterPapiHook() && getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
new MultiverseCorePlaceholders(this).register();
Logging.config("Registered PlaceholderAPI hook.");
private void loadPlaceholderAPIIntegration() {
if (getConfigProvider().getConfig().isRegisterPapiHook()
&& getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
Try.run(() -> serviceLocator.createAndInitialize(MultiverseCorePlaceholders.class))
.onFailure(e -> Logging.severe("Failed to load PlaceholderAPI integration.", e));
}
}
private MVCoreConfigProvider getConfigProvider() {
return configProvider;
}
/**
* {@inheritDoc}
*/
@ -280,21 +287,6 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
return PROTOCOL;
}
/**
* {@inheritDoc}
*/
public MVEconomist getEconomist() {
return economist;
}
/**
* {@inheritDoc}
*/
@Override
public MVPermissions getMVPerms() {
return this.mvPermissions;
}
/**
* {@inheritDoc}
*/
@ -319,14 +311,6 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
return authors.toString();
}
/**
* {@inheritDoc}
*/
@Override
public MVCommandManager getMVCommandManager() {
return this.commandManager;
}
/**
* {@inheritDoc}
*/
@ -357,37 +341,22 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
this.pluginCount -= 1;
}
/**
* {@inheritDoc}
*/
@Override
public DestinationsProvider getDestinationsProvider() {
return this.destinationsProvider;
}
/**
* {@inheritDoc}
*/
@Override
public MVWorldManager getMVWorldManager() {
return this.worldManager;
}
/**
* {@inheritDoc}
*/
@Override
public void loadConfigs() {
config = DefaultMVConfig.init(this);
this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));
int level = Logging.getDebugLevel();
Logging.setDebugLevel(getMVConfig().getGlobalDebug());
if (level != Logging.getDebugLevel()) {
getServer().getPluginManager().callEvent(new MVDebugModeEvent(level));
}
getConfigProvider().loadConfigs();
// TODO move to config provider
// config = DefaultMVConfig.init(this);
//
// this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));
//
// int level = Logging.getDebugLevel();
// Logging.setDebugLevel(getMVConfig().getGlobalDebug());
// if (level != Logging.getDebugLevel()) {
// getServer().getPluginManager().callEvent(new MVDebugModeEvent(level));
// }
}
/**
@ -395,8 +364,13 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
*/
@Override
public boolean saveMVConfig() {
this.config.save();
return true;
return getConfigProvider().saveConfig()
.map(v -> true)
.recover(e -> {
Logging.severe(e.getMessage(), e);
return false;
})
.get();
}
/**
@ -404,91 +378,9 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
*/
@Override
public boolean saveAllConfigs() {
return this.saveMVConfig() && this.worldManager.saveWorldsConfig();
return this.saveMVConfig() && worldManagerProvider.get().saveWorldsConfig();
}
/**
* {@inheritDoc}
*/
@Override
public AnchorManager getAnchorManager() {
return this.anchorManager;
}
/**
* {@inheritDoc}
*/
@Override
public BlockSafety getBlockSafety() {
return blockSafety;
}
/**
* {@inheritDoc}
*/
@Override
public void setBlockSafety(BlockSafety blockSafety) {
if (blockSafety == null) {
throw new NullPointerException("block safety may not be null.");
}
this.blockSafety = blockSafety;
}
/**
* {@inheritDoc}
*/
@Override
public LocationManipulation getLocationManipulation() {
return locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public void setLocationManipulation(LocationManipulation locationManipulation) {
if (locationManipulation == null) {
throw new NullPointerException("location manipulation may not be null.");
}
this.locationManipulation = locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public SafeTTeleporter getSafeTTeleporter() {
return safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public void setSafeTTeleporter(SafeTTeleporter safeTTeleporter) {
if (safeTTeleporter == null) {
throw new NullPointerException("safeTTeleporter may not be null.");
}
this.safeTTeleporter = safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public MVConfig getMVConfig() {
return config;
}
/**
* {@inheritDoc}
*/
@Override
public UnsafeCallWrapper getUnsafeCallWrapper() {
return this.unsafeCallWrapper;
}
//TODO: REMOVE THIS STATIC CRAP - START
private static final Map<String, String> teleportQueue = new HashMap<String, String>();
@ -535,42 +427,6 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
super(loader, description, dataFolder, file);
}
/**
* Gets the {@link MVPlayerListener}.
*
* @return The {@link MVPlayerListener}.
*/
public MVPlayerListener getPlayerListener() {
return this.playerListener;
}
/**
* Gets the {@link MVChatListener}.
*
* @return The {@link MVChatListener}.
*/
public MVChatListener getChatListener() {
return this.chatListener;
}
/**
* Gets the {@link MVEntityListener}.
*
* @return The {@link MVEntityListener}.
*/
public MVEntityListener getEntityListener() {
return this.entityListener;
}
/**
* Gets the {@link MVWeatherListener}.
*
* @return The {@link MVWeatherListener}.
*/
public MVWeatherListener getWeatherListener() {
return this.weatherListener;
}
/**
* Gets the server's root-folder as {@link File}.
*
@ -591,4 +447,43 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
this.serverFolder = newServerFolder;
}
/**
* Gets the best service from this plugin that implements the given contract or has the given implementation.
*
* @param contractOrImpl The contract or concrete implementation to get the best instance of
* @param qualifiers The set of qualifiers that must match this service definition
* @return An instance of the contract or impl if it is a service and is already instantiated, null otherwise
* @throws MultiException if there was an error during service lookup
*/
@Nullable
public <T> T getService(@NotNull Class<T> contractOrImpl, Annotation... qualifiers) throws MultiException {
var handle = serviceLocator.getServiceHandle(contractOrImpl, qualifiers);
if (handle != null && handle.isActive()) {
return handle.getService();
}
return null;
}
/**
* Gets all services from this plugin that implement the given contract or have the given implementation and have
* the provided qualifiers.
*
* @param contractOrImpl The contract or concrete implementation to get the best instance of
* @param qualifiers The set of qualifiers that must match this service definition
* @return A list of services implementing this contract or concrete implementation. May not return null, but may
* return an empty list
* @throws MultiException if there was an error during service lookup
*/
@NotNull
public <T> List<T> getAllServices(
@NotNull Class<T> contractOrImpl,
Annotation... qualifiers
) throws MultiException {
var handles = serviceLocator.getAllServiceHandles(contractOrImpl, qualifiers);
return handles.stream()
.filter(ServiceHandle::isActive)
.map(ServiceHandle::getService)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,18 @@
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVCore;
import com.onarandombox.MultiverseCore.inject.binder.JavaPluginBinder;
import org.glassfish.hk2.utilities.binding.ScopedBindingBuilder;
import org.jetbrains.annotations.NotNull;
class MultiverseCorePluginBinder extends JavaPluginBinder<MultiverseCore> {
protected MultiverseCorePluginBinder(@NotNull MultiverseCore plugin) {
super(plugin);
}
@Override
protected ScopedBindingBuilder<MultiverseCore> bindPluginClass(ScopedBindingBuilder<MultiverseCore> bindingBuilder) {
return super.bindPluginClass(bindingBuilder).to(MVCore.class).to(MultiverseCore.class);
}
}

View File

@ -9,11 +9,16 @@ package com.onarandombox.MultiverseCore.anchor;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import jakarta.inject.Inject;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jvnet.hk2.annotations.Service;
import java.io.File;
import java.io.IOException;
@ -22,18 +27,29 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
/**
* Manages anchors.
*/
@Service
public class AnchorManager {
private MultiverseCore plugin;
private Map<String, Location> anchors;
private FileConfiguration anchorConfig;
public AnchorManager(MultiverseCore plugin) {
private final Plugin plugin;
private final LocationManipulation locationManipulation;
private final MVCoreConfigProvider configProvider;
@Inject
public AnchorManager(
MultiverseCore plugin,
LocationManipulation locationManipulation,
MVCoreConfigProvider configProvider
) {
this.plugin = plugin;
this.locationManipulation = locationManipulation;
this.configProvider = configProvider;
this.anchors = new HashMap<String, Location>();
}
@ -48,7 +64,7 @@ public class AnchorManager {
Set<String> anchorKeys = anchorsSection.getKeys(false);
for (String key : anchorKeys) {
//world:x,y,z:pitch:yaw
Location anchorLocation = plugin.getLocationManipulation().stringToLocation(anchorsSection.getString(key, ""));
Location anchorLocation = this.locationManipulation.stringToLocation(anchorsSection.getString(key, ""));
if (anchorLocation != null) {
Logging.config("Loading anchor: '%s'...", key);
this.anchors.put(key, anchorLocation);
@ -98,7 +114,7 @@ public class AnchorManager {
* @return True if the anchor was successfully saved.
*/
public boolean saveAnchorLocation(String anchor, String location) {
Location parsed = plugin.getLocationManipulation().stringToLocation(location);
Location parsed = this.locationManipulation.stringToLocation(location);
return parsed != null && this.saveAnchorLocation(anchor, parsed);
}
@ -112,7 +128,7 @@ public class AnchorManager {
if (l == null) {
return false;
}
this.anchorConfig.set("anchors." + anchor, plugin.getLocationManipulation().locationToString(l));
this.anchorConfig.set("anchors." + anchor, this.locationManipulation.locationToString(l));
this.anchors.put(anchor, l);
return this.saveAnchors();
}
@ -144,8 +160,8 @@ public class AnchorManager {
// Add to the list if we're not enforcing access
// OR
// We are enforcing access and the user has the permission.
if (!this.plugin.getMVConfig().getEnforceAccess() ||
(this.plugin.getMVConfig().getEnforceAccess() && p.hasPermission(worldPerm))) {
if (!this.configProvider.getConfig().getEnforceAccess() ||
(this.configProvider.getConfig().getEnforceAccess() && p.hasPermission(worldPerm))) {
myAnchors.add(anchor);
} else {
Logging.finer(String.format("Not adding anchor %s to the list, user %s doesn't have the %s " +

View File

@ -4,10 +4,12 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
import org.jvnet.hk2.annotations.Contract;
/**
* Used to get block/location-related information.
*/
@Contract
public interface BlockSafety {
/**
* This function checks whether the block at the given coordinates are above air or not.

View File

@ -5,7 +5,9 @@ import java.util.Collection;
import co.aikar.commands.BukkitCommandIssuer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Contract;
@Contract
public interface Destination<T extends DestinationInstance> {
/**
* Returns the identifier or prefix that is required for this destination.

View File

@ -3,10 +3,12 @@ package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import org.jvnet.hk2.annotations.Contract;
/**
* Used to manipulate locations.
*/
@Contract
public interface LocationManipulation {
/**
* Convert a Location into a Colon separated string to allow us to store it in text.

View File

@ -7,29 +7,12 @@
package com.onarandombox.MultiverseCore.api;
import com.onarandombox.MultiverseCore.anchor.AnchorManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
import com.onarandombox.MultiverseCore.economy.MVEconomist;
import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety;
import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.teleportation.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
/**
* Multiverse 2 Core API
* <p>
* This API contains a bunch of useful things you can get out of Multiverse in general!
*/
public interface MVCore extends MVPlugin {
/**
* Retrieves Multiverse's friendly economist. The economist can be used for dealing with economies without
* worrying about any of the messy details.
*
* @return the economy manager for Multiverse.
*/
MVEconomist getEconomist();
/**
* Reloads the Multiverse Configuration files:
@ -37,44 +20,6 @@ public interface MVCore extends MVPlugin {
*/
void loadConfigs();
/**
* Gets the {@link UnsafeCallWrapper} class.
*
* @return A non-null {@link UnsafeCallWrapper}.
*/
UnsafeCallWrapper getUnsafeCallWrapper();
/**
* Multiverse uses an advanced permissions setup, this object
* simplifies getting/setting permissions.
*
* @return A non-null {@link MVPermissions}.
*/
MVPermissions getMVPerms();
/**
* Multiverse uses {@link MVCommandManager} to make adding and using commands
* a piece of cake.
*
* @return A non-null {@link MVCommandManager}.
*/
MVCommandManager getMVCommandManager();
/**
* Gets the class responsible for loading many different destinations
* on demand.
*
* @return A valid {@link DestinationsProvider}.
*/
DestinationsProvider getDestinationsProvider();
/**
* Gets the primary class responsible for managing Multiverse Worlds.
*
* @return {@link MVWorldManager}.
*/
MVWorldManager getMVWorldManager();
/**
* Saves the Multiverse-Config.
*
@ -89,13 +34,6 @@ public interface MVCore extends MVPlugin {
*/
boolean saveAllConfigs();
/**
* Gets the {@link AnchorManager}.
*
* @return The {@link AnchorManager}
*/
AnchorManager getAnchorManager();
/**
* Decrements the number of plugins that have specifically hooked into core.
*/
@ -112,58 +50,4 @@ public interface MVCore extends MVPlugin {
* @return The number if plugins that have hooked into core.
*/
int getPluginCount();
/**
* Gets the {@link BlockSafety} this {@link MVCore} is using.
* @return The {@link BlockSafety} this {@link MVCore} is using.
* @see BlockSafety
* @see SimpleBlockSafety
*/
BlockSafety getBlockSafety();
/**
* Sets the {@link BlockSafety} this {@link MVCore} is using.
* @param blockSafety The new {@link BlockSafety}.
* @see BlockSafety
* @see SimpleBlockSafety
*/
void setBlockSafety(BlockSafety blockSafety);
/**
* Gets the {@link LocationManipulation} this {@link MVCore} is using.
* @return The {@link LocationManipulation} this {@link MVCore} is using.
* @see LocationManipulation
* @see SimpleLocationManipulation
*/
LocationManipulation getLocationManipulation();
/**
* Sets the {@link LocationManipulation} this {@link MVCore} is using.
* @param locationManipulation The new {@link LocationManipulation}.
* @see LocationManipulation
* @see SimpleLocationManipulation
*/
void setLocationManipulation(LocationManipulation locationManipulation);
/**
* Gets the {@link SafeTTeleporter} this {@link MVCore} is using.
* @return The {@link SafeTTeleporter} this {@link MVCore} is using.
* @see SafeTTeleporter
* @see SimpleSafeTTeleporter
*/
SafeTTeleporter getSafeTTeleporter();
/**
* Sets the {@link SafeTTeleporter} this {@link MVCore} is using.
* @param safeTTeleporter The new {@link SafeTTeleporter}.
* @see SafeTTeleporter
* @see SimpleSafeTTeleporter
*/
void setSafeTTeleporter(SafeTTeleporter safeTTeleporter);
/**
* Gets the {@link MVConfig}.
* @return The configuration.
*/
MVConfig getMVConfig();
}

View File

@ -17,6 +17,7 @@ import org.bukkit.World.Environment;
import org.bukkit.WorldType;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.generator.ChunkGenerator;
import org.jvnet.hk2.annotations.Contract;
/**
* Multiverse 2 World Manager API
@ -24,6 +25,7 @@ import org.bukkit.generator.ChunkGenerator;
* This API contains all of the world managing
* functions that your heart desires!
*/
@Contract
public interface MVWorldManager {
/**
* Add a new World to the Multiverse Setup.
@ -221,15 +223,6 @@ public interface MVWorldManager {
*/
void loadDefaultWorlds();
/**
* Gets the {@link WorldPurger}.
* <p>
* @return The {@link WorldPurger} this {@link MVWorldManager} is using.
* @see WorldPurger
* @see SimpleWorldPurger
*/
WorldPurger getTheWorldPurger();
/**
* Gets the world players will spawn in on first join.
* Currently this always returns worlds.get(0) from Bukkit.

View File

@ -6,10 +6,12 @@ import com.onarandombox.MultiverseCore.teleportation.TeleportResult;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.jvnet.hk2.annotations.Contract;
/**
* Used to safely teleport people.
*/
@Contract
public interface SafeTTeleporter extends Teleporter {
/**

View File

@ -4,7 +4,9 @@ import co.aikar.commands.BukkitCommandIssuer;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import com.onarandombox.MultiverseCore.teleportation.TeleportResult;
import org.bukkit.entity.Entity;
import org.jvnet.hk2.annotations.Contract;
@Contract
public interface Teleporter {
/**
* Teleport the entity to the Multiverse Destination.

View File

@ -4,10 +4,12 @@ import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.jvnet.hk2.annotations.Contract;
/**
* Used to remove animals from worlds that don't belong there.
*/
@Contract
public interface WorldPurger {
/**
* Synchronizes the given worlds with their settings.

View File

@ -7,16 +7,26 @@ import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import jakarta.inject.Inject;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class CheckCommand extends MultiverseCoreCommand {
public CheckCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class CheckCommand extends MultiverseCommand {
private final DestinationsProvider destinationsProvider;
@Inject
public CheckCommand(@NotNull MVCommandManager commandManager, @NotNull DestinationsProvider destinationsProvider) {
super(commandManager);
this.destinationsProvider = destinationsProvider;
}
@Subcommand("check")
@ -38,6 +48,6 @@ public class CheckCommand extends MultiverseCoreCommand {
"{player}", player.getName(),
"{destination}", destination.toString());
//TODO More detailed output on permissions required.
this.plugin.getDestinationsProvider().checkTeleportPermissions(issuer, player, destination);
this.destinationsProvider.checkTeleportPermissions(issuer, player, destination);
}
}

View File

@ -9,15 +9,24 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class CloneCommand extends MultiverseCoreCommand {
public CloneCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class CloneCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public CloneCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
super(commandManager);
this.worldManager = worldManager;
}
@Subcommand("clone")
@ -42,7 +51,7 @@ public class CloneCommand extends MultiverseCoreCommand {
"{world}", worldName,
"{newWorld}", newWorldName);
if (!this.plugin.getMVWorldManager().cloneWorld(worldName, newWorldName)) {
if (!this.worldManager.cloneWorld(worldName, newWorldName)) {
issuer.sendError(MVCorei18n.CLONE_FAILED);
return;
}

View File

@ -5,19 +5,25 @@ import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class ConfirmCommand extends MultiverseCoreCommand {
public ConfirmCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class ConfirmCommand extends MultiverseCommand {
@Inject
public ConfirmCommand(@NotNull MVCommandManager commandManager) {
super(commandManager);
}
@Subcommand("confirm")
@CommandPermission("multiverse.core.confirm")
@Description("{@@mv-core.confirm.description}")
public void onConfirmCommand(@NotNull BukkitCommandIssuer issuer) {
this.plugin.getMVCommandManager().getCommandQueueManager().runQueuedCommand(issuer.getIssuer());
this.commandManager.getCommandQueueManager().runQueuedCommand(issuer.getIssuer());
}
}

View File

@ -17,22 +17,38 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlag;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag;
import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
import jakarta.inject.Inject;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldType;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class CreateCommand extends MultiverseCoreCommand {
public CreateCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class CreateCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public CreateCommand(
@NotNull MVCommandManager commandManager,
@NotNull MVWorldManager worldManager,
@NotNull UnsafeCallWrapper unsafeCallWrapper
) {
super(commandManager);
this.worldManager = worldManager;
registerFlagGroup(CommandFlagGroup.builder("mvcreate")
.add(CommandValueFlag.builder("--seed", String.class)
@ -43,7 +59,7 @@ public class CreateCommand extends MultiverseCoreCommand {
.addAlias("-g")
.completion(() -> Arrays.stream(Bukkit.getServer().getPluginManager().getPlugins())
.filter(Plugin::isEnabled)
.filter(genplugin -> this.plugin.getUnsafeCallWrapper().wrap(
.filter(genplugin -> unsafeCallWrapper.wrap(
() -> genplugin.getDefaultWorldGenerator("world", ""),
genplugin.getName(),
"Get generator"

View File

@ -9,13 +9,30 @@ import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class DebugCommand extends MultiverseCoreCommand {
public DebugCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class DebugCommand extends MultiverseCommand {
private final MVCoreConfigProvider configProvider;
private final MultiverseCore plugin;
@Inject
public DebugCommand(
@NotNull MVCommandManager commandManager,
@NotNull MVCoreConfigProvider configProvider,
@NotNull MultiverseCore plugin
) {
super(commandManager);
this.configProvider = configProvider;
this.plugin = plugin;
}
@Subcommand("debug")
@ -36,13 +53,13 @@ public class DebugCommand extends MultiverseCoreCommand {
@Description("{@@mv-core.debug.change.level.description}")
int level) {
this.plugin.getMVConfig().setGlobalDebug(level);
this.configProvider.getConfig().setGlobalDebug(level);
this.plugin.saveAllConfigs();
this.displayDebugMode(issuer);
}
private void displayDebugMode(BukkitCommandIssuer issuer) {
final int debugLevel = this.plugin.getMVConfig().getGlobalDebug();
final int debugLevel = this.configProvider.getConfig().getGlobalDebug();
if (debugLevel == 0) {
issuer.sendInfo(MVCorei18n.DEBUG_INFO_OFF);
return;

View File

@ -10,17 +10,25 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class DeleteCommand extends MultiverseCoreCommand {
public DeleteCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class DeleteCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public DeleteCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
super(commandManager);
this.worldManager = worldManager;
}
@Subcommand("delete")
@ -36,12 +44,12 @@ public class DeleteCommand extends MultiverseCoreCommand {
@Description("The world you want to delete.")
String worldName
) {
this.plugin.getMVCommandManager().getCommandQueueManager().addToQueue(new QueuedCommand(
this.commandManager.getCommandQueueManager().addToQueue(new QueuedCommand(
issuer.getIssuer(),
() -> {
issuer.sendInfo(MVCorei18n.DELETE_DELETING,
"{world}", worldName);
if (!this.plugin.getMVWorldManager().deleteWorld(worldName)) {
if (!this.worldManager.deleteWorld(worldName)) {
issuer.sendError(MVCorei18n.DELETE_FAILED,
"{world}", worldName);
return;
@ -49,7 +57,7 @@ public class DeleteCommand extends MultiverseCoreCommand {
issuer.sendInfo(MVCorei18n.DELETE_SUCCESS,
"{world}", worldName);
},
this.plugin.getMVCommandManager().formatMessage(
this.commandManager.formatMessage(
issuer,
MessageType.INFO,
MVCorei18n.DELETE_PROMPT,

View File

@ -8,18 +8,23 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.commandtools.context.GameRuleValue;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.bukkit.GameRule;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class GameruleCommand extends MultiverseCoreCommand {
public GameruleCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class GameruleCommand extends MultiverseCommand {
@Inject
public GameruleCommand(@NotNull MVCommandManager commandManager) {
super(commandManager);
}
@Subcommand("gamerule")

View File

@ -12,30 +12,43 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlag;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag;
import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
import jakarta.inject.Inject;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class ImportCommand extends MultiverseCoreCommand {
public ImportCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class ImportCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public ImportCommand(
@NotNull MVCommandManager commandManager,
@NotNull MVWorldManager worldManager,
@NotNull UnsafeCallWrapper unsafeCallWrapper
) {
super(commandManager);
this.worldManager = worldManager;
registerFlagGroup(CommandFlagGroup.builder("mvimport")
.add(CommandValueFlag.builder("--generator", String.class)
.addAlias("-g")
.completion(() -> Arrays.stream(Bukkit.getServer().getPluginManager().getPlugins())
.filter(Plugin::isEnabled)
.filter(genplugin -> this.plugin.getUnsafeCallWrapper().wrap(
.filter(genplugin -> unsafeCallWrapper.wrap(
() -> genplugin.getDefaultWorldGenerator("world", ""),
genplugin.getName(),
"Get generator"

View File

@ -9,14 +9,24 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class LoadCommand extends MultiverseCoreCommand {
public LoadCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class LoadCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public LoadCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
super(commandManager);
this.worldManager = worldManager;
}
@Subcommand("load")
@ -35,7 +45,7 @@ public class LoadCommand extends MultiverseCoreCommand {
issuer.sendInfo(MVCorei18n.LOAD_LOADING,
"{world}", worldName);
if (!this.plugin.getMVWorldManager().loadWorld(worldName)) {
if (!this.worldManager.loadWorld(worldName)) {
issuer.sendError(MVCorei18n.LOAD_FAILED,
"{world}", worldName);
return;

View File

@ -1,20 +0,0 @@
package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import org.jetbrains.annotations.NotNull;
/**
* A base command for Multiverse.
*/
abstract class MultiverseCoreCommand extends MultiverseCommand {
protected final MultiverseCore plugin;
protected final MVWorldManager worldManager;
protected MultiverseCoreCommand(@NotNull MultiverseCore plugin) {
super(plugin);
this.plugin = plugin;
this.worldManager = plugin.getMVWorldManager();
}
}

View File

@ -13,20 +13,29 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlag;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag;
import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags;
import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class RegenCommand extends MultiverseCoreCommand {
public RegenCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class RegenCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public RegenCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
super(commandManager);
this.worldManager = worldManager;
registerFlagGroup(CommandFlagGroup.builder("mvregen")
.add(CommandValueFlag.builder("--seed", String.class)
@ -59,12 +68,12 @@ public class RegenCommand extends MultiverseCoreCommand {
) {
ParsedCommandFlags parsedFlags = parseFlags(flags);
this.plugin.getMVCommandManager().getCommandQueueManager().addToQueue(new QueuedCommand(
this.commandManager.getCommandQueueManager().addToQueue(new QueuedCommand(
issuer.getIssuer(),
() -> {
issuer.sendInfo(MVCorei18n.REGEN_REGENERATING,
"{world}", worldName);
if (!this.plugin.getMVWorldManager().regenWorld(
if (!this.worldManager.regenWorld(
worldName,
parsedFlags.hasFlag("--seed"),
!parsedFlags.hasFlagValue("--seed"),
@ -78,7 +87,7 @@ public class RegenCommand extends MultiverseCoreCommand {
issuer.sendInfo(MVCorei18n.REGEN_SUCCESS,
"{world}", worldName);
},
this.plugin.getMVCommandManager().formatMessage(
this.commandManager.formatMessage(
issuer,
MessageType.INFO,
MVCorei18n.REGEN_PROMPT,

View File

@ -9,15 +9,39 @@ import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.anchor.AnchorManager;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.event.MVConfigReloadEvent;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class ReloadCommand extends MultiverseCoreCommand {
public ReloadCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class ReloadCommand extends MultiverseCommand {
private final MultiverseCore plugin;
private final AnchorManager anchorManager;
private final MVWorldManager worldManager;
private final PluginManager pluginManager;
@Inject
public ReloadCommand(
@NotNull MVCommandManager commandManager,
@NotNull MultiverseCore plugin,
@NotNull AnchorManager anchorManager,
@NotNull MVWorldManager worldManager,
@NotNull PluginManager pluginManager
) {
super(commandManager);
this.plugin = plugin;
this.anchorManager = anchorManager;
this.worldManager = worldManager;
this.pluginManager = pluginManager;
}
@Subcommand("reload")
@ -26,8 +50,8 @@ public class ReloadCommand extends MultiverseCoreCommand {
public void onReloadCommand(@NotNull BukkitCommandIssuer issuer) {
issuer.sendInfo(MVCorei18n.RELOAD_RELOADING);
this.plugin.loadConfigs();
this.plugin.getAnchorManager().loadAnchors();
this.plugin.getMVWorldManager().loadWorlds(true);
this.anchorManager.loadAnchors();
this.worldManager.loadWorlds(true);
List<String> configsLoaded = new ArrayList<>();
configsLoaded.add("Multiverse-Core - config.yml");
@ -35,7 +59,7 @@ public class ReloadCommand extends MultiverseCoreCommand {
configsLoaded.add("Multiverse-Core - anchors.yml");
MVConfigReloadEvent configReload = new MVConfigReloadEvent(configsLoaded);
this.plugin.getServer().getPluginManager().callEvent(configReload);
this.pluginManager.callEvent(configReload);
// @TODO: replace this sendMessage and format the configsLoaded above, maybe?
configReload.getAllConfigsLoaded().forEach(issuer::sendMessage);

View File

@ -9,15 +9,24 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Single;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class RemoveCommand extends MultiverseCoreCommand {
public RemoveCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class RemoveCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public RemoveCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
super(commandManager);
this.worldManager = worldManager;
}
@Subcommand("remove")
@ -33,7 +42,7 @@ public class RemoveCommand extends MultiverseCoreCommand {
@Description("{@@mv-core.remove.world.description}")
String worldName
) {
if (!this.plugin.getMVWorldManager().removeWorldFromConfig(worldName)) {
if (!this.worldManager.removeWorldFromConfig(worldName)) {
issuer.sendError(MVCorei18n.REMOVE_FAILED);
return;
}

View File

@ -3,14 +3,24 @@ package com.onarandombox.MultiverseCore.commands;
import co.aikar.commands.CommandIssuer;
import co.aikar.commands.annotation.CommandAlias;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import org.bukkit.ChatColor;
import jakarta.inject.Inject;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
public class RootCommand extends MultiverseCoreCommand {
public RootCommand(@NotNull MultiverseCore plugin) {
super(plugin);
@Service
public class RootCommand extends MultiverseCommand {
private final Plugin plugin;
@Inject
public RootCommand(@NotNull MVCommandManager commandManager, @NotNull MultiverseCore plugin) {
super(commandManager);
this.plugin = plugin;
}
@CommandAlias("mv")

View File

@ -8,15 +8,25 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import jakarta.inject.Inject;
import org.bukkit.entity.Player;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class TeleportCommand extends MultiverseCoreCommand {
public TeleportCommand(MultiverseCore plugin) {
super(plugin);
public class TeleportCommand extends MultiverseCommand {
private final DestinationsProvider destinationsProvider;
@Inject
public TeleportCommand(MVCommandManager commandManager, DestinationsProvider destinationsProvider) {
super(commandManager);
this.destinationsProvider = destinationsProvider;
}
@Subcommand("teleport|tp")
@ -39,12 +49,12 @@ public class TeleportCommand extends MultiverseCoreCommand {
issuer.sendInfo(MVCorei18n.TELEPORT_SUCCESS,
"{player}", issuer.getPlayer() == player ? "you" : player.getName(),
"{destination}", destination.toString());
this.plugin.getDestinationsProvider().playerTeleport(issuer, player, destination);
this.destinationsProvider.playerTeleport(issuer, player, destination);
}
}
@Override
public boolean hasPermission(CommandIssuer issuer) {
return this.plugin.getDestinationsProvider().hasAnyTeleportPermission(issuer);
return this.destinationsProvider.hasAnyTeleportPermission(issuer);
}
}

View File

@ -7,15 +7,25 @@ import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import com.onarandombox.MultiverseCore.utils.MVCorei18n;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class UnloadCommand extends MultiverseCoreCommand {
public UnloadCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class UnloadCommand extends MultiverseCommand {
private final MVWorldManager worldManager;
@Inject
public UnloadCommand(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
super(commandManager);
this.worldManager = worldManager;
}
@Subcommand("unload")
@ -33,7 +43,7 @@ public class UnloadCommand extends MultiverseCoreCommand {
"{world}", world.getColoredWorldString());
//TODO API: Should be able to use MVWorld object directly
if (!this.plugin.getMVWorldManager().unloadWorld(world.getName())) {
if (!this.worldManager.unloadWorld(world.getName())) {
issuer.sendError(MVCorei18n.UNLOAD_FAILURE,
"{world}", world.getColoredWorldString());
return;

View File

@ -8,13 +8,19 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.HelpCommand;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager;
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
@CommandAlias("mv")
public class UsageCommand extends MultiverseCoreCommand {
public UsageCommand(@NotNull MultiverseCore plugin) {
super(plugin);
public class UsageCommand extends MultiverseCommand {
@Inject
public UsageCommand(@NotNull MVCommandManager commandManager) {
super(commandManager);
}
@HelpCommand
@ -28,6 +34,6 @@ public class UsageCommand extends MultiverseCoreCommand {
// Prevent flooding the chat
help.setPerPage(4);
}
this.plugin.getMVCommandManager().showUsage(help);
this.commandManager.showUsage(help);
}
}

View File

@ -16,24 +16,33 @@ import co.aikar.commands.PaperCommandCompletions;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.RootCommand;
import com.google.common.collect.Sets;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.configuration.MVConfigNodes;
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import jakarta.inject.Inject;
import org.bukkit.GameRule;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
@Service
public class MVCommandCompletions extends PaperCommandCompletions {
protected final MVCommandManager commandManager;
private final MultiverseCore plugin;
private final MVWorldManager worldManager;
public MVCommandCompletions(MVCommandManager mvCommandManager, MultiverseCore plugin) {
protected final MVCommandManager commandManager;
private final MVWorldManager worldManager;
private final DestinationsProvider destinationsProvider;
@Inject
public MVCommandCompletions(
@NotNull MVCommandManager mvCommandManager,
@NotNull MVWorldManager worldManager,
@NotNull DestinationsProvider destinationsProvider
) {
super(mvCommandManager);
this.commandManager = mvCommandManager;
this.plugin = plugin;
this.worldManager = plugin.getMVWorldManager();
this.worldManager = worldManager;
this.destinationsProvider = destinationsProvider;
registerAsyncCompletion("commands", this::suggestCommands);
registerAsyncCompletion("destinations", this::suggestDestinations);
@ -54,7 +63,7 @@ public class MVCommandCompletions extends PaperCommandCompletions {
return Collections.emptyList();
}
RootCommand rootCommand = this.plugin.getMVCommandManager().getRegisteredRootCommands().stream()
RootCommand rootCommand = this.commandManager.getRegisteredRootCommands().stream()
.unordered()
.filter(c -> c.getCommandName().equals(rootCmdName))
.findFirst()
@ -72,7 +81,7 @@ public class MVCommandCompletions extends PaperCommandCompletions {
}
private boolean checkPerms(CommandIssuer issuer, RegisteredCommand<?> command) {
return this.plugin.getMVCommandManager().hasPermission(issuer, command.getRequiredPermissions());
return this.commandManager.hasPermission(issuer, command.getRequiredPermissions());
}
private Collection<String> suggestDestinations(BukkitCommandCompletionContext context) {
@ -80,7 +89,7 @@ public class MVCommandCompletions extends PaperCommandCompletions {
return Collections.emptyList();
}
return this.plugin.getDestinationsProvider()
return this.destinationsProvider
.suggestDestinations((BukkitCommandIssuer)context.getIssuer(), context.getInput());
}

View File

@ -6,21 +6,26 @@ import co.aikar.commands.BukkitConditionContext;
import co.aikar.commands.CommandConditions;
import co.aikar.commands.ConditionContext;
import co.aikar.commands.ConditionFailedException;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.world.WorldNameChecker;
import jakarta.annotation.PostConstruct;
import org.jetbrains.annotations.NotNull;
public class MVCommandConditions {
static void load(MVCommandManager commandManager, MultiverseCore plugin) {
new MVCommandConditions(commandManager, plugin);
static void load(MVCommandManager commandManager, MVWorldManager worldManager) {
new MVCommandConditions(commandManager, worldManager);
}
private final MVWorldManager worldManager;
private final MVCommandManager commandManager;
private final MultiverseCore plugin;
public MVCommandConditions(MVCommandManager commandManager, MultiverseCore plugin) {
private MVCommandConditions(@NotNull MVCommandManager commandManager, @NotNull MVWorldManager worldManager) {
this.worldManager = worldManager;
this.commandManager = commandManager;
this.plugin = plugin;
}
@PostConstruct
private void registerConditions() {
CommandConditions<BukkitCommandIssuer, BukkitCommandExecutionContext, BukkitConditionContext> conditions
= commandManager.getCommandConditions();
@ -36,14 +41,14 @@ public class MVCommandConditions {
switch (scope) {
// Worlds that are loaded
case "loaded":
if (!this.plugin.getMVWorldManager().isMVWorld(worldName)) {
if (!this.worldManager.isMVWorld(worldName)) {
throw new ConditionFailedException("World with name '" + worldName + "' does not exist or is not loaded!");
}
break;
// Worlds that are unloaded
case "unloaded":
if (!this.plugin.getMVWorldManager().hasUnloadedWorld(worldName, false)) {
if (this.plugin.getMVWorldManager().isMVWorld(worldName)) {
if (!this.worldManager.hasUnloadedWorld(worldName, false)) {
if (this.worldManager.isMVWorld(worldName)) {
throw new ConditionFailedException("World with name '" + worldName + "' is loaded already!");
}
throw new ConditionFailedException("World with name '" + worldName + "' does not exist!");
@ -51,13 +56,13 @@ public class MVCommandConditions {
break;
// World that are loaded or unloaded
case "both":
if (!this.plugin.getMVWorldManager().hasUnloadedWorld(worldName, true)) {
if (!this.worldManager.hasUnloadedWorld(worldName, true)) {
throw new ConditionFailedException("World with name '" + worldName + "' does not exist!");
}
break;
// World that are does not exist
case "new":
if (this.plugin.getMVWorldManager().hasUnloadedWorld(worldName, true)) {
if (this.worldManager.hasUnloadedWorld(worldName, true)) {
throw new ConditionFailedException("World with name '" + worldName + "' already exists!");
}
switch (WorldNameChecker.checkName(worldName)) {

View File

@ -12,9 +12,11 @@ import co.aikar.commands.contexts.ContextResolver;
import com.google.common.base.Strings;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.context.GameRuleValue;
import com.onarandombox.MultiverseCore.commandtools.context.MVConfigValue;
import com.onarandombox.MultiverseCore.configuration.MVConfigNodes;
import com.onarandombox.MultiverseCore.destination.DestinationsProvider;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import com.onarandombox.MultiverseCore.display.filters.ContentFilter;
import com.onarandombox.MultiverseCore.display.filters.DefaultContentFilter;
@ -23,15 +25,26 @@ import com.onarandombox.MultiverseCore.utils.PlayerFinder;
import io.github.townyadvanced.commentedconfiguration.setting.CommentedNode;
import io.github.townyadvanced.commentedconfiguration.setting.TypedValueNode;
import io.github.townyadvanced.commentedconfiguration.setting.ValueNode;
import jakarta.inject.Inject;
import org.bukkit.GameRule;
import org.bukkit.entity.Player;
import org.jvnet.hk2.annotations.Service;
@Service
public class MVCommandContexts extends PaperCommandContexts {
private final MultiverseCore plugin;
public MVCommandContexts(MVCommandManager mvCommandManager, MultiverseCore plugin) {
private final DestinationsProvider destinationsProvider;
private final MVWorldManager worldManager;
@Inject
public MVCommandContexts(
MVCommandManager mvCommandManager,
DestinationsProvider destinationsProvider,
MVWorldManager worldManager
) {
super(mvCommandManager);
this.plugin = plugin;
this.destinationsProvider = destinationsProvider;
this.worldManager = worldManager;
registerIssuerOnlyContext(BukkitCommandIssuer.class, BukkitCommandExecutionContext::getIssuer);
registerOptionalContext(ContentFilter.class, this::parseContentFilter);
@ -59,7 +72,7 @@ public class MVCommandContexts extends PaperCommandContexts {
throw new InvalidCommandArgument("No destination specified.");
}
ParsedDestination<?> parsedDestination = plugin.getDestinationsProvider().parseDestination(destination);
ParsedDestination<?> parsedDestination = destinationsProvider.parseDestination(destination);
if (parsedDestination == null) {
throw new InvalidCommandArgument("The destination " + destination + " is not valid.");
}
@ -143,7 +156,7 @@ public class MVCommandContexts extends PaperCommandContexts {
// Get world based on sender only
if (resolve.equals("issuerOnly")) {
if (context.getIssuer().isPlayer()) {
return plugin.getMVWorldManager().getMVWorld(context.getIssuer().getPlayer().getWorld());
return worldManager.getMVWorld(context.getIssuer().getPlayer().getWorld());
}
if (context.isOptional()) {
return null;
@ -152,7 +165,7 @@ public class MVCommandContexts extends PaperCommandContexts {
}
String worldName = context.getFirstArg();
MVWorld world = plugin.getMVWorldManager().getMVWorld(worldName);
MVWorld world = worldManager.getMVWorld(worldName);
// Get world based on input, fallback to sender if input is not a world
if (resolve.equals("issuerAware")) {
@ -161,7 +174,7 @@ public class MVCommandContexts extends PaperCommandContexts {
return world;
}
if (context.getIssuer().isPlayer()) {
return plugin.getMVWorldManager().getMVWorld(context.getIssuer().getPlayer().getWorld());
return worldManager.getMVWorld(context.getIssuer().getPlayer().getWorld());
}
if (context.isOptional()) {
return null;
@ -185,7 +198,7 @@ public class MVCommandContexts extends PaperCommandContexts {
MVWorld playerWorld = null;
if (context.getIssuer().isPlayer()) {
playerWorld = plugin.getMVWorldManager().getMVWorld(context.getIssuer().getPlayer().getWorld());
playerWorld = worldManager.getMVWorld(context.getIssuer().getPlayer().getWorld());
}
// Get world based on sender only
@ -204,10 +217,10 @@ public class MVCommandContexts extends PaperCommandContexts {
Set<MVWorld> worlds = new HashSet<>(worldNames.length);
for (String worldName : worldNames) {
if ("*".equals(worldName)) {
worlds.addAll(plugin.getMVWorldManager().getMVWorlds());
worlds.addAll(worldManager.getMVWorlds());
break;
}
MVWorld world = plugin.getMVWorldManager().getMVWorld(worldName);
MVWorld world = worldManager.getMVWorld(worldName);
if (world == null) {
throw new InvalidCommandArgument("World " + worldName + " is not a loaded multiverse world.");
}

View File

@ -10,26 +10,42 @@ import co.aikar.commands.CommandHelp;
import co.aikar.commands.HelpEntry;
import co.aikar.commands.PaperCommandManager;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagsManager;
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
/**
* Main class to manage permissions.
*/
@Service
public class MVCommandManager extends PaperCommandManager {
private final MultiverseCore plugin;
private CommandFlagsManager flagsManager;
private CommandQueueManager commandQueueManager;
private final CommandFlagsManager flagsManager;
private final CommandQueueManager commandQueueManager;
private final Provider<MVCommandContexts> commandContextsProvider;
private final Provider<MVCommandCompletions> commandCompletionsProvider;
private PluginLocales pluginLocales;
public MVCommandManager(@NotNull MultiverseCore plugin) {
@Inject
public MVCommandManager(
@NotNull MultiverseCore plugin,
@NotNull CommandFlagsManager flagsManager,
@NotNull CommandQueueManager commandQueueManager,
@NotNull Provider<MVCommandContexts> commandContextsProvider,
@NotNull Provider<MVCommandCompletions> commandCompletionsProvider,
@NotNull MVWorldManager worldManager
) {
super(plugin);
this.plugin = plugin;
this.flagsManager = flagsManager;
this.commandQueueManager = commandQueueManager;
this.commandContextsProvider = commandContextsProvider;
this.commandCompletionsProvider = commandCompletionsProvider;
// Setup conditions
MVCommandConditions.load(this, plugin);
MVCommandConditions.load(this, worldManager);
}
/**
@ -38,9 +54,6 @@ public class MVCommandManager extends PaperCommandManager {
* @return A not-null {@link CommandFlagsManager}.
*/
public synchronized @NotNull CommandFlagsManager getFlagsManager() {
if (this.flagsManager == null) {
this.flagsManager = new CommandFlagsManager();
}
return flagsManager;
}
@ -65,9 +78,6 @@ public class MVCommandManager extends PaperCommandManager {
* @return A non-null {@link CommandQueueManager}.
*/
public synchronized @NotNull CommandQueueManager getCommandQueueManager() {
if (this.commandQueueManager == null) {
this.commandQueueManager = new CommandQueueManager(this.plugin);
}
return commandQueueManager;
}
@ -79,7 +89,7 @@ public class MVCommandManager extends PaperCommandManager {
@Override
public synchronized @NotNull CommandContexts<BukkitCommandExecutionContext> getCommandContexts() {
if (this.contexts == null) {
this.contexts = new MVCommandContexts(this, plugin);
this.contexts = commandContextsProvider.get();
}
return this.contexts;
}
@ -92,7 +102,7 @@ public class MVCommandManager extends PaperCommandManager {
@Override
public synchronized @NotNull CommandCompletions<BukkitCommandCompletionContext> getCommandCompletions() {
if (this.completions == null) {
this.completions = new MVCommandCompletions(this, plugin);
this.completions = commandCompletionsProvider.get();
}
return this.completions;
}
@ -105,7 +115,7 @@ public class MVCommandManager extends PaperCommandManager {
public void showUsage(@NotNull CommandHelp help) {
List<HelpEntry> entries = help.getHelpEntries();
if (entries.size() == 1) {
this.plugin.getMVCommandManager().getHelpFormatter().showDetailedHelp(help, entries.get(0));
getHelpFormatter().showDetailedHelp(help, entries.get(0));
return;
}
help.showHelp();

View File

@ -1,29 +1,35 @@
package com.onarandombox.MultiverseCore.commandtools;
import co.aikar.commands.BaseCommand;
import com.onarandombox.MultiverseCore.api.MVPlugin;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup;
import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagsManager;
import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Contract;
@Contract
public abstract class MultiverseCommand extends BaseCommand {
protected final CommandFlagsManager flagsManager;
protected final MVCommandManager commandManager;
private String flagGroupName;
protected MultiverseCommand(@NotNull MVPlugin plugin) {
this.flagsManager = plugin.getCore().getMVCommandManager().getFlagsManager();
protected MultiverseCommand(@NotNull MVCommandManager commandManager) {
this.commandManager = commandManager;
}
protected CommandFlagsManager getFlagsManager() {
return commandManager.getFlagsManager();
}
protected void registerFlagGroup(@NotNull CommandFlagGroup flagGroup) {
if (flagGroupName != null) {
throw new IllegalStateException("Flag group already registered! (name: " + flagGroupName + ")");
}
flagsManager.registerFlagGroup(flagGroup);
getFlagsManager().registerFlagGroup(flagGroup);
flagGroupName = flagGroup.getName();
}
protected @NotNull ParsedCommandFlags parseFlags(@NotNull String[] flags) {
return flagsManager.parse(flagGroupName, flags);
return getFlagsManager().parse(flagGroupName, flags);
}
}

View File

@ -9,10 +9,12 @@ import java.util.Map;
import co.aikar.commands.InvalidCommandArgument;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
/**
* Manages all the flag groups and parsing.
*/
@Service
public class CommandFlagsManager {
private final Map<String, CommandFlagGroup> flagGroupMap;

View File

@ -12,13 +12,16 @@ import java.util.WeakHashMap;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import jakarta.inject.Inject;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.block.data.type.CommandBlock;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
/**
* <p>Manages the queuing of dangerous commands that require {@code /mv confirm} before executing.</p>
@ -26,14 +29,16 @@ import org.jetbrains.annotations.NotNull;
* <p>Each sender can only have one command in queue at any given time. When a queued command is added
* for a sender that already has a command in queue, it will replace the old queued command.</p>
*/
@Service
public class CommandQueueManager {
private static final long TICKS_PER_SECOND = 20;
private static final DummyCommandBlockSender COMMAND_BLOCK = new DummyCommandBlockSender();
private final MultiverseCore plugin;
private final Plugin plugin;
private final Map<CommandSender, QueuedCommand> queuedCommandMap;
@Inject
public CommandQueueManager(@NotNull MultiverseCore plugin) {
this.plugin = plugin;
this.queuedCommandMap = new WeakHashMap<>();

View File

@ -0,0 +1,140 @@
package com.onarandombox.MultiverseCore.config;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.MultiverseCoreConfiguration;
import com.onarandombox.MultiverseCore.api.MVConfig;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
import io.vavr.control.Option;
import io.vavr.control.Try;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
@Service
public final class MVCoreConfigProvider {
private static final String CONFIG_FILE = "config.yml";
private static final String DEFAULTS_CONFIG_FILE = "/defaults/config.yml";
private static final String WORLDS_CONFIG_FILE = "worlds.yml";
private static final String CHARACTER_ENCODING = "UTF-8";
private static final String CONFIG_KEY = "multiverse-configuration";
private FileConfiguration multiverseConfig;
private volatile MultiverseCoreConfiguration config;
private final Plugin plugin;
private final PluginManager pluginManager;
private final Provider<MVWorldManager> worldManagerProvider; // TODO remove this dependency
@Inject
MVCoreConfigProvider(
MultiverseCore plugin,
PluginManager pluginManager,
Provider<MVWorldManager> worldManagerProvider
) {
this.plugin = plugin;
this.pluginManager = pluginManager;
this.worldManagerProvider = worldManagerProvider;
}
/**
* Checks if the config is loaded.
*
* @return True if the config is loaded, false otherwise
*/
public boolean isConfigLoaded() {
return config != null;
}
/**
* Gets the Core configuration instance.
*
* @return The config
* @throws IllegalStateException If the config is not loaded
*/
@NotNull
public MVConfig getConfig() throws IllegalStateException {
if (config == null) {
throw new IllegalStateException("Config is not loaded");
}
return config;
}
public void loadConfigs() {
multiverseConfig = loadConfigWithDefaults();
setConfigOptions(multiverseConfig);
config = getOrCreateConfigObject(multiverseConfig);
loadWorldConfigs();
setDebugLevelFromConfig(config);
}
@NotNull
private FileConfiguration loadConfigWithDefaults() {
var config = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), CONFIG_FILE));
Option.of(plugin.getClass().getResourceAsStream(DEFAULTS_CONFIG_FILE))
.toTry()
.mapTry(defaultsStream -> YamlConfiguration.loadConfiguration(
new BufferedReader(new InputStreamReader(defaultsStream, CHARACTER_ENCODING))))
.andThen(config::setDefaults)
.onFailure(e -> {
Logging.severe("Couldn't load default config with UTF-8 encoding. Details follow:");
e.printStackTrace();
Logging.severe("Default configs NOT loaded.");
});
return config;
}
private void setConfigOptions(@NotNull FileConfiguration config) {
config.options().copyDefaults(false);
config.options().copyHeader(true);
}
@NotNull
private MultiverseCoreConfiguration getOrCreateConfigObject(@NotNull FileConfiguration config) {
return Try.of(() -> (MultiverseCoreConfiguration) config.get(CONFIG_KEY))
.toOption() // Ignore exceptions
.map(c -> c == null ? new MultiverseCoreConfiguration() : c)
.getOrElse(new MultiverseCoreConfiguration());
}
private void loadWorldConfigs() {
worldManagerProvider.get().loadWorldConfig(new File(plugin.getDataFolder(), WORLDS_CONFIG_FILE));
}
private void setDebugLevelFromConfig(@NotNull MVConfig config) {
int level = Logging.getDebugLevel();
Logging.setDebugLevel(config.getGlobalDebug());
if (level != Logging.getDebugLevel()) {
pluginManager.callEvent(new MVDebugModeEvent(level));
}
}
@NotNull
public Try<Void> saveConfig() {
try {
this.multiverseConfig.set(CONFIG_KEY, config);
this.multiverseConfig.save(new File(plugin.getDataFolder(), CONFIG_FILE));
return Try.success(null);
} catch (IOException e) {
return Try.failure(new MultiverseConfigurationException(
"Could not save Multiverse config.yml config. Please check your file permissions.", e));
}
}
}

View File

@ -0,0 +1,9 @@
package com.onarandombox.MultiverseCore.config;
import java.io.IOException;
public class MultiverseConfigurationException extends IOException {
public MultiverseConfigurationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -10,31 +10,37 @@ import co.aikar.commands.CommandIssuer;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Destination;
import com.onarandombox.MultiverseCore.api.DestinationInstance;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.Teleporter;
import jakarta.inject.Inject;
import org.bukkit.Server;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
/**
* Provides destinations for teleportation.
*/
@Service
public class DestinationsProvider {
private static final String SEPARATOR = ":";
private static final String PERMISSION_PREFIX = "multiverse.teleport.";
private final MultiverseCore plugin;
private final PluginManager pluginManager;
private final SafeTTeleporter safeTTeleporter;
private final Map<String, Destination<?>> destinationMap;
/**
* Creates a new destinations provider.
*
* @param plugin The plugin.
*/
public DestinationsProvider(@NotNull MultiverseCore plugin) {
this.plugin = plugin;
@Inject
public DestinationsProvider(@NotNull PluginManager pluginManager, @NotNull SafeTTeleporter safeTTeleporter) {
this.pluginManager = pluginManager;
this.safeTTeleporter = safeTTeleporter;
this.destinationMap = new HashMap<>();
}
@ -49,7 +55,6 @@ public class DestinationsProvider {
}
private void registerDestinationPerms(@NotNull Destination<?> destination) {
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
pluginManager.addPermission(new Permission(PERMISSION_PREFIX + "self." + destination.getIdentifier()));
pluginManager.addPermission(new Permission(PERMISSION_PREFIX + "other." + destination.getIdentifier()));
}
@ -148,7 +153,7 @@ public class DestinationsProvider {
) {
Teleporter teleportHandler = destination.getDestination().getTeleporter();
if (teleportHandler == null) {
teleportHandler = this.plugin.getSafeTTeleporter();
teleportHandler = safeTTeleporter;
}
teleportHandler.teleport(teleporter, teleportee, destination);
}

View File

@ -3,23 +3,23 @@ package com.onarandombox.MultiverseCore.destination.core;
import java.util.Collection;
import co.aikar.commands.BukkitCommandIssuer;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.anchor.AnchorManager;
import com.onarandombox.MultiverseCore.api.Destination;
import com.onarandombox.MultiverseCore.api.Teleporter;
import jakarta.inject.Inject;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class AnchorDestination implements Destination<AnchorDestinationInstance> {
private final MultiverseCore plugin;
/**
* Constructor.
*
* @param plugin The MultiverseCore plugin.
*/
public AnchorDestination(MultiverseCore plugin) {
this.plugin = plugin;
private final AnchorManager anchorManager;
@Inject
public AnchorDestination(AnchorManager anchorManager) {
this.anchorManager = anchorManager;
}
/**
@ -35,7 +35,7 @@ public class AnchorDestination implements Destination<AnchorDestinationInstance>
*/
@Override
public @Nullable AnchorDestinationInstance getDestinationInstance(@Nullable String destinationParams) {
Location anchorLocation = this.plugin.getAnchorManager().getAnchorLocation(destinationParams);
Location anchorLocation = this.anchorManager.getAnchorLocation(destinationParams);
if (anchorLocation == null) {
return null;
}
@ -47,7 +47,7 @@ public class AnchorDestination implements Destination<AnchorDestinationInstance>
*/
@Override
public @NotNull Collection<String> suggestDestinations(@NotNull BukkitCommandIssuer issuer, @Nullable String destinationParams) {
return this.plugin.getAnchorManager().getAnchors(issuer.getPlayer());
return this.anchorManager.getAnchors(issuer.getPlayer());
}
/**

View File

@ -12,7 +12,9 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class BedDestination implements Destination<BedDestinationInstance> {
public static final String OWN_BED_STRING = "playerbed";

View File

@ -4,24 +4,24 @@ import java.util.Collection;
import java.util.Collections;
import co.aikar.commands.BukkitCommandIssuer;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Destination;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.Teleporter;
import jakarta.inject.Inject;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class CannonDestination implements Destination<CannonDestinationInstance> {
private final MultiverseCore plugin;
/**
* Constructor.
*
* @param plugin The MultiverseCore plugin.
*/
public CannonDestination(MultiverseCore plugin) {
this.plugin = plugin;
private final MVWorldManager worldManager;
@Inject
public CannonDestination(MVWorldManager worldManager) {
this.worldManager = worldManager;
}
/**
@ -53,7 +53,7 @@ public class CannonDestination implements Destination<CannonDestinationInstance>
return null;
}
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(worldName);
MVWorld world = this.worldManager.getMVWorld(worldName);
if (world == null) {
return null;
}

View File

@ -4,24 +4,24 @@ import java.util.Collection;
import java.util.Collections;
import co.aikar.commands.BukkitCommandIssuer;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Destination;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.Teleporter;
import jakarta.inject.Inject;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class ExactDestination implements Destination<ExactDestinationInstance> {
private final MultiverseCore plugin;
/**
* Constructor.
*
* @param plugin The MultiverseCore plugin.
*/
public ExactDestination(MultiverseCore plugin) {
this.plugin = plugin;
private final MVWorldManager worldManager;
@Inject
public ExactDestination(MVWorldManager worldManager) {
this.worldManager = worldManager;
}
/**
@ -49,7 +49,7 @@ public class ExactDestination implements Destination<ExactDestinationInstance> {
return null;
}
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(worldName);
MVWorld world = this.worldManager.getMVWorld(worldName);
if (world == null) {
return null;
}

View File

@ -11,7 +11,9 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class PlayerDestination implements Destination<PlayerDestinationInstance> {
/**
* Creates a new instance of the PlayerDestination.

View File

@ -4,24 +4,26 @@ import java.util.Collection;
import java.util.Collections;
import co.aikar.commands.BukkitCommandIssuer;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Destination;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.Teleporter;
import jakarta.inject.Inject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class WorldDestination implements Destination<WorldDestinationInstance> {
private final MultiverseCore plugin;
private final MVWorldManager worldManager;
private final LocationManipulation locationManipulation;
/**
* Constructor.
*
* @param plugin The MultiverseCore plugin.
*/
public WorldDestination(MultiverseCore plugin) {
this.plugin = plugin;
@Inject
public WorldDestination(MVWorldManager worldManager, LocationManipulation locationManipulation) {
this.worldManager = worldManager;
this.locationManipulation = locationManipulation;
}
/**
@ -43,13 +45,13 @@ public class WorldDestination implements Destination<WorldDestinationInstance> {
}
String worldName = items[0];
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(worldName);
MVWorld world = this.worldManager.getMVWorld(worldName);
if (world == null) {
return null;
}
String direction = (items.length == 2) ? items[1] : null;
float yaw = direction != null ? this.plugin.getLocationManipulation().getYaw(direction) : -1;
float yaw = direction != null ? this.locationManipulation.getYaw(direction) : -1;
return new WorldDestinationInstance(world, direction, yaw);
}

View File

@ -1,18 +1,22 @@
package com.onarandombox.MultiverseCore.economy;
import jakarta.inject.Inject;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's Friendly Economist. This is used to deal with external economies and also item costs for stuff in MV.
*/
@Service
public class MVEconomist {
private final VaultHandler vaultHandler;
@Inject
public MVEconomist(Plugin plugin) {
vaultHandler = new VaultHandler(plugin);
}

View File

@ -0,0 +1,7 @@
package com.onarandombox.MultiverseCore.inject;
import org.bukkit.event.Listener;
import org.jvnet.hk2.annotations.Contract;
@Contract
public interface InjectableListener extends Listener { }

View File

@ -0,0 +1,126 @@
package com.onarandombox.MultiverseCore.inject;
import com.onarandombox.MultiverseCore.inject.binder.JavaPluginBinder;
import com.onarandombox.MultiverseCore.inject.binder.PluginBinder;
import com.onarandombox.MultiverseCore.inject.binder.ServerBinder;
import io.vavr.control.Try;
import org.bukkit.plugin.Plugin;
import org.glassfish.hk2.api.DynamicConfigurationService;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.ServiceLocatorFactory;
import org.glassfish.hk2.internal.ServiceLocatorFactoryImpl;
import org.glassfish.hk2.utilities.ClasspathDescriptorFileFinder;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
import org.jetbrains.annotations.NotNull;
/**
* Provides methods to set up dependency injection for plugins.
* <br/>
* This class is a wrapper around the HK2 dependency injection library. It provides methods to create a service locators
* for plugins and to perform injection tasks on plugin instances on enable and disable.
*/
public final class PluginInjection {
/**
* Creates a {@link ServiceLocator} for the given plugin binder.
* <br/>
* The service locator is populated with the plugin instance and all dependencies that are bound in the
* {@link PluginBinder} of the plugin. Plugins must implement their own {@link PluginBinder} to use this class.
* {@link JavaPluginBinder} is provided as a convenience for plugins that extend
* {@link org.bukkit.plugin.java.JavaPlugin}.
*
* @param pluginBinder The plugin binder for the plugin.
* @return
*/
@NotNull
public static Try<ServiceLocator> createServiceLocator(@NotNull PluginBinder<?> pluginBinder) {
var factory = new ServiceLocatorFactoryImpl();
return createSystemServiceLocator(factory)
.flatMap(systemLocator -> createServerServiceLocator(factory, systemLocator))
.flatMap(serverLocator -> new PluginInjection(pluginBinder, factory, serverLocator).load());
}
/**
* Performs necessary steps to enable dependency injection for the given plugin.
* <br/>
* This method will inject all dependencies into the plugin instance and call the {@code @PostConstruct} methods.
*
* @param plugin The plugin to enable dependency injection for.
* @param pluginServiceLocator The service locator for the plugin.
*/
public static void enable(@NotNull Plugin plugin, @NotNull ServiceLocator pluginServiceLocator) {
pluginServiceLocator.inject(plugin);
pluginServiceLocator.postConstruct(plugin);
}
/**
* Performs necessary steps to disable dependency injection for the given plugin.
* <br/>
* This method will call the {@code @PreDestroy} methods and shutdown the service locator.
*
* @param plugin The plugin to disable dependency injection for.
* @param pluginServiceLocator The service locator for the plugin.
*/
public static void disable(@NotNull Plugin plugin, @NotNull ServiceLocator pluginServiceLocator) {
pluginServiceLocator.preDestroy(plugin);
pluginServiceLocator.shutdown();
}
private final PluginBinder<?> pluginBinder;
private final Plugin plugin;
private final ServiceLocator pluginServiceLocator;
private PluginInjection(
@NotNull PluginBinder<?> pluginBinder,
@NotNull ServiceLocatorFactory serviceLocatorFactory,
@NotNull ServiceLocator serverServiceLocator
) {
this.pluginBinder = pluginBinder;
plugin = pluginBinder.getPlugin();
pluginServiceLocator = serviceLocatorFactory.create(plugin.getName(), serverServiceLocator);
}
private Try<ServiceLocator> load() {
return Try.runRunnable(() -> ServiceLocatorUtilities.bind(pluginServiceLocator, pluginBinder))
.flatMap(ignored -> populatePluginServiceLocator(pluginServiceLocator, plugin));
}
@NotNull
private static Try<ServiceLocator> createServerServiceLocator(
@NotNull ServiceLocatorFactory serviceLocatorFactory,
@NotNull ServiceLocator systemServiceLocator
) {
return Try.of(() -> serviceLocatorFactory.create("server", systemServiceLocator))
.andThenTry(locator -> ServiceLocatorUtilities.bind(locator, new ServerBinder()));
}
@NotNull
private static Try<ServiceLocator> createSystemServiceLocator(
@NotNull ServiceLocatorFactory serviceLocatorFactory
) {
ServiceLocator serviceLocator = serviceLocatorFactory.create("system");
return Try.of(() -> serviceLocator.getService(DynamicConfigurationService.class))
.mapTry(dynamicConfigurationService -> {
dynamicConfigurationService.getPopulator().populate();
return serviceLocator;
});
}
@NotNull
private static Try<ServiceLocator> populatePluginServiceLocator(
@NotNull ServiceLocator serviceLocator,
@NotNull Plugin plugin
) {
return Try.of(() -> serviceLocator.getService(DynamicConfigurationService.class))
.mapTry(dynamicConfigurationService -> {
dynamicConfigurationService
.getPopulator()
.populate(new ClasspathDescriptorFileFinder(
plugin.getClass().getClassLoader(),
plugin.getName()));
return serviceLocator;
});
}
}

View File

@ -0,0 +1,22 @@
package com.onarandombox.MultiverseCore.inject.binder;
import org.bukkit.plugin.java.JavaPlugin;
import org.glassfish.hk2.utilities.binding.ScopedBindingBuilder;
import org.jetbrains.annotations.NotNull;
/**
* A base class for java plugin binders. Binds the plugin to the {@link JavaPlugin} interface.
*
* @param <T> The type of the plugin.
*/
public abstract class JavaPluginBinder<T extends JavaPlugin> extends PluginBinder<T> {
protected JavaPluginBinder(@NotNull T plugin) {
super(plugin);
}
@Override
protected ScopedBindingBuilder<T> bindPluginClass(ScopedBindingBuilder<T> bindingBuilder) {
return bindingBuilder.to(JavaPlugin.class);
}
}

View File

@ -0,0 +1,41 @@
package com.onarandombox.MultiverseCore.inject.binder;
import org.bukkit.plugin.Plugin;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.hk2.utilities.binding.ScopedBindingBuilder;
import org.jetbrains.annotations.NotNull;
import java.util.logging.Logger;
/**
* The base class for all plugin binders. Initiates the binding of the plugin instance and initially binds it to the
* {@link Plugin} interface.
*
* @param <T> The type of the plugin.
*/
public abstract class PluginBinder<T extends Plugin> extends AbstractBinder {
private final T plugin;
protected PluginBinder(@NotNull T plugin) {
this.plugin = plugin;
}
@NotNull
public T getPlugin() {
return plugin;
}
@Override
protected final void configure() {
var bindingBuilder = bindPlugin(getPlugin());
bindingBuilder.to(Plugin.class);
bind(plugin.getLogger()).to(Logger.class);
}
private ScopedBindingBuilder<T> bindPlugin(T plugin) {
return bind(plugin);
}
protected abstract ScopedBindingBuilder<T> bindPluginClass(ScopedBindingBuilder<T> bindingBuilder);
}

View File

@ -0,0 +1,18 @@
package com.onarandombox.MultiverseCore.inject.binder;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.plugin.PluginManager;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
/**
* Binds the Bukkit {@link Server} and it's associated services we make use of in Multiverse.
*/
public class ServerBinder extends AbstractBinder {
@Override
protected void configure() {
bind(Bukkit.getServer()).to(Server.class);
bind(Bukkit.getPluginManager()).to(PluginManager.class);
}
}

View File

@ -1,25 +1,33 @@
package com.onarandombox.MultiverseCore.listeners;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import jakarta.inject.Inject;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's {@link org.bukkit.event.Listener} for players.
* Multiverse's Listener for players.
*/
public class MVChatListener implements Listener {
private final MultiverseCore plugin;
@Service
public class MVChatListener implements InjectableListener {
private final MVCoreConfigProvider configProvider;
private final MVWorldManager worldManager;
private final MVPlayerListener playerListener;
public MVChatListener(MultiverseCore plugin, MVPlayerListener playerListener) {
this.plugin = plugin;
this.worldManager = plugin.getMVWorldManager();
@Inject
public MVChatListener(
MVCoreConfigProvider configProvider,
MVWorldManager worldManager,
MVPlayerListener playerListener
) {
this.configProvider = configProvider;
this.worldManager = worldManager;
this.playerListener = playerListener;
}
@ -34,7 +42,7 @@ public class MVChatListener implements Listener {
}
// Check whether the Server is set to prefix the chat with the World name.
// If not we do nothing, if so we need to check if the World has an Alias.
if (plugin.getMVConfig().isEnablePrefixChat()) {
if (configProvider.getConfig().isEnablePrefixChat()) {
String world = playerListener.getPlayerWorld().get(event.getPlayer().getName());
if (world == null) {
world = event.getPlayer().getWorld().getName();
@ -52,7 +60,7 @@ public class MVChatListener implements Listener {
prefix = mvworld.getColoredWorldString();
String chat = event.getFormat();
String prefixChatFormat = plugin.getMVConfig().getPrefixChatFormat();
String prefixChatFormat = configProvider.getConfig().getPrefixChatFormat();
prefixChatFormat = prefixChatFormat.replace("%world%", prefix).replace("%chat%", chat);
prefixChatFormat = ChatColor.translateAlternateColorCodes('&', prefixChatFormat);

View File

@ -8,9 +8,12 @@
package com.onarandombox.MultiverseCore.listeners;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import jakarta.inject.Inject;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -22,17 +25,27 @@ import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.jetbrains.annotations.NotNull;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's Entity {@link Listener}.
*/
public class MVEntityListener implements Listener {
private MultiverseCore plugin;
private MVWorldManager worldManager;
@Service
public class MVEntityListener implements InjectableListener {
private final MVCoreConfigProvider configProvider;
private final MVWorldManager worldManager;
private final WorldPurger worldPurger;
public MVEntityListener(MultiverseCore plugin) {
this.plugin = plugin;
this.worldManager = plugin.getMVWorldManager();
@Inject
public MVEntityListener(
@NotNull MVCoreConfigProvider configProvider,
@NotNull MVWorldManager worldManager,
@NotNull WorldPurger worldPurger
) {
this.configProvider = configProvider;
this.worldManager = worldManager;
this.worldPurger = worldPurger;
}
/**
@ -46,7 +59,7 @@ public class MVEntityListener implements Listener {
}
if (event.getEntity() instanceof Player) {
Player p = (Player) event.getEntity();
MVWorld w = this.plugin.getMVWorldManager().getMVWorld(p.getWorld().getName());
MVWorld w = this.worldManager.getMVWorld(p.getWorld().getName());
if (w != null && !w.getHunger()) {
// If the world has hunger set to false, do not let the level go down
if (event.getFoodLevel() < ((Player) event.getEntity()).getFoodLevel()) {
@ -103,7 +116,7 @@ public class MVEntityListener implements Listener {
}
MVWorld mvworld = this.worldManager.getMVWorld(world.getName());
event.setCancelled(this.plugin.getMVWorldManager().getTheWorldPurger().shouldWeKillThisCreature(mvworld, event.getEntity()));
event.setCancelled(this.worldPurger.shouldWeKillThisCreature(mvworld, event.getEntity()));
}
/**
@ -115,8 +128,8 @@ public class MVEntityListener implements Listener {
if (event.isCancelled() || event.getTo() == null) {
return;
}
if (this.plugin.getMVConfig().isUsingCustomPortalSearch()) {
event.setSearchRadius(this.plugin.getMVConfig().getCustomPortalSearchRadius());
if (!this.configProvider.getConfig().isUsingCustomPortalSearch()) {
event.setSearchRadius(this.configProvider.getConfig().getCustomPortalSearchRadius());
}
}
}

View File

@ -14,37 +14,71 @@ import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
import com.onarandombox.MultiverseCore.utils.PermissionTools;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.Plugin;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's {@link Listener} for players.
* Multiverse's Listener for players.
*/
public class MVPlayerListener implements Listener {
private final MultiverseCore plugin;
private final MVWorldManager worldManager;
@Service
public class MVPlayerListener implements InjectableListener {
private final Plugin plugin;
private final MVCoreConfigProvider configProvider;
private final Provider<MVWorldManager> worldManagerProvider;
private final PermissionTools pt;
private final Provider<MVPermissions> mvPermsProvider;
private final SafeTTeleporter safeTTeleporter;
private final Server server;
private final Map<String, String> playerWorld = new ConcurrentHashMap<String, String>();
public MVPlayerListener(MultiverseCore plugin) {
@Inject
public MVPlayerListener(
MultiverseCore plugin,
MVCoreConfigProvider configProvider,
Provider<MVWorldManager> worldManagerProvider,
PermissionTools permissionTools,
Provider<MVPermissions> mvPermsProvider,
SafeTTeleporter safeTTeleporter,
Server server
) {
this.plugin = plugin;
worldManager = plugin.getMVWorldManager();
pt = new PermissionTools(plugin);
this.configProvider = configProvider;
this.worldManagerProvider = worldManagerProvider;
this.pt = permissionTools;
this.mvPermsProvider = mvPermsProvider;
this.safeTTeleporter = safeTTeleporter;
this.server = server;
}
private MVWorldManager getWorldManager() {
return worldManagerProvider.get();
}
private MVPermissions getMVPerms() {
return mvPermsProvider.get();
}
/**
@ -61,7 +95,7 @@ public class MVPlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void playerRespawn(PlayerRespawnEvent event) {
World world = event.getPlayer().getWorld();
MVWorld mvWorld = this.worldManager.getMVWorld(world.getName());
MVWorld mvWorld = getWorldManager().getMVWorld(world.getName());
// If it's not a World MV manages we stop.
if (mvWorld == null) {
return;
@ -74,8 +108,8 @@ public class MVPlayerListener implements Listener {
// Get the instance of the World the player should respawn at.
MVWorld respawnWorld = null;
if (this.worldManager.isMVWorld(mvWorld.getRespawnToWorld())) {
respawnWorld = this.worldManager.getMVWorld(mvWorld.getRespawnToWorld());
if (getWorldManager().isMVWorld(mvWorld.getRespawnToWorld())) {
respawnWorld = getWorldManager().getMVWorld(mvWorld.getRespawnToWorld());
}
// If it's null then it either means the World doesn't exist or the value is blank, so we don't handle it.
@ -87,12 +121,12 @@ public class MVPlayerListener implements Listener {
Location respawnLocation = getMostAccurateRespawnLocation(world);
MVRespawnEvent respawnEvent = new MVRespawnEvent(respawnLocation, event.getPlayer(), "compatability");
this.plugin.getServer().getPluginManager().callEvent(respawnEvent);
this.server.getPluginManager().callEvent(respawnEvent);
event.setRespawnLocation(respawnEvent.getPlayersRespawnLocation());
}
private Location getMostAccurateRespawnLocation(World w) {
MVWorld mvw = this.worldManager.getMVWorld(w.getName());
MVWorld mvw = getWorldManager().getMVWorld(w.getName());
if (mvw != null) {
return mvw.getSpawnLocation();
}
@ -108,16 +142,16 @@ public class MVPlayerListener implements Listener {
Player p = event.getPlayer();
if (!p.hasPlayedBefore()) {
Logging.finer("Player joined for the FIRST time!");
if (plugin.getMVConfig().getFirstSpawnOverride()) {
if (configProvider.getConfig().getFirstSpawnOverride()) {
Logging.fine("Moving NEW player to(firstspawnoverride): "
+ worldManager.getFirstSpawnWorld().getSpawnLocation());
+ getWorldManager().getFirstSpawnWorld().getSpawnLocation());
this.sendPlayerToDefaultWorld(p);
}
return;
} else {
Logging.finer("Player joined AGAIN!");
if (this.plugin.getMVConfig().getEnforceAccess() // check this only if we're enforcing access!
&& !this.plugin.getMVPerms().hasPermission(p, "multiverse.access." + p.getWorld().getName(), false)) {
if (this.configProvider.getConfig().getEnforceAccess() // check this only if we're enforcing access!
&& !this.getMVPerms().hasPermission(p, "multiverse.access." + p.getWorld().getName(), false)) {
p.sendMessage("[MV] - Sorry you can't be in this world anymore!");
this.sendPlayerToDefaultWorld(p);
}
@ -155,15 +189,15 @@ public class MVPlayerListener implements Listener {
if (teleporterName != null) {
if (teleporterName.equals("CONSOLE")) {
Logging.finer("We know the teleporter is the console! Magical!");
teleporter = this.plugin.getServer().getConsoleSender();
teleporter = this.server.getConsoleSender();
} else {
teleporter = this.plugin.getServer().getPlayerExact(teleporterName);
teleporter = this.server.getPlayerExact(teleporterName);
}
}
Logging.finer("Inferred sender '" + teleporter + "' from name '"
+ teleporterName + "', fetched from name '" + teleportee.getName() + "'");
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
MVWorld fromWorld = getWorldManager().getMVWorld(event.getFrom().getWorld().getName());
MVWorld toWorld = getWorldManager().getMVWorld(event.getTo().getWorld().getName());
if (toWorld == null) {
Logging.fine("Player '" + teleportee.getName() + "' is teleporting to world '"
+ event.getTo().getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
@ -188,7 +222,7 @@ public class MVPlayerListener implements Listener {
}
// Check if player is allowed to enter the world if we're enforcing permissions
if (plugin.getMVConfig().getEnforceAccess()) {
if (configProvider.getConfig().getEnforceAccess()) {
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, teleporter, teleportee));
if (event.isCancelled() && teleporter != null) {
Logging.fine("Player '" + teleportee.getName()
@ -241,7 +275,7 @@ public class MVPlayerListener implements Listener {
// REMEMBER! getTo MAY be NULL HERE!!!
// If the player was actually outside of the portal, adjust the from location
if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.NETHER_PORTAL) {
Location newloc = this.plugin.getSafeTTeleporter().findPortalBlockNextTo(event.getFrom());
Location newloc = this.safeTTeleporter.findPortalBlockNextTo(event.getFrom());
// TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what
// TODO: we want to do here.
if (newloc != null) {
@ -266,8 +300,8 @@ public class MVPlayerListener implements Listener {
if (event.getTo() == null) {
return;
}
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
MVWorld fromWorld = getWorldManager().getMVWorld(event.getFrom().getWorld().getName());
MVWorld toWorld = getWorldManager().getMVWorld(event.getTo().getWorld().getName());
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
// The player is Portaling to the same world.
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
@ -280,7 +314,7 @@ public class MVPlayerListener implements Listener {
+ "' because they don't have the FUNDS required to enter.");
return;
}
if (plugin.getMVConfig().getEnforceAccess()) {
if (configProvider.getConfig().getEnforceAccess()) {
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
if (event.isCancelled()) {
Logging.fine("Player '" + event.getPlayer().getName()
@ -292,18 +326,18 @@ public class MVPlayerListener implements Listener {
+ "' was allowed to go to '" + event.getTo().getWorld().getName()
+ "' because enforceaccess is off.");
}
if (this.plugin.getMVConfig().isUsingCustomPortalSearch()) {
event.setSearchRadius(this.plugin.getMVConfig().getCustomPortalSearchRadius());
if (!this.configProvider.getConfig().isUsingCustomPortalSearch()) {
event.setSearchRadius(this.configProvider.getConfig().getCustomPortalSearchRadius());
}
}
private void sendPlayerToDefaultWorld(final Player player) {
// Remove the player 1 tick after the login. I'm sure there's GOT to be a better way to do this...
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
this.server.getScheduler().scheduleSyncDelayedTask(this.plugin,
new Runnable() {
@Override
public void run() {
player.teleport(plugin.getMVWorldManager().getFirstSpawnWorld().getSpawnLocation());
player.teleport(getWorldManager().getFirstSpawnWorld().getSpawnLocation());
}
}, 1L);
}
@ -311,7 +345,7 @@ public class MVPlayerListener implements Listener {
// FOLLOWING 2 Methods and Private class handle Per Player GameModes.
private void handleGameModeAndFlight(Player player, World world) {
MVWorld mvWorld = this.worldManager.getMVWorld(world.getName());
MVWorld mvWorld = getWorldManager().getMVWorld(world.getName());
if (mvWorld != null) {
this.handleGameModeAndFlight(player, mvWorld);
} else {
@ -328,7 +362,7 @@ public class MVPlayerListener implements Listener {
public void handleGameModeAndFlight(final Player player, final MVWorld world) {
// We perform this task one tick later to MAKE SURE that the player actually reaches the
// destination world, otherwise we'd be changing the player mode if they havent moved anywhere.
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
this.server.getScheduler().scheduleSyncDelayedTask(this.plugin,
new Runnable() {
@Override
public void run() {

View File

@ -8,26 +8,30 @@
package com.onarandombox.MultiverseCore.listeners;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import jakarta.inject.Inject;
import org.bukkit.Material;
import org.bukkit.PortalType;
import org.bukkit.block.BlockState;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.PortalCreateEvent;
import org.jvnet.hk2.annotations.Service;
/**
* A custom listener for portal related events.
*/
public class MVPortalListener implements Listener {
@Service
public class MVPortalListener implements InjectableListener {
private MultiverseCore plugin;
private MVWorldManager worldManager;
public MVPortalListener(MultiverseCore core) {
this.plugin = core;
@Inject
public MVPortalListener(MVWorldManager worldManager) {
this.worldManager = worldManager;
}
/**
@ -38,7 +42,7 @@ public class MVPortalListener implements Listener {
public void portalForm(PortalCreateEvent event) {
Logging.fine("Attempting to create portal at '%s' with reason: %s", event.getWorld().getName(), event.getReason());
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getWorld());
MVWorld world = this.worldManager.getMVWorld(event.getWorld());
if (world == null) {
Logging.fine("World '%s' is not managed by Multiverse! Ignoring at PortalCreateEvent.", event.getWorld().getName());
return;
@ -94,7 +98,7 @@ public class MVPortalListener implements Listener {
return;
}
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getPlayer().getWorld());
MVWorld world = this.worldManager.getMVWorld(event.getPlayer().getWorld());
if (world == null) {
Logging.fine("World '%s' is not managed by Multiverse! Ignoring at PlayerInteractEvent.",
event.getPlayer().getWorld().getName());

View File

@ -7,21 +7,26 @@
package com.onarandombox.MultiverseCore.listeners;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import jakarta.inject.Inject;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.weather.ThunderChangeEvent;
import org.bukkit.event.weather.WeatherChangeEvent;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's Weather {@link Listener}.
* Multiverse's Weather Listener.
*/
public class MVWeatherListener implements Listener {
private MultiverseCore plugin;
@Service
public class MVWeatherListener implements InjectableListener {
public MVWeatherListener(MultiverseCore plugin) {
this.plugin = plugin;
private MVWorldManager worldManager;
@Inject
public MVWeatherListener(MVWorldManager worldManager) {
this.worldManager = worldManager;
}
/**
@ -33,7 +38,7 @@ public class MVWeatherListener implements Listener {
if (event.isCancelled()) {
return;
}
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getWorld().getName());
MVWorld world = this.worldManager.getMVWorld(event.getWorld().getName());
if (world != null) {
// If it's going to start raining and we have weather disabled
event.setCancelled((event.toWeatherState() && !world.isWeatherEnabled()));
@ -49,7 +54,7 @@ public class MVWeatherListener implements Listener {
if (event.isCancelled()) {
return;
}
MVWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getWorld().getName());
MVWorld world = this.worldManager.getMVWorld(event.getWorld().getName());
if (world != null) {
// If it's going to start raining and we have weather disabled
event.setCancelled((event.toThunderState() && !world.isWeatherEnabled()));

View File

@ -7,22 +7,26 @@
package com.onarandombox.MultiverseCore.listeners;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import jakarta.inject.Inject;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import org.jvnet.hk2.annotations.Service;
public class MVWorldInitListener implements Listener {
@Service
public class MVWorldInitListener implements InjectableListener {
MultiverseCore plugin;
private final MVWorldManager worldManager;
public MVWorldInitListener(MultiverseCore plugin) {
this.plugin = plugin;
@Inject
public MVWorldInitListener(MVWorldManager worldManager) {
this.worldManager = worldManager;
}
@EventHandler
public void initWorld(WorldInitEvent event) {
if (!plugin.getMVWorldManager().isKeepingSpawnInMemory(event.getWorld())) {
if (!worldManager.isKeepingSpawnInMemory(event.getWorld())) {
event.getWorld().setKeepSpawnInMemory(false);
}
}

View File

@ -7,25 +7,27 @@
package com.onarandombox.MultiverseCore.listeners;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import jakarta.inject.Inject;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's World {@link Listener}.
* Multiverse's World Listener.
*/
public class MVWorldListener implements Listener {
private MultiverseCore plugin;
@Service
public class MVWorldListener implements InjectableListener {
private MVWorldManager worldManager;
public MVWorldListener(MultiverseCore plugin) {
this.plugin = plugin;
this.worldManager = plugin.getMVWorldManager();
@Inject
public MVWorldListener(MVWorldManager worldManager) {
this.worldManager = worldManager;
}
/**
@ -40,7 +42,7 @@ public class MVWorldListener implements Listener {
if (event.getWorld() instanceof World) {
World world = (World) event.getWorld();
if (world != null) {
this.plugin.getMVWorldManager().unloadWorld(world.getName(), false);
this.worldManager.unloadWorld(world.getName(), false);
}
}
}
@ -53,10 +55,10 @@ public class MVWorldListener implements Listener {
public void loadWorld(WorldLoadEvent event) {
World world = event.getWorld();
if (world != null) {
if (this.plugin.getMVWorldManager().getUnloadedWorlds().contains(world.getName())) {
this.plugin.getMVWorldManager().loadWorld(world.getName());
if (this.worldManager.getUnloadedWorlds().contains(world.getName())) {
this.worldManager.loadWorld(world.getName());
}
MVWorld mvWorld = plugin.getMVWorldManager().getMVWorld(world);
MVWorld mvWorld = worldManager.getMVWorld(world);
if (mvWorld != null) {
// This is where we can temporarily fix those pesky property issues!
world.setPVP(mvWorld.isPVPEnabled());

View File

@ -14,13 +14,13 @@ import com.onarandombox.MultiverseCore.event.MVTeleportEvent;
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent;
import com.onarandombox.MultiverseCore.event.MVWorldPropertyChangeEvent;
import com.onarandombox.MultiverseCore.inject.InjectableListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
/**
* Subclasses of this listener can be used to conveniently listen to MultiverseCore-events.
*/
public abstract class MultiverseCoreListener implements Listener {
public abstract class MultiverseCoreListener implements InjectableListener {
/**
* Called when a {@link MVWorldPropertyChangeEvent} is fired.
* @param event The event.

View File

@ -6,22 +6,33 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.economy.MVEconomist;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Inject;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service;
@Service
public class MultiverseCorePlaceholders extends PlaceholderExpansion {
private final MultiverseCore plugin;
private final MVWorldManager worldManager;
private final MVEconomist economist;
public MultiverseCorePlaceholders(MultiverseCore plugin) {
@Inject
public MultiverseCorePlaceholders(MultiverseCore plugin, MVWorldManager worldManager, MVEconomist economist) {
this.plugin = plugin;
this.worldManager = plugin.getMVWorldManager();
this.economist = plugin.getEconomist();
this.worldManager = worldManager;
this.economist = economist;
}
@PostConstruct
@Override
public boolean register() {
return super.register();
}
@Override

View File

@ -9,7 +9,8 @@ package com.onarandombox.MultiverseCore.teleportation;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MVCore;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import jakarta.inject.Inject;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
@ -18,6 +19,7 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Bed;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
import org.jvnet.hk2.annotations.Service;
import java.util.EnumSet;
import java.util.Iterator;
@ -26,8 +28,9 @@ import java.util.Set;
/**
* The default-implementation of {@link BlockSafety}.
*/
@Service
public class SimpleBlockSafety implements BlockSafety {
private final MVCore plugin;
private final LocationManipulation locationManipulation;
private static final Set<BlockFace> AROUND_BLOCK = EnumSet.noneOf(BlockFace.class);
static {
@ -41,8 +44,9 @@ public class SimpleBlockSafety implements BlockSafety {
AROUND_BLOCK.add(BlockFace.NORTH_WEST);
}
public SimpleBlockSafety(MVCore plugin) {
this.plugin = plugin;
@Inject
public SimpleBlockSafety(LocationManipulation locationManipulation) {
this.locationManipulation = locationManipulation;
}
/**
@ -248,7 +252,7 @@ public class SimpleBlockSafety implements BlockSafety {
if (this.isBlockAboveAir(cart.getLocation())) {
return true;
}
if (this.isEntitiyOnTrack(plugin.getLocationManipulation().getNextBlock(cart))) {
if (this.isEntitiyOnTrack(locationManipulation.getNextBlock(cart))) {
return true;
}
return false;

View File

@ -15,6 +15,7 @@ import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import org.jvnet.hk2.annotations.Service;
import java.text.DecimalFormat;
import java.util.Collections;
@ -25,6 +26,7 @@ import java.util.Map;
/**
* The default-implementation of {@link LocationManipulation}.
*/
@Service
public class SimpleLocationManipulation implements LocationManipulation {
private static final Map<String, Integer> ORIENTATION_INTS;

View File

@ -10,9 +10,12 @@ package com.onarandombox.MultiverseCore.teleportation;
import co.aikar.commands.BukkitCommandIssuer;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.DestinationInstance;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import jakarta.inject.Inject;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -24,15 +27,26 @@ import org.bukkit.entity.Minecart;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import org.jvnet.hk2.annotations.Service;
/**
* The default-implementation of {@link SafeTTeleporter}.
*/
@Service
public class SimpleSafeTTeleporter implements SafeTTeleporter {
private MultiverseCore plugin;
private final MultiverseCore plugin;
private final LocationManipulation locationManipulation;
private final BlockSafety blockSafety;
public SimpleSafeTTeleporter(MultiverseCore plugin) {
@Inject
public SimpleSafeTTeleporter(
MultiverseCore plugin,
LocationManipulation locationManipulation,
BlockSafety blockSafety
) {
this.plugin = plugin;
this.locationManipulation = locationManipulation;
this.blockSafety = blockSafety;
}
private static final Vector DEFAULT_VECTOR = new Vector();
@ -58,7 +72,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
if (safe != null) {
safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
Logging.fine("Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
Logging.fine("Hey! I found one: " + locationManipulation.strCoordsRaw(safe));
} else {
Logging.fine("Uh oh! No safe place found!");
}
@ -72,7 +86,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
}
// We want half of it, so we can go up and down
tolerance /= 2;
Logging.finer("Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
Logging.finer("Given Location of: " + locationManipulation.strCoordsRaw(l));
Logging.finer("Checking +-" + tolerance + " with a radius of " + radius);
// For now this will just do a straight up block.
@ -140,13 +154,13 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
// ...
int adjustedCircle = ((circle - 1) / 2);
checkLoc.add(adjustedCircle, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
if (blockSafety.playerCanSpawnHereSafely(checkLoc)) {
return true;
}
// Now we go to the right that adjustedCircle many
for (int i = 0; i < adjustedCircle; i++) {
checkLoc.add(0, 0, 1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
if (blockSafety.playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
@ -154,7 +168,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
// Then down adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(-1, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
if (blockSafety.playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
@ -162,7 +176,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
// Then left adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(0, 0, -1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
if (blockSafety.playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
@ -170,7 +184,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
// Then up Then left adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(1, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
if (blockSafety.playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
@ -178,7 +192,7 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
// Then finish up by doing adjustedCircle - 1
for (int i = 0; i < adjustedCircle - 1; i++) {
checkLoc.add(0, 0, 1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
if (blockSafety.playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
@ -251,25 +265,25 @@ public class SimpleSafeTTeleporter implements SafeTTeleporter {
@Override
public Location getSafeLocation(Entity entity, DestinationInstance destination) {
Location l = destination.getLocation(entity);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(l)) {
if (blockSafety.playerCanSpawnHereSafely(l)) {
Logging.fine("The first location you gave me was safe.");
return l;
}
if (entity instanceof Minecart) {
Minecart m = (Minecart) entity;
if (!plugin.getBlockSafety().canSpawnCartSafely(m)) {
if (!blockSafety.canSpawnCartSafely(m)) {
return null;
}
} else if (entity instanceof Vehicle) {
Vehicle v = (Vehicle) entity;
if (!plugin.getBlockSafety().canSpawnVehicleSafely(v)) {
if (!blockSafety.canSpawnVehicleSafely(v)) {
return null;
}
}
Location safeLocation = this.getSafeLocation(l);
if (safeLocation != null) {
// Add offset to account for a vehicle on dry land!
if (entity instanceof Minecart && !plugin.getBlockSafety().isEntitiyOnTrack(safeLocation)) {
if (entity instanceof Minecart && !blockSafety.isEntitiyOnTrack(safeLocation)) {
safeLocation.setY(safeLocation.getBlockY() + .5);
Logging.finer("Player was inside a minecart. Offsetting Y location.");
}

View File

@ -10,29 +10,39 @@ package com.onarandombox.MultiverseCore.utils;
import java.util.List;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import jakarta.inject.Inject;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginManager;
import org.jvnet.hk2.annotations.Service;
/**
* Multiverse's permission checker
*/
@Service
public class MVPermissions {
private MultiverseCore plugin;
private MVWorldManager worldMgr;
public MVPermissions(MultiverseCore plugin) {
this.plugin = plugin;
this.worldMgr = plugin.getMVWorldManager();
private final PluginManager pluginManager;
private final MVCoreConfigProvider configProvider;
private final MVWorldManager worldMgr;
@Inject
public MVPermissions(
PluginManager pluginManager,
MVCoreConfigProvider configProvider,
MVWorldManager worldManager
) {
this.pluginManager = pluginManager;
this.configProvider = configProvider;
this.worldMgr = worldManager;
}
/**
@ -98,7 +108,7 @@ public class MVPermissions {
*/
public boolean canEnterWorld(Player p, MVWorld w) {
// If we're not enforcing access, anyone can enter.
if (!plugin.getMVConfig().getEnforceAccess()) {
if (!configProvider.getConfig().getEnforceAccess()) {
Logging.finest("EnforceAccess is OFF. Player was allowed in " + w.getAlias());
return true;
}
@ -110,7 +120,7 @@ public class MVPermissions {
return false;
}
String worldName = l.getWorld().getName();
if (!this.plugin.getMVWorldManager().isMVWorld(worldName)) {
if (!this.worldMgr.isMVWorld(worldName)) {
return false;
}
return this.hasPermission(p, "multiverse.access." + worldName, false);
@ -339,12 +349,12 @@ public class MVPermissions {
* @return The permission as {@link Permission}.
*/
public Permission addPermission(String string, PermissionDefault defaultValue) {
if (this.plugin.getServer().getPluginManager().getPermission(string) == null) {
if (this.pluginManager.getPermission(string) == null) {
Permission permission = new Permission(string, defaultValue);
this.plugin.getServer().getPluginManager().addPermission(permission);
this.pluginManager.addPermission(permission);
this.addToParentPerms(string);
}
return this.plugin.getServer().getPluginManager().getPermission(string);
return this.pluginManager.getPermission(string);
}
private void addToParentPerms(String permString) {
@ -357,36 +367,36 @@ public class MVPermissions {
addToRootPermission("*.*", permStringChopped);
return;
}
Permission parentPermission = this.plugin.getServer().getPluginManager().getPermission(parentPermString);
Permission parentPermission = this.pluginManager.getPermission(parentPermString);
// Creat parent and grandparents
if (parentPermission == null) {
parentPermission = new Permission(parentPermString);
this.plugin.getServer().getPluginManager().addPermission(parentPermission);
this.pluginManager.addPermission(parentPermission);
this.addToParentPerms(parentPermString);
}
// Create actual perm.
Permission actualPermission = this.plugin.getServer().getPluginManager().getPermission(permString);
Permission actualPermission = this.pluginManager.getPermission(permString);
// Extra check just to make sure the actual one is added
if (actualPermission == null) {
actualPermission = new Permission(permString);
this.plugin.getServer().getPluginManager().addPermission(actualPermission);
this.pluginManager.addPermission(actualPermission);
}
if (!parentPermission.getChildren().containsKey(permString)) {
parentPermission.getChildren().put(actualPermission.getName(), true);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(parentPermission);
this.pluginManager.recalculatePermissionDefaults(parentPermission);
}
}
private void addToRootPermission(String rootPerm, String permStringChopped) {
Permission rootPermission = this.plugin.getServer().getPluginManager().getPermission(rootPerm);
Permission rootPermission = this.pluginManager.getPermission(rootPerm);
if (rootPermission == null) {
rootPermission = new Permission(rootPerm);
this.plugin.getServer().getPluginManager().addPermission(rootPermission);
this.pluginManager.addPermission(rootPermission);
}
rootPermission.getChildren().put(permStringChopped + ".*", true);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(rootPermission);
this.pluginManager.recalculatePermissionDefaults(rootPermission);
}
/**

View File

@ -8,23 +8,45 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import com.onarandombox.MultiverseCore.economy.MVEconomist;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.PluginManager;
import org.jvnet.hk2.annotations.Service;
/**
* Utility-class for permissions.
*/
@Service
public class PermissionTools {
private MultiverseCore plugin;
public PermissionTools(MultiverseCore plugin) {
this.plugin = plugin;
private final MVCoreConfigProvider configProvider;
private final PluginManager pluginManager;
private final Provider<MVPermissions> mvPermsProvider;
private final MVEconomist economist;
@Inject
public PermissionTools(
MVCoreConfigProvider configProvider,
PluginManager pluginManager,
Provider<MVPermissions> mvPermsProvider,
MVEconomist economist)
{
this.configProvider = configProvider;
this.pluginManager = pluginManager;
this.mvPermsProvider = mvPermsProvider;
this.economist = economist;
}
private MVPermissions getMVPerms() {
return this.mvPermsProvider.get();
}
/**
@ -41,36 +63,36 @@ public class PermissionTools {
addToRootPermission("*.*", permStringChopped);
return;
}
Permission parentPermission = this.plugin.getServer().getPluginManager().getPermission(parentPermString);
Permission parentPermission = this.pluginManager.getPermission(parentPermString);
// Creat parent and grandparents
if (parentPermission == null) {
parentPermission = new Permission(parentPermString);
this.plugin.getServer().getPluginManager().addPermission(parentPermission);
this.pluginManager.addPermission(parentPermission);
this.addToParentPerms(parentPermString);
}
// Create actual perm.
Permission actualPermission = this.plugin.getServer().getPluginManager().getPermission(permString);
Permission actualPermission = this.pluginManager.getPermission(permString);
// Extra check just to make sure the actual one is added
if (actualPermission == null) {
actualPermission = new Permission(permString);
this.plugin.getServer().getPluginManager().addPermission(actualPermission);
this.pluginManager.addPermission(actualPermission);
}
if (!parentPermission.getChildren().containsKey(permString)) {
parentPermission.getChildren().put(actualPermission.getName(), true);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(parentPermission);
this.pluginManager.recalculatePermissionDefaults(parentPermission);
}
}
private void addToRootPermission(String rootPerm, String permStringChopped) {
Permission rootPermission = this.plugin.getServer().getPluginManager().getPermission(rootPerm);
Permission rootPermission = this.pluginManager.getPermission(rootPerm);
if (rootPermission == null) {
rootPermission = new Permission(rootPerm);
this.plugin.getServer().getPluginManager().addPermission(rootPermission);
this.pluginManager.addPermission(rootPermission);
}
rootPermission.getChildren().put(permStringChopped + ".*", true);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(rootPermission);
this.pluginManager.recalculatePermissionDefaults(rootPermission);
}
/**
@ -101,7 +123,7 @@ public class PermissionTools {
*/
public boolean playerHasMoneyToEnter(MVWorld fromWorld, MVWorld toWorld, CommandSender teleporter, Player teleportee, boolean pay) {
Player teleporterPlayer;
if (plugin.getMVConfig().getTeleportIntercept()) {
if (configProvider.getConfig().getTeleportIntercept()) {
if (teleporter instanceof ConsoleCommandSender) {
return true;
}
@ -141,11 +163,10 @@ public class PermissionTools {
return true;
}
// If the player does not have to pay, return now.
if (this.plugin.getMVPerms().hasPermission(teleporter, toWorld.getExemptPermission().getName(), true)) {
if (this.getMVPerms().hasPermission(teleporter, toWorld.getExemptPermission().getName(), true)) {
return true;
}
final MVEconomist economist = plugin.getEconomist();
final Material currency = toWorld.getCurrency();
final String formattedAmount = economist.formatPrice(price, currency);
@ -198,7 +219,7 @@ public class PermissionTools {
Logging.finest("Checking '" + teleporter + "' can send '" + teleportee + "' somewhere");
Player teleporterPlayer;
if (plugin.getMVConfig().getTeleportIntercept()) {
if (configProvider.getConfig().getTeleportIntercept()) {
// The console can send anyone anywhere
if (teleporter instanceof ConsoleCommandSender) {
return true;
@ -229,7 +250,7 @@ public class PermissionTools {
// Actual checks
if (toWorld != null) {
if (!this.plugin.getMVPerms().canEnterWorld(teleporterPlayer, toWorld)) {
if (!this.getMVPerms().canEnterWorld(teleporterPlayer, toWorld)) {
if (teleportee.equals(teleporter)) {
teleporter.sendMessage("You don't have access to go here...");
} else {
@ -274,8 +295,7 @@ public class PermissionTools {
return true;
}
MVPermissions perms = plugin.getMVPerms();
if (perms.hasPermission(teleportee, "mv.bypass.playerlimit." + toWorld.getName(), false)) {
if (getMVPerms().hasPermission(teleportee, "mv.bypass.playerlimit." + toWorld.getName(), false)) {
return true;
} else {
teleporter.sendMessage("The world " + toWorld.getColoredWorldString() + " is full");
@ -292,7 +312,7 @@ public class PermissionTools {
*/
public boolean playerCanIgnoreGameModeRestriction(MVWorld toWorld, Player teleportee) {
if (toWorld != null) {
return this.plugin.getMVPerms().canIgnoreGameModeRestriction(teleportee, toWorld);
return this.getMVPerms().canIgnoreGameModeRestriction(teleportee, toWorld);
} else {
// TODO: Determine if this value is false because a world didn't exist
// or if it was because a world wasn't imported.

View File

@ -1,18 +1,22 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.MVCore;
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider;
import jakarta.inject.Inject;
import org.jvnet.hk2.annotations.Service;
import java.util.concurrent.Callable;
/**
* Wraps calls that could result in exceptions that are not Multiverse's fault.
*/
@Service
public class UnsafeCallWrapper {
private final MVCore core;
private final MVCoreConfigProvider configProvider;
public UnsafeCallWrapper(MVCore core) {
this.core = core;
@Inject
public UnsafeCallWrapper(MVCoreConfigProvider configProvider) {
this.configProvider = configProvider;
}
/**
@ -36,7 +40,7 @@ public class UnsafeCallWrapper {
actualFormatArgs[formatArgs.length] = t;
Logging.warning(action, actualFormatArgs);
Logging.warning("This is a bug in %s, NOT a bug in Multiverse!", plugin);
if (core.getMVConfig().getGlobalDebug() >= 1)
if (configProvider.getConfig().getGlobalDebug() >= 1)
t.printStackTrace();
return null;
}

View File

@ -8,36 +8,37 @@ import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MVWorld;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Inject;
import org.apache.commons.lang.WordUtils;
import org.bstats.bukkit.Metrics;
import org.bukkit.World;
import org.jvnet.hk2.annotations.Service;
@Service
public class MetricsConfigurator {
private static final int PLUGIN_ID = 7765;
private static final String NO_GENERATOR_NAME = "N/A";
public static void configureMetrics(MultiverseCore plugin) {
MetricsConfigurator configurator = new MetricsConfigurator(plugin);
configurator.initMetrics();
}
private final MultiverseCore plugin;
private final MVWorldManager worldManager;
private final Metrics metrics;
private MetricsConfigurator(MultiverseCore plugin) {
this.plugin = plugin;
@Inject
private MetricsConfigurator(MultiverseCore plugin, MVWorldManager worldManager) {
this.worldManager = worldManager;
this.metrics = new Metrics(plugin, PLUGIN_ID);
}
private MVWorldManager getWorldManager() {
return plugin.getMVWorldManager();
return worldManager;
}
private Collection<MVWorld> getMVWorlds() {
return getWorldManager().getMVWorlds();
}
@PostConstruct
private void initMetrics() {
try {
addCustomGeneratorsMetric();

View File

@ -15,9 +15,13 @@ import java.util.UUID;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.world.configuration.AllowedPortalType;
import com.onarandombox.MultiverseCore.world.configuration.EnglishChatColor;
import com.onarandombox.MultiverseCore.world.configuration.SpawnLocation;
@ -32,6 +36,7 @@ import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldType;
@ -49,20 +54,55 @@ public class SimpleMVWorld implements MVWorld {
private static final int SPAWN_LOCATION_SEARCH_TOLERANCE = 16;
private static final int SPAWN_LOCATION_SEARCH_RADIUS = 16;
private final MultiverseCore plugin; // Hold the Plugin Instance.
private final MVWorldManager worldManager;
private final WorldPurger worldPurger;
private final MVPlayerListener playerListener;
private final BlockSafety blockSafety;
private final SafeTTeleporter safeTTeleporter;
private final LocationManipulation locationManipulation;
private final Server server;
private final String name; // The Worlds Name, EG its folder name.
private final UUID worldUID;
private final WorldProperties props;
public SimpleMVWorld(MultiverseCore plugin, World world, WorldProperties properties) {
this(plugin, world, properties, true);
public SimpleMVWorld(
MVWorldManager worldManager,
WorldPurger worldPurger,
MVPlayerListener playerListener,
BlockSafety blockSafety,
SafeTTeleporter safeTTeleporter,
LocationManipulation locationManipulation,
Server server,
World world,
WorldProperties properties
) {
this(worldManager, worldPurger, playerListener, blockSafety, safeTTeleporter,
locationManipulation, server, world, properties, true);
}
/*
* We have to use setCBWorld(), setPlugin() and initPerms() to prepare this object for use.
*/
public SimpleMVWorld(MultiverseCore plugin, World world, WorldProperties properties, boolean fixSpawn) {
this.plugin = plugin;
public SimpleMVWorld(
MVWorldManager worldManager,
WorldPurger worldPurger,
MVPlayerListener playerListener,
BlockSafety blockSafety,
SafeTTeleporter safeTTeleporter,
LocationManipulation locationManipulation,
Server server,
World world,
WorldProperties properties,
boolean fixSpawn
) {
this.worldManager = worldManager;
this.worldPurger = worldPurger;
this.playerListener = playerListener;
this.blockSafety = blockSafety;
this.safeTTeleporter = safeTTeleporter;
this.locationManipulation = locationManipulation;
this.server = server;
this.name = world.getName();
this.worldUID = world.getUID();
this.props = properties;
@ -227,7 +267,7 @@ public class SimpleMVWorld implements MVWorld {
@Override
public String validateChange(String property, String newValue, String oldValue,
SimpleMVWorld object) throws ChangeDeniedException {
if (!newValue.isEmpty() && !plugin.getMVWorldManager().isMVWorld(newValue))
if (!newValue.isEmpty() && !worldManager.isMVWorld(newValue))
throw new ChangeDeniedException();
return super.validateChange(property, newValue, oldValue, object);
}
@ -281,8 +321,8 @@ public class SimpleMVWorld implements MVWorld {
}
world.setSpawnFlags(allowMonsters, allowAnimals);
}
if (plugin.getMVConfig().isAutoPurgeEntities()) {
plugin.getMVWorldManager().getTheWorldPurger().purgeWorld(SimpleMVWorld.this);
if (MultiverseCoreConfiguration.getInstance().isAutoPurgeEntities()) {
worldPurger.purgeWorld(SimpleMVWorld.this);
}
return super.validateChange(property, newValue, oldValue, object);
}
@ -295,10 +335,10 @@ public class SimpleMVWorld implements MVWorld {
@Override
public GameMode validateChange(String property, GameMode newValue, GameMode oldValue,
SimpleMVWorld object) throws ChangeDeniedException {
for (Player p : plugin.getServer().getWorld(getName()).getPlayers()) {
for (Player p : server.getWorld(getName()).getPlayers()) {
Logging.finer(String.format("Setting %s's GameMode to %s",
p.getName(), newValue.toString()));
plugin.getPlayerListener().handleGameModeAndFlight(p, SimpleMVWorld.this);
playerListener.handleGameModeAndFlight(p, SimpleMVWorld.this);
}
return super.validateChange(property, newValue, oldValue, object);
}
@ -314,20 +354,18 @@ public class SimpleMVWorld implements MVWorld {
if (newValue == null)
throw new ChangeDeniedException();
if (props.getAdjustSpawn()) {
BlockSafety bs = plugin.getBlockSafety();
// verify that the location is safe
if (!bs.playerCanSpawnHereSafely(newValue)) {
if (!blockSafety.playerCanSpawnHereSafely(newValue)) {
// it's not ==> find a better one!
Logging.warning(String.format("Somebody tried to set the spawn location for '%s' to an unsafe value! Adjusting...", getAlias()));
Logging.warning("Old Location: " + plugin.getLocationManipulation().strCoordsRaw(oldValue));
Logging.warning("New (unsafe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
SafeTTeleporter teleporter = plugin.getSafeTTeleporter();
newValue = teleporter.getSafeLocation(newValue, SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
Logging.warning("Old Location: " + locationManipulation.strCoordsRaw(oldValue));
Logging.warning("New (unsafe) Location: " + locationManipulation.strCoordsRaw(newValue));
newValue = safeTTeleporter.getSafeLocation(newValue, SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
if (newValue == null) {
Logging.warning("Couldn't fix the location. I have to abort the spawn location-change :/");
throw new ChangeDeniedException();
}
Logging.warning("New (safe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
Logging.warning("New (safe) Location: " + locationManipulation.strCoordsRaw(newValue));
}
}
return super.validateChange(property, newValue, oldValue, object);
@ -398,10 +436,10 @@ public class SimpleMVWorld implements MVWorld {
this.limitbypassperm = new Permission("mv.bypass.playerlimit." + this.getName(),
"A player who can enter this world regardless of wether its full", PermissionDefault.OP);
try {
this.plugin.getServer().getPluginManager().addPermission(this.permission);
this.plugin.getServer().getPluginManager().addPermission(this.exempt);
this.plugin.getServer().getPluginManager().addPermission(this.ignoreperm);
this.plugin.getServer().getPluginManager().addPermission(this.limitbypassperm);
this.server.getPluginManager().addPermission(this.permission);
this.server.getPluginManager().addPermission(this.exempt);
this.server.getPluginManager().addPermission(this.ignoreperm);
this.server.getPluginManager().addPermission(this.limitbypassperm);
// Add the permission and exempt to parents.
this.addToUpperLists(this.permission);
@ -417,9 +455,8 @@ public class SimpleMVWorld implements MVWorld {
private Location readSpawnFromWorld(World w) {
Location location = w.getSpawnLocation();
// Set the worldspawn to our configspawn
BlockSafety bs = this.plugin.getBlockSafety();
// Verify that location was safe
if (!bs.playerCanSpawnHereSafely(location)) {
if (!blockSafety.playerCanSpawnHereSafely(location)) {
if (!this.getAdjustSpawn()) {
Logging.fine("Spawn location from world.dat file was unsafe!!");
Logging.fine("NOT adjusting spawn for '" + this.getAlias() + "' because you told me not to.");
@ -428,25 +465,24 @@ public class SimpleMVWorld implements MVWorld {
return location;
}
// If it's not, find a better one.
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
Logging.warning("Spawn location from world.dat file was unsafe. Adjusting...");
Logging.warning("Original Location: " + plugin.getLocationManipulation().strCoordsRaw(location));
Location newSpawn = teleporter.getSafeLocation(location,
Logging.warning("Original Location: " + locationManipulation.strCoordsRaw(location));
Location newSpawn = safeTTeleporter.getSafeLocation(location,
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
// I think we could also do this, as I think this is what Notch does.
// Not sure how it will work in the nether...
//Location newSpawn = this.spawnLocation.getWorld().getHighestBlockAt(this.spawnLocation).getLocation();
if (newSpawn != null) {
Logging.info("New Spawn for '%s' is located at: %s",
this.getName(), plugin.getLocationManipulation().locationToString(newSpawn));
this.getName(), locationManipulation.locationToString(newSpawn));
return newSpawn;
} else {
// If it's a standard end world, let's check in a better place:
Location newerSpawn;
newerSpawn = bs.getTopBlock(new Location(w, 0, 0, 0));
newerSpawn = blockSafety.getTopBlock(new Location(w, 0, 0, 0));
if (newerSpawn != null) {
Logging.info("New Spawn for '%s' is located at: %s",
this.getName(), plugin.getLocationManipulation().locationToString(newerSpawn));
this.getName(), locationManipulation.locationToString(newerSpawn));
return newerSpawn;
} else {
Logging.severe("Safe spawn NOT found!!!");
@ -457,29 +493,29 @@ public class SimpleMVWorld implements MVWorld {
}
private void addToUpperLists(Permission perm) {
Permission all = this.plugin.getServer().getPluginManager().getPermission("multiverse.*");
Permission allWorlds = this.plugin.getServer().getPluginManager().getPermission("multiverse.access.*");
Permission allExemption = this.plugin.getServer().getPluginManager().getPermission("multiverse.exempt.*");
Permission all = this.server.getPluginManager().getPermission("multiverse.*");
Permission allWorlds = this.server.getPluginManager().getPermission("multiverse.access.*");
Permission allExemption = this.server.getPluginManager().getPermission("multiverse.exempt.*");
if (allWorlds == null) {
allWorlds = new Permission("multiverse.access.*");
this.plugin.getServer().getPluginManager().addPermission(allWorlds);
this.server.getPluginManager().addPermission(allWorlds);
}
allWorlds.getChildren().put(perm.getName(), true);
if (allExemption == null) {
allExemption = new Permission("multiverse.exempt.*");
this.plugin.getServer().getPluginManager().addPermission(allExemption);
this.server.getPluginManager().addPermission(allExemption);
}
allExemption.getChildren().put(this.exempt.getName(), true);
if (all == null) {
all = new Permission("multiverse.*");
this.plugin.getServer().getPluginManager().addPermission(all);
this.server.getPluginManager().addPermission(all);
}
all.getChildren().put("multiverse.access.*", true);
all.getChildren().put("multiverse.exempt.*", true);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(all);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allWorlds);
this.server.getPluginManager().recalculatePermissionDefaults(all);
this.server.getPluginManager().recalculatePermissionDefaults(allWorlds);
}
/**
@ -503,7 +539,7 @@ public class SimpleMVWorld implements MVWorld {
*/
@Override
public World getCBWorld() {
final World world = plugin.getServer().getWorld(worldUID);
final World world = server.getWorld(worldUID);
if (world == null) {
throw new IllegalStateException("Lost reference to bukkit world '" + name + "'");
}
@ -899,7 +935,7 @@ public class SimpleMVWorld implements MVWorld {
*/
@Override
public World getRespawnToWorld() {
return this.plugin.getServer().getWorld(props.getRespawnToWorld());
return this.server.getWorld(props.getRespawnToWorld());
}
/**
@ -907,7 +943,7 @@ public class SimpleMVWorld implements MVWorld {
*/
@Override
public boolean setRespawnToWorld(String respawnToWorld) {
if (!this.plugin.getMVWorldManager().isMVWorld(respawnToWorld)) return false;
if (!this.worldManager.isMVWorld(respawnToWorld)) return false;
return this.props.setRespawnToWorld(respawnToWorld);
}

View File

@ -26,15 +26,21 @@ import java.util.stream.Collectors;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
import com.onarandombox.MultiverseCore.utils.file.FileUtils;
import jakarta.inject.Inject;
import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
@ -47,12 +53,20 @@ import org.bukkit.generator.ChunkGenerator;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.Plugin;
import org.jvnet.hk2.annotations.Service;
/**
* Public facing API to add/remove Multiverse worlds.
*/
@Service
public class SimpleMVWorldManager implements MVWorldManager {
private final MultiverseCore plugin;
private final MVPlayerListener playerListener;
private final BlockSafety blockSafety;
private final SafeTTeleporter safeTTeleporter;
private final LocationManipulation locationManipulation;
private final UnsafeCallWrapper unsafeCallWrapper;
private final Server server;
private final WorldPurger worldPurger;
private final Map<String, MVWorld> worlds;
private Map<String, WorldProperties> worldsFromTheConfig;
@ -60,11 +74,28 @@ public class SimpleMVWorldManager implements MVWorldManager {
private Map<String, String> defaultGens;
private String firstSpawn;
public SimpleMVWorldManager(MultiverseCore core) {
this.plugin = core;
@Inject
public SimpleMVWorldManager(
MultiverseCore plugin,
MVPlayerListener playerListener,
BlockSafety blockSafety,
SafeTTeleporter safeTTeleporter,
LocationManipulation locationManipulation,
UnsafeCallWrapper unsafeCallWrapper,
WorldPurger worldPurger,
Server server
) {
this.plugin = plugin;
this.playerListener = playerListener;
this.blockSafety = blockSafety;
this.safeTTeleporter = safeTTeleporter;
this.locationManipulation = locationManipulation;
this.unsafeCallWrapper = unsafeCallWrapper;
this.worldPurger = worldPurger;
this.server = server;
this.worldsFromTheConfig = new HashMap<String, WorldProperties>();
this.worlds = new ConcurrentHashMap<String, MVWorld>();
this.worldPurger = new SimpleWorldPurger(plugin);
}
/**
@ -121,8 +152,8 @@ public class SimpleMVWorldManager implements MVWorldManager {
return false;
}
final File oldWorldFile = new File(this.plugin.getServer().getWorldContainer(), oldName);
final File newWorldFile = new File(this.plugin.getServer().getWorldContainer(), newName);
final File oldWorldFile = new File(this.server.getWorldContainer(), oldName);
final File newWorldFile = new File(this.server.getWorldContainer(), newName);
final List<String> ignoreFiles = new ArrayList<>(Arrays.asList("session.lock", "uid.dat"));
// Make sure the new world doesn't exist outside of multiverse.
@ -134,7 +165,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
// Load the old world... but just the metadata.
boolean wasJustLoaded = false;
boolean wasLoadSpawn = false;
if (this.plugin.getServer().getWorld(oldName) == null) {
if (this.server.getWorld(oldName) == null) {
wasJustLoaded = true;
WorldProperties props = this.worldsFromTheConfig.get(oldName);
wasLoadSpawn = props.isKeepingSpawnInMemory();
@ -145,7 +176,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
if (!this.loadWorld(oldName)) {
return false;
}
this.plugin.getServer().getWorld(oldName).setAutoSave(false);
this.server.getWorld(oldName).setAutoSave(false);
}
// Grab a bit of metadata from the old world.
@ -293,11 +324,11 @@ public class SimpleMVWorldManager implements MVWorldManager {
return null;
}
final Plugin myPlugin = this.plugin.getServer().getPluginManager().getPlugin(generator);
final Plugin myPlugin = this.server.getPluginManager().getPlugin(generator);
if (myPlugin == null) {
return null;
} else {
return plugin.getUnsafeCallWrapper().wrap(new Callable<ChunkGenerator>() {
return unsafeCallWrapper.wrap(new Callable<ChunkGenerator>() {
@Override
public ChunkGenerator call() throws Exception {
return myPlugin.getDefaultWorldGenerator(worldName, generatorID);
@ -331,8 +362,8 @@ public class SimpleMVWorldManager implements MVWorldManager {
*/
@Override
public void setFirstSpawnWorld(String world) {
if ((world == null) && (this.plugin.getServer().getWorlds().size() > 0)) {
this.firstSpawn = this.plugin.getServer().getWorlds().get(0).getName();
if ((world == null) && (this.server.getWorlds().size() > 0)) {
this.firstSpawn = this.server.getWorlds().get(0).getName();
} else {
this.firstSpawn = world;
}
@ -348,7 +379,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
// If the spawn world was unloaded, get the default world
Logging.warning("The world specified as the spawn world (" + this.firstSpawn + ") did not exist!!");
try {
return this.getMVWorld(this.plugin.getServer().getWorlds().get(0));
return this.getMVWorld(this.server.getWorlds().get(0));
} catch (IndexOutOfBoundsException e) {
// This should only happen in tests.
return null;
@ -383,10 +414,10 @@ public class SimpleMVWorldManager implements MVWorldManager {
} else {
Logging.warning("World '%s' could not be unloaded from Bukkit. Is it a default world?", name);
}
} else if (this.plugin.getServer().getWorld(name) != null) {
} else if (this.server.getWorld(name) != null) {
Logging.warning("Hmm Multiverse does not know about this world but it's loaded in memory.");
Logging.warning("To let Multiverse know about it, use:");
Logging.warning("/mv import %s %s", name, this.plugin.getServer().getWorld(name).getEnvironment().toString());
Logging.warning("/mv import %s %s", name, this.server.getWorld(name).getEnvironment().toString());
} else if (this.worldsFromTheConfig.containsKey(name)) {
return true; // it's already unloaded
} else {
@ -443,7 +474,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
boolean generatorSuccess = true;
if ((world.getGenerator() != null) && (!world.getGenerator().equals("null")))
generatorSuccess = null != plugin.getUnsafeCallWrapper().wrap(new Callable<Object>() {
generatorSuccess = null != unsafeCallWrapper.wrap(new Callable<Object>() {
@Override
public Object call() throws Exception {
creator.generator(world.getGenerator());
@ -461,7 +492,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
if (worlds.containsKey(worldName))
throw new IllegalArgumentException("That world is already loaded!");
if (!ignoreExists && !new File(this.plugin.getServer().getWorldContainer(), worldName).exists() && !new File(this.plugin.getServer().getWorldContainer().getParent(), worldName).exists()) {
if (!ignoreExists && !new File(this.server.getWorldContainer(), worldName).exists() && !new File(this.server.getWorldContainer().getParent(), worldName).exists()) {
Logging.warning("WorldManager: Can't load this world because the folder was deleted/moved: " + worldName);
Logging.warning("Use '/mv remove' to remove it from the config!");
return false;
@ -480,8 +511,9 @@ public class SimpleMVWorldManager implements MVWorldManager {
nullWorld(worldName);
return false;
}
SimpleMVWorld world = new SimpleMVWorld(plugin, cbworld, mvworld);
if (plugin.getMVConfig().isAutoPurgeEntities()) {
SimpleMVWorld world = new SimpleMVWorld(this, worldPurger, playerListener, blockSafety, safeTTeleporter,
locationManipulation, server, cbworld, mvworld);
if (MultiverseCoreConfiguration.getInstance().isAutoPurgeEntities()) {
this.worldPurger.purgeWorld(world);
}
this.worlds.put(worldName, world);
@ -500,7 +532,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
}
}
World world = this.plugin.getServer().getWorld(name);
World world = this.server.getWorld(name);
if (world == null) {
// We can only delete loaded worlds
return false;
@ -508,7 +540,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
// call the event!
MVWorldDeleteEvent mvwde = new MVWorldDeleteEvent(getMVWorld(name), removeFromConfig);
this.plugin.getServer().getPluginManager().callEvent(mvwde);
this.server.getPluginManager().callEvent(mvwde);
if (mvwde.isCancelled()) {
Logging.fine("Tried to delete a world, but the event was cancelled!");
return false;
@ -571,7 +603,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
*/
private boolean unloadWorldFromBukkit(String name, boolean safely) {
this.removePlayersFromWorld(name);
return this.plugin.getServer().unloadWorld(name, safely);
return this.server.unloadWorld(name, safely);
}
/**
@ -579,14 +611,13 @@ public class SimpleMVWorldManager implements MVWorldManager {
*/
@Override
public void removePlayersFromWorld(String name) {
World w = this.plugin.getServer().getWorld(name);
World w = this.server.getWorld(name);
if (w != null) {
World safeWorld = this.plugin.getServer().getWorlds().get(0);
World safeWorld = this.server.getWorlds().get(0);
List<Player> ps = w.getPlayers();
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
for (Player p : ps) {
// We're removing players forcefully from a world, they'd BETTER spawn safely.
teleporter.safelyTeleport(null, p, safeWorld.getSpawnLocation(), true);
this.safeTTeleporter.safelyTeleport(null, p, safeWorld.getSpawnLocation(), true);
}
}
}
@ -693,7 +724,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
@Override
public void loadDefaultWorlds() {
this.ensureConfigIsPrepared();
List<World> myWorlds = this.plugin.getServer().getWorlds();
List<World> myWorlds = this.server.getWorlds();
for (World w : myWorlds) {
String name = w.getName();
if (!worldsFromTheConfig.containsKey(name)) {
@ -726,8 +757,8 @@ public class SimpleMVWorldManager implements MVWorldManager {
// Force the worlds to be loaded, ie don't just load new worlds.
if (forceLoad) {
// Remove all world permissions.
Permission allAccess = this.plugin.getServer().getPluginManager().getPermission("multiverse.access.*");
Permission allExempt = this.plugin.getServer().getPluginManager().getPermission("multiverse.exempt.*");
Permission allAccess = this.server.getPluginManager().getPermission("multiverse.access.*");
Permission allExempt = this.server.getPluginManager().getPermission("multiverse.exempt.*");
for (MVWorld w : this.worlds.values()) {
// Remove this world from the master list
if (allAccess != null) {
@ -736,14 +767,14 @@ public class SimpleMVWorldManager implements MVWorldManager {
if (allExempt != null) {
allExempt.getChildren().remove(w.getAccessPermission().getName());
}
this.plugin.getServer().getPluginManager().removePermission(w.getAccessPermission().getName());
this.plugin.getServer().getPluginManager().removePermission(w.getExemptPermission().getName());
this.server.getPluginManager().removePermission(w.getAccessPermission().getName());
this.server.getPluginManager().removePermission(w.getExemptPermission().getName());
// Special namespace for gamemodes
this.plugin.getServer().getPluginManager().removePermission("mv.bypass.gamemode." + w.getName());
this.server.getPluginManager().removePermission("mv.bypass.gamemode." + w.getName());
}
// Recalc the all permission
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allAccess);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allExempt);
this.server.getPluginManager().recalculatePermissionDefaults(allAccess);
this.server.getPluginManager().recalculatePermissionDefaults(allExempt);
this.worlds.clear();
}
@ -764,21 +795,13 @@ public class SimpleMVWorldManager implements MVWorldManager {
}
private void ensureSecondNamespaceIsPrepared() {
Permission special = this.plugin.getServer().getPluginManager().getPermission("mv.bypass.gamemode.*");
Permission special = this.server.getPluginManager().getPermission("mv.bypass.gamemode.*");
if (special == null) {
special = new Permission("mv.bypass.gamemode.*", PermissionDefault.FALSE);
this.plugin.getServer().getPluginManager().addPermission(special);
this.server.getPluginManager().addPermission(special);
}
}
/**
* {@inheritDoc}
*/
@Override
public WorldPurger getTheWorldPurger() {
return worldPurger;
}
private static final char SEPARATOR = '\uF8FF';
public boolean isKeepingSpawnInMemory(World world) {
@ -856,7 +879,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
*/
@Override
public MVWorld getSpawnWorld() {
return this.getMVWorld(this.plugin.getServer().getWorlds().get(0));
return this.getMVWorld(this.server.getWorlds().get(0));
}
/**
@ -949,10 +972,9 @@ public class SimpleMVWorldManager implements MVWorldManager {
}
// Send all players that were in the old world, BACK to it!
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
Location newSpawn = world.getSpawnLocation();
for (Player p : ps) {
teleporter.safelyTeleport(null, p, newSpawn, true);
this.safeTTeleporter.safelyTeleport(null, p, newSpawn, true);
}
return true;
@ -995,7 +1017,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
*/
@Override
public Collection<String> getPotentialWorlds() {
File worldContainer = this.plugin.getServer().getWorldContainer();
File worldContainer = this.server.getWorldContainer();
if (worldContainer == null) {
return Collections.emptyList();
}

View File

@ -24,6 +24,7 @@ import org.bukkit.entity.Phantom;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Squid;
import org.jvnet.hk2.annotations.Service;
import java.util.ArrayList;
import java.util.Iterator;
@ -32,14 +33,12 @@ import java.util.List;
/**
* Utility class that removes animals from worlds that don't belong there.
*/
@Service
public class SimpleWorldPurger implements WorldPurger {
private MultiverseCore plugin;
private Class<Entity> ambientClass = null;
public SimpleWorldPurger(MultiverseCore plugin) {
this.plugin = plugin;
public SimpleWorldPurger() {
try {
Class entityClass = Class.forName("org.bukkit.entity.Ambient");
if (Entity.class.isAssignableFrom(entityClass)) {

View File

@ -0,0 +1 @@
com.onarandombox.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl

View File

@ -63,6 +63,7 @@ public class TestDebugMode {
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
// Assert debug mode is off
Assert.assertEquals(0, core.getMVConfig().getGlobalDebug());
@ -71,5 +72,6 @@ public class TestDebugMode {
plugin.onCommand(mockCommandSender, mockCommand, "", debugArgs);
Assert.assertEquals(3, core.getMVConfig().getGlobalDebug());
*/
}
}

View File

@ -33,7 +33,9 @@ import static org.mockito.Mockito.when;
public class TestEntitySpawnRules {
TestInstanceCreator creator;
MultiverseCore core;
/* This block is preserved for the transition to MV5, just in case
MVEntityListener listener;
*/
MVWorld mvWorld;
World cbworld;
@ -49,7 +51,9 @@ public class TestEntitySpawnRules {
creator = new TestInstanceCreator();
assertTrue(creator.setUp());
core = creator.getCore();
/* This block is preserved for the transition to MV5, just in case
listener = core.getEntityListener();
*/
mvWorld = mock(MVWorld.class);
cbworld = MockWorldFactory.makeNewMockWorld("world", World.Environment.NORMAL, WorldType.NORMAL);
@ -60,9 +64,11 @@ public class TestEntitySpawnRules {
when(worldman.getMVWorld(anyString())).thenReturn(mvWorld);
Field worldmanfield = MVEntityListener.class.getDeclaredField("worldManager");
worldmanfield.setAccessible(true);
/* This block is preserved for the transition to MV5, just in case
worldmanfield.set(listener, worldman);
core.getMVConfig().setGlobalDebug(3);
*/
}
@After
@ -82,8 +88,10 @@ public class TestEntitySpawnRules {
private void spawnAll(SpawnReason reason) {
sheepEvent = mockSpawnEvent(sheep, reason);
zombieEvent = mockSpawnEvent(zombie, reason);
/* This block is preserved for the transition to MV5, just in case
listener.creatureSpawn(sheepEvent);
listener.creatureSpawn(zombieEvent);
*/
}
private void spawnAllNatural() {

View File

@ -30,8 +30,10 @@ public class TestModifyCommand {
mockCommandSender = creator.getCommandSender();
core = creator.getCore();
/* This block is preserved for the transition to MV5, just in case
// create world
assertTrue(core.getMVWorldManager().addWorld("world", Environment.NORMAL, null, null, null, null));
*/
}
@After
@ -44,6 +46,7 @@ public class TestModifyCommand {
Command cmd = mock(Command.class);
when(cmd.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
MVWorld world = core.getMVWorldManager().getMVWorld("world");
assertNotNull(world);
@ -51,5 +54,6 @@ public class TestModifyCommand {
assertTrue(core.onCommand(mockCommandSender, cmd, "", // run the command
new String[] { "modify", "set", "hidden", "true", "world" }));
assertTrue(world.isHidden()); // test if it worked
*/
}
}

View File

@ -125,6 +125,7 @@ public class TestWorldProperties {
// ////////////////////////////////////////////////
// let's set some world-properties
// we can test the API with this, too :D
/* This block is preserved for the transition to MV5, just in case
MVWorldManager worldManager = core.getMVWorldManager();
assertNotNull(worldManager);
@ -134,10 +135,12 @@ public class TestWorldProperties {
assertNotNull(netherWorld);
assertSame(mvWorld, worldManager.getFirstSpawnWorld());
assertSame(mvWorld, worldManager.getSpawnWorld());
*/
/* ***************************** *
* Check defaults
* ***************************** */
/* This block is preserved for the transition to MV5, just in case
assertFalse(mvWorld.isHidden());
assertEquals(mvWorld.getName(), mvWorld.getAlias());
assertEquals(ChatColor.WHITE, mvWorld.getColor());
@ -158,10 +161,12 @@ public class TestWorldProperties {
assertTrue(mvWorld.getBedRespawn());
assertTrue(mvWorld.getAutoLoad());
assertEquals(new SpawnLocation(0, 64, 0), mvWorld.getSpawnLocation());
*/
/* ****************************************** *
* Call some events and verify behavior
* ****************************************** */
/* This block is preserved for the transition to MV5, just in case
createEvents(mvWorld);
// call both weather change events
@ -196,16 +201,17 @@ public class TestWorldProperties {
verify(playerRespawnBed, never()).setRespawnLocation(any(Location.class));
core.getPlayerListener().playerRespawn(playerRespawnNormal);
verify(playerRespawnNormal).setRespawnLocation(mvWorld.getSpawnLocation());
// call entity regain health event
core.getEntityListener().entityRegainHealth(entityRegainHealthEvent);
// autoheal is on so nothing should happen
verify(entityRegainHealthEvent, never()).setCancelled(true);
*/
/* ************************ *
* Modify & Verify
* ************************ */
/* This block is preserved for the transition to MV5, just in case
mvWorld.setHidden(true);
assertEquals(true, mvWorld.isHidden());
mvWorld.setAlias("alias");
@ -250,11 +256,13 @@ public class TestWorldProperties {
assertEquals(false, mvWorld.getAutoLoad());
mvWorld.setSpawnLocation(new Location(mvWorld.getCBWorld(), 1, 1, 1));
assertEquals(new SpawnLocation(1, 1, 1), mvWorld.getSpawnLocation());
*/
/* ****************************************** *
* Call some events and verify behavior
* ****************************************** */
/* This block is preserved for the transition to MV5, just in case
// We have to recreate the events and the mock-objects
createEvents(mvWorld);
@ -301,11 +309,13 @@ public class TestWorldProperties {
core.getEntityListener().entityRegainHealth(entityRegainHealthEvent);
// autoheal is off so something should happen
verify(entityRegainHealthEvent).setCancelled(true);
*/
/* ****************************************** *
* Test saving/loading
* ****************************************** */
/* This block is preserved for the transition to MV5, just in case
assertTrue(core.saveAllConfigs());
// change a value here
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(core.getDataFolder(), "worlds.yml"));
@ -339,6 +349,7 @@ public class TestWorldProperties {
assertEquals(false, mvWorld.getBedRespawn());
assertEquals(false, mvWorld.getAutoLoad());
assertEquals(new SpawnLocation(1, 1, 1), mvWorld.getSpawnLocation());
*/
}
public void createEvents(MVWorld mvWorld) {

View File

@ -35,8 +35,10 @@ public class TestWorldPurger {
creator = new TestInstanceCreator();
assertTrue(creator.setUp());
core = creator.getCore();
/* This block is preserved for the transition to MV5, just in case
purger = core.getMVWorldManager().getTheWorldPurger();
core.getMVConfig().setGlobalDebug(3);
*/
mvWorld = mock(MVWorld.class);
cbworld = mock(World.class);
when(mvWorld.getCBWorld()).thenReturn(cbworld);

View File

@ -77,6 +77,7 @@ public class TestWorldStuff {
when(mockCommand.getName()).thenReturn("mv");
String[] normalArgs = new String[]{ "import", "world", "normal" };
/* This block is preserved for the transition to MV5, just in case
// Ensure we have a fresh copy of MV, 0 worlds.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
@ -87,6 +88,7 @@ public class TestWorldStuff {
// We should still have no worlds.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
*/
}
@Test
@ -108,6 +110,8 @@ public class TestWorldStuff {
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
// Ensure that there are no worlds imported. This is a fresh setup.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
@ -137,6 +141,7 @@ public class TestWorldStuff {
verify(mockCommandSender).sendMessage("Starting import of world 'world_nether'...");
verify(mockCommandSender).sendMessage("Starting import of world 'world_the_end'...");
verify(mockCommandSender, VerificationModeFactory.times(3)).sendMessage(ChatColor.GREEN + "Complete!");
*/
}
@Test
@ -154,6 +159,7 @@ public class TestWorldStuff {
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
// Ensure that there are no worlds imported. This is a fresh setup.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
@ -170,6 +176,7 @@ public class TestWorldStuff {
WorldCreatorMatcher matcher = new WorldCreatorMatcher(new WorldCreator("newworld"));
verify(mockServer).createWorld(ArgumentMatchers.argThat(matcher));
*/
}
@Test
@ -187,6 +194,7 @@ public class TestWorldStuff {
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
// Ensure that there are no worlds imported. This is a fresh setup.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
@ -199,6 +207,7 @@ public class TestWorldStuff {
// Verify
verify(mockCommandSender).sendMessage("Invalid generator! 'BogusGen'. " + ChatColor.RED + "Aborting world creation.");
*/
}
@Test
@ -216,6 +225,7 @@ public class TestWorldStuff {
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
// Ensure that there are no worlds imported. This is a fresh setup.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
@ -233,6 +243,7 @@ public class TestWorldStuff {
WorldCreatorMatcher matcher = new WorldCreatorMatcher(new WorldCreator("nullworld"));
verify(mockServer).createWorld(ArgumentMatchers.argThat(matcher));
*/
}
@Test
@ -243,6 +254,7 @@ public class TestWorldStuff {
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
/* This block is preserved for the transition to MV5, just in case
// Ensure that there are no worlds imported. This is a fresh setup.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
this.createInitialWorlds(plugin, mockCommand);
@ -275,6 +287,7 @@ public class TestWorldStuff {
plugin.onCommand(mockCommandSender, mockCommand, "", new String[]{ "modify", "set", "blah", "fish", "world" });
verify(mockCommandSender).sendMessage(ChatColor.RED + "Sorry, You can't set: '" + ChatColor.GRAY + "blah" + ChatColor.RED + "'");
*/
}
private void createInitialWorlds(Plugin plugin, Command command) {

View File

@ -203,6 +203,7 @@ public class TestInstanceCreator {
serverfield.setAccessible(true);
serverfield.set(core, mockServer);
/* This block is preserved for the transition to MV5, just in case
// Set worldManager
SimpleMVWorldManager wm = spy(new SimpleMVWorldManager(core));
Field worldmanagerfield = MultiverseCore.class.getDeclaredField("worldManager");
@ -226,6 +227,7 @@ public class TestInstanceCreator {
Field weatherlistenerfield = MultiverseCore.class.getDeclaredField("weatherListener");
weatherlistenerfield.setAccessible(true);
weatherlistenerfield.set(core, wl);
*/
// Init our command sender
final Logger commandSenderLogger = Logger.getLogger("CommandSender");
@ -263,11 +265,13 @@ public class TestInstanceCreator {
}
public boolean tearDown() {
/* This block is preserved for the transition to MV5, just in case
List<MVWorld> worlds = new ArrayList<MVWorld>(core.getMVWorldManager()
.getMVWorlds());
for (MVWorld world : worlds) {
core.getMVWorldManager().deleteWorld(world.getName());
}
*/
try {
Field serverField = Bukkit.class.getDeclaredField("server");

View File

@ -1,33 +1,12 @@
package org.mvplugins.multiverse.core
import be.seeseemelk.mockbukkit.MockBukkit
import be.seeseemelk.mockbukkit.ServerMock
import com.onarandombox.MultiverseCore.MultiverseCore
import com.onarandombox.MultiverseCore.utils.TestingMode
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertNotNull
class MockBukkitTest {
lateinit var server: ServerMock
lateinit var plugin: MultiverseCore
@BeforeTest
fun setUp() {
TestingMode.enable()
server = MockBukkit.mock()
plugin = MockBukkit.load(MultiverseCore::class.java)
}
@AfterTest
fun tearDown() {
MockBukkit.unmock()
}
open class MockBukkitTest : TestWithMockBukkit() {
@Test
fun `MockBukkit loads the plugin`() {
assertNotNull(plugin)
assertNotNull(multiverseCore)
}
}

View File

@ -0,0 +1,29 @@
package org.mvplugins.multiverse.core
import be.seeseemelk.mockbukkit.MockBukkit
import be.seeseemelk.mockbukkit.ServerMock
import com.onarandombox.MultiverseCore.MultiverseCore
import com.onarandombox.MultiverseCore.utils.TestingMode
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
/**
* Basic abstract test class that sets up MockBukkit and MultiverseCore.
*/
abstract class TestWithMockBukkit {
protected lateinit var server: ServerMock
protected lateinit var multiverseCore: MultiverseCore
@BeforeTest
fun setUp() {
TestingMode.enable()
server = MockBukkit.mock()
multiverseCore = MockBukkit.load(MultiverseCore::class.java)
}
@AfterTest
fun tearDown() {
MockBukkit.unmock()
}
}

View File

@ -0,0 +1,145 @@
package org.mvplugins.multiverse.core.inject
import com.onarandombox.MultiverseCore.anchor.AnchorManager
import com.onarandombox.MultiverseCore.api.BlockSafety
import com.onarandombox.MultiverseCore.api.Destination
import com.onarandombox.MultiverseCore.api.LocationManipulation
import com.onarandombox.MultiverseCore.api.MVConfig
import com.onarandombox.MultiverseCore.api.MVWorldManager
import com.onarandombox.MultiverseCore.api.SafeTTeleporter
import com.onarandombox.MultiverseCore.commandtools.MVCommandManager
import com.onarandombox.MultiverseCore.commandtools.MultiverseCommand
import com.onarandombox.MultiverseCore.config.MVCoreConfigProvider
import com.onarandombox.MultiverseCore.economy.MVEconomist
import com.onarandombox.MultiverseCore.listeners.MVChatListener
import com.onarandombox.MultiverseCore.listeners.MVEntityListener
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener
import com.onarandombox.MultiverseCore.listeners.MVPortalListener
import com.onarandombox.MultiverseCore.listeners.MVWeatherListener
import com.onarandombox.MultiverseCore.listeners.MVWorldInitListener
import com.onarandombox.MultiverseCore.listeners.MVWorldListener
import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety
import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation
import com.onarandombox.MultiverseCore.teleportation.SimpleSafeTTeleporter
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator
import com.onarandombox.MultiverseCore.world.SimpleMVWorldManager
import org.mvplugins.multiverse.core.TestWithMockBukkit
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.Test
import kotlin.test.assertNull
class InjectionTest : TestWithMockBukkit() {
@Test
fun `AnchorManager is available as a service`() {
assertNotNull(multiverseCore.getService(AnchorManager::class.java))
}
@Test
fun `BlockSafety is available as a service`() {
assertNotNull(multiverseCore.getService(BlockSafety::class.java))
assertNotNull(multiverseCore.getService(SimpleBlockSafety::class.java))
}
@Test
fun `MVCommandManager is available as a service`() {
assertNotNull(multiverseCore.getService(MVCommandManager::class.java))
}
@Test
fun `MVEconomist is available as a service`() {
assertNotNull(multiverseCore.getService(MVEconomist::class.java))
}
@Test
fun `LocationManipulation is available as a service`() {
assertNotNull(multiverseCore.getService(LocationManipulation::class.java))
assertNotNull(multiverseCore.getService(SimpleLocationManipulation::class.java))
}
@Test
fun `SafeTTeleporter is available as a service`() {
assertNotNull(multiverseCore.getService(SafeTTeleporter::class.java))
assertNotNull(multiverseCore.getService(SimpleSafeTTeleporter::class.java))
}
@Test
fun `UnsafeCallWrapper is available as a service`() {
assertNotNull(multiverseCore.getService(UnsafeCallWrapper::class.java))
}
@Test
fun `MVWorldManager is available as a service`() {
assertNotNull(multiverseCore.getService(MVWorldManager::class.java))
assertNotNull(multiverseCore.getService(SimpleMVWorldManager::class.java))
}
@Test
fun `MVEntityListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVEntityListener::class.java))
}
@Test
fun `MVPlayerListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVPlayerListener::class.java))
}
@Test
fun `MVChatListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVChatListener::class.java))
}
@Test
fun `MVPortalListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVPortalListener::class.java))
}
@Test
fun `MVWeatherListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVWeatherListener::class.java))
}
@Test
fun `MVWorldListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVWorldListener::class.java))
}
@Test
fun `MVWorldInitListener is available as a service`() {
assertNotNull(multiverseCore.getService(MVWorldInitListener::class.java))
}
@Test
fun `MVCoreConfigProvider is available as a service`() {
assertNotNull(multiverseCore.getService(MVCoreConfigProvider::class.java))
}
@Test
fun `Commands are available as services`() {
val commands = multiverseCore.getAllServices(MultiverseCommand::class.java)
// TODO come up with a better way to test this like via actually testing the effect of calling each command
assertEquals(16, commands.size)
}
@Test
fun `Destinations are available as services`() {
val destinations = multiverseCore.getAllServices(Destination::class.java)
// TODO come up with a better way to test this like via actually testing the effect of using each destination
assertEquals(6, destinations.size)
}
@Test
fun `MVConfig is not available as a service`() {
// We need one test case for asking for non-services to make sure we don't accidentally make them available
// and that the getService method doesn't throw an exception
assertNull(multiverseCore.getService(MVConfig::class.java))
}
@Test
fun `MetricsConfigurator is not available as a service`() {
// Also making sure this is not loaded automatically since it's supposed to be disabled during tests
assertNull(multiverseCore.getService(MetricsConfigurator::class.java))
}
}