forked from upstream/Multiverse-Core
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
167f6f8a37 | ||
|
|
325b5d7643 | ||
|
|
6c50bfb08e | ||
|
|
37c0580828 | ||
|
|
e1a42cec92 | ||
|
|
a6cc8bd68e | ||
|
|
ee4cd18522 | ||
|
|
b6c309a332 | ||
|
|
87571e7037 | ||
|
|
0822b1460a | ||
|
|
1220998c12 | ||
|
|
e078c5e5dd | ||
|
|
c1ef8f656b | ||
|
|
86e2112d87 | ||
|
|
8a77dc807e | ||
|
|
77382dacf3 | ||
|
|
588a8e1baf | ||
|
|
5bd37d17c3 | ||
|
|
815637e00f | ||
|
|
78194389eb | ||
|
|
2db55fab3b | ||
|
|
c505da76ec | ||
|
|
6152620541 | ||
|
|
cf70b3b839 | ||
|
|
527085713c | ||
|
|
f446c94dbc | ||
|
|
aac0111dde | ||
|
|
f66e673ea9 | ||
|
|
1434ca176a | ||
|
|
212b68437e | ||
|
|
05d01884ad | ||
|
|
65c399740e |
No files matched your search
@@ -1 +0,0 @@
|
||||
.gitea/CODEOWNERS linguist-detectable=false
|
||||
@@ -1,3 +0,0 @@
|
||||
# Pull requests request review from the eligible staff team(s).
|
||||
# One approval from either an Admin or Developer satisfies branch protection.
|
||||
* @trueog/Admins @trueog/Developers
|
||||
@@ -1,4 +0,0 @@
|
||||
kotlin version: 2.0.21
|
||||
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
|
||||
1. Kotlin compile daemon is ready
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id 'org.mvplugins.multiverse-plugin' version '1.2.2'
|
||||
}
|
||||
|
||||
group = 'org.mvplugins.multiverse.core'
|
||||
description = 'Multiverse-Core'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = 'aikar repo'
|
||||
url = uri('https://repo.aikar.co/content/groups/aikar/')
|
||||
}
|
||||
|
||||
maven {
|
||||
name = 'glaremasters repo'
|
||||
url = 'https://repo.glaremasters.me/repository/towny/'
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "helpchatRepoReleases"
|
||||
url = uri("https://repo.helpch.at/releases/")
|
||||
}
|
||||
}
|
||||
|
||||
configure(apiDependencies) {
|
||||
serverApiVersion = '1.21.11-R0.1-SNAPSHOT'
|
||||
mockBukkitServerApiVersion = '1.21'
|
||||
mockBukkitVersion = '4.100.0'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Economy
|
||||
externalPlugin('com.github.MilkBowl:VaultAPI:1.7.1') {
|
||||
exclude group: 'org.bukkit', module: 'bukkit'
|
||||
}
|
||||
|
||||
// PlaceholderAPI
|
||||
externalPlugin 'me.clip:placeholderapi:2.11.6'
|
||||
|
||||
// Command Framework
|
||||
shadowed 'co.aikar:acf-paper:0.5.1-SNAPSHOT'
|
||||
|
||||
// Config
|
||||
shadowed('io.github.townyadvanced.commentedconfiguration:CommentedConfiguration:1.0.1') {
|
||||
exclude group: 'org.spigotmc', module: 'spigot-api'
|
||||
}
|
||||
|
||||
// Utils
|
||||
shadowed 'io.vavr:vavr:0.10.7'
|
||||
shadowed 'org.glassfish.hk2:hk2-locator:3.1.1'
|
||||
shadowed('org.glassfish.hk2:hk2-inhabitant-generator:3.1.1') {
|
||||
exclude group: 'org.apache.maven', module: 'maven-core'
|
||||
}
|
||||
shadowed('com.dumptruckman.minecraft:Logging:1.1.1') {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
shadowed 'de.themoep.idconverter:mappings:1.2-SNAPSHOT'
|
||||
shadowed('org.bstats:bstats-bukkit:3.1.0') {
|
||||
exclude group: 'org.bukkit', module: 'bukkit'
|
||||
}
|
||||
shadowed 'net.minidev:json-smart:2.5.2'
|
||||
shadowed 'org.jetbrains:annotations:26.0.2'
|
||||
shadowed 'io.papermc:paperlib:1.0.8'
|
||||
|
||||
// Tests
|
||||
testImplementation('com.googlecode.json-simple:json-simple:1.1.1') {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
testImplementation("org.hamcrest:hamcrest:3.0")
|
||||
}
|
||||
|
||||
ext.bitlyAccessToken = System.getenv('BITLY_ACCESS_TOKEN') ?: 'bitly-access-token'
|
||||
|
||||
tasks.register('prepareSource', Sync) {
|
||||
inputs.property 'bitlyAccessToken', bitlyAccessToken
|
||||
from sourceSets.main.java
|
||||
into "$buildDir/src"
|
||||
filter(ReplaceTokens, tokens: [
|
||||
'bitly-access-token': bitlyAccessToken,
|
||||
])
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
relocate 'co.aikar', 'org.mvplugins.multiverse.external.acf'
|
||||
relocate 'com.dumptruckman.minecraft.util.Logging', 'org.mvplugins.multiverse.core.utils.CoreLogging'
|
||||
relocate 'com.dumptruckman.minecraft.util.DebugLog', 'org.mvplugins.multiverse.core.utils.DebugFileLogger'
|
||||
relocate 'de.themoep.idconverter', 'org.mvplugins.multiverse.external.idconverter'
|
||||
relocate 'io.github.townyadvanced.commentedconfiguration', 'org.mvplugins.multiverse.external.commentedconfiguration'
|
||||
relocate 'org.bstats', 'org.mvplugins.multiverse.external.bstats'
|
||||
relocate 'com.sun', 'org.mvplugins.multiverse.external.sun'
|
||||
relocate 'net.minidev', 'org.mvplugins.multiverse.external.minidev'
|
||||
relocate 'org.objectweb', 'org.mvplugins.multiverse.external.objectweb'
|
||||
relocate 'io.vavr', 'org.mvplugins.multiverse.external.vavr'
|
||||
relocate 'jakarta', 'org.mvplugins.multiverse.external.jakarta'
|
||||
relocate 'javassist', 'org.mvplugins.multiverse.external.javassist'
|
||||
relocate 'org.aopalliance', 'org.mvplugins.multiverse.external.aopalliance'
|
||||
relocate 'org.glassfish', 'org.mvplugins.multiverse.external.glassfish'
|
||||
relocate 'org.jvnet', 'org.mvplugins.multiverse.external.jvnet'
|
||||
relocate 'org.intellij', 'org.mvplugins.multiverse.external.intellij'
|
||||
relocate 'org.jetbrains', 'org.mvplugins.multiverse.external.jetbrains'
|
||||
relocate 'io.papermc.lib', 'org.mvplugins.multiverse.external.paperlib'
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "GitHubPackages"
|
||||
url = "https://maven.pkg.github.com/Multiverse/Multiverse-Core"
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_ACTOR")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import groovy.util.Node
|
||||
import groovy.util.NodeList
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.credentials.PasswordCredentials
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.api.tasks.Sync
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
||||
import org.gradle.external.javadoc.StandardJavadocDocletOptions
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
eclipse
|
||||
`maven-publish`
|
||||
id("com.gradleup.shadow") version "8.3.9"
|
||||
kotlin("jvm") version "2.0.21"
|
||||
}
|
||||
|
||||
group = "org.mvplugins.multiverse.core"
|
||||
version = System.getenv("GITHUB_VERSION") ?: "5.3.4.17"
|
||||
description = "Multiverse-Core"
|
||||
|
||||
val sourceSets = extensions.getByType<SourceSetContainer>()
|
||||
|
||||
val serverApi: Configuration by configurations.creating
|
||||
val externalPlugin: Configuration by configurations.creating
|
||||
val shadowed: Configuration by configurations.creating
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
|
||||
maven {
|
||||
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri("https://repo.onarandombox.com/content/groups/public")
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri("https://hub.spigotmc.org/nexus/content/groups/public/")
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri("https://jitpack.io")
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri("https://repo.minebench.de/")
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri("https://repo.maven.apache.org/maven2/")
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "aikar repo"
|
||||
url = uri("https://repo.aikar.co/content/groups/aikar/")
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "glaremasters repo"
|
||||
url = uri("https://repo.glaremasters.me/repository/towny/")
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "helpchatRepoReleases"
|
||||
url = uri("https://repo.helpch.at/releases/")
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "papermc repo"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
// Purpur API
|
||||
maven("https://repo.purpurmc.org/snapshots")
|
||||
}
|
||||
|
||||
// Configuration wiring like in the Groovy build
|
||||
configurations["compileOnly"].extendsFrom(serverApi)
|
||||
configurations["runtimeClasspath"].extendsFrom(serverApi)
|
||||
|
||||
configurations["implementation"].extendsFrom(externalPlugin)
|
||||
|
||||
configurations["compileClasspath"].extendsFrom(shadowed)
|
||||
configurations["testCompileClasspath"].extendsFrom(shadowed)
|
||||
configurations["testRuntimeClasspath"].extendsFrom(shadowed)
|
||||
|
||||
dependencies {
|
||||
// Server API: Purpur 1.19.4
|
||||
serverApi("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT")
|
||||
|
||||
// Economy
|
||||
externalPlugin("com.github.MilkBowl:VaultAPI:1.7.1") {
|
||||
exclude(group = "org.bukkit", module = "bukkit")
|
||||
}
|
||||
|
||||
// PlaceholderAPI
|
||||
externalPlugin("me.clip:placeholderapi:2.11.6")
|
||||
|
||||
// Command Framework
|
||||
shadowed("co.aikar:acf-paper:0.5.1-SNAPSHOT")
|
||||
|
||||
// Config
|
||||
shadowed("io.github.townyadvanced.commentedconfiguration:CommentedConfiguration:1.0.1") {
|
||||
exclude(group = "org.spigotmc", module = "spigot-api")
|
||||
}
|
||||
|
||||
// Utils
|
||||
shadowed("io.vavr:vavr:0.10.4")
|
||||
shadowed("org.glassfish.hk2:hk2-locator:3.0.3")
|
||||
shadowed("org.glassfish.hk2:hk2-inhabitant-generator:3.0.3") {
|
||||
exclude(group = "org.apache.maven", module = "maven-core")
|
||||
}
|
||||
shadowed("com.dumptruckman.minecraft:Logging:1.1.1") {
|
||||
exclude(group = "junit", module = "junit")
|
||||
}
|
||||
shadowed("de.themoep.idconverter:mappings:1.2-SNAPSHOT")
|
||||
shadowed("org.bstats:bstats-bukkit:3.1.0") {
|
||||
exclude(group = "org.bukkit", module = "bukkit")
|
||||
}
|
||||
shadowed("net.minidev:json-smart:2.4.9")
|
||||
shadowed("org.jetbrains:annotations:22.0.0")
|
||||
shadowed("io.papermc:paperlib:1.0.8")
|
||||
|
||||
// Tests
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21")
|
||||
testImplementation("com.github.seeseemelk:MockBukkit-v1.19:3.1.0")
|
||||
testImplementation("com.googlecode.json-simple:json-simple:1.1.1") {
|
||||
exclude(group = "junit", module = "junit")
|
||||
}
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||
testImplementation("com.natpryce:hamkrest:1.8.0.1")
|
||||
testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
|
||||
|
||||
// Annotation Processors
|
||||
annotationProcessor("org.glassfish.hk2:hk2-metadata-generator:3.0.3")
|
||||
testAnnotationProcessor("org.glassfish.hk2:hk2-metadata-generator:3.0.3")
|
||||
}
|
||||
|
||||
java {
|
||||
// Plugin is compiled for Java 17 (GraalVM 17-friendly)
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
val bitlyAccessToken: String = System.getenv("BITLY_ACCESS_TOKEN") ?: "bitly-access-token"
|
||||
|
||||
// === Token-filtered source generation (prepareSource) ===
|
||||
val prepareSource by tasks.registering(Sync::class) {
|
||||
inputs.property("bitlyAccessToken", bitlyAccessToken)
|
||||
from(sourceSets["main"].java)
|
||||
// avoid deprecated buildDir getter
|
||||
into(layout.buildDirectory.dir("src"))
|
||||
filter<ReplaceTokens>(
|
||||
"tokens" to mapOf(
|
||||
"bitly-access-token" to bitlyAccessToken,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Use ONLY the filtered sources for compileJava (fixes duplicate classes)
|
||||
tasks.named<JavaCompile>("compileJava") {
|
||||
dependsOn(prepareSource)
|
||||
source = prepareSource.get().outputs.files.asFileTree
|
||||
sourceCompatibility = JavaVersion.VERSION_17.toString()
|
||||
targetCompatibility = JavaVersion.VERSION_17.toString()
|
||||
}
|
||||
|
||||
tasks.named<JavaCompile>("compileTestJava") {
|
||||
sourceCompatibility = JavaVersion.VERSION_17.toString()
|
||||
targetCompatibility = JavaVersion.VERSION_17.toString()
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
options.compilerArgs.add(
|
||||
"-Aorg.glassfish.hk2.metadata.location=META-INF/hk2-locator/Multiverse-Core",
|
||||
)
|
||||
}
|
||||
|
||||
tasks.withType<Javadoc>().configureEach {
|
||||
(options as StandardJavadocDocletOptions).encoding = "UTF-8"
|
||||
}
|
||||
|
||||
tasks.named<KotlinCompile>("compileTestKotlin") {
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
javaParameters.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
// We're not using Kotlin in the plugin itself, just tests!
|
||||
tasks.named<KotlinCompile>("compileKotlin") {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
configurations
|
||||
.filterNot { it.name.startsWith("test") }
|
||||
.forEach {
|
||||
it.exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk8")
|
||||
}
|
||||
|
||||
tasks.named<ProcessResources>("processResources") {
|
||||
val props = mapOf("version" to project.version.toString())
|
||||
inputs.properties(props)
|
||||
filteringCharset = "UTF-8"
|
||||
filesMatching("plugin.yml") {
|
||||
expand(props)
|
||||
}
|
||||
// Never up-to-date: tests depend on fresh version expansion
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
|
||||
tasks.named<Javadoc>("javadoc") {
|
||||
source = sourceSets["main"].allJava
|
||||
classpath = configurations["compileClasspath"]
|
||||
}
|
||||
|
||||
// Removed: configurations["api"].isCanBeResolved = true (deprecated in Gradle 8/9)
|
||||
|
||||
val jarTask = tasks.named<Jar>("jar")
|
||||
val shadowJarTask = tasks.named<ShadowJar>("shadowJar")
|
||||
|
||||
listOf("apiElements", "runtimeElements").forEach { configurationName ->
|
||||
configurations.named(configurationName) {
|
||||
outgoing.artifacts.removeIf { artifact ->
|
||||
artifact.buildDependencies.getDependencies(null).contains(jarTask.get())
|
||||
}
|
||||
outgoing.artifact(shadowJarTask)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("co.aikar", "org.mvplugins.multiverse.external.acf")
|
||||
relocate("com.dumptruckman.minecraft.util.Logging", "org.mvplugins.multiverse.core.utils.CoreLogging")
|
||||
relocate("com.dumptruckman.minecraft.util.DebugLog", "org.mvplugins.multiverse.core.utils.DebugFileLogger")
|
||||
relocate("de.themoep.idconverter", "org.mvplugins.multiverse.external.idconverter")
|
||||
relocate("io.github.townyadvanced.commentedconfiguration", "org.mvplugins.multiverse.external.commentedconfiguration")
|
||||
relocate("me.main__.util", "org.mvplugins.multiverse.external.serializationconfig")
|
||||
relocate("org.bstats", "org.mvplugins.multiverse.external.bstats")
|
||||
relocate("com.sun", "org.mvplugins.multiverse.external.sun")
|
||||
relocate("net.minidev", "org.mvplugins.multiverse.external.minidev")
|
||||
relocate("org.objectweb", "org.mvplugins.multiverse.external.objectweb")
|
||||
relocate("io.vavr", "org.mvplugins.multiverse.external.vavr")
|
||||
relocate("jakarta", "org.mvplugins.multiverse.external.jakarta")
|
||||
relocate("javassist", "org.mvplugins.multiverse.external.javassist")
|
||||
relocate("org.aopalliance", "org.mvplugins.multiverse.external.aopalliance")
|
||||
relocate("org.glassfish", "org.mvplugins.multiverse.external.glassfish")
|
||||
relocate("org.jvnet", "org.mvplugins.multiverse.external.jvnet")
|
||||
relocate("org.intellij", "org.mvplugins.multiverse.external.intellij")
|
||||
relocate("org.jetbrains", "org.mvplugins.multiverse.external.jetbrains")
|
||||
relocate("io.papermc.lib", "org.mvplugins.multiverse.external.paperlib")
|
||||
|
||||
configurations = listOf(project.configurations["shadowed"])
|
||||
|
||||
archiveClassifier.set("")
|
||||
|
||||
dependencies {
|
||||
exclude { dependency ->
|
||||
dependency.moduleGroup == "org.jetbrains.kotlin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("build") {
|
||||
dependsOn("shadowJar")
|
||||
}
|
||||
|
||||
tasks.named<Jar>("jar") {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
tasks.named<Test>("test") {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
exceptionFormat = TestExceptionFormat.FULL
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
|
||||
pom.withXml {
|
||||
val pomNode = asNode()
|
||||
|
||||
val dependenciesNode = (
|
||||
(pomNode.get("dependencies") as? NodeList)
|
||||
?.firstOrNull() as? Node
|
||||
) ?: (pomNode.appendNode("dependencies") as Node)
|
||||
|
||||
val dependencyNodes = dependenciesNode.children().filterIsInstance<Node>().toList()
|
||||
|
||||
// Remove Kotlin dependency
|
||||
dependencyNodes
|
||||
.filter { dependencyNode ->
|
||||
val groupIdNodes = dependencyNode.get("groupId") as? NodeList ?: return@filter false
|
||||
val groupId = (groupIdNodes.firstOrNull() as? Node)?.text()
|
||||
groupId == "org.jetbrains.kotlin"
|
||||
}
|
||||
.forEach { dependencyNode ->
|
||||
dependenciesNode.remove(dependencyNode)
|
||||
}
|
||||
|
||||
// Switch runtime deps to provided
|
||||
dependencyNodes.forEach { dependencyNode ->
|
||||
val scopeNodes = dependencyNode.get("scope") as? NodeList ?: return@forEach
|
||||
val scopeNode = scopeNodes.firstOrNull() as? Node ?: return@forEach
|
||||
if (scopeNode.text() == "runtime") {
|
||||
scopeNode.setValue("provided")
|
||||
}
|
||||
}
|
||||
|
||||
// Add server API (Purpur) to pom as provided
|
||||
configurations["serverApi"].allDependencies.forEach { dependency ->
|
||||
val depNode = dependenciesNode.appendNode("dependency")
|
||||
depNode.appendNode("groupId", dependency.group)
|
||||
depNode.appendNode("artifactId", dependency.name)
|
||||
depNode.appendNode("version", dependency.version)
|
||||
depNode.appendNode("scope", "provided")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
name = "GitHubPackages"
|
||||
url = uri("https://maven.pkg.github.com/Multiverse/Multiverse-Core")
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_ACTOR")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = "multiverse"
|
||||
val releasesRepoUrl = uri("https://repo.dumptruckman.com/multiverse-releases")
|
||||
val snapshotsRepoUrl = uri("https://repo.dumptruckman.com/multiverse-snapshots")
|
||||
url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
|
||||
credentials(PasswordCredentials::class)
|
||||
}
|
||||
|
||||
maven {
|
||||
// todo: remove before mv5 release
|
||||
name = "multiverseBeta"
|
||||
url = uri("https://repo.c0ding.party/multiverse-beta")
|
||||
credentials(PasswordCredentials::class)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -1,7 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -15,8 +15,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -57,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -85,9 +83,10 @@ done
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -134,13 +133,10 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
@@ -148,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -156,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -201,15 +197,11 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
||||
Vendored
+10
-12
@@ -13,8 +13,6 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@@ -45,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -59,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
url = uri('https://repo.onarandombox.com/multiverse-releases')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = 'multiverse-core'
|
||||
@@ -1,11 +0,0 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
url = uri("https://repo.onarandombox.com/multiverse-releases")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "Multiverse-Core"
|
||||
|
||||
@@ -126,6 +126,7 @@ public class MultiverseCore extends MultiverseModule {
|
||||
MultiverseCoreApi.shutdown();
|
||||
shutdownDependencyInjection();
|
||||
PluginServiceLocatorFactory.get().shutdown();
|
||||
Logging.info("- Disabled");
|
||||
Logging.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.mvplugins.multiverse.core;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import io.vavr.control.Option;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.inject.Inject;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
@@ -12,11 +13,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig;
|
||||
import org.mvplugins.multiverse.core.economy.MVEconomist;
|
||||
import org.mvplugins.multiverse.core.utils.MinecraftTimeFormatter;
|
||||
import org.mvplugins.multiverse.core.utils.REPatterns;
|
||||
import org.mvplugins.multiverse.core.utils.StringFormatter;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.MultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
|
||||
import java.util.List;
|
||||
@@ -26,12 +29,17 @@ import java.util.Locale;
|
||||
final class PlaceholderExpansionHook extends PlaceholderExpansion {
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private final CoreConfig coreConfig;
|
||||
private final WorldManager worldManager;
|
||||
private final MVEconomist economist;
|
||||
|
||||
@Inject
|
||||
public PlaceholderExpansionHook(MultiverseCore plugin, WorldManager worldManager, MVEconomist economist) {
|
||||
public PlaceholderExpansionHook(@NotNull MultiverseCore plugin,
|
||||
@NotNull CoreConfig coreConfig,
|
||||
@NotNull WorldManager worldManager,
|
||||
@NotNull MVEconomist economist) {
|
||||
this.plugin = plugin;
|
||||
this.coreConfig = coreConfig;
|
||||
this.worldManager = worldManager;
|
||||
this.economist = economist;
|
||||
}
|
||||
@@ -42,6 +50,13 @@ final class PlaceholderExpansionHook extends PlaceholderExpansion {
|
||||
return super.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(String msg) {
|
||||
if (coreConfig.getWarnInvalidPapiFormat()) {
|
||||
super.warning(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "multiverse-core";
|
||||
@@ -80,136 +95,101 @@ final class PlaceholderExpansionHook extends PlaceholderExpansion {
|
||||
return null;
|
||||
}
|
||||
|
||||
final var placeholder = paramsArray.remove(0);
|
||||
final var placeholder = paramsArray.remove(0).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
String worldName = parseWorldName(offlinePlayer, paramsArray);
|
||||
if (worldName == null) return null;
|
||||
|
||||
return worldManager.getLoadedWorld(worldName)
|
||||
.onEmpty(() -> warning("Multiverse World not found: " + worldName))
|
||||
.map(world -> getWorldPlaceHolderValue(placeholder, paramsArray, world))
|
||||
.getOrNull();
|
||||
return parseWorldName(offlinePlayer, paramsArray)
|
||||
.flatMap(worldName -> worldManager.getWorld(worldName)
|
||||
.onEmpty(() -> warning("Multiverse World not found: " + worldName)))
|
||||
.flatMap(world -> world.asLoadedWorld()
|
||||
.flatMap(loadedWorld -> getLoadedWorldPlaceHolderValue(placeholder, paramsArray, loadedWorld))
|
||||
.orElse(() -> getWorldPlaceHolderValue(placeholder, paramsArray, world)))
|
||||
.getOrElse(() -> coreConfig.getInvalidPapiFormatReturnsBlank() ? "" : null);
|
||||
}
|
||||
|
||||
private @Nullable String parseWorldName(OfflinePlayer offlinePlayer, List<String> paramsArray) {
|
||||
private @NotNull Option<String> parseWorldName(OfflinePlayer offlinePlayer, List<String> paramsArray) {
|
||||
// No world defined, get from player
|
||||
if (paramsArray.isEmpty()) {
|
||||
if (offlinePlayer instanceof Player player) {
|
||||
return player.getWorld().getName();
|
||||
return Option.of(player.getWorld().getName());
|
||||
} else {
|
||||
warning("You must specify a world name for non-player placeholders");
|
||||
return null;
|
||||
return Option.none();
|
||||
}
|
||||
}
|
||||
|
||||
// Try get from params
|
||||
String paramWorldName = paramsArray.get(paramsArray.size() - 1);
|
||||
if (worldManager.isLoadedWorld(paramWorldName)) {
|
||||
if (worldManager.isWorld(paramWorldName)) {
|
||||
paramsArray.remove(paramsArray.size() - 1);
|
||||
return paramWorldName;
|
||||
return Option.of(paramWorldName);
|
||||
}
|
||||
|
||||
// Param not a world, fallback to player
|
||||
if (offlinePlayer instanceof Player player) {
|
||||
return player.getWorld().getName();
|
||||
return Option.of(player.getWorld().getName());
|
||||
}
|
||||
warning("Multiverse World not found: " + paramWorldName);
|
||||
return null;
|
||||
return Option.none();
|
||||
}
|
||||
|
||||
private @Nullable String getWorldPlaceHolderValue(@NotNull String placeholder,
|
||||
@NotNull List<String> placeholderParams,
|
||||
@NotNull LoadedMultiverseWorld world) {
|
||||
// Switch to find what specific placeholder we want
|
||||
switch (placeholder.toLowerCase(Locale.ENGLISH)) {
|
||||
case "alias" -> {
|
||||
return world.getAliasOrName();
|
||||
private @NotNull Option<String> getWorldPlaceHolderValue(@NotNull String placeholder,
|
||||
@NotNull List<String> placeholderParams,
|
||||
@NotNull MultiverseWorld world) {
|
||||
return Option.of(switch (placeholder) {
|
||||
case "alias" -> world.getAliasOrName();
|
||||
case "animalspawn" -> String.valueOf(world.getEntitySpawnConfig()
|
||||
.getSpawnCategoryConfig(SpawnCategory.ANIMAL)
|
||||
.isSpawn());
|
||||
case "autoheal" -> String.valueOf(world.getAutoHeal());
|
||||
case "blacklist" -> String.join(", ", world.getWorldBlacklist());
|
||||
case "currency" -> String.valueOf(world.getCurrency());
|
||||
case "difficulty" -> world.getDifficulty().toString();
|
||||
case "entryfee" -> economist.formatPrice(world.getPrice(), world.getCurrency());
|
||||
case "environment" -> world.getEnvironment().toString().toLowerCase();
|
||||
case "flight" -> String.valueOf(world.isAllowFlight());
|
||||
case "gamemode" -> world.getGameMode().toString().toLowerCase();
|
||||
case "generator" -> world.getGenerator();
|
||||
case "hunger" -> String.valueOf(world.isHunger());
|
||||
case "monstersspawn" -> String.valueOf(world.getEntitySpawnConfig()
|
||||
.getSpawnCategoryConfig(SpawnCategory.MONSTER)
|
||||
.isSpawn());
|
||||
case "name" -> world.getName();
|
||||
case "playerlimit" -> String.valueOf(world.getPlayerLimit());
|
||||
case "price" -> String.valueOf(world.getPrice());
|
||||
case "pvp" -> String.valueOf(world.getPvp());
|
||||
case "seed" -> String.valueOf(world.getSeed());
|
||||
case "weather" -> String.valueOf(world.isAllowWeather());
|
||||
case "playercount", "time", "type" -> {
|
||||
warning("Placeholder '" + placeholder + "' is only available for loaded worlds.");
|
||||
yield null;
|
||||
}
|
||||
case "animalspawn" -> {
|
||||
return String.valueOf(world.getEntitySpawnConfig().getSpawnCategoryConfig(SpawnCategory.ANIMAL).isSpawn());
|
||||
}
|
||||
case "autoheal" -> {
|
||||
return String.valueOf(world.getAutoHeal());
|
||||
}
|
||||
case "blacklist" -> {
|
||||
return String.join(", ", world.getWorldBlacklist());
|
||||
}
|
||||
case "currency" -> {
|
||||
return String.valueOf(world.getCurrency());
|
||||
}
|
||||
case "difficulty" -> {
|
||||
return world.getDifficulty().toString();
|
||||
}
|
||||
case "entryfee" -> {
|
||||
return economist.formatPrice(world.getPrice(), world.getCurrency());
|
||||
}
|
||||
case "environment" -> {
|
||||
return world.getEnvironment().toString().toLowerCase();
|
||||
}
|
||||
case "flight" -> {
|
||||
return String.valueOf(world.isAllowFlight());
|
||||
}
|
||||
case "gamemode" -> {
|
||||
return world.getGameMode().toString().toLowerCase();
|
||||
}
|
||||
case "generator" -> {
|
||||
return world.getGenerator();
|
||||
}
|
||||
case "hunger" -> {
|
||||
return String.valueOf(world.isHunger());
|
||||
}
|
||||
case "monstersspawn" -> {
|
||||
return String.valueOf(world.getEntitySpawnConfig().getSpawnCategoryConfig(SpawnCategory.MONSTER).isSpawn());
|
||||
}
|
||||
case "name" -> {
|
||||
return world.getName();
|
||||
}
|
||||
case "playercount" -> {
|
||||
return String.valueOf(world.getBukkitWorld()
|
||||
.map(World::getPlayers)
|
||||
.map(List::size)
|
||||
.getOrElse(-1));
|
||||
}
|
||||
case "playerlimit" -> {
|
||||
return String.valueOf(world.getPlayerLimit());
|
||||
}
|
||||
case "price" -> {
|
||||
return String.valueOf(world.getPrice());
|
||||
}
|
||||
case "pvp" -> {
|
||||
return String.valueOf(world.getPvp());
|
||||
}
|
||||
case "seed" -> {
|
||||
return String.valueOf(world.getSeed());
|
||||
default -> {
|
||||
warning("Unknown Placeholder: " + placeholder);
|
||||
yield null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private @NotNull Option<String> getLoadedWorldPlaceHolderValue(@NotNull String placeholder,
|
||||
@NotNull List<String> placeholderParams,
|
||||
@NotNull LoadedMultiverseWorld world) {
|
||||
return Option.of(switch (placeholder) {
|
||||
case "playercount" -> String.valueOf(world.getBukkitWorld()
|
||||
.map(World::getPlayers)
|
||||
.map(List::size)
|
||||
.getOrElse(-1));
|
||||
case "time" -> {
|
||||
String timeFormat = !placeholderParams.isEmpty() ? placeholderParams.get(0) : "";
|
||||
long time = world.getBukkitWorld().map(World::getTime).getOrElse(0L);
|
||||
switch (timeFormat) {
|
||||
case "" -> {
|
||||
return String.valueOf(time);
|
||||
}
|
||||
case "12h" -> {
|
||||
return MinecraftTimeFormatter.format12h(time);
|
||||
}
|
||||
case "24h" -> {
|
||||
return MinecraftTimeFormatter.format24h(time);
|
||||
}
|
||||
default -> {
|
||||
return MinecraftTimeFormatter.formatTime(time, timeFormat);
|
||||
}
|
||||
}
|
||||
yield switch (timeFormat) {
|
||||
case "" -> String.valueOf(time);
|
||||
case "12h" -> MinecraftTimeFormatter.format12h(time);
|
||||
case "24h" -> MinecraftTimeFormatter.format24h(time);
|
||||
default -> MinecraftTimeFormatter.formatTime(time, timeFormat);
|
||||
};
|
||||
}
|
||||
case "type" -> {
|
||||
return world.getBukkitWorld().map(World::getWorldType).map(Enum::name).getOrElse("null");
|
||||
}
|
||||
case "weather" -> {
|
||||
return String.valueOf(world.isAllowWeather());
|
||||
}
|
||||
default -> {
|
||||
warning("Unknown placeholder: " + placeholder);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
case "type" -> world.getBukkitWorld().map(World::getWorldType).map(Enum::name).getOrElse("null");
|
||||
default -> null;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
import org.mvplugins.multiverse.core.world.generators.GeneratorPlugin;
|
||||
import org.mvplugins.multiverse.core.world.generators.GeneratorProvider;
|
||||
|
||||
import static org.mvplugins.multiverse.core.utils.StringFormatter.addonToCommaSeperated;
|
||||
import static org.mvplugins.multiverse.core.utils.StringFormatter.addOnToCommaSeparated;
|
||||
|
||||
@Service
|
||||
public class MVCommandCompletions extends PaperCommandCompletions {
|
||||
@@ -163,7 +163,7 @@ public class MVCommandCompletions extends PaperCommandCompletions {
|
||||
}
|
||||
}
|
||||
if (context.hasConfig("multiple")) {
|
||||
return addonToCommaSeperated(context.getInput(), handler.getCompletions(context));
|
||||
return addOnToCommaSeparated(context.getInput(), handler.getCompletions(context));
|
||||
}
|
||||
return handler.getCompletions(context);
|
||||
}
|
||||
@@ -334,7 +334,7 @@ public class MVCommandCompletions extends PaperCommandCompletions {
|
||||
matchedPlayers.add(name);
|
||||
}
|
||||
}
|
||||
return addonToCommaSeperated(context.getInput(), matchedPlayers);
|
||||
return addOnToCommaSeparated(context.getInput(), matchedPlayers);
|
||||
}
|
||||
|
||||
private Collection<String> suggestSpawnCategoryPropsName(BukkitCommandCompletionContext context) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.jvnet.hk2.annotations.Service;
|
||||
|
||||
import org.mvplugins.multiverse.core.command.LegacyAliasCommand;
|
||||
import org.mvplugins.multiverse.core.command.MVCommandIssuer;
|
||||
import org.mvplugins.multiverse.core.command.MVCommandManager;
|
||||
import org.mvplugins.multiverse.core.command.flag.CommandFlag;
|
||||
import org.mvplugins.multiverse.core.command.flag.CommandFlagsManager;
|
||||
import org.mvplugins.multiverse.core.command.flag.CommandValueFlag;
|
||||
@@ -27,6 +26,7 @@ import org.mvplugins.multiverse.core.command.flag.FlagBuilder;
|
||||
import org.mvplugins.multiverse.core.command.flag.ParsedCommandFlags;
|
||||
import org.mvplugins.multiverse.core.locale.MVCorei18n;
|
||||
import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace;
|
||||
import org.mvplugins.multiverse.core.utils.StringFormatter;
|
||||
import org.mvplugins.multiverse.core.utils.result.Attempt.Failure;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
@@ -53,7 +53,7 @@ class CreateCommand extends CoreCommand {
|
||||
@CommandPermission("multiverse.core.create")
|
||||
@CommandCompletion("@empty @environments @flags:groupName=" + Flags.NAME)
|
||||
@Syntax("<name> <environment> [--seed <seed> --generator <generator[:id]> --world-type <worldtype> --adjust-spawn "
|
||||
+ "--no-structures --biome <biome>]")
|
||||
+ "--no-structures --biome <biome> --properties <prop1=value1,prop2=value2,...>]")
|
||||
@Description("{@@mv-core.create.description}")
|
||||
void onCreateCommand(
|
||||
MVCommandIssuer issuer,
|
||||
@@ -68,7 +68,7 @@ class CreateCommand extends CoreCommand {
|
||||
|
||||
@Optional
|
||||
@Syntax("[--seed <seed> --generator <generator[:id]> --world-type <worldtype> --adjust-spawn "
|
||||
+ "--no-structures --biome <biome>]")
|
||||
+ "--no-structures --biome <biome> --properties <prop1=value1,prop2=value2,...>]")
|
||||
@Description("{@@mv-core.create.flags.description}")
|
||||
String[] flagArray) {
|
||||
ParsedCommandFlags parsedFlags = flags.parse(flagArray);
|
||||
@@ -78,14 +78,15 @@ class CreateCommand extends CoreCommand {
|
||||
issuer.sendInfo(MVCorei18n.CREATE_LOADING);
|
||||
|
||||
worldManager.createWorld(CreateWorldOptions.worldName(worldName)
|
||||
.biome(parsedFlags.flagValue(flags.biome, ""))
|
||||
.environment(environment)
|
||||
.seed(parsedFlags.flagValue(flags.seed))
|
||||
.worldType(parsedFlags.flagValue(flags.worldType, WorldType.NORMAL))
|
||||
.useSpawnAdjust(!parsedFlags.hasFlag(flags.noAdjustSpawn))
|
||||
.generator(parsedFlags.flagValue(flags.generator, ""))
|
||||
.generatorSettings(parsedFlags.flagValue(flags.generatorSettings, ""))
|
||||
.generateStructures(!parsedFlags.hasFlag(flags.noStructures)))
|
||||
.biome(parsedFlags.flagValue(flags.biome, ""))
|
||||
.environment(environment)
|
||||
.seed(parsedFlags.flagValue(flags.seed))
|
||||
.worldType(parsedFlags.flagValue(flags.worldType, WorldType.NORMAL))
|
||||
.useSpawnAdjust(!parsedFlags.hasFlag(flags.noAdjustSpawn))
|
||||
.generator(parsedFlags.flagValue(flags.generator, ""))
|
||||
.generatorSettings(parsedFlags.flagValue(flags.generatorSettings, ""))
|
||||
.generateStructures(!parsedFlags.hasFlag(flags.noStructures))
|
||||
.worldPropertyStrings(StringFormatter.parseCSVMap(parsedFlags.flagValue(flags.properties))))
|
||||
.onSuccess(newWorld -> messageSuccess(issuer, newWorld))
|
||||
.onFailure(failure -> messageFailure(issuer, failure));
|
||||
}
|
||||
@@ -180,6 +181,10 @@ class CreateCommand extends CoreCommand {
|
||||
.addAlias("-b")
|
||||
.completion(input -> biomeProviderFactory.suggestBiomeString(input))
|
||||
.build());
|
||||
|
||||
private final CommandValueFlag<String> properties = flag(CommandValueFlag.builder("--properties", String.class)
|
||||
.addAlias("-p")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Service
|
||||
|
||||
@@ -186,6 +186,16 @@ public final class CoreConfig {
|
||||
return configHandle.get(configNodes.enforceFlight);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public Try<Void> setGamemodeAndFlightEnforceDelay(int delayTicks) {
|
||||
return configHandle.set(configNodes.gamemodeAndFlightEnforceDelay, delayTicks);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public int getGamemodeAndFlightEnforceDelay() {
|
||||
return configHandle.get(configNodes.gamemodeAndFlightEnforceDelay);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.3")
|
||||
public Try<Void> setApplyEntitySpawnRate(boolean applyEntitySpawnRate) {
|
||||
return configHandle.set(configNodes.applyEntitySpawnRate, applyEntitySpawnRate);
|
||||
@@ -493,6 +503,26 @@ public final class CoreConfig {
|
||||
return configHandle.get(configNodes.registerPapiHook);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public Try<Void> setWarnInvalidPapiFormat(boolean warnInvalidPapiFormat) {
|
||||
return configHandle.set(configNodes.warnInvalidPapiFormat, warnInvalidPapiFormat);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public boolean getWarnInvalidPapiFormat() {
|
||||
return configHandle.get(configNodes.warnInvalidPapiFormat);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public Try<Void> setInvalidPapiFormatReturnsBlank(boolean invalidPapiFormatReturnsBlank) {
|
||||
return configHandle.set(configNodes.invalidPapiFormatReturnsBlank, invalidPapiFormatReturnsBlank);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public boolean getInvalidPapiFormatReturnsBlank() {
|
||||
return configHandle.get(configNodes.invalidPapiFormatReturnsBlank);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -621,6 +651,16 @@ public final class CoreConfig {
|
||||
return configHandle.get(configNodes.eventPriorityPlayerTeleport);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public Try<Void> setEventPriorityPlayerWorldChange(EventPriority eventPriorityPlayerWorldChange) {
|
||||
return configHandle.set(configNodes.eventPriorityPlayerWorldChange, eventPriorityPlayerWorldChange);
|
||||
}
|
||||
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public EventPriority getEventPriorityPlayerWorldChange() {
|
||||
return configHandle.get(configNodes.eventPriorityPlayerWorldChange);
|
||||
}
|
||||
|
||||
public Try<Void> setBukkitYmlPath(String bukkitYmlPath) {
|
||||
return configHandle.set(configNodes.bukkitYmlPath, bukkitYmlPath);
|
||||
}
|
||||
|
||||
@@ -135,6 +135,16 @@ final class CoreConfigNodes {
|
||||
.name("enforce-flight")
|
||||
.build());
|
||||
|
||||
final ConfigNode<Integer> gamemodeAndFlightEnforceDelay = node(ConfigNode.builder("world.gamemode-and-flight-enforce-delay", Integer.class)
|
||||
.comment("")
|
||||
.comment("Sets the delay in ticks before Multiverse enforces gamemode and flight ability on world change.")
|
||||
.comment("Increase this value if you are experiencing issues with other plugins overriding gamemode or flight ability.")
|
||||
.comment("Or set to 0 to enforce immediately during world change event.")
|
||||
.defaultValue(1)
|
||||
.name("gamemode-and-flight-enforce-delay")
|
||||
.suggester((sender -> List.of("0", "1", "2", "5", "10")))
|
||||
.build());
|
||||
|
||||
final ConfigNode<Boolean> applyEntitySpawnRate = node(ConfigNode.builder("world.apply-entity-spawn-rate", Boolean.class)
|
||||
.comment("")
|
||||
.comment("Sets whether Multiverse will apply the world's entity `tick-rate` config in worlds.yml.")
|
||||
@@ -390,6 +400,23 @@ final class CoreConfigNodes {
|
||||
.name("register-papi-hook")
|
||||
.build());
|
||||
|
||||
final ConfigNode<Boolean> warnInvalidPapiFormat = node(ConfigNode.builder("messaging.warn-invalid-papi-format", Boolean.class)
|
||||
.comment("")
|
||||
.comment("This config option defines whether or not Multiverse should warn about invalid PlaceholderAPI formats.")
|
||||
.comment("Only applies if PlaceholderAPI is installed, and only to multiverse placeholders.")
|
||||
.defaultValue(true)
|
||||
.name("warn-invalid-papi-format")
|
||||
.build());
|
||||
|
||||
final ConfigNode<Boolean> invalidPapiFormatReturnsBlank = node(ConfigNode.builder("messaging.invalid-papi-format-returns-blank", Boolean.class)
|
||||
.comment("")
|
||||
.comment("By default, invalid formats will return the original placeholder string.")
|
||||
.comment("This config option defines whether or not Multiverse should show invalid PlaceholderAPI formats as blank.")
|
||||
.comment("Only applies if PlaceholderAPI is installed, and only to multiverse placeholders.")
|
||||
.defaultValue(false)
|
||||
.name("invalid-papi-format-returns-blank")
|
||||
.build());
|
||||
|
||||
final ConfigNode<Locale> defaultLocale = node(ConfigNode.builder("messaging.default-locale", Locale.class)
|
||||
.comment("")
|
||||
.comment("This config option defines the default language Multiverse should use.")
|
||||
@@ -528,6 +555,18 @@ final class CoreConfigNodes {
|
||||
"full effect after a server restart."))
|
||||
.build());
|
||||
|
||||
final ConfigNode<EventPriority> eventPriorityPlayerWorldChange = node(ConfigNode.builder("event-priority.player-changed-world", EventPriority.class)
|
||||
.defaultValue(EventPriority.NORMAL)
|
||||
.name("event-priority-player-changed-world")
|
||||
.comment("")
|
||||
.comment("This config option defines the priority for the PlayerChangedWorldEvent.")
|
||||
.onLoadAndChange((oldValue, newValue) ->
|
||||
eventPriorityMapper.get().setPriority("mvcore-player-changed-world", newValue))
|
||||
.onChange((sender, oldValue, newValue) ->
|
||||
sender.sendMessage(ChatColor.YELLOW + "'event-priority.player-changed-world' config option will only take " +
|
||||
"full effect after a server restart."))
|
||||
.build());
|
||||
|
||||
private final ConfigHeaderNode miscHeader = node(ConfigHeaderNode.builder("misc")
|
||||
.comment("")
|
||||
.comment("")
|
||||
|
||||
@@ -120,9 +120,9 @@ public class ListConfigNode<I> extends ConfigNode<List<I>> implements ListValueN
|
||||
private void setDefaultSuggester() {
|
||||
if (itemSuggester instanceof SenderNodeSuggester senderItemSuggester) {
|
||||
this.suggester = (SenderNodeSuggester)(sender, input) ->
|
||||
StringFormatter.addonToCommaSeperated(input, senderItemSuggester.suggest(sender, input));
|
||||
StringFormatter.addOnToCommaSeparated(input, senderItemSuggester.suggest(sender, input));
|
||||
} else {
|
||||
this.suggester = input -> StringFormatter.addonToCommaSeperated(input, itemSuggester.suggest(input));
|
||||
this.suggester = input -> StringFormatter.addOnToCommaSeparated(input, itemSuggester.suggest(input));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
package org.mvplugins.multiverse.core.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import io.vavr.control.Option;
|
||||
@@ -38,6 +36,7 @@ import org.mvplugins.multiverse.core.destination.DestinationsProvider;
|
||||
import org.mvplugins.multiverse.core.dynamiclistener.annotations.DefaultEventPriority;
|
||||
import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventMethod;
|
||||
import org.mvplugins.multiverse.core.dynamiclistener.annotations.EventPriorityKey;
|
||||
import org.mvplugins.multiverse.core.dynamiclistener.annotations.IgnoreIfCancelled;
|
||||
import org.mvplugins.multiverse.core.economy.MVEconomist;
|
||||
import org.mvplugins.multiverse.core.event.MVRespawnEvent;
|
||||
import org.mvplugins.multiverse.core.locale.PluginLocales;
|
||||
@@ -257,9 +256,9 @@ final class MVPlayerListener implements CoreListener {
|
||||
* @param event The Event that was fired.
|
||||
*/
|
||||
@EventMethod
|
||||
@DefaultEventPriority(EventPriority.MONITOR)
|
||||
@EventPriorityKey("mvcore-player-changed-world")
|
||||
@DefaultEventPriority(EventPriority.NORMAL)
|
||||
void playerChangedWorld(PlayerChangedWorldEvent event) {
|
||||
// Permissions now determine whether or not to handle a gamemode.
|
||||
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
||||
}
|
||||
|
||||
@@ -271,12 +270,28 @@ final class MVPlayerListener implements CoreListener {
|
||||
@EventPriorityKey("mvcore-player-teleport")
|
||||
@DefaultEventPriority(EventPriority.HIGHEST)
|
||||
void playerTeleport(PlayerTeleportEvent event) {
|
||||
Logging.finer("Got teleport event for player '"
|
||||
+ event.getPlayer().getName() + "' with cause '" + event.getCause() + "'");
|
||||
Player teleportee = event.getPlayer();
|
||||
|
||||
if (event.isCancelled()) {
|
||||
Logging.finer("Teleport event for player '" + teleportee.getName() + "' was already cancelled.");
|
||||
return;
|
||||
}
|
||||
Player teleportee = event.getPlayer();
|
||||
|
||||
Logging.finer("Got teleport event for player '"
|
||||
+ teleportee.getName() + "' with cause '" + event.getCause() + "'");
|
||||
|
||||
Location fromLocation = event.getFrom();
|
||||
if (fromLocation == null || fromLocation.getWorld() == null) { // should never be null, but just in case
|
||||
Logging.finer("Teleport event for player '" + teleportee.getName() + "' has null from-location or world.");
|
||||
return;
|
||||
}
|
||||
|
||||
Location toLocation = event.getTo();
|
||||
if (toLocation == null || toLocation.getWorld() == null) { // may be null on spigot
|
||||
Logging.finer("Teleport event for player '" + teleportee.getName() + "' has null to-location or world.");
|
||||
return;
|
||||
}
|
||||
|
||||
Option<String> teleporterName = teleportQueue.popFromQueue(teleportee.getName());
|
||||
CommandSender teleporter = teleporterName.map(name -> {
|
||||
if (name.equalsIgnoreCase("CONSOLE")) {
|
||||
@@ -297,17 +312,17 @@ final class MVPlayerListener implements CoreListener {
|
||||
}
|
||||
|
||||
Logging.finer("Teleporter %s is teleporting %s from %s to %s", teleporter.getName(), teleportee.getName(),
|
||||
event.getFrom(), event.getTo());
|
||||
fromLocation, toLocation);
|
||||
|
||||
MultiverseWorld fromWorld = getWorldManager().getLoadedWorld(event.getFrom().getWorld()).getOrNull();
|
||||
LoadedMultiverseWorld toWorld = getWorldManager().getLoadedWorld(event.getTo().getWorld()).getOrNull();
|
||||
MultiverseWorld fromWorld = getWorldManager().getLoadedWorld(fromLocation.getWorld()).getOrNull();
|
||||
LoadedMultiverseWorld toWorld = getWorldManager().getLoadedWorld(toLocation.getWorld()).getOrNull();
|
||||
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 "
|
||||
+ toLocation.getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
||||
+ "actions will be taken by Multiverse-Core.");
|
||||
return;
|
||||
}
|
||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
||||
if (fromLocation.getWorld().equals(toLocation.getWorld())) {
|
||||
// The player is Teleporting to the same world.
|
||||
Logging.finer("Player '" + teleportee.getName() + "' is teleporting to the same world.");
|
||||
this.stateSuccess(teleportee.getName(), toWorld.getName());
|
||||
@@ -341,20 +356,19 @@ final class MVPlayerListener implements CoreListener {
|
||||
*/
|
||||
@EventMethod
|
||||
@DefaultEventPriority(EventPriority.LOWEST)
|
||||
@IgnoreIfCancelled
|
||||
void playerPortalCheck(PlayerPortalEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (event.getFrom().getWorld() == null) {
|
||||
Location fromLocation = event.getFrom();
|
||||
if (fromLocation == null || fromLocation.getWorld() == null) {
|
||||
Logging.warning("PlayerPortalEvent's from world is null!");
|
||||
return;
|
||||
}
|
||||
if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() == Material.NETHER_PORTAL) {
|
||||
if (fromLocation.getWorld().getBlockAt(fromLocation).getType() == Material.NETHER_PORTAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Player was actually outside of the portal, adjust the from location
|
||||
Location newLocation = blockSafety.findPortalBlockNextTo(event.getFrom());
|
||||
Location newLocation = blockSafety.findPortalBlockNextTo(fromLocation);
|
||||
if (newLocation != null) {
|
||||
event.setFrom(newLocation);
|
||||
}
|
||||
@@ -367,28 +381,33 @@ final class MVPlayerListener implements CoreListener {
|
||||
@EventMethod
|
||||
@EventPriorityKey("mvcore-player-portal")
|
||||
@DefaultEventPriority(EventPriority.HIGH)
|
||||
@IgnoreIfCancelled
|
||||
void playerPortal(PlayerPortalEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
Location fromLocation = event.getFrom();
|
||||
if (fromLocation == null || fromLocation.getWorld() == null) { // should never be null, but just in case
|
||||
Logging.finer("PlayerPortalEvent's from world is null!");
|
||||
return;
|
||||
}
|
||||
if (event.getTo() == null || event.getTo().getWorld() == null) {
|
||||
|
||||
Location toLocation = event.getTo();
|
||||
if (toLocation == null || toLocation.getWorld() == null) { // may be null on spigot
|
||||
Logging.finer("PlayerPortalEvent's to world is null!");
|
||||
return;
|
||||
}
|
||||
if (config.isUsingCustomPortalSearch()) {
|
||||
event.setSearchRadius(config.getCustomPortalSearchRadius());
|
||||
}
|
||||
if (Objects.equals(event.getFrom().getWorld(), event.getTo().getWorld())) {
|
||||
if (Objects.equals(fromLocation.getWorld(), toLocation.getWorld())) {
|
||||
// The player is Portaling to the same world.
|
||||
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
||||
return;
|
||||
}
|
||||
|
||||
MultiverseWorld fromWorld = getWorldManager().getLoadedWorld(event.getFrom().getWorld()).getOrNull();
|
||||
LoadedMultiverseWorld toWorld = getWorldManager().getLoadedWorld(event.getTo().getWorld()).getOrNull();
|
||||
MultiverseWorld fromWorld = getWorldManager().getLoadedWorld(fromLocation.getWorld()).getOrNull();
|
||||
LoadedMultiverseWorld toWorld = getWorldManager().getLoadedWorld(toLocation.getWorld()).getOrNull();
|
||||
if (toWorld == null) {
|
||||
Logging.fine("Player '" + event.getPlayer().getName() + "' is portaling to world '"
|
||||
+ event.getTo().getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
||||
+ toLocation.getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
||||
+ "actions will be taken by Multiverse-Core.");
|
||||
return;
|
||||
}
|
||||
@@ -402,21 +421,31 @@ final class MVPlayerListener implements CoreListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the gamemode for the specified {@link Player}.
|
||||
* Handles the gamemode for the specified {@link Player}. Delays the enforcement if configured to do so
|
||||
* to ensure multiverse has final say over other plugins changing gamemodes.
|
||||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param world The {@link World} the player is supposed to be in.
|
||||
*/
|
||||
private void handleGameModeAndFlight(final Player player, World 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.server.getScheduler().runTaskLater(this.plugin, () -> {
|
||||
if (!player.isOnline() || !player.getWorld().equals(world)) {
|
||||
return;
|
||||
}
|
||||
Logging.finer("Handling gamemode and flight for player %s in world '%s'", player.getName(), world.getName());
|
||||
enforcementHandler.handleFlightEnforcement(player);
|
||||
enforcementHandler.handleGameModeEnforcement(player);
|
||||
}, 1L);
|
||||
if (config.getGamemodeAndFlightEnforceDelay() <= 0) {
|
||||
doGameModeAndFlightEnforcement(player, world);
|
||||
return;
|
||||
}
|
||||
server.getScheduler().runTaskLater(
|
||||
this.plugin,
|
||||
() -> doGameModeAndFlightEnforcement(player, world),
|
||||
config.getGamemodeAndFlightEnforceDelay()
|
||||
);
|
||||
}
|
||||
|
||||
private void doGameModeAndFlightEnforcement(Player player, World world) {
|
||||
if (!player.isOnline() || !player.getWorld().equals(world)) {
|
||||
Logging.finer("Player %s is no longer online or not in the expected world '%s'", player.getName(), world.getName());
|
||||
return;
|
||||
}
|
||||
Logging.finer("Handling gamemode and flight for player %s in world '%s'", player.getName(), world.getName());
|
||||
enforcementHandler.handleFlightEnforcement(player);
|
||||
enforcementHandler.handleGameModeEnforcement(player);
|
||||
}
|
||||
}
|
||||
+5
-8
@@ -238,15 +238,12 @@ public final class AsyncSafetyTeleporterAction {
|
||||
@NotNull Location location,
|
||||
@NotNull List<Entity> passengers
|
||||
) {
|
||||
List<Entity> toTeleport = new ArrayList<>(passengers.size() + 1);
|
||||
toTeleport.add(teleportee);
|
||||
toTeleport.addAll(passengers);
|
||||
List<Entity> toTeleport = new ArrayList<>(passengers);
|
||||
toTeleport.addFirst(teleportee);
|
||||
|
||||
return AsyncAttemptsAggregate.allOfAggregate(
|
||||
toTeleport.stream()
|
||||
.map(passenger -> doAsyncTeleport(passenger, location))
|
||||
.toList()
|
||||
)
|
||||
return AsyncAttemptsAggregate.allOfAggregate(toTeleport.stream()
|
||||
.map(passenger -> doAsyncTeleport(passenger, location))
|
||||
.toList())
|
||||
.onSuccess(() -> Bukkit.getScheduler().runTask(multiverseCore, () -> {
|
||||
passengers.forEach(teleportee::addPassenger);
|
||||
Logging.finer("Mounted %d passengers to %s", passengers.size(), teleportee.getName());
|
||||
|
||||
@@ -132,6 +132,10 @@ public final class BlockSafety {
|
||||
*/
|
||||
public boolean canSpawnAtBlockSafely(@NotNull Block block) {
|
||||
Logging.finest("Checking spawn safety for location: %s, %s, %s", block.getX(), block.getY(), block.getZ());
|
||||
if (!block.getWorld().getWorldBorder().isInside(block.getLocation())) {
|
||||
Logging.finest("Location is outside world border.");
|
||||
return false;
|
||||
}
|
||||
if (isUnsafeSpawnBody(block)) {
|
||||
// Player body will be stuck in solid
|
||||
Logging.finest("Unsafe location for player's body: " + block);
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package org.mvplugins.multiverse.core.utils;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A map with case-insensitive String keys. All keys are stored in lower-case form.
|
||||
*
|
||||
* @param <T> the type of mapped values
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public class CaseInsensitiveStringMap<T> implements Map<String, T> {
|
||||
|
||||
private final Map<String, T> map;
|
||||
|
||||
public CaseInsensitiveStringMap() {
|
||||
map = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return map.containsKey(normalizeKey(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return map.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(Object key) {
|
||||
return map.get(normalizeKey(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable T put(String key, T value) {
|
||||
return map.put(normalizeKey(key), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T remove(Object key) {
|
||||
return map.remove(normalizeKey(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(@NonNull Map<? extends String, ? extends T> m) {
|
||||
m.forEach((key, value) -> map.put(normalizeKey(key), value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Set<String> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Collection<T> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Set<Entry<String, T>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
private String normalizeKey(Object key) {
|
||||
return String.valueOf(key).toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,17 @@ package org.mvplugins.multiverse.core.utils;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -30,15 +34,15 @@ public final class StringFormatter {
|
||||
* @param list the list of strings to join. If the list is empty, an empty string is returned.
|
||||
* @return the concatenated string
|
||||
*/
|
||||
public static @NotNull String joinAnd(List<String> list) {
|
||||
public static @NotNull String joinAnd(@Nullable List<String> list) {
|
||||
return join(list, ", ", " and ");
|
||||
}
|
||||
|
||||
public static @NotNull String join(Collection list, String separator) {
|
||||
public static @NotNull String join(@Nullable Collection<?> list, @NotNull String separator) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return list.stream().map(String::valueOf).collect(Collectors.joining(separator)).toString();
|
||||
return list.stream().map(String::valueOf).collect(Collectors.joining(separator));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +54,7 @@ public final class StringFormatter {
|
||||
* @param lastSeparator the separator to use before the last element. For example, " and ".
|
||||
* @return the concatenated string
|
||||
*/
|
||||
public static @NotNull String join(List<String> list, String separator, String lastSeparator) {
|
||||
public static @NotNull String join(@Nullable List<String> list, @NotNull String separator, @NotNull String lastSeparator) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
@@ -71,11 +75,30 @@ public final class StringFormatter {
|
||||
|
||||
/**
|
||||
* Appends a list of suggestions to the end of the input string, separated by commas.
|
||||
*
|
||||
* @param input The current input
|
||||
* @param addons The autocomplete suggestions
|
||||
* @return A collection of suggestions with the next suggestion appended
|
||||
*
|
||||
* @deprecated Method name has a spelling error. Use {@link #addOnToCommaSeparated(String, Collection)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "5.5")
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "6.0")
|
||||
public static Collection<String> addonToCommaSeperated(@Nullable String input, @NotNull Collection<String> addons) {
|
||||
return addOnToCommaSeparated(input, addons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a list of suggestions to the end of the input string, separated by commas.
|
||||
*
|
||||
* @param input The current input
|
||||
* @param addons The autocomplete suggestions
|
||||
* @return A collection of suggestions with the next suggestion appended
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public static Collection<String> addOnToCommaSeparated(@Nullable String input, @NotNull Collection<String> addons) {
|
||||
if (Strings.isNullOrEmpty(input)) {
|
||||
return addons;
|
||||
}
|
||||
@@ -94,7 +117,7 @@ public final class StringFormatter {
|
||||
* @param args The args to parse
|
||||
* @return The parsed args
|
||||
*/
|
||||
public static Collection<String> parseQuotesInArgs(String[] args) {
|
||||
public static @NotNull Collection<String> parseQuotesInArgs(@NotNull String[] args) {
|
||||
List<String> result = new ArrayList<>(args.length);
|
||||
StringBuilder current = new StringBuilder();
|
||||
boolean inQuotes = false;
|
||||
@@ -139,7 +162,28 @@ public final class StringFormatter {
|
||||
* @param input The string to add quotes to
|
||||
* @return The quoted string
|
||||
*/
|
||||
public static String quoteMultiWordString(String input) {
|
||||
return input.contains(" ") ? "\"" + input + "\"" : input;
|
||||
@Contract("null -> null")
|
||||
public static @Nullable String quoteMultiWordString(@Nullable String input) {
|
||||
return input != null && input.contains(" ") ? "\"" + input + "\"" : input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a CSV string of key=value pairs into a map.
|
||||
* E.g. "key1=value1,key2=value2" -> {key1=value1, key2=value2}
|
||||
*
|
||||
* @param input The CSV string to parse
|
||||
* @return The parsed map
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public static @Unmodifiable Map<String, String> parseCSVMap(@Nullable String input) {
|
||||
if (Strings.isNullOrEmpty(input)) {
|
||||
return Map.of();
|
||||
}
|
||||
return REPatterns.COMMA.splitAsStream(input)
|
||||
.map(s -> REPatterns.EQUALS.split(s, 2))
|
||||
.filter(parts -> parts.length == 2)
|
||||
.collect(Collectors.toUnmodifiableMap(parts -> parts[0], parts -> parts[1]));
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.mvplugins.multiverse.core.world;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import io.vavr.control.Option;
|
||||
import io.vavr.control.Try;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Difficulty;
|
||||
@@ -10,6 +11,7 @@ import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -66,7 +68,8 @@ public sealed class MultiverseWorld permits LoadedMultiverseWorld {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this world is loaded.
|
||||
* Gets whether this world is loaded. Note that this may return false even if this is a stored instance of
|
||||
* {@link LoadedMultiverseWorld} as worlds can be unloaded anytime.
|
||||
*
|
||||
* @return True if the world is loaded, else false.
|
||||
*/
|
||||
@@ -74,6 +77,23 @@ public sealed class MultiverseWorld permits LoadedMultiverseWorld {
|
||||
return worldConfig.isLoadedWorld();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get loaded world instance. Only returns a value if the world is loaded at the time of calling, even
|
||||
* if this is a stored instance of {@link LoadedMultiverseWorld}.
|
||||
* <br/>
|
||||
* You may use {@link #isLoaded()} to check if the world is loaded first.
|
||||
*
|
||||
* @return Loaded world instance wrapped in an Option, or None if the world is not loaded.
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public Option<LoadedMultiverseWorld> asLoadedWorld() {
|
||||
return Option.of(worldConfig.getMVWorld())
|
||||
.filter(world -> world instanceof LoadedMultiverseWorld)
|
||||
.map(world -> (LoadedMultiverseWorld) world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties handler of this world.
|
||||
*
|
||||
|
||||
@@ -381,6 +381,10 @@ final class WorldConfig {
|
||||
configNodes.setWorld(world);
|
||||
}
|
||||
|
||||
MultiverseWorld getMVWorld() {
|
||||
return configNodes.getWorld();
|
||||
}
|
||||
|
||||
boolean isLoadedWorld() {
|
||||
return configNodes.getWorld() instanceof LoadedMultiverseWorld;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -48,6 +46,7 @@ import org.mvplugins.multiverse.core.locale.message.MessageReplacement.Replace;
|
||||
import org.mvplugins.multiverse.core.permissions.CorePermissions;
|
||||
import org.mvplugins.multiverse.core.teleportation.BlockSafety;
|
||||
import org.mvplugins.multiverse.core.teleportation.LocationManipulation;
|
||||
import org.mvplugins.multiverse.core.utils.CaseInsensitiveStringMap;
|
||||
import org.mvplugins.multiverse.core.utils.ReflectHelper;
|
||||
import org.mvplugins.multiverse.core.utils.ServerProperties;
|
||||
import org.mvplugins.multiverse.core.utils.result.Attempt;
|
||||
@@ -91,8 +90,8 @@ public final class WorldManager {
|
||||
private static final DimensionFormat DEFAULT_NETHER_FORMAT = new DimensionFormat("%overworld%_nether");
|
||||
private static final DimensionFormat DEFAULT_END_FORMAT = new DimensionFormat("%overworld%_the_end");
|
||||
|
||||
private final Map<String, MultiverseWorld> worldsMap;
|
||||
private final Map<String, LoadedMultiverseWorld> loadedWorldsMap;
|
||||
private final CaseInsensitiveStringMap<MultiverseWorld> worldsMap;
|
||||
private final CaseInsensitiveStringMap<LoadedMultiverseWorld> loadedWorldsMap;
|
||||
private final List<String> unloadTracker;
|
||||
private final List<String> loadTracker;
|
||||
private final WorldsConfigManager worldsConfigManager;
|
||||
@@ -135,8 +134,8 @@ public final class WorldManager {
|
||||
this.config = config;
|
||||
this.entityPurger = entityPurger;
|
||||
|
||||
this.worldsMap = new HashMap<>();
|
||||
this.loadedWorldsMap = new HashMap<>();
|
||||
this.worldsMap = new CaseInsensitiveStringMap<>();
|
||||
this.loadedWorldsMap = new CaseInsensitiveStringMap<>();
|
||||
this.unloadTracker = new ArrayList<>();
|
||||
this.loadTracker = new ArrayList<>();
|
||||
}
|
||||
@@ -176,7 +175,7 @@ public final class WorldManager {
|
||||
private void removeWorldsNotInConfigs(Collection<String> removedWorlds) {
|
||||
removedWorlds.forEach(worldName -> getWorld(worldName)
|
||||
.map(world -> removeWorld(RemoveWorldOptions.world(world)))
|
||||
.getOrElse(() -> worldActionResult(RemoveFailureReason.UNLOAD_FAILED, worldName))
|
||||
.getOrElse(() -> worldActionResult(RemoveFailureReason.WORLD_NON_EXISTENT, worldName))
|
||||
.onFailure(failure ->
|
||||
Logging.severe("Failed to unload world %s: %s", worldName, failure))
|
||||
.onSuccess(success ->
|
||||
@@ -277,7 +276,16 @@ public final class WorldManager {
|
||||
generatorString,
|
||||
options.biome(),
|
||||
options.useSpawnAdjust()))
|
||||
.peek(loadedWorld -> pluginManager.callEvent(new MVWorldCreatedEvent(loadedWorld)));
|
||||
.peek(loadedWorld -> postCreateWorld(loadedWorld, options));
|
||||
}
|
||||
|
||||
private void postCreateWorld(LoadedMultiverseWorld loadedWorld, CreateWorldOptions options) {
|
||||
options.worldPropertyStrings().forEach((key, value) -> loadedWorld.getStringPropertyHandle()
|
||||
.setPropertyString(key, value)
|
||||
.onFailure(failure -> Logging.warning("Failed to set property '%s' to '%s' for world %s: %s",
|
||||
key, value, loadedWorld.getName(), failure.getMessage())));
|
||||
pluginManager.callEvent(new MVWorldCreatedEvent(loadedWorld));
|
||||
saveWorldsConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,7 +353,7 @@ public final class WorldManager {
|
||||
|
||||
private MultiverseWorld newMultiverseWorld(String worldName, WorldConfig worldConfig) {
|
||||
MultiverseWorld mvWorld = new MultiverseWorld(worldName, worldConfig, config);
|
||||
worldsMap.put(mvWorld.getName().toLowerCase(Locale.ENGLISH), mvWorld);
|
||||
worldsMap.put(mvWorld.getName(), mvWorld);
|
||||
corePermissions.addWorldPermissions(mvWorld);
|
||||
return mvWorld;
|
||||
}
|
||||
@@ -382,7 +390,7 @@ public final class WorldManager {
|
||||
locationManipulation,
|
||||
entityPurger
|
||||
);
|
||||
loadedWorldsMap.put(loadedWorld.getName().toLowerCase(Locale.ENGLISH), loadedWorld);
|
||||
loadedWorldsMap.put(loadedWorld.getName(), loadedWorld);
|
||||
saveWorldsConfig();
|
||||
pluginManager.callEvent(new MVWorldLoadedEvent(loadedWorld));
|
||||
return loadedWorld;
|
||||
@@ -501,7 +509,7 @@ public final class WorldManager {
|
||||
locationManipulation,
|
||||
entityPurger
|
||||
);
|
||||
loadedWorldsMap.put(loadedWorld.getName().toLowerCase(Locale.ENGLISH), loadedWorld);
|
||||
loadedWorldsMap.put(loadedWorld.getName(), loadedWorld);
|
||||
saveWorldsConfig();
|
||||
pluginManager.callEvent(new MVWorldLoadedEvent(loadedWorld));
|
||||
return Attempt.success(loadedWorld);
|
||||
@@ -891,7 +899,9 @@ public final class WorldManager {
|
||||
}).onFailure(exception -> {
|
||||
Logging.severe("Failed to create bukkit world: " + worldCreator.name());
|
||||
exception.printStackTrace();
|
||||
}).andFinally(() -> this.loadTracker.remove(worldCreator.name())).fold(throwable -> Attempt.failure(WorldCreatorFailureReason.BUKKIT_CREATION_FAILED,
|
||||
}).andFinally(() -> {
|
||||
this.loadTracker.remove(worldCreator.name());
|
||||
}).fold(throwable -> Attempt.failure(WorldCreatorFailureReason.BUKKIT_CREATION_FAILED,
|
||||
Replace.WORLD.with(worldCreator.name()),
|
||||
Replace.ERROR.with(throwable)),
|
||||
Attempt::success);
|
||||
@@ -1008,7 +1018,7 @@ public final class WorldManager {
|
||||
* @return True if the world is a world is known to multiverse, but may or may not be loaded.
|
||||
*/
|
||||
public boolean isWorld(@Nullable String worldName) {
|
||||
return worldName != null && worldsMap.containsKey(worldName.toLowerCase(Locale.ENGLISH));
|
||||
return worldName != null && worldsMap.containsKey(worldName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1020,7 +1030,7 @@ public final class WorldManager {
|
||||
public Option<MultiverseWorld> getUnloadedWorld(@Nullable String worldName) {
|
||||
return isLoadedWorld(worldName)
|
||||
? Option.none()
|
||||
: Option.of(worldName).flatMap(name -> Option.of(worldsMap.get(name.toLowerCase(Locale.ENGLISH))));
|
||||
: Option.of(worldName).flatMap(name -> Option.of(worldsMap.get(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1093,7 +1103,7 @@ public final class WorldManager {
|
||||
*/
|
||||
public Option<LoadedMultiverseWorld> getLoadedWorld(@Nullable String worldName) {
|
||||
return Option.of(worldName)
|
||||
.flatMap(name -> Option.of(loadedWorldsMap.get(name.toLowerCase(Locale.ENGLISH))));
|
||||
.flatMap(name -> Option.of(loadedWorldsMap.get(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1154,7 +1164,7 @@ public final class WorldManager {
|
||||
* @return True if the world is a multiverse world that is loaded.
|
||||
*/
|
||||
public boolean isLoadedWorld(@Nullable String worldName) {
|
||||
return worldName != null && loadedWorldsMap.containsKey(worldName.toLowerCase(Locale.ENGLISH));
|
||||
return worldName != null && loadedWorldsMap.containsKey(worldName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+21
-25
@@ -1,40 +1,36 @@
|
||||
package org.mvplugins.multiverse.core.world.biomeprovider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A parser for {@link SingleBiomeProvider}
|
||||
*/
|
||||
final class SingleBiomeProviderParser implements BiomeProviderParser {
|
||||
|
||||
private List<String> biomes;
|
||||
private List<String> biomes;
|
||||
|
||||
@Override
|
||||
public BiomeProvider parseBiomeProvider(@NotNull String worldName, @NotNull String params) {
|
||||
final NamespacedKey biomeKey = NamespacedKey.fromString(StringUtils.lowerCase(params, Locale.ENGLISH));
|
||||
return new SingleBiomeProvider(Registry.BIOME.get(biomeKey));
|
||||
}
|
||||
@Override
|
||||
public BiomeProvider parseBiomeProvider(@NotNull String worldName, @NotNull String params) {
|
||||
NamespacedKey biomeKey = NamespacedKey.fromString(params.toLowerCase(Locale.ENGLISH));
|
||||
return new SingleBiomeProvider(Registry.BIOME.get(biomeKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> suggestParams(@NotNull String currentInput) {
|
||||
if (biomes == null) {
|
||||
final List<String> result = new ArrayList<>();
|
||||
for (Biome biome : Registry.BIOME) {
|
||||
result.add(StringUtils.lowerCase(biome.getKey().getKey(), Locale.ENGLISH));
|
||||
}
|
||||
biomes = result;
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public Collection<String> suggestParams(@NotNull String currentInput) {
|
||||
if (biomes == null) {
|
||||
biomes = Registry.BIOME.stream()
|
||||
.map(biome -> biome.getKey().getKey().toLowerCase(Locale.ENGLISH))
|
||||
.toList();
|
||||
}
|
||||
return biomes;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,14 @@ package org.mvplugins.multiverse.core.world.options;
|
||||
import co.aikar.commands.ACFUtil;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnmodifiableView;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Options for customizing the creation of a new world.
|
||||
@@ -31,6 +37,7 @@ public final class CreateWorldOptions {
|
||||
private boolean useSpawnAdjust = true;
|
||||
private WorldType worldType = WorldType.NORMAL;
|
||||
private boolean doFolderCheck = true;
|
||||
private final Map<String, String> worldPropertyStrings = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link CreateWorldOptions} instance with the given world name.
|
||||
@@ -260,4 +267,46 @@ public final class CreateWorldOptions {
|
||||
public boolean doFolderCheck() {
|
||||
return doFolderCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a world property string key-value pair. Overwrites any existing key.
|
||||
*
|
||||
* @param key The key of the world property string.
|
||||
* @param value The value of the world property string.
|
||||
* @return This {@link CreateWorldOptions} instance.
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public @NotNull CreateWorldOptions worldPropertyString(@NotNull String key, @Nullable String value) {
|
||||
this.worldPropertyStrings.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple world property string key-value pairs. Overwrites any existing keys.
|
||||
*
|
||||
* @param worldProperties A map of world property string key-value pairs.
|
||||
* @return This {@link CreateWorldOptions} instance.
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public @NotNull CreateWorldOptions worldPropertyStrings(@NotNull Map<@NotNull String, @Nullable String> worldProperties) {
|
||||
this.worldPropertyStrings.putAll(worldProperties);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an unmodifiable view of the world property strings. Use {@link #worldPropertyString(String, String)} and
|
||||
* {@link #worldPropertyStrings(Map)} to modify the world property strings.
|
||||
*
|
||||
* @return An unmodifiable view of the world property strings.
|
||||
*
|
||||
* @since 5.5
|
||||
*/
|
||||
@ApiStatus.AvailableSince("5.5")
|
||||
public @UnmodifiableView @NotNull Map<String, String> worldPropertyStrings() {
|
||||
return Collections.unmodifiableMap(worldPropertyStrings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.mvplugins.multiverse.core
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
open class MockBukkitTest : TestWithMockBukkit() {
|
||||
|
||||
@Test
|
||||
fun `MockBukkit loads the plugin`() {
|
||||
assertNotNull(multiverseCore)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.mvplugins.multiverse.core
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.configuration.MemorySection
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import org.mockbukkit.mockbukkit.MockBukkit
|
||||
import org.mvplugins.multiverse.core.inject.PluginServiceLocator
|
||||
import org.mvplugins.multiverse.core.mock.MVServerMock
|
||||
import kotlin.test.*
|
||||
|
||||
/**
|
||||
* Basic abstract test class that sets up MockBukkit and MultiverseCore.
|
||||
*/
|
||||
abstract class TestWithMockBukkit {
|
||||
|
||||
protected lateinit var server: MVServerMock
|
||||
protected lateinit var multiverseCore: MultiverseCore
|
||||
protected lateinit var serviceLocator : PluginServiceLocator
|
||||
|
||||
@BeforeTest
|
||||
fun setUpMockBukkit() {
|
||||
TestingMode.enable()
|
||||
server = MockBukkit.mock(MVServerMock())
|
||||
multiverseCore = MockBukkit.load(MultiverseCore::class.java)
|
||||
Logging.setDebugLevel(3)
|
||||
serviceLocator = multiverseCore.serviceLocator
|
||||
assertNotNull(server.commandMap)
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
fun tearDownMockBukkit() {
|
||||
MockBukkit.unmock()
|
||||
}
|
||||
|
||||
fun getResourceAsText(path: String): String? = object {}.javaClass.getResource(path)?.readText()
|
||||
|
||||
fun writeResourceFileToPluginDataFolder(resourcePath: String, dataPath: String) {
|
||||
val resourceString = getResourceAsText(resourcePath)
|
||||
assertNotNull(resourceString)
|
||||
multiverseCore.dataFolder.toPath().resolve(dataPath).toFile().writeText(resourceString)
|
||||
}
|
||||
|
||||
fun assertConfigEquals(expectedPath: String, actualPath: String) {
|
||||
val actualString = multiverseCore.dataFolder.toPath().resolve(actualPath).toFile().readText()
|
||||
val expectedString = getResourceAsText(expectedPath)
|
||||
assertNotNull(expectedString)
|
||||
|
||||
val actualYaml = YamlConfiguration()
|
||||
actualYaml.loadFromString(actualString)
|
||||
val actualYamlKeys = HashSet(actualYaml.getKeys(true))
|
||||
|
||||
val expectedYaml = YamlConfiguration()
|
||||
expectedYaml.loadFromString(expectedString)
|
||||
val expectedYamlKeys = HashSet(expectedYaml.getKeys(true))
|
||||
|
||||
for (key in expectedYamlKeys) {
|
||||
assertNotNull(actualYamlKeys.remove(key), "Key $key is missing in actual config")
|
||||
val actualValue = actualYaml.get(key)
|
||||
if (actualValue is MemorySection) {
|
||||
continue
|
||||
}
|
||||
assertEquals(expectedYaml.get(key), actualYaml.get(key), "Value for $key is different.")
|
||||
}
|
||||
for (key in actualYamlKeys) {
|
||||
assertNull(actualYaml.get(key), "Key $key is present in actual config when it should be empty.")
|
||||
}
|
||||
|
||||
assertEquals(0, actualYamlKeys.size,
|
||||
"Actual config has more keys than expected config. The following keys are missing: $actualYamlKeys")
|
||||
}
|
||||
|
||||
fun assertLocationEquals(expected: Location?, actual: Location?) {
|
||||
assertEquals(expected?.world, actual?.world, "Worlds don't match for location comparison ($expected, $actual)")
|
||||
assertEquals(expected?.x, actual?.x, "X values don't match for location comparison ($expected, $actual)")
|
||||
assertEquals(expected?.y, actual?.y, "Y values don't match for location comparison ($expected, $actual)")
|
||||
assertEquals(expected?.z, actual?.z, "Z values don't match for location comparison ($expected, $actual)")
|
||||
assertEquals(expected?.yaw, actual?.yaw, "Yaw values don't match for location comparison ($expected, $actual)")
|
||||
assertEquals(expected?.pitch, actual?.pitch, "Pitch values don't match for location comparison ($expected, $actual)")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.mvplugins.multiverse.core.anchor
|
||||
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.world.location.UnloadedWorldLocation
|
||||
import kotlin.test.*
|
||||
|
||||
class AnchorManagerTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var anchorManager: AnchorManager
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
anchorManager = serviceLocator.getActiveService(AnchorManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("AnchorManager is not available as a service") }
|
||||
|
||||
writeResourceFileToPluginDataFolder("/anchors/default_anchors.yml", "anchors.yml")
|
||||
assertTrue(anchorManager.loadAnchors().isSuccess)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Loaded correct Anchors from file`() {
|
||||
assertEquals(2, anchorManager.allAnchors.size)
|
||||
|
||||
val a1 = anchorManager.getAnchor("a1").orNull
|
||||
assertNotNull(a1)
|
||||
assertLocationEquals(UnloadedWorldLocation("w1", 0.5, 70.0, 0.5, -68.25f, 10.35f), a1.location)
|
||||
|
||||
val a2 = anchorManager.getAnchor("a2").orNull
|
||||
assertNotNull(a2)
|
||||
assertLocationEquals(UnloadedWorldLocation("w2", 3.3, 9.9, 6.6, -1.1f, 2.0f), a2.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Set new location for existing anchor`() {
|
||||
val a1 = anchorManager.getAnchor("a1").orNull
|
||||
assertNotNull(a1)
|
||||
val newLocation = UnloadedWorldLocation("w1", 1.0, 1.0, 1.0, 1.0f, 1.0f)
|
||||
anchorManager.setAnchor("a1", newLocation)
|
||||
assertLocationEquals(newLocation, a1.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create new anchor`() {
|
||||
val newLocation = UnloadedWorldLocation("w3", 3.0, 3.0, 3.0, -3.0f, 3.0f)
|
||||
anchorManager.setAnchor("a3", newLocation)
|
||||
assertLocationEquals(newLocation, anchorManager.getAnchor("a3").orNull?.location)
|
||||
|
||||
assertConfigEquals("/anchors/anchors_saved.yml", "anchors.yml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Delete anchor`() {
|
||||
val a1 = anchorManager.getAnchor("a1").orNull
|
||||
assertNotNull(a1)
|
||||
anchorManager.deleteAnchor(a1)
|
||||
assertNull(anchorManager.getAnchor("a1").orNull)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.mvplugins.multiverse.core.api
|
||||
|
||||
import org.mvplugins.multiverse.core.MultiverseCoreApi
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class MultiverseCoreApiTest : TestWithMockBukkit() {
|
||||
|
||||
@Test
|
||||
fun `MultiverseCoreApi is available`() {
|
||||
val api = assertNotNull(MultiverseCoreApi.get())
|
||||
assertNotNull(api.blockSafety)
|
||||
assertNotNull(api.destinationsProvider)
|
||||
assertNotNull(api.generatorProvider)
|
||||
assertNotNull(api.locationManipulation)
|
||||
assertNotNull(api.coreConfig)
|
||||
assertNotNull(api.safetyTeleporter)
|
||||
assertNotNull(api.worldManager)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get MultiverseCoreApi from bukkit service`() {
|
||||
val registeredService = server.servicesManager.getRegistration(MultiverseCoreApi::class.java)
|
||||
val api = assertNotNull(registeredService?.provider)
|
||||
testApiAccess(api)
|
||||
}
|
||||
|
||||
private fun testApiAccess(api: MultiverseCoreApi?) {
|
||||
assertNotNull(api?.anchorManager)
|
||||
assertNotNull(api?.blockSafety)
|
||||
assertNotNull(api?.destinationsProvider)
|
||||
assertNotNull(api?.mvEconomist)
|
||||
assertNotNull(api?.generatorProvider)
|
||||
assertNotNull(api?.locationManipulation)
|
||||
assertNotNull(api?.coreConfig)
|
||||
assertNotNull(api?.safetyTeleporter)
|
||||
assertNotNull(api?.worldManager)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
package org.mvplugins.multiverse.core.command
|
||||
|
||||
import com.natpryce.hamkrest.assertion.assertThat
|
||||
import com.natpryce.hamkrest.containsSubstring
|
||||
import com.natpryce.hamkrest.endsWith
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.mockbukkit.mockbukkit.entity.PlayerMock
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.locale.MVCorei18n
|
||||
import org.mvplugins.multiverse.core.locale.PluginLocales
|
||||
import org.mvplugins.multiverse.core.locale.message.Message
|
||||
import org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace
|
||||
import java.util.Locale
|
||||
import kotlin.test.*
|
||||
|
||||
class LocalizationTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var locales: PluginLocales
|
||||
private lateinit var commandManager: MVCommandManager
|
||||
|
||||
@BeforeTest
|
||||
fun setUpLocale() {
|
||||
commandManager = assertNotNull(serviceLocator.getActiveService(MVCommandManager::class.java))
|
||||
locales = commandManager.locales
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with only a non-localized message")
|
||||
inner class BasicMessage {
|
||||
|
||||
private val messageString = "This is a test message"
|
||||
private val message = Message.of(messageString)
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the same as the original`() {
|
||||
assertEquals(messageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be the same as the original`() {
|
||||
assertEquals(messageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales for a CommandIssuer should be the same as the original`() {
|
||||
assertEquals(messageString, message.formatted(locales, commandManager.consoleCommandIssuer))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
verify(sender).sendMessage("§9§9$messageString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with a non-localized message and one replacement")
|
||||
inner class MessageWithOneReplacement {
|
||||
|
||||
private val replacementKey = "{count}"
|
||||
private val messageString = "This is a test message with $replacementKey replacement"
|
||||
private val replacedMessageString = messageString.replace(replacementKey, "one")
|
||||
|
||||
private val message = Message.of(messageString, replace(replacementKey).with("one"))
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales for a CommandIssuer should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales, commandManager.consoleCommandIssuer))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
verify(sender).sendMessage("§9§9$replacedMessageString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with a non-localized message and two replacements")
|
||||
inner class MessageWithTwoReplacements {
|
||||
|
||||
private val replacementKey1 = "{thing1}"
|
||||
private val replacementKey2 = "{thing2}"
|
||||
private val messageString = "$replacementKey1 $replacementKey2"
|
||||
private val replacedMessageString = messageString
|
||||
.replace(replacementKey1, "one")
|
||||
.replace(replacementKey2, "two")
|
||||
|
||||
private val message = Message.of(
|
||||
messageString,
|
||||
replace(replacementKey1).with("one"),
|
||||
replace(replacementKey2).with("two"),
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales for a CommandIssuer should be the replaced message string`() {
|
||||
assertEquals(replacedMessageString, message.formatted(locales, commandManager.consoleCommandIssuer))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
verify(sender).sendMessage("§9§9$replacedMessageString")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Given a Message with a localized message with one replacement")
|
||||
inner class LocalizedMessage {
|
||||
|
||||
private val replacementKey = "{world}"
|
||||
private val replacementValue = "World"
|
||||
private val messageString = "Hello $replacementKey!"
|
||||
private val replacedMessageString = messageString.replace(replacementKey, replacementValue)
|
||||
|
||||
private val message = MVCorei18n.CLONE_SUCCESS
|
||||
.bundle(messageString, replace(replacementKey).with(replacementValue))
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced original string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be different from the replaced original string`() {
|
||||
assertNotEquals(replacedMessageString, message.formatted(locales))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should have performed replacement`() {
|
||||
assertThat(message.formatted(locales), !containsSubstring(replacementKey))
|
||||
assertThat(message.formatted(locales), containsSubstring(replacementValue))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
val sentMessage = argumentCaptor<String> {
|
||||
verify(sender).sendMessage(capture())
|
||||
}.firstValue
|
||||
|
||||
assertNotEquals(replacedMessageString, sentMessage)
|
||||
assertThat(sentMessage, !containsSubstring(replacementKey))
|
||||
assertThat(sentMessage, containsSubstring(replacementValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class WithMessagesAsReplacement {
|
||||
private val replacementKey = "{world}"
|
||||
private val replacementValue = Message.of(
|
||||
MVCorei18n.GENERIC_SUCCESS, "success")
|
||||
private val messageString = "Hello $replacementKey!"
|
||||
private val replacedMessageString = "Hello success!"
|
||||
private val replacedMessageStringLocale = "World cloned to 'Success!'!"
|
||||
|
||||
private val message = MVCorei18n.CLONE_SUCCESS
|
||||
.bundle(messageString, replace(replacementKey).with(replacementValue))
|
||||
|
||||
@Test
|
||||
fun `The raw message should be the same as the original`() {
|
||||
assertEquals(messageString, message.raw())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message should be the replaced original string`() {
|
||||
assertEquals(replacedMessageString, message.formatted())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should be different from the replaced original string`() {
|
||||
assertThat(message.formatted(locales), endsWith(replacedMessageStringLocale))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `The formatted message with PluginLocales should have performed replacement`() {
|
||||
assertThat(message.formatted(locales), !containsSubstring(replacementKey))
|
||||
assertThat(message.formatted(locales), containsSubstring("Success!"))
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("And a command sender is provided")
|
||||
inner class WithCommandSender {
|
||||
|
||||
private lateinit var sender: CommandSender
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
sender = spy(Bukkit.getConsoleSender())
|
||||
issuer = commandManager.getCommandIssuer(sender)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Sending the issuer the message should send the formatted message to the sender`() {
|
||||
issuer.sendInfo(message);
|
||||
|
||||
val sentMessage = argumentCaptor<String> {
|
||||
verify(sender).sendMessage(capture())
|
||||
}.firstValue
|
||||
|
||||
assertNotEquals(replacedMessageString, sentMessage)
|
||||
assertThat(sentMessage, !containsSubstring(replacementKey))
|
||||
assertThat(sentMessage, containsSubstring(replacedMessageStringLocale))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class LocaleConfiguration {
|
||||
private lateinit var config: CoreConfig
|
||||
private lateinit var player: PlayerMock
|
||||
private lateinit var issuer: MVCommandIssuer
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
config = assertNotNull(serviceLocator.getActiveService(CoreConfig::class.java))
|
||||
player = server.addPlayer("benji_0224")
|
||||
issuer = commandManager.getCommandIssuer(player)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Change default locale to chinese without per player locale should get chinese message`() {
|
||||
config.perPlayerLocale = false
|
||||
config.defaultLocale = Locale.CHINESE
|
||||
assertEquals("成功!", Message.of(
|
||||
MVCorei18n.GENERIC_SUCCESS, "").formatted(locales, issuer))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Change default locale to chinese with per player locale should get default english message`() {
|
||||
config.perPlayerLocale = true
|
||||
config.defaultLocale = Locale.CHINESE
|
||||
assertEquals("Success!", Message.of(
|
||||
MVCorei18n.GENERIC_SUCCESS, "").formatted(locales, issuer))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PerPlayerLocale enabled - Player with chinese locale should get chinese message`() {
|
||||
config.perPlayerLocale = true
|
||||
player.setLocale(Locale.CHINESE)
|
||||
assertEquals("成功!", Message.of(
|
||||
MVCorei18n.GENERIC_SUCCESS, "").formatted(locales, issuer))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PerPlayerLocale disabled - Player with chinese locale should get default english message`() {
|
||||
config.perPlayerLocale = false
|
||||
player.setLocale(Locale.CHINESE)
|
||||
assertEquals("Success!", Message.of(
|
||||
MVCorei18n.GENERIC_SUCCESS, "").formatted(locales, issuer))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.permissions.PermissionAttachment
|
||||
import org.mockbukkit.mockbukkit.command.ConsoleCommandSenderMock
|
||||
import org.mockbukkit.mockbukkit.entity.PlayerMock
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.command.MVCommandManager
|
||||
import org.mvplugins.multiverse.core.locale.PluginLocales
|
||||
import org.mvplugins.multiverse.core.locale.message.Message
|
||||
import org.mvplugins.multiverse.core.utils.text.ChatTextFormatter
|
||||
import org.mvplugins.multiverse.core.world.WorldManager
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
abstract class AbstractCommandTest : TestWithMockBukkit() {
|
||||
|
||||
protected lateinit var worldManager: WorldManager
|
||||
protected lateinit var player: PlayerMock
|
||||
protected lateinit var console: ConsoleCommandSenderMock
|
||||
|
||||
private lateinit var locales : PluginLocales
|
||||
private lateinit var attachment : PermissionAttachment
|
||||
|
||||
@BeforeTest
|
||||
fun setUpCommand() {
|
||||
worldManager = serviceLocator.getActiveService(WorldManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldManager is not available as a service") }
|
||||
assertTrue(worldManager.createWorld(CreateWorldOptions.worldName("world")).isSuccess)
|
||||
|
||||
val commandManager = serviceLocator.getActiveService(MVCommandManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("MVCommandManager is not available as a service") }
|
||||
locales = commandManager.locales
|
||||
|
||||
console = server.consoleSender
|
||||
player = server.addPlayer("benwoo1110");
|
||||
assertEquals(player, server.getPlayer("benwoo1110"))
|
||||
attachment = player.addAttachment(multiverseCore)
|
||||
assertNotNull(attachment)
|
||||
}
|
||||
|
||||
fun addPermission(permission: String) {
|
||||
attachment.setPermission(permission, true)
|
||||
}
|
||||
|
||||
fun assertCommandOutput(message : Message) {
|
||||
assertEquals(
|
||||
ChatTextFormatter.removeColor(message.formatted(locales)),
|
||||
ChatTextFormatter.removeColor(player.nextMessage())
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import co.aikar.commands.MessageKeys
|
||||
import org.bukkit.Bukkit
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.locale.MVCorei18n
|
||||
import org.mvplugins.multiverse.core.locale.message.Message
|
||||
import org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ConfigCommandTest : AbstractCommandTest() {
|
||||
|
||||
@Test
|
||||
fun `Modify config global-debug`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv config global-debug 2"))
|
||||
val coreConfig = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
assertEquals(2, coreConfig.globalDebug)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Modify config global-debug player no permission`() {
|
||||
assertTrue(player.performCommand("mv config global-debug 2"))
|
||||
assertCommandOutput(Message.of(MessageKeys.PERMISSION_DENIED, ""))
|
||||
|
||||
val coreConfig = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
assertEquals(0, coreConfig.globalDebug)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Modify non-existing config property`() {
|
||||
addPermission("multiverse.core.config")
|
||||
assertTrue(player.performCommand("mv config invalid-property test"))
|
||||
player.nextMessage() // ignore the first line
|
||||
assertCommandOutput(
|
||||
Message.of(
|
||||
MVCorei18n.CONFIG_NODE_NOTFOUND,
|
||||
"",
|
||||
replace("{node}").with("invalid-property")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Modify config global-debug invalid type`() {
|
||||
addPermission("multiverse.core.config")
|
||||
assertTrue(player.performCommand("mv config global-debug what"))
|
||||
player.nextMessage() // ignore the first line
|
||||
assertCommandOutput(Message.of("Unable to convert 'what' to number. (integer)"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.World
|
||||
import org.bukkit.WorldType
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class CreateCommandTest : AbstractCommandTest() {
|
||||
|
||||
@Test
|
||||
fun `Create nether world with default options`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv create world1_nether nether"))
|
||||
val world = worldManager.getLoadedWorld("world1_nether")
|
||||
assertTrue(world.isDefined)
|
||||
assertEquals(World.Environment.NETHER, world.get().environment)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create normal world with specific seed and flat world type without structures`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv create world1 normal --seed 1234 --world-type flat --no-structures"))
|
||||
val world = worldManager.getLoadedWorld("world1")
|
||||
assertTrue(world.isDefined)
|
||||
assertEquals(1234L, world.get().seed)
|
||||
assertEquals(WorldType.FLAT, world.get().worldType.get())
|
||||
assertFalse(world.get().canGenerateStructures().get())
|
||||
}
|
||||
|
||||
//todo: Fix mockbukkit getBiomeProvider then added test on single biome world creation
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.mvplugins.multiverse.core.command.queue.ConfirmMode
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.UnloadWorldOptions
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DeleteCommandTest : AbstractCommandTest() {
|
||||
|
||||
private lateinit var testWorld : LoadedMultiverseWorld
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
// Disable confirmation to make tests easier
|
||||
val config = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
config.confirmMode = ConfirmMode.DISABLE
|
||||
|
||||
testWorld = worldManager.createWorld(CreateWorldOptions.worldName("test")).get()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Delete loaded world`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv delete test"))
|
||||
assertFalse(worldManager.getWorld("test").isDefined)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Delete unloaded world`() {
|
||||
worldManager.unloadWorld(UnloadWorldOptions.world(testWorld))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv delete test"))
|
||||
assertFalse(worldManager.getWorld("test").isDefined)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.mvplugins.multiverse.core.command.queue.ConfirmMode
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ModifyCommandTest : AbstractCommandTest() {
|
||||
|
||||
private lateinit var testWorld : LoadedMultiverseWorld
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
// Disable confirmation to make tests easier
|
||||
val config = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
config.confirmMode = ConfirmMode.DISABLE
|
||||
|
||||
testWorld = worldManager.createWorld(CreateWorldOptions.worldName("test")).get()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Modify alias name with space`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv modify test set alias \"Test World\""))
|
||||
assertEquals("Test World", testWorld.alias)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.GameRule
|
||||
import org.mvplugins.multiverse.core.command.queue.ConfirmMode
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import kotlin.test.*
|
||||
|
||||
class RegenCommandTest : AbstractCommandTest() {
|
||||
|
||||
private lateinit var testWorld : LoadedMultiverseWorld
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
// Disable confirmation to make tests easier
|
||||
val config = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
assertTrue(config.setConfirmMode(ConfirmMode.DISABLE).isSuccess)
|
||||
|
||||
testWorld = worldManager.createWorld(CreateWorldOptions.worldName("test")).get()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world`() {
|
||||
val previousUID = testWorld.uid
|
||||
val previousSeed = testWorld.seed
|
||||
testWorld.scale = 69.5
|
||||
testWorld.bukkitWorld.map {
|
||||
it.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false)
|
||||
}
|
||||
testWorld.bukkitWorld.map {
|
||||
it.worldBorder.size = 123.4
|
||||
}
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv regen test"))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv confirm"))
|
||||
|
||||
val newWorld = worldManager.getLoadedWorld("test").orNull
|
||||
|
||||
assertNotNull(newWorld)
|
||||
assertNotEquals(previousUID, newWorld.uid)
|
||||
assertEquals(previousSeed, newWorld.seed)
|
||||
assertEquals(69.5, newWorld.scale)
|
||||
assertEquals(false, newWorld.bukkitWorld.map { it.getGameRuleValue(GameRule.DO_DAYLIGHT_CYCLE) }.orNull)
|
||||
assertEquals(123.4, newWorld.bukkitWorld.map { it.worldBorder.size }.orNull)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world with specific seed`() {
|
||||
val previousUID = testWorld.uid
|
||||
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv regen test --seed 456"))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv confirm"))
|
||||
|
||||
val newWorld = worldManager.getLoadedWorld("test").orNull
|
||||
|
||||
assertNotNull(newWorld)
|
||||
assertNotEquals(previousUID, newWorld.uid)
|
||||
assertEquals(456, newWorld.seed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world with random seed`() {
|
||||
val previousUID = testWorld.uid
|
||||
val previousSeed = testWorld.seed
|
||||
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv regen test --seed"))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv confirm"))
|
||||
|
||||
val newWorld = worldManager.getLoadedWorld("test").orNull
|
||||
|
||||
assertNotNull(newWorld)
|
||||
assertNotEquals(previousUID, newWorld.uid)
|
||||
assertNotEquals(previousSeed, newWorld.seed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world and reset world config`() {
|
||||
val previousUID = testWorld.uid
|
||||
testWorld.scale = 69.5
|
||||
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv regen test --reset-world-config"))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv confirm"))
|
||||
|
||||
val newWorld = worldManager.getLoadedWorld("test").orNull
|
||||
|
||||
assertNotNull(newWorld)
|
||||
assertNotEquals(previousUID, newWorld.uid)
|
||||
assertEquals(1.0, newWorld.scale)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world and reset gamerules`() {
|
||||
val previousUID = testWorld.uid
|
||||
testWorld.bukkitWorld.map {
|
||||
it.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false)
|
||||
}
|
||||
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv regen test --reset-gamerules"))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv confirm"))
|
||||
|
||||
val newWorld = worldManager.getLoadedWorld("test").orNull
|
||||
|
||||
assertNotNull(newWorld)
|
||||
assertNotEquals(previousUID, newWorld.uid)
|
||||
assertEquals(true, newWorld.bukkitWorld.map { it.getGameRuleValue(GameRule.DO_DAYLIGHT_CYCLE) }.orNull)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world and reset world border`() {
|
||||
val previousUID = testWorld.uid
|
||||
testWorld.bukkitWorld.map {
|
||||
it.worldBorder.size = 123.4
|
||||
}
|
||||
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv regen test --reset-world-border"))
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv confirm"))
|
||||
|
||||
val newWorld = worldManager.getLoadedWorld("test").orNull
|
||||
|
||||
assertNotNull(newWorld)
|
||||
assertNotEquals(previousUID, newWorld.uid)
|
||||
assertEquals(6.0E7, newWorld.bukkitWorld.map { it.worldBorder.size }.orNull)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.mvplugins.multiverse.core.world.location.SpawnLocation
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class SpawnCommandTest : AbstractCommandTest() {
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
server.addPlayer("Player1")
|
||||
server.addPlayer("Player2")
|
||||
server.addPlayer("Player3")
|
||||
assertTrue(worldManager.createWorld(CreateWorldOptions.worldName("otherworld")).isSuccess)
|
||||
server.getWorld("otherworld")?.spawnLocation?.let { Bukkit.getPlayer("Player1")?.teleport(it) }
|
||||
worldManager.getLoadedWorld("world").get().setSpawnLocation(SpawnLocation(20.0, 20.0, 20.0))
|
||||
worldManager.getLoadedWorld("otherworld").get().setSpawnLocation(SpawnLocation(20.0, 20.0, 20.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Teleport player to spawn location`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv spawn Player1 --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Teleport multiple players to spawn location`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv spawn Player1,Player2,Player3 --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player3")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `No permission to teleport to spawn`() {
|
||||
assertTrue(player.performCommand("mv spawn"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(Location(server.getWorld("world"), 0.0, 5.0, 0.0), player.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Self permission to teleport to spawn`() {
|
||||
addPermission("multiverse.core.spawn.self.world")
|
||||
assertTrue(player.performCommand("mv spawn --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, player.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Other permission to teleport to spawn`() {
|
||||
addPermission("multiverse.core.spawn.other.world")
|
||||
assertTrue(player.performCommand("mv spawn Player1,Player2 --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(Location(server.getWorld("otherworld"), 0.0, 5.0, 0.0), server.getPlayer("Player1")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
}
|
||||
@Test
|
||||
fun `Teleport others to spawn but not self`() {
|
||||
addPermission("multiverse.core.spawn.other.otherworld")
|
||||
assertTrue(player.performCommand("mv spawn benwoo1110,Player1 --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(Location(server.getWorld("world"), 0.0, 5.0, 0.0), server.getPlayer("benwoo1110")?.location)
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class TeleportCommandTest : AbstractCommandTest() {
|
||||
|
||||
private lateinit var config : CoreConfig
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
config = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
|
||||
server.addPlayer("Player1")
|
||||
server.addPlayer("Player2")
|
||||
server.addPlayer("Player3")
|
||||
assertTrue(worldManager.createWorld(CreateWorldOptions.worldName("otherworld")).isSuccess)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Teleport a player to other world`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv tp Player1 otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Teleport multiple players to other world`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv tp Player1,Player2 otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Teleport multiple players to invalid world`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv tp Player1,Player2 invalidworld"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player no permission to teleport`() {
|
||||
assertTrue(player.performCommand("mv tp otherworld"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player permission to teleport self`() {
|
||||
addPermission("multiverse.teleport.self.w.otherworld")
|
||||
|
||||
assertTrue(player.performCommand("mv tp otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, player.location)
|
||||
|
||||
assertTrue(player.performCommand("mv tp Player1 world --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
|
||||
assertTrue(player.performCommand("mv tp Player2,Player3 world --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player3")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player permission to teleport others`() {
|
||||
addPermission("multiverse.teleport.other.w.otherworld")
|
||||
|
||||
assertTrue(player.performCommand("mv tp Player1 otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
|
||||
assertTrue(player.performCommand("mv tp Player2,Player3 otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player3")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player permission to teleport others cannot teleport self`() {
|
||||
addPermission("multiverse.teleport.other.w.otherworld")
|
||||
|
||||
assertTrue(player.performCommand("mv tp otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, player.location)
|
||||
|
||||
assertTrue(player.performCommand("mv tp benwoo1110,Player1,Player2 world --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("benwoo1110")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player permission to teleport self without finer permission`() {
|
||||
config.setUseFinerTeleportPermissions(false)
|
||||
addPermission("multiverse.teleport.self.w")
|
||||
|
||||
assertTrue(player.performCommand("mv tp otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, player.location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player permission to teleport others without finer permission`() {
|
||||
config.setUseFinerTeleportPermissions(false)
|
||||
addPermission("multiverse.teleport.other.w")
|
||||
|
||||
assertTrue(player.performCommand("mv tp Player1,Player2 otherworld --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player1")?.location)
|
||||
assertLocationEquals(server.getWorld("otherworld")?.spawnLocation, server.getPlayer("Player2")?.location)
|
||||
|
||||
assertTrue(player.performCommand("mv tp benwoo1110,Player3 world --unsafe"))
|
||||
Thread.sleep(10) // wait for the player to teleport asynchronously
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("benwoo1110")?.location)
|
||||
assertLocationEquals(server.getWorld("world")?.spawnLocation, server.getPlayer("Player3")?.location)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.mvplugins.multiverse.core.commands
|
||||
|
||||
import co.aikar.commands.MessageKeys
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.mvplugins.multiverse.core.locale.MVCorei18n
|
||||
import org.mvplugins.multiverse.core.locale.message.Message
|
||||
import org.mvplugins.multiverse.core.locale.message.MessageReplacement.replace
|
||||
import org.mvplugins.multiverse.core.utils.text.ChatTextFormatter
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class VersionCommandTest : AbstractCommandTest() {
|
||||
|
||||
@Test
|
||||
fun `Run version command as console`() {
|
||||
assertTrue(Bukkit.dispatchCommand(console, "mv version"))
|
||||
val output = ChatTextFormatter.removeColor(console.nextMessage())
|
||||
assertEquals("Multiverse Core Version v" + multiverseCore.getDescription().getVersion(), output)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Run version command as player`() {
|
||||
addPermission("multiverse.core.version")
|
||||
assertTrue(player.performCommand("mv version"))
|
||||
assertCommandOutput(
|
||||
Message.of(
|
||||
MVCorei18n.VERSION_MV,
|
||||
"",
|
||||
replace("{version}").with(multiverseCore.getDescription().getVersion())))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Run version command as player - no permission`() {
|
||||
assertTrue(player.performCommand("mv version"))
|
||||
assertCommandOutput(Message.of(MessageKeys.PERMISSION_DENIED, ""))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.mvplugins.multiverse.core.config
|
||||
|
||||
import org.bukkit.Location
|
||||
import org.mockbukkit.mockbukkit.entity.PlayerMock
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter
|
||||
import org.mvplugins.multiverse.core.world.WorldManager
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import java.lang.AssertionError
|
||||
import kotlin.test.*
|
||||
|
||||
class ConfigTeleportInterceptTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var config: CoreConfig
|
||||
private lateinit var safetyTeleporter: AsyncSafetyTeleporter
|
||||
private lateinit var player: PlayerMock
|
||||
private lateinit var location: Location
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
config = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
|
||||
safetyTeleporter = serviceLocator.getActiveService(AsyncSafetyTeleporter::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("AsyncSafetyTeleporter is not available as a service") }
|
||||
|
||||
val worldManager = serviceLocator.getActiveService(WorldManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldManager is not available as a service") }
|
||||
|
||||
player = server.addPlayer()
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("world2")).get()
|
||||
location = Location(server.getWorld("world2"), 0.0, 5.0, 0.0)
|
||||
config.enforceAccess = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Generic teleport with teleport intercept enabled`() {
|
||||
config.teleportIntercept = true
|
||||
assertFalse(player.teleport(location))
|
||||
assertEquals("world", player.world.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Generic teleport with teleport intercept disabled - no access checking`() {
|
||||
config.teleportIntercept = false
|
||||
assertTrue(player.teleport(location))
|
||||
assertEquals("world2", player.world.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Multiverse API teleport with teleport intercept disabled`() {
|
||||
config.teleportIntercept = false
|
||||
safetyTeleporter.to(location).teleport(player).toAttempt()
|
||||
.onSuccess (Runnable { throw AssertionError("Teleport should have failed") })
|
||||
.onFailure(Runnable { assertEquals("world", player.world.name) })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package org.mvplugins.multiverse.core.config
|
||||
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.command.queue.ConfirmMode
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.test.*
|
||||
|
||||
class ConfigTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var config : CoreConfig
|
||||
private lateinit var configFile : File
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
configFile = File(Path.of(multiverseCore.dataFolder.absolutePath, "config.yml").absolutePathString())
|
||||
if (configFile.exists()) configFile.delete()
|
||||
|
||||
config = serviceLocator.getActiveService(CoreConfig::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("CoreConfig is not available as a service") }
|
||||
|
||||
assertTrue(config.load().isSuccess)
|
||||
assertTrue(config.save().isSuccess)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Config is loaded`() {
|
||||
assertTrue(config.isLoaded)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Config is fresh`() {
|
||||
assertConfigEquals("/configs/fresh_config.yml", "config.yml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Old config is migrated`() {
|
||||
val oldConfig = getResourceAsText("/configs/old_config.yml")
|
||||
assertNotNull(oldConfig)
|
||||
multiverseCore.dataFolder.toPath().resolve("config.yml").toFile().writeText(oldConfig)
|
||||
assertTrue(config.load().isSuccess)
|
||||
assertTrue(config.save().isSuccess)
|
||||
|
||||
assertEquals(true, config.enforceAccess)
|
||||
assertEquals(false, config.isEnablePrefixChat)
|
||||
assertEquals("[%world%]>>%chat%", config.prefixChatFormat)
|
||||
assertEquals(false, config.teleportIntercept)
|
||||
assertEquals(true, config.firstSpawnOverride)
|
||||
assertEquals(2, config.globalDebug)
|
||||
assertEquals(false, config.silentStart)
|
||||
assertEquals("world", config.firstSpawnLocation)
|
||||
assertEquals(false, config.isUsingCustomPortalSearch)
|
||||
assertEquals(128, config.customPortalSearchRadius)
|
||||
assertEquals(true, config.isAutoPurgeEntities)
|
||||
assertEquals(false, config.isShowingDonateMessage)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting existing config property with getProperty returns expected value`() {
|
||||
assertEquals(false, config.stringPropertyHandle.getProperty("enforce-access").get())
|
||||
assertEquals("", config.stringPropertyHandle.getProperty("first-spawn-location").get())
|
||||
assertEquals(ConfirmMode.ENABLE, config.stringPropertyHandle.getProperty("confirm-mode").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting non-existing config property with getProperty returns null`() {
|
||||
assertTrue(config.stringPropertyHandle.getProperty("invalid-property").isFailure)
|
||||
assertTrue(config.stringPropertyHandle.getProperty("version").isFailure)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting existing config property by getter returns expected value`() {
|
||||
assertEquals(false, config.enforceAccess)
|
||||
assertEquals("", config.firstSpawnLocation)
|
||||
assertEquals(ConfirmMode.ENABLE, config.confirmMode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating an existing config property with setProperty reflects the changes in getProperty`() {
|
||||
assertTrue(config.stringPropertyHandle.setProperty("enforce-access", true).isSuccess)
|
||||
assertEquals(true, config.stringPropertyHandle.getProperty("enforce-access").get())
|
||||
|
||||
assertTrue(config.stringPropertyHandle.setProperty("chat-prefix-format", "%world% %chat%").isSuccess)
|
||||
assertEquals("%world% %chat%", config.stringPropertyHandle.getProperty("chat-prefix-format").get())
|
||||
|
||||
assertTrue(config.stringPropertyHandle.setProperty("global-debug", 1).isSuccess)
|
||||
assertEquals(1, config.stringPropertyHandle.getProperty("global-debug").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating an existing config property with setPropertyString reflects the changes in getProperty`() {
|
||||
assertTrue(config.stringPropertyHandle.setPropertyString("enforce-access", "true").isSuccess)
|
||||
assertEquals(true, config.stringPropertyHandle.getProperty("enforce-access").get())
|
||||
|
||||
assertTrue(config.stringPropertyHandle.setPropertyString("chat-prefix-format", "%world% %chat%").isSuccess)
|
||||
assertEquals("%world% %chat%", config.stringPropertyHandle.getProperty("chat-prefix-format").get())
|
||||
|
||||
assertTrue(config.stringPropertyHandle.setPropertyString("global-debug", "1").isSuccess)
|
||||
assertEquals(1, config.stringPropertyHandle.getProperty("global-debug").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating a non-existing property with setProperty returns false`() {
|
||||
assertTrue(config.stringPropertyHandle.setProperty("invalid-property", false).isFailure)
|
||||
assertTrue(config.stringPropertyHandle.setProperty("version", 1.1).isFailure)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Broken config should regen fresh config`() {
|
||||
val brokenConfigData = getResourceAsText("/configs/broken_config.yml")
|
||||
assertNotNull(brokenConfigData)
|
||||
configFile.writeText(brokenConfigData)
|
||||
assertTrue(config.load().isSuccess)
|
||||
assertTrue(config.save().isSuccess)
|
||||
val brokenConfigFile = configFile.parentFile.listFiles({ _, fileName -> fileName.startsWith("config.yml.broken") })
|
||||
assertNotNull(brokenConfigFile)
|
||||
assertEquals(1, brokenConfigFile.size)
|
||||
assertConfigEquals("/configs/fresh_config.yml", "config.yml")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package org.mvplugins.multiverse.core.destination
|
||||
|
||||
import org.bukkit.Location
|
||||
import org.mockbukkit.mockbukkit.entity.PlayerMock
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.destination.core.*
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld
|
||||
import org.mvplugins.multiverse.core.world.WorldManager
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DestinationTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var worldManager: WorldManager
|
||||
private lateinit var destinationsProvider: DestinationsProvider
|
||||
private lateinit var world: LoadedMultiverseWorld
|
||||
private lateinit var player: PlayerMock
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
worldManager = serviceLocator.getActiveService(WorldManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldManager is not available as a service") }
|
||||
destinationsProvider = serviceLocator.getActiveService(DestinationsProvider::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("DestinationsProvider is not available as a service") }
|
||||
|
||||
world = worldManager.createWorld(CreateWorldOptions.worldName("world")).get()
|
||||
player = server.addPlayer("benji_0224")
|
||||
player.bedSpawnLocation = Location(world.bukkitWorld.orNull, 5.0, 10.0, 5.0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Bed destination instance`() {
|
||||
assertTrue(destinationsProvider.getDestinationById("b") is BedDestination)
|
||||
val destination = destinationsProvider.parseDestination("b:benji_0224").get()
|
||||
assertTrue(destination is BedDestinationInstance)
|
||||
assertEquals(player.bedSpawnLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("b:benji_0224", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Bed destination instance own player`() {
|
||||
val destination = destinationsProvider.parseDestination("b:playerbed").orNull
|
||||
assertTrue(destination is BedDestinationInstance)
|
||||
assertEquals(player.bedSpawnLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("b:playerbed", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Cannon destination instance`() {
|
||||
assertTrue(destinationsProvider.getDestinationById("ca") is CannonDestination)
|
||||
val destination = destinationsProvider.parseDestination("ca:world:1.2,2,3:10.5:9.5:5").orNull
|
||||
assertTrue(destination is CannonDestinationInstance)
|
||||
val expectedLocation = Location(world.bukkitWorld.orNull, 1.2, 2.0, 3.0, 9.5F, 10.5F)
|
||||
assertLocationEquals(expectedLocation, destination.getLocation(player).orNull)
|
||||
// todo: assert the Vector
|
||||
assertEquals("ca:world:1.2,2.0,3.0:10.5:9.5:5.0", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Exact destination instance`() {
|
||||
assertTrue(destinationsProvider.getDestinationById("e") is ExactDestination)
|
||||
val destination = destinationsProvider.parseDestination("e:world:1.2,2,3:10.5:9.5").orNull
|
||||
assertTrue(destination is ExactDestinationInstance)
|
||||
val expectedLocation = Location(world.bukkitWorld.orNull, 1.2, 2.0, 3.0, 9.5F, 10.5F)
|
||||
assertLocationEquals(expectedLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("e:world:1.2,2.0,3.0:10.5:9.5", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Exact destination instance with relative position`() {
|
||||
val destination = destinationsProvider.parseDestination("e:world:~1.5,2,~-3:10.5:~9.5").orNull
|
||||
assertTrue(destination is ExactDestinationInstance)
|
||||
val expectedLocation = Location(
|
||||
world.bukkitWorld.orNull,
|
||||
player.location.x + 1.5,
|
||||
2.0,
|
||||
player.location.z - 3.0,
|
||||
player.location.yaw + 9.5F,
|
||||
10.5F
|
||||
)
|
||||
assertLocationEquals(expectedLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("e:world:~1.5,2.0,~-3.0:10.5:~9.5", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Exact destination instance from location`() {
|
||||
val exactDestination = serviceLocator.getActiveService(ExactDestination::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("ExactDestination is not available as a service") }
|
||||
|
||||
val location = Location(world.bukkitWorld.orNull, 1.2, 2.0, 3.0, 9.5F, 10.5F)
|
||||
val destination = exactDestination.fromLocation(location)
|
||||
assertEquals(location, destination.getLocation(player).orNull)
|
||||
assertEquals("e:world:1.2,2.0,3.0:10.5:9.5", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Player destination instance`() {
|
||||
assertTrue(destinationsProvider.getDestinationById("pl") is PlayerDestination)
|
||||
val destination = destinationsProvider.parseDestination("pl:benji_0224").orNull
|
||||
assertTrue(destination is PlayerDestinationInstance)
|
||||
assertEquals(player.location, destination.getLocation(player).orNull)
|
||||
assertEquals("pl:benji_0224", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `World destination instance`() {
|
||||
assertTrue(destinationsProvider.getDestinationById("w") is WorldDestination)
|
||||
val destination = destinationsProvider.parseDestination("w:world").orNull
|
||||
assertTrue(destination is WorldDestinationInstance)
|
||||
assertEquals(world.spawnLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("w:world", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `World destination instance without identifier`() {
|
||||
val destination = destinationsProvider.parseDestination("world").orNull
|
||||
assertTrue(destination is WorldDestinationInstance)
|
||||
assertEquals(world.spawnLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("w:world", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `World destination instance from alias name`() {
|
||||
world.setAlias("testalias")
|
||||
val destination = destinationsProvider.parseDestination("testalias").orNull
|
||||
assertTrue(destination is WorldDestinationInstance)
|
||||
assertEquals(world.spawnLocation, destination.getLocation(player).orNull)
|
||||
assertEquals("w:world", destination.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Invalid destination instance`() {
|
||||
assertTrue(destinationsProvider.parseDestination("").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("idk:world").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("a:invalid-anchor").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("b:invalid-bed").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("ca:invalid-cannon").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("e:world:1,2,x").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("e:world:1,2,3:").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("pl:invalid-player").isFailure)
|
||||
assertTrue(destinationsProvider.parseDestination("w:invalid-world").isFailure)
|
||||
// todo: should we make invalid yaw for WorldDestination fail?
|
||||
// assertTrue(destinationsProvider.parseDestination("w:world:f").isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.mvplugins.multiverse.core.inject
|
||||
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.anchor.AnchorManager
|
||||
import org.mvplugins.multiverse.core.commands.CoreCommand
|
||||
import org.mvplugins.multiverse.core.command.MVCommandManager
|
||||
import org.mvplugins.multiverse.core.config.CoreConfig
|
||||
import org.mvplugins.multiverse.core.destination.Destination
|
||||
import org.mvplugins.multiverse.core.economy.MVEconomist
|
||||
import org.mvplugins.multiverse.core.listeners.CoreListener
|
||||
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter
|
||||
import org.mvplugins.multiverse.core.teleportation.BlockSafety
|
||||
import org.mvplugins.multiverse.core.teleportation.LocationManipulation
|
||||
import org.mvplugins.multiverse.core.teleportation.TeleportQueue
|
||||
import org.mvplugins.multiverse.core.world.WorldManager
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class InjectionTest : TestWithMockBukkit() {
|
||||
|
||||
@Test
|
||||
fun `AnchorManager is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(AnchorManager::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AsyncSafetyTeleporter is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(AsyncSafetyTeleporter::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `BlockSafety is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(BlockSafety::class.java))
|
||||
assertNotNull(serviceLocator.getActiveService(BlockSafety::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `MVCommandManager is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(MVCommandManager::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `MVEconomist is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(MVEconomist::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `LocationManipulation is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(LocationManipulation::class.java))
|
||||
assertNotNull(serviceLocator.getActiveService(LocationManipulation::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `TeleportQueue is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(TeleportQueue::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `MVWorldManager is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(WorldManager::class.java))
|
||||
assertNotNull(serviceLocator.getActiveService(WorldManager::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CoreListener(s) is available as a service`() {
|
||||
val listeners = assertNotNull(serviceLocator.getAllServices(CoreListener::class.java))
|
||||
assertEquals(7, listeners.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CoreConfig is available as a service`() {
|
||||
assertNotNull(serviceLocator.getActiveService(CoreConfig::class.java))
|
||||
assertNotNull(serviceLocator.getActiveService(CoreConfig::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Commands are available as services`() {
|
||||
val commands = serviceLocator.getAllActiveServices(CoreCommand::class.java)
|
||||
assertEquals(57, commands.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Destinations are available as services`() {
|
||||
val destinations = serviceLocator.getAllActiveServices(Destination::class.java)
|
||||
assertEquals(6, destinations.size)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.mvplugins.multiverse.core.mock;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.mockbukkit.mockbukkit.ServerMock;
|
||||
import org.mockbukkit.mockbukkit.command.CommandMapMock;
|
||||
import org.mockbukkit.mockbukkit.world.WorldMock;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class MVServerMock extends ServerMock {
|
||||
|
||||
private final File worldContainer;
|
||||
|
||||
public MVServerMock() throws IOException {
|
||||
super();
|
||||
this.worldContainer = Files.createTempDirectory("world-container").toFile();
|
||||
this.worldContainer.deleteOnExit();
|
||||
System.out.println("Created test world folder: " + this.worldContainer.getAbsolutePath());
|
||||
}
|
||||
|
||||
// This is required for acf reflection to work
|
||||
@Override
|
||||
public @NotNull CommandMapMock getCommandMap() {
|
||||
return super.getCommandMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull File getWorldContainer() {
|
||||
return this.worldContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World createWorld(@NotNull WorldCreator creator) {
|
||||
WorldMock world = new MVWorldMock(creator);
|
||||
world.getWorldFolder().mkdirs();
|
||||
createFile(new File(world.getWorldFolder(), "uid.dat"));
|
||||
createFile(new File(world.getWorldFolder(), "level.dat"));
|
||||
addWorld(world);
|
||||
return world;
|
||||
}
|
||||
|
||||
private void createFile(File file) {
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.mvplugins.multiverse.core.mock;
|
||||
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.mockbukkit.mockbukkit.MockBukkit;
|
||||
import org.mockbukkit.mockbukkit.world.WorldMock;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MVWorldMock extends WorldMock {
|
||||
|
||||
private final File worldFolder;
|
||||
|
||||
public MVWorldMock(@NotNull WorldCreator creator) {
|
||||
super(creator);
|
||||
this.worldFolder = new File(MockBukkit.getMock().getWorldContainer(), getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull File getWorldFolder() {
|
||||
return this.worldFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MVWorldMock{'name': '" + this.getName() + "'}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.mvplugins.multiverse.core.utils
|
||||
|
||||
import org.bukkit.Material
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class MaterialConverterTest {
|
||||
|
||||
@Test
|
||||
fun `Convert dirt name to material`() {
|
||||
assertEquals(Material.DIRT, MaterialConverter.stringToMaterial("dirt"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Convert Spruce Planks numerical id to material`() {
|
||||
assertEquals(Material.SPRUCE_PLANKS, MaterialConverter.stringToMaterial("5:1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Convert Oak Sapling item id to material`() {
|
||||
assertEquals(Material.OAK_SAPLING, MaterialConverter.stringToMaterial("minecraft:oak_sapling"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Convert invalid string to material`() {
|
||||
assertNull(MaterialConverter.stringToMaterial("invalid"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.mvplugins.multiverse.core.utils
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class StringFormatterTest {
|
||||
@Test
|
||||
fun `StringFormatter parseQuotesInArgs`() {
|
||||
assertEquals(
|
||||
listOf("before", "this is a test", "after"),
|
||||
StringFormatter.parseQuotesInArgs(arrayOf("before", "\"this", "is", "a", "test\"", "after"))
|
||||
)
|
||||
assertEquals(
|
||||
listOf("\""),
|
||||
StringFormatter.parseQuotesInArgs(arrayOf("\""))
|
||||
)
|
||||
assertEquals(
|
||||
listOf("\"", "after"),
|
||||
StringFormatter.parseQuotesInArgs(arrayOf("\"", "after"))
|
||||
)
|
||||
assertEquals(
|
||||
listOf("\"word", "after"),
|
||||
StringFormatter.parseQuotesInArgs(arrayOf("\"word", "after"))
|
||||
)
|
||||
assertEquals(
|
||||
listOf("word\"", "after\""),
|
||||
StringFormatter.parseQuotesInArgs(arrayOf("word\"", "after\""))
|
||||
)
|
||||
assertEquals(
|
||||
listOf("word\"", "af\"ter"),
|
||||
StringFormatter.parseQuotesInArgs(arrayOf("word\"", "af\"ter"))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `StringFormatter quoteMultiWordString`() {
|
||||
assertEquals(
|
||||
"\"this is a test\"",
|
||||
StringFormatter.quoteMultiWordString("this is a test")
|
||||
)
|
||||
assertEquals(
|
||||
"test",
|
||||
StringFormatter.quoteMultiWordString("test")
|
||||
)
|
||||
assertNull(StringFormatter.quoteMultiWordString(null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `StringFormatter parseCSVMap`() {
|
||||
assertEquals(
|
||||
emptyMap<String, String>(),
|
||||
StringFormatter.parseCSVMap("")
|
||||
)
|
||||
assertEquals(
|
||||
mapOf("key" to "value"),
|
||||
StringFormatter.parseCSVMap("key=value")
|
||||
)
|
||||
assertEquals(
|
||||
mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3"),
|
||||
StringFormatter.parseCSVMap("key1=value1,key2=value2,key3=value3")
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.mvplugins.multiverse.core.utils
|
||||
|
||||
import org.mvplugins.multiverse.core.utils.matcher.ExactStringMatcher
|
||||
import org.mvplugins.multiverse.core.utils.matcher.RegexStringMatcher
|
||||
import org.mvplugins.multiverse.core.utils.matcher.WildcardStringMatcher
|
||||
import kotlin.test.Test
|
||||
|
||||
class StringMatcherTest {
|
||||
|
||||
@Test
|
||||
fun `exact string matcher - single string`() {
|
||||
val matcher = ExactStringMatcher("test")
|
||||
assert(matcher.matches("test"))
|
||||
assert(!matcher.matches("Test"))
|
||||
assert(!matcher.matches("testing"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `exact string matcher - multiple strings`() {
|
||||
val matcher = ExactStringMatcher(setOf("test", "example", "sample"));
|
||||
assert(matcher.matches("test"))
|
||||
assert(matcher.matches("example"))
|
||||
assert(matcher.matches("sample"))
|
||||
assert(!matcher.matches("Test"))
|
||||
assert(!matcher.matches("testing"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `wildcard string matcher - single`() {
|
||||
val matcher = WildcardStringMatcher("test*")
|
||||
assert(matcher.matches("test"))
|
||||
assert(matcher.matches("test123"))
|
||||
assert(matcher.matches("testing"))
|
||||
assert(!matcher.matches("TEST"))
|
||||
assert(!matcher.matches("nottest123"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `wildcard string matcher - multiple`() {
|
||||
val matcher = WildcardStringMatcher("test-*_*-world")
|
||||
assert(matcher.matches("test-123_pl-world"))
|
||||
assert(matcher.matches("test-abc_xyz-world"))
|
||||
assert(matcher.matches("test-hello_world-world"))
|
||||
assert(!matcher.matches("test-hello-world"))
|
||||
assert(!matcher.matches("test-hello_world-world!"))
|
||||
assert(!matcher.matches("TEST-123_PL-WORLD"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `regex string matcher`() {
|
||||
val matcher = RegexStringMatcher("r=^test[0-9]+$")
|
||||
assert(matcher.matches("test123"))
|
||||
assert(matcher.matches("test456"))
|
||||
assert(!matcher.matches("test"))
|
||||
assert(!matcher.matches("TEST123"))
|
||||
assert(!matcher.matches("testing"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package org.mvplugins.multiverse.core.world
|
||||
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.World.Environment
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.entity.SpawnCategory
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.economy.MVEconomist
|
||||
import org.mvplugins.multiverse.core.world.location.SpawnLocation
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.test.*
|
||||
|
||||
class WorldConfigMangerTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var worldConfigManager : WorldsConfigManager
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
val defaultWorldsData = getResourceAsText("/worlds/default_worlds.yml")
|
||||
assertNotNull(defaultWorldsData)
|
||||
val worldsFile = File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds.yml").absolutePathString())
|
||||
if (worldsFile.exists()) worldsFile.delete()
|
||||
worldsFile.writeText(defaultWorldsData)
|
||||
|
||||
worldConfigManager = serviceLocator.getActiveService(WorldsConfigManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldsConfigManager is not available as a service") }
|
||||
assertTrue(worldConfigManager.load().isSuccess)
|
||||
assertTrue(worldConfigManager.isLoaded)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Old world config is migrated`() {
|
||||
val oldConfig = getResourceAsText("/worlds/old_worlds.yml")
|
||||
assertNotNull(oldConfig)
|
||||
File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds.yml").absolutePathString()).writeText(oldConfig)
|
||||
|
||||
assertTrue(worldConfigManager.load().isSuccess)
|
||||
assertTrue(worldConfigManager.save().isSuccess)
|
||||
|
||||
val endWorldConfig = worldConfigManager.getWorldConfig("world_the_end").orNull
|
||||
assertNotNull(endWorldConfig)
|
||||
|
||||
assertEquals("&aworld the end", endWorldConfig.alias)
|
||||
assertEquals(Environment.THE_END, endWorldConfig.environment)
|
||||
assertFalse(endWorldConfig.isEntryFeeEnabled)
|
||||
assertEquals(MVEconomist.VAULT_ECONOMY_MATERIAL, endWorldConfig.entryFeeCurrency)
|
||||
assertEquals(0.0, endWorldConfig.entryFeeAmount)
|
||||
|
||||
val worldConfig = worldConfigManager.getWorldConfig("world.a.b").orNull
|
||||
assertNotNull(worldConfig)
|
||||
|
||||
assertEquals(-5176596003035866649, worldConfig.seed)
|
||||
assertEquals(listOf("test"), worldConfig.worldBlacklist)
|
||||
assertTrue(worldConfig.isEntryFeeEnabled)
|
||||
assertEquals(Material.DIRT, worldConfig.entryFeeCurrency)
|
||||
assertEquals(5.0, worldConfig.entryFeeAmount)
|
||||
|
||||
val world2Config = worldConfigManager.getWorldConfig("world.a.c").orNull
|
||||
assertNotNull(world2Config)
|
||||
|
||||
assertConfigEquals("/worlds/migrated_worlds.yml", "worlds.yml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Add a new world to config`() {
|
||||
val worldConfig = worldConfigManager.addWorldConfig("new.world")
|
||||
assertNotNull(worldConfig)
|
||||
assertEquals("new.world", worldConfig.worldName)
|
||||
assertTrue(worldConfigManager.save().isSuccess)
|
||||
assertConfigEquals("/worlds/newworld_worlds.yml", "worlds.yml")
|
||||
|
||||
// Make sure the world still can be loaded after save
|
||||
assertTrue(worldConfigManager.load().isSuccess)
|
||||
assertEquals("new.world", worldConfigManager.getWorldConfig("new.world").orNull?.worldName)
|
||||
assertConfigEquals("/worlds/newworld_worlds.yml", "worlds.yml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating existing world properties`() {
|
||||
val worldConfig = worldConfigManager.getWorldConfig("world").orNull
|
||||
assertNotNull(worldConfig)
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("adjust-spawn", true).isSuccess)
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("alias", "newalias").isSuccess)
|
||||
assertTrue(worldConfig.setSpawnLocation(
|
||||
SpawnLocation(
|
||||
-50.0,
|
||||
50.0,
|
||||
50.0
|
||||
)
|
||||
).isSuccess)
|
||||
worldConfig.entitySpawnConfig.getSpawnCategoryConfig(SpawnCategory.MISC).isSpawn = false
|
||||
worldConfig.entitySpawnConfig.getSpawnCategoryConfig(SpawnCategory.ANIMAL).tickRate = 111
|
||||
worldConfig.entitySpawnConfig.getSpawnCategoryConfig(SpawnCategory.ANIMAL).exceptions = listOf(EntityType.COW, EntityType.PIG)
|
||||
assertTrue(worldConfigManager.save().isSuccess)
|
||||
assertConfigEquals("/worlds/updated_worlds.yml", "worlds.yml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Delete world section from config`() {
|
||||
worldConfigManager.deleteWorldConfig("world")
|
||||
assertTrue(worldConfigManager.save().isSuccess)
|
||||
assertConfigEquals("/worlds/delete_worlds.yml", "worlds.yml")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Edge case parsing tests for world config`() {
|
||||
val edgecaseConfig = getResourceAsText("/worlds/edgecase_worlds.yml")
|
||||
assertNotNull(edgecaseConfig)
|
||||
File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds.yml").absolutePathString()).writeText(edgecaseConfig)
|
||||
|
||||
assertTrue(worldConfigManager.load().isSuccess)
|
||||
assertTrue(worldConfigManager.save().isSuccess)
|
||||
|
||||
val worldConfig = assertNotNull(worldConfigManager.getWorldConfig("world").orNull)
|
||||
|
||||
assertEquals("1234", worldConfig.alias)
|
||||
assertTrue(worldConfig.bedRespawn)
|
||||
assertEquals(GameMode.SURVIVAL, worldConfig.gameMode)
|
||||
assertEquals(4.0, worldConfig.scale)
|
||||
assertEquals(listOf("a", "1", "2"), worldConfig.worldBlacklist)
|
||||
assertEquals(listOf(EntityType.COW), worldConfig.entitySpawnConfig.getSpawnCategoryConfig(SpawnCategory.ANIMAL).exceptions)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package org.mvplugins.multiverse.core.world
|
||||
|
||||
import org.bukkit.Material
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.test.*
|
||||
|
||||
class WorldConfigTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var worldConfigManager : WorldsConfigManager
|
||||
private lateinit var worldConfig : WorldConfig
|
||||
private lateinit var worldNetherConfig : WorldConfig
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
val defaultConfig = getResourceAsText("/worlds/default_worlds.yml")
|
||||
assertNotNull(defaultConfig)
|
||||
File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds.yml").absolutePathString()).writeText(defaultConfig)
|
||||
|
||||
worldConfigManager = serviceLocator.getActiveService(WorldsConfigManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldsConfigManager is not available as a service") }
|
||||
|
||||
assertTrue(worldConfigManager.load().isSuccess)
|
||||
worldConfig = worldConfigManager.getWorldConfig("world").orNull.takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldConfig for world is not available") }
|
||||
assertNotNull(worldConfig)
|
||||
worldNetherConfig = worldConfigManager.getWorldConfig("world_nether").orNull.takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldConfig for world is not available") }
|
||||
assertNotNull(worldNetherConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting existing world property with getProperty returns expected value`() {
|
||||
assertEquals("my world", worldConfig.stringPropertyHandle.getProperty("alias").get())
|
||||
assertEquals(false, worldConfig.stringPropertyHandle.getProperty("hidden").get())
|
||||
assertEquals(1.0, worldConfig.stringPropertyHandle.getProperty("scale").get())
|
||||
assertEquals(8.0, worldNetherConfig.stringPropertyHandle.getProperty("scale").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting non-existing world property with getProperty returns null`() {
|
||||
assertTrue(worldConfig.stringPropertyHandle.getProperty("invalid-property").isFailure)
|
||||
assertTrue(worldConfig.stringPropertyHandle.getProperty("version").isFailure)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Getting existing world property by getter returns expected value`() {
|
||||
assertEquals("my world", worldConfig.alias)
|
||||
assertEquals(false, worldConfig.isHidden)
|
||||
assertEquals(emptyList(), worldConfig.worldBlacklist)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating an existing world property with setProperty reflects the changes in getProperty`() {
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("adjust-spawn", true).isSuccess)
|
||||
assertEquals(true, worldConfig.stringPropertyHandle.getProperty("adjust-spawn").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("alias", "abc").isSuccess)
|
||||
assertEquals("abc", worldConfig.stringPropertyHandle.getProperty("alias").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("scale", 2.0).isSuccess)
|
||||
assertEquals(2.0, worldConfig.stringPropertyHandle.getProperty("scale").get())
|
||||
|
||||
val blacklists = listOf("a", "b", "c")
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("world-blacklist", blacklists).isSuccess)
|
||||
assertEquals(blacklists, worldConfig.stringPropertyHandle.getProperty("world-blacklist").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("entryfee-currency", Material.JUNGLE_WOOD).isSuccess)
|
||||
assertEquals(Material.JUNGLE_WOOD, worldConfig.stringPropertyHandle.getProperty("entryfee-currency").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating an existing world property with setPropertyString reflects the changes in getProperty`() {
|
||||
assertTrue(worldConfig.stringPropertyHandle.setPropertyString("adjust-spawn", "true").isSuccess)
|
||||
assertEquals(true, worldConfig.getStringPropertyHandle().getProperty("adjust-spawn").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setPropertyString("alias", "abc").isSuccess)
|
||||
assertEquals("abc", worldConfig.stringPropertyHandle.getProperty("alias").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setPropertyString("scale", "2.0").isSuccess)
|
||||
assertEquals(2.0, worldConfig.stringPropertyHandle.getProperty("scale").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setPropertyString("world-blacklist", "a,b,c").isSuccess)
|
||||
assertEquals(listOf("a", "b", "c"), worldConfig.stringPropertyHandle.getProperty("world-blacklist").get())
|
||||
|
||||
assertTrue(worldConfig.stringPropertyHandle.setPropertyString("entryfee-currency", "jungle_wood").isSuccess)
|
||||
assertEquals(Material.JUNGLE_WOOD, worldConfig.stringPropertyHandle.getProperty("entryfee-currency").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Updating a non-existing property with setProperty returns false`() {
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("invalid-property", false).isFailure)
|
||||
assertTrue(worldConfig.stringPropertyHandle.setProperty("version", 1.1).isFailure)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
package org.mvplugins.multiverse.core.world
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.World
|
||||
import org.bukkit.WorldType
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher.hasFiredEventInstance
|
||||
import org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher.hasNotFiredEventInstance
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.event.world.*
|
||||
import org.mvplugins.multiverse.core.world.options.CloneWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.CreateWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.DeleteWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.LoadWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.RegenWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.RemoveWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.options.UnloadWorldOptions
|
||||
import org.mvplugins.multiverse.core.world.reasons.CloneFailureReason
|
||||
import org.mvplugins.multiverse.core.world.reasons.CreateFailureReason
|
||||
import org.mvplugins.multiverse.core.world.reasons.LoadFailureReason
|
||||
import java.io.File
|
||||
import kotlin.test.*
|
||||
|
||||
class WorldManagerTest : TestWithMockBukkit() {
|
||||
|
||||
private lateinit var worldManager: WorldManager
|
||||
private lateinit var world: LoadedMultiverseWorld
|
||||
private lateinit var world2: LoadedMultiverseWorld
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
worldManager = serviceLocator.getActiveService(WorldManager::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldManager is not available as a service") }
|
||||
|
||||
assertTrue(worldManager.createWorld(CreateWorldOptions.worldName("world")).isSuccess)
|
||||
world = worldManager.getLoadedWorld("world").get()
|
||||
assertNotNull(world)
|
||||
|
||||
assertTrue(worldManager.createWorld(CreateWorldOptions.worldName("World2")).isSuccess)
|
||||
world2 = worldManager.getLoadedWorld("World2").get()
|
||||
assertNotNull(world2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world with custom options`() {
|
||||
assertTrue(worldManager.createWorld(
|
||||
CreateWorldOptions.worldName("Section/my-nether_world")
|
||||
.environment(World.Environment.NETHER)
|
||||
.generateStructures(false)
|
||||
.seed(1234L)
|
||||
.useSpawnAdjust(false)
|
||||
.worldType(WorldType.FLAT)
|
||||
).isSuccess)
|
||||
|
||||
val getWorld = worldManager.getLoadedWorld("Section/my-nether_world")
|
||||
assertTrue(getWorld.isDefined)
|
||||
val world = getWorld.get()
|
||||
assertNotNull(world)
|
||||
assertEquals("Section/my-nether_world", world.name)
|
||||
assertEquals(World.Environment.NETHER, world.environment)
|
||||
assertFalse(world.canGenerateStructures().get())
|
||||
assertEquals(1234L, world.seed)
|
||||
assertFalse(world.adjustSpawn)
|
||||
assertEquals(WorldType.FLAT, world.worldType.get())
|
||||
assertEquals("", world.generator)
|
||||
assertEquals(8.0, world.scale)
|
||||
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldLoadedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldCreatedEvent::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - invalid worldname`() {
|
||||
assertEquals(
|
||||
CreateFailureReason.INVALID_WORLDNAME,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("*!@^&#*(")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - world exists and loaded`() {
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_LOADED,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("world")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - world exists and loaded (case insensitive)`() {
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_LOADED,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("WoRld2")).failureReason
|
||||
)
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_LOADED,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("WORLD2")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - world exists but unloaded`() {
|
||||
assertTrue(worldManager.unloadWorld(UnloadWorldOptions.world(world)).isSuccess)
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_UNLOADED,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("world")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Create world failed - world folder exists`() {
|
||||
File(Bukkit.getWorldContainer(), "worldfolder").mkdir()
|
||||
assertEquals(
|
||||
CreateFailureReason.WORLD_EXIST_FOLDER,
|
||||
worldManager.createWorld(CreateWorldOptions.worldName("worldfolder")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Remove world`() {
|
||||
assertTrue(worldManager.removeWorld(RemoveWorldOptions.world(world)).isSuccess)
|
||||
assertFalse(worldManager.getWorld("world").isDefined)
|
||||
assertFalse(worldManager.getLoadedWorld("world").isDefined)
|
||||
assertFalse(worldManager.getUnloadedWorld("world").isDefined)
|
||||
|
||||
assertTrue(worldManager.removeWorld(RemoveWorldOptions.world(world2)).isSuccess)
|
||||
assertFalse(worldManager.getWorld("World2").isDefined)
|
||||
assertFalse(worldManager.getLoadedWorld("World2").isDefined)
|
||||
assertFalse(worldManager.getUnloadedWorld("World2").isDefined)
|
||||
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldUnloadedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldRemovedEvent::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Delete world`() {
|
||||
assertTrue(File(Bukkit.getWorldContainer(), "world").isDirectory)
|
||||
assertTrue(worldManager.deleteWorld(DeleteWorldOptions.world(world)).isSuccess)
|
||||
assertFalse(worldManager.getWorld("world").isDefined)
|
||||
assertFalse(worldManager.getLoadedWorld("world").isDefined)
|
||||
assertFalse(worldManager.getUnloadedWorld("world").isDefined)
|
||||
assertFalse(File(Bukkit.getWorldContainer(), "world").isDirectory)
|
||||
|
||||
assertTrue(File(Bukkit.getWorldContainer(), "World2").isDirectory)
|
||||
assertTrue(worldManager.deleteWorld(DeleteWorldOptions.world(world2)).isSuccess)
|
||||
assertFalse(worldManager.getWorld("World2").isDefined)
|
||||
assertFalse(worldManager.getLoadedWorld("World2").isDefined)
|
||||
assertFalse(worldManager.getUnloadedWorld("World2").isDefined)
|
||||
assertFalse(File(Bukkit.getWorldContainer(), "World2").isDirectory)
|
||||
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldDeleteEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldUnloadedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldRemovedEvent::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Unload and load world`() {
|
||||
assertTrue(worldManager.unloadWorld(UnloadWorldOptions.world(world2).saveBukkitWorld(true)).isSuccess)
|
||||
assertFalse(world2.isLoaded)
|
||||
assertFalse(world2.bukkitWorld.isDefined)
|
||||
assertFalse(worldManager.getLoadedWorld("World2").isDefined)
|
||||
assertTrue(worldManager.getWorld("World2").isDefined)
|
||||
assertTrue(worldManager.getUnloadedWorld("World2").isDefined)
|
||||
|
||||
assertTrue(worldManager.loadWorld(LoadWorldOptions.world(world2)).isSuccess)
|
||||
assertTrue(world2.isLoaded)
|
||||
assertTrue(worldManager.getLoadedWorld("World2").flatMap{ w -> w.bukkitWorld }.isDefined)
|
||||
assertTrue(worldManager.getLoadedWorld("World2").isDefined)
|
||||
assertFalse(worldManager.getUnloadedWorld("World2").isDefined)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Load world failed - invalid world folder`() {
|
||||
assertTrue(worldManager.unloadWorld(UnloadWorldOptions.world(world2)).isSuccess)
|
||||
File(Bukkit.getWorldContainer(), "World2/").deleteRecursively()
|
||||
assertEquals(
|
||||
LoadFailureReason.WORLD_FOLDER_INVALID,
|
||||
worldManager.loadWorld(LoadWorldOptions.world(world2)).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Load world failed - non-existent world`() {
|
||||
assertEquals(
|
||||
LoadFailureReason.WORLD_NON_EXISTENT,
|
||||
worldManager.loadWorld("ghost").failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Load world failed - world folder exists but not imported`() {
|
||||
File(Bukkit.getWorldContainer(), "worldfolder").mkdir()
|
||||
File(Bukkit.getWorldContainer(), "worldfolder/level.dat").createNewFile()
|
||||
assertEquals(
|
||||
LoadFailureReason.WORLD_EXIST_FOLDER,
|
||||
worldManager.loadWorld("worldfolder").failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Regen world`() {
|
||||
assertTrue(worldManager.regenWorld(
|
||||
RegenWorldOptions
|
||||
.world(world2)
|
||||
.seed(4321L)
|
||||
).isSuccess)
|
||||
|
||||
val getWorld = worldManager.getLoadedWorld("World2")
|
||||
assertTrue(getWorld.isDefined)
|
||||
val world = getWorld.get()
|
||||
assertNotNull(world)
|
||||
assertEquals(4321L, world.seed)
|
||||
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldDeleteEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldUnloadedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldRemovedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldLoadedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldCreatedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldRegeneratedEvent::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Clone world`() {
|
||||
assertTrue(worldManager.cloneWorld(CloneWorldOptions.fromTo(world, "cloneworld").saveBukkitWorld(false)).isSuccess)
|
||||
val getWorld = worldManager.getLoadedWorld("cloneworld")
|
||||
assertTrue(getWorld.isDefined)
|
||||
val world = getWorld.get()
|
||||
assertNotNull(world)
|
||||
assertEquals("cloneworld", world.name)
|
||||
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldLoadedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldImportedEvent::class.java))
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldClonedEvent::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Clone world failed - invalid world name`() {
|
||||
assertEquals(
|
||||
CloneFailureReason.INVALID_WORLDNAME,
|
||||
worldManager.cloneWorld(CloneWorldOptions.fromTo(world, "HU(@*!#")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Clone world failed - target world exists and loaded`() {
|
||||
assertEquals(
|
||||
CloneFailureReason.WORLD_EXIST_LOADED,
|
||||
worldManager.cloneWorld(CloneWorldOptions.fromTo(world, "World2")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Clone world failed - target world exists but unloaded`() {
|
||||
assertTrue(worldManager.unloadWorld(UnloadWorldOptions.world(world2)).isSuccess)
|
||||
assertEquals(
|
||||
CloneFailureReason.WORLD_EXIST_UNLOADED,
|
||||
worldManager.cloneWorld(CloneWorldOptions.fromTo(world, "World2")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Clone world failed - target world folder exists`() {
|
||||
File(Bukkit.getWorldContainer(), "worldfolder").mkdir()
|
||||
assertEquals(
|
||||
CloneFailureReason.WORLD_EXIST_FOLDER,
|
||||
worldManager.cloneWorld(CloneWorldOptions.fromTo(world, "worldfolder")).failureReason
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get potential worlds`() {
|
||||
File(Bukkit.getWorldContainer(), "newworld1").mkdir()
|
||||
File(Bukkit.getWorldContainer(), "newworld1/level.dat").createNewFile()
|
||||
File(Bukkit.getWorldContainer(), "newworld2").mkdir()
|
||||
File(Bukkit.getWorldContainer(), "newworld2/level.dat").createNewFile()
|
||||
assertEquals(setOf("newworld1", "newworld2"), worldManager.getPotentialWorlds().toSet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get world with alias`() {
|
||||
world.setAlias("testalias")
|
||||
assertEquals(world, worldManager.getLoadedWorldByNameOrAlias("testalias").orNull)
|
||||
assertEquals(world, worldManager.getWorldByNameOrAlias("testalias").orNull)
|
||||
assertNull(worldManager.getUnloadedWorldByNameOrAlias("testalias").orNull)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get world`() {
|
||||
assertEquals(world, worldManager.getLoadedWorld("world").orNull)
|
||||
assertNull(worldManager.getUnloadedWorld("world").orNull)
|
||||
assertEquals(world, worldManager.getWorld("world").orNull)
|
||||
|
||||
assertTrue(worldManager.isLoadedWorld("world"))
|
||||
assertFalse(worldManager.isUnloadedWorld("world"))
|
||||
assertTrue(worldManager.isWorld("world"))
|
||||
|
||||
val unloadedWorld = worldManager.unloadWorld(UnloadWorldOptions.world(world)).get()
|
||||
|
||||
assertNull(worldManager.getLoadedWorld("world").orNull)
|
||||
assertEquals(unloadedWorld, worldManager.getUnloadedWorld("world").orNull)
|
||||
assertEquals(unloadedWorld, worldManager.getWorld("world").orNull)
|
||||
|
||||
assertFalse(worldManager.isLoadedWorld("world"))
|
||||
assertTrue(worldManager.isUnloadedWorld("world"))
|
||||
assertTrue(worldManager.isWorld("world"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Get world is case insensitive`() {
|
||||
assertEquals(world2, worldManager.getLoadedWorld("WORLD2").orNull)
|
||||
assertNull(worldManager.getUnloadedWorld("wOrld2").orNull)
|
||||
assertEquals(world2, worldManager.getWorld("wOrld2").orNull)
|
||||
|
||||
assertTrue(worldManager.isLoadedWorld("WoRlD2"))
|
||||
assertFalse(worldManager.isUnloadedWorld("WoRlD2"))
|
||||
assertTrue(worldManager.isWorld("wORLD2"))
|
||||
|
||||
val unloadedWorld2 = worldManager.unloadWorld(UnloadWorldOptions.world(world2)).get()
|
||||
|
||||
assertNull(worldManager.getLoadedWorld("wOrld2").orNull)
|
||||
assertEquals(unloadedWorld2, worldManager.getUnloadedWorld("wOrld2").orNull)
|
||||
assertEquals(unloadedWorld2, worldManager.getWorld("wORLD2").orNull)
|
||||
|
||||
assertFalse(worldManager.isLoadedWorld("WoRlD2"))
|
||||
assertTrue(worldManager.isUnloadedWorld("WoRlD2"))
|
||||
assertTrue(worldManager.isWorld("wORLD2"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Set different value - MVWorldPropertyChangedEvent event is fired`() {
|
||||
server.pluginManager.clearEvents()
|
||||
world.scale = 8.0
|
||||
assertThat(server.pluginManager, hasFiredEventInstance(MVWorldPropertyChangedEvent::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Set equal value - MVWorldPropertyChangedEvent event is not fired`() {
|
||||
server.pluginManager.clearEvents()
|
||||
world.scale = 1.0
|
||||
assertThat(server.pluginManager, hasNotFiredEventInstance(MVWorldPropertyChangedEvent::class.java))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.mvplugins.multiverse.core.world
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.world.helpers.WorldNameChecker
|
||||
import java.io.File
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.*
|
||||
|
||||
class WorldNameCheckerTest : TestWithMockBukkit() {
|
||||
|
||||
lateinit var worldNameChecker: WorldNameChecker
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
worldNameChecker = serviceLocator.getActiveService(WorldNameChecker::class.java).takeIf { it != null } ?: run {
|
||||
throw IllegalStateException("WorldNameChecker is not available as a service") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Valid world name`() {
|
||||
assertEquals(WorldNameChecker.NameStatus.VALID, worldNameChecker.checkName("test"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Invalid characters in world name`() {
|
||||
assertEquals(WorldNameChecker.NameStatus.INVALID_CHARS, worldNameChecker.checkName("test!"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Empty world name`() {
|
||||
assertEquals(WorldNameChecker.NameStatus.EMPTY, worldNameChecker.checkName(null))
|
||||
assertEquals(WorldNameChecker.NameStatus.EMPTY, worldNameChecker.checkName(""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Blacklisted world name`() {
|
||||
assertEquals(WorldNameChecker.NameStatus.BLACKLISTED, worldNameChecker.checkName("logs"))
|
||||
assertEquals(WorldNameChecker.NameStatus.BLACKLISTED, worldNameChecker.checkName("plugins"))
|
||||
assertEquals(WorldNameChecker.NameStatus.BLACKLISTED, worldNameChecker.checkName("CACHE"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Valid world folder`() {
|
||||
File(Bukkit.getWorldContainer(), "test").mkdir()
|
||||
File(Bukkit.getWorldContainer(), "test/level.dat").createNewFile()
|
||||
assertEquals(WorldNameChecker.FolderStatus.VALID, worldNameChecker.checkFolder("test"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Not a valid world folder`() {
|
||||
File(Bukkit.getWorldContainer(), "test").mkdir()
|
||||
File(Bukkit.getWorldContainer(), "test/random.txt").createNewFile()
|
||||
assertEquals(WorldNameChecker.FolderStatus.NOT_A_WORLD, worldNameChecker.checkFolder("test"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `World folder does not exist`() {
|
||||
File(Bukkit.getWorldContainer(), "test").mkdir()
|
||||
assertEquals(WorldNameChecker.FolderStatus.DOES_NOT_EXIST, worldNameChecker.checkFolder("test2"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.mvplugins.multiverse.core.world.helper
|
||||
|
||||
import org.mvplugins.multiverse.core.TestWithMockBukkit
|
||||
import org.mvplugins.multiverse.core.world.helpers.DimensionFinder.DimensionFormat
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
class DimensionFormatTest : TestWithMockBukkit() {
|
||||
|
||||
@Test
|
||||
fun `Test invalid DimensionFormat`() {
|
||||
assertFailsWith(IllegalArgumentException::class) {
|
||||
DimensionFormat("%idk%_nether")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Test DimensionFormat replace`() {
|
||||
val dimensionFormat = DimensionFormat("%overworld%_nether")
|
||||
assertEquals("cool_nether", dimensionFormat.replaceOverworld("cool"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Test DimensionFormat get overworld`() {
|
||||
val dimensionFormat = DimensionFormat("%overworld%_n")
|
||||
assertEquals("cool", dimensionFormat.getOverworldFromName("cool_n").get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Test DimensionFormat does not match`() {
|
||||
val dimensionFormat = DimensionFormat("%overworld%_nether")
|
||||
assertFalse(dimensionFormat.getOverworldFromName("cool_end").isDefined)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
anchors:
|
||||
a1: w1:0.50,70.00,0.50:-68.25:10.35
|
||||
a2: w2:3.3,9.9,6.6:-1.1:2
|
||||
a3: w3:3.00,3.00,3.00:-3.00:3.00
|
||||
@@ -0,0 +1,3 @@
|
||||
anchors:
|
||||
a1: w1:0.50,70.00,0.50:-68.25:10.35
|
||||
a2: w2:3.3,9.9,6.6:-1.1:2
|
||||
@@ -0,0 +1,38 @@
|
||||
world:
|
||||
enforce-access: false
|
||||
enforce-gamemode: true
|
||||
auto-purge-entities: false
|
||||
|
||||
teleport:
|
||||
use-finer-teleport-permissions: true
|
||||
concurrent-teleport-limit: 50
|
||||
teleport-intercept: true
|
||||
|
||||
spawn:
|
||||
first-spawn-override: true
|
||||
first-spawn-location: ''
|
||||
enable-join-destination: false
|
||||
join-destination: ''
|
||||
|
||||
portal:
|
||||
use-custom-portal-search: false
|
||||
custom-portal-search-radius: 128
|
||||
|
||||
messaging:
|
||||
enable-chat-prefix: false
|
||||
chat-prefix-format: '[%world%]%chat%'
|
||||
register-papi-hook: true
|
||||
default-locale: en
|
||||
per-player-locale: true
|
||||
?!
|
||||
command:
|
||||
resolve-alias-name: true
|
||||
confirm-mode: enable
|
||||
use-confirm-otp: true
|
||||
|
||||
misc:
|
||||
global-debug: 0
|
||||
silent-start: false
|
||||
show-donation-message: true
|
||||
|
||||
version: 5.1
|
||||
@@ -0,0 +1,69 @@
|
||||
world:
|
||||
auto-import-default-worlds: true
|
||||
auto-import-3rd-party-worlds: true
|
||||
enforce-access: false
|
||||
enforce-gamemode: true
|
||||
enforce-flight: true
|
||||
gamemode-and-flight-enforce-delay: 1
|
||||
apply-entity-spawn-rate: true
|
||||
apply-entity-spawn-limit: true
|
||||
auto-purge-entities: false
|
||||
world-name-format:
|
||||
nether: '%overworld%_nether'
|
||||
end: '%overworld%_the_end'
|
||||
|
||||
teleport:
|
||||
use-finer-teleport-permissions: true
|
||||
passenger-mode: default
|
||||
concurrent-teleport-limit: 50
|
||||
teleport-intercept: true
|
||||
safe-location-horizontal-search-radius: 3
|
||||
safe-location-vertical-search-radius: 3
|
||||
|
||||
spawn:
|
||||
first-spawn-override: false
|
||||
first-spawn-location: ''
|
||||
enable-join-destination: false
|
||||
join-destination: ''
|
||||
default-respawn-in-overworld: true
|
||||
default-respawn-within-same-world: true
|
||||
enforce-respawn-at-world-spawn: true
|
||||
|
||||
portal:
|
||||
use-custom-portal-search: false
|
||||
custom-portal-search-radius: 128
|
||||
|
||||
messaging:
|
||||
enable-chat-prefix: false
|
||||
chat-prefix-format: '[%world%]%chat%'
|
||||
register-papi-hook: true
|
||||
warn-invalid-papi-format: true
|
||||
invalid-papi-format-returns-blank: false
|
||||
default-locale: en
|
||||
per-player-locale: true
|
||||
|
||||
command:
|
||||
resolve-alias-name: true
|
||||
simplified-destination-tab-completion: false
|
||||
confirm-mode: enable
|
||||
use-confirm-otp: true
|
||||
confirm-timeout: 30
|
||||
show-legacy-aliases: false
|
||||
|
||||
event-priority:
|
||||
player-portal: high
|
||||
player-respawn: low
|
||||
player-spawn-location: normal
|
||||
player-teleport: highest
|
||||
player-changed-world: normal
|
||||
|
||||
misc:
|
||||
bukkit-yml-path: bukkit.yml
|
||||
server-properties-path: server.properties
|
||||
auto-detect-generator-plugins: true
|
||||
global-debug: 0
|
||||
debug-permissions: false
|
||||
silent-start: false
|
||||
show-donation-message: true
|
||||
|
||||
version: 5.2
|
||||
@@ -0,0 +1,20 @@
|
||||
multiverse-configuration:
|
||||
==: com.onarandombox.MultiverseCore.MultiverseCoreConfiguration
|
||||
enforceaccess: 'true'
|
||||
prefixchat: 'false'
|
||||
prefixchatformat: '[%world%]>>%chat%'
|
||||
useasyncchat: 'true'
|
||||
teleportintercept: 'false'
|
||||
firstspawnoverride: 'true'
|
||||
displaypermerrors: 'false'
|
||||
enablebuscript: 'false'
|
||||
globaldebug: '2'
|
||||
silentstart: 'false'
|
||||
messagecooldown: '5000'
|
||||
version: '2.9'
|
||||
firstspawnworld: world
|
||||
teleportcooldown: '1000'
|
||||
defaultportalsearch: 'true'
|
||||
portalsearchradius: '128'
|
||||
autopurge: 'true'
|
||||
idonotwanttodonate: 'true'
|
||||
@@ -0,0 +1,156 @@
|
||||
world:
|
||||
adjust-spawn: false
|
||||
alias: my world
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: normal
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
world_nether:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: nether
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 8.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
@@ -0,0 +1,78 @@
|
||||
world_nether:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: nether
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 8.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
@@ -0,0 +1,158 @@
|
||||
world:
|
||||
adjust-spawn: false
|
||||
alias: 1234 # should be parsed as string and not integer
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: allow # should parse to true as boolean
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: dirt # should be parsed to @minecraft:dirt
|
||||
environment: normal
|
||||
gamemode: sUrvivAl # random casing shouldn't affect parsing
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: '4' # string number should be parsed as double
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
spawn: falSe
|
||||
tick-rate: 123
|
||||
spawn-limit: '@unset'
|
||||
exceptions: [ cow ]
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: # should be parsed as list of string
|
||||
- a
|
||||
- 1
|
||||
- 2
|
||||
version: 1.2
|
||||
world_nether:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: nether
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 8.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
@@ -0,0 +1,236 @@
|
||||
world_the_end:
|
||||
adjust-spawn: false
|
||||
alias: '&aworld the end'
|
||||
allow-advancement-grant: true
|
||||
allow-flight: true
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: the_end
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 16.0
|
||||
seed: -5176596003035866649
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: 0.0
|
||||
y: 65.0
|
||||
z: 0.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@bukkit'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@bukkit'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
world[dot]a[dot]b:
|
||||
adjust-spawn: true
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: true
|
||||
amount: 5.0
|
||||
currency: DIRT
|
||||
environment: normal
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -5176596003035866649
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@bukkit'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@bukkit'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist:
|
||||
- test
|
||||
version: 1.2
|
||||
world[dot]a[dot]c:
|
||||
adjust-spawn: true
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: true
|
||||
amount: 5.0
|
||||
currency: DIRT
|
||||
environment: normal
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -5176596003035866649
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@bukkit'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@bukkit'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist:
|
||||
- test
|
||||
version: 1.2
|
||||
@@ -0,0 +1,229 @@
|
||||
world:
|
||||
adjust-spawn: false
|
||||
alias: my world
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: normal
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
world_nether:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: nether
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 8.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
new[dot]world:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
biome: '@error'
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: normal
|
||||
gamemode: survival
|
||||
generator: '@error'
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
@@ -0,0 +1,146 @@
|
||||
worlds:
|
||||
world_the_end:
|
||||
==: MVWorld
|
||||
hidden: 'false'
|
||||
alias: world the end
|
||||
color: GREEN
|
||||
style: NORMAL
|
||||
pvp: 'true'
|
||||
scale: '16.0'
|
||||
respawnWorld: ''
|
||||
allowWeather: 'true'
|
||||
difficulty: NORMAL
|
||||
spawning:
|
||||
==: MVSpawnSettings
|
||||
animals:
|
||||
==: MVSpawnSubSettings
|
||||
spawn: 'true'
|
||||
spawnrate: '-1'
|
||||
exceptions: []
|
||||
monsters:
|
||||
==: MVSpawnSubSettings
|
||||
spawn: 'true'
|
||||
spawnrate: '-1'
|
||||
exceptions: []
|
||||
entryfee:
|
||||
==: MVEntryFee
|
||||
amount: '0.0'
|
||||
hunger: 'true'
|
||||
autoHeal: 'true'
|
||||
adjustSpawn: 'false'
|
||||
portalForm: ALL
|
||||
gameMode: SURVIVAL
|
||||
keepSpawnInMemory: 'true'
|
||||
spawnLocation:
|
||||
==: MVSpawnLocation
|
||||
x: 0.0
|
||||
y: 65.0
|
||||
z: 0.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
autoLoad: 'true'
|
||||
bedRespawn: 'true'
|
||||
worldBlacklist: []
|
||||
environment: THE_END
|
||||
seed: '-5176596003035866649'
|
||||
generator: 'null'
|
||||
playerLimit: '-1'
|
||||
allowFlight: 'true'
|
||||
world.a.b:
|
||||
==: MVWorld
|
||||
hidden: 'false'
|
||||
alias: ''
|
||||
color: WHITE
|
||||
style: NORMAL
|
||||
pvp: 'true'
|
||||
scale: '1.0'
|
||||
respawnWorld: ''
|
||||
allowWeather: 'true'
|
||||
difficulty: NORMAL
|
||||
spawning:
|
||||
==: MVSpawnSettings
|
||||
animals:
|
||||
==: MVSpawnSubSettings
|
||||
spawn: 'true'
|
||||
spawnrate: '-1'
|
||||
exceptions: []
|
||||
monsters:
|
||||
==: MVSpawnSubSettings
|
||||
spawn: 'true'
|
||||
spawnrate: '-1'
|
||||
exceptions: []
|
||||
entryfee:
|
||||
==: MVEntryFee
|
||||
amount: '5.0'
|
||||
currency: 'DIRT'
|
||||
hunger: 'true'
|
||||
autoHeal: 'true'
|
||||
adjustSpawn: 'true'
|
||||
portalForm: ALL
|
||||
gameMode: SURVIVAL
|
||||
keepSpawnInMemory: 'true'
|
||||
spawnLocation:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
autoLoad: 'true'
|
||||
bedRespawn: 'true'
|
||||
worldBlacklist:
|
||||
- test
|
||||
environment: NORMAL
|
||||
seed: '-5176596003035866649'
|
||||
generator: 'null'
|
||||
playerLimit: '-1'
|
||||
allowFlight: 'false'
|
||||
world.a.c:
|
||||
==: MVWorld
|
||||
hidden: 'false'
|
||||
alias: ''
|
||||
color: WHITE
|
||||
style: NORMAL
|
||||
pvp: 'true'
|
||||
scale: '1.0'
|
||||
respawnWorld: ''
|
||||
allowWeather: 'true'
|
||||
difficulty: NORMAL
|
||||
spawning:
|
||||
==: MVSpawnSettings
|
||||
animals:
|
||||
==: MVSpawnSubSettings
|
||||
spawn: 'true'
|
||||
spawnrate: '-1'
|
||||
exceptions: []
|
||||
monsters:
|
||||
==: MVSpawnSubSettings
|
||||
spawn: 'true'
|
||||
spawnrate: '-1'
|
||||
exceptions: []
|
||||
entryfee:
|
||||
==: MVEntryFee
|
||||
amount: '5.0'
|
||||
currency: 'DIRT'
|
||||
hunger: 'true'
|
||||
autoHeal: 'true'
|
||||
adjustSpawn: 'true'
|
||||
portalForm: ALL
|
||||
gameMode: SURVIVAL
|
||||
keepSpawnInMemory: 'true'
|
||||
spawnLocation:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
autoLoad: 'true'
|
||||
bedRespawn: 'true'
|
||||
worldBlacklist:
|
||||
- test
|
||||
environment: NORMAL
|
||||
seed: '-5176596003035866649'
|
||||
generator: 'null'
|
||||
playerLimit: '-1'
|
||||
allowFlight: 'false'
|
||||
@@ -0,0 +1,151 @@
|
||||
world:
|
||||
adjust-spawn: true
|
||||
alias: newalias
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: @vault-economy
|
||||
environment: NORMAL
|
||||
gamemode: SURVIVAL
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: ALL
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
world_nether:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: NORMAL
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: @vault-economy
|
||||
environment: NETHER
|
||||
gamemode: SURVIVAL
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: ALL
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVNullLocation (It's a bug if you see this in your config file)
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
@@ -0,0 +1,158 @@
|
||||
world:
|
||||
adjust-spawn: true
|
||||
alias: newalias
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: normal
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 1.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -50.0
|
||||
y: 50.0
|
||||
z: 50.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
spawn: true
|
||||
tick-rate: 111
|
||||
spawn-limit: '@unset'
|
||||
exceptions:
|
||||
- cow
|
||||
- pig
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
spawn: false
|
||||
tick-rate: '@unset'
|
||||
spawn-limit: '@unset'
|
||||
exceptions: [ ]
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
world_nether:
|
||||
adjust-spawn: false
|
||||
alias: ''
|
||||
allow-advancement-grant: true
|
||||
allow-flight: false
|
||||
allow-weather: true
|
||||
anchor-respawn: true
|
||||
auto-heal: true
|
||||
auto-load: true
|
||||
bed-respawn: true
|
||||
difficulty: normal
|
||||
entry-fee:
|
||||
enabled: false
|
||||
amount: 0.0
|
||||
currency: '@vault-economy'
|
||||
environment: nether
|
||||
gamemode: survival
|
||||
biome: ''
|
||||
generator: ''
|
||||
hidden: false
|
||||
hunger: true
|
||||
keep-spawn-in-memory: true
|
||||
player-limit: -1
|
||||
portal-form: all
|
||||
pvp: true
|
||||
respawn-world: ''
|
||||
scale: 8.0
|
||||
seed: -9223372036854775808
|
||||
spawn-location:
|
||||
==: MVSpawnLocation
|
||||
x: -64.0
|
||||
y: 64.0
|
||||
z: 48.0
|
||||
pitch: 0.0
|
||||
yaw: 0.0
|
||||
spawning:
|
||||
monster:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_animal:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
water_underground_creature:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
ambient:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
axolotl:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
misc:
|
||||
exceptions: [ ]
|
||||
spawn: true
|
||||
spawn-limit: '@unset'
|
||||
tick-rate: '@unset'
|
||||
world-blacklist: []
|
||||
version: 1.2
|
||||
Reference in new issue
Block a user