diff --git a/.gitignore b/.gitignore index 94fdbf97..b29966b3 100755 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ ehthumbs_vista.db # Dump file *.stackdump +.j* # Folder config file [Dd]esktop.ini @@ -102,6 +103,7 @@ $RECYCLE.BIN/ *.lnk target/ +target pom.xml.tag pom.xml.releaseBackup @@ -124,3 +126,12 @@ qodana.yaml /Changes /Changes.md /SpigotMC.bbcode + +# Gradle +.gradle/** +build/** +gradle/** + +# Markdown files +*.md +!README.md diff --git a/.mvn/jvm.config b/.mvn/jvm.config deleted file mode 100644 index 97c58ccb..00000000 --- a/.mvn/jvm.config +++ /dev/null @@ -1,2 +0,0 @@ ---add-opens=java.base/java.lang=ALL-UNNAMED ---add-opens=java.base/java.io=ALL-UNNAMED \ No newline at end of file diff --git a/TODO b/TODO deleted file mode 100644 index 95890e6f..00000000 --- a/TODO +++ /dev/null @@ -1,8 +0,0 @@ -- /status (Health, GameMode, ...) - -- Command Swapper -- Command Deactivator - -- Essentials to ServerSystem Migrator -- ServerSystem to Essentials Migrator -^ Also CMI? Needs more research \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..14538b3b --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,131 @@ +import io.papermc.paperweight.userdev.ReobfArtifactConfiguration +import io.papermc.paperweight.util.path +import org.apache.tools.ant.filters.ReplaceTokens +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +plugins { + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.spring) + alias(libs.plugins.plugins.maven.shade) + alias(libs.plugins.paperweight.userdev) + alias(libs.plugins.git.version) +} + +group = "me.testaccount666" +val cleanVersion = "4.1.0" + +@Suppress("UNCHECKED_CAST") +val gitVersion = extra["gitVersion"] as groovy.lang.Closure +version = "${cleanVersion}-" + gitVersion().dropWhile { it != '-' }.drop(1).replace("dirty", getFormattedDate()) + +fun getFormattedDate(): String { + return DateTimeFormatter.ofPattern("yyyy-MM-dd.HH-mm").format(LocalDateTime.now()) +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(libs.versions.java.get()) + } +} + +val generateVersionInfo = tasks.register("generateVersionInfo") { + val template = file("src/main/resources/templates/VersionInfo.kt") + val outputDir = layout.buildDirectory.dir("generated/kotlin") + + inputs.file(template) + outputs.dir(outputDir) + + doLast { + val outputFile = outputDir.get().file("me/testaccount666/serversystem/utils/VersionInfo.kt").asFile + outputFile.parentFile.mkdirs() + template.copyTo(outputFile, true) + outputFile.writeText(outputFile.readText().replace("@CLEAN_VERSION@", cleanVersion)) + } +} + +kotlin { + compilerOptions { freeCompilerArgs.addAll("-Xjsr305=strict", "-jvm-target=21") } + + sourceSets.main { kotlin.srcDir(generateVersionInfo) } +} + +configurations { + compileOnly { + extendsFrom(configurations.annotationProcessor.get()) + } +} + +repositories { + mavenCentral() + maven("https://repo.essentialsx.net/releases") + maven("https://repo.papermc.io/repository/maven-public") + maven("https://oss.sonatype.org/content/groups/public") + maven("https://repo.extendedclip.com/content/repositories/placeholderapi") + maven("https://jitpack.io") + maven("https://repo.codemc.io/repository/maven-public") + maven("https://gitlab.com/api/v4/projects/80077577/packages/maven") +} + +dependencies { + paperweightDevelopmentBundle(libs.paperdevbundle) + implementation(libs.paperktx) { + exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib") + exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-core") + } + compileOnly(libs.kotlin.stdlib) + compileOnly(libs.kotlin.reflect) + compileOnly(libs.paperapi) + compileOnly(libs.clip.placeholderapi) + compileOnly(libs.milkbowl.vaultapi) + compileOnly(libs.essentialsx.essentialsx) { exclude("**", "**") } + compileOnly(libs.tr7zw.item.nbt.api.plugin) + compileOnly(libs.classgraph) + compileOnly(libs.bytebuddy.byte.buddy) + compileOnly(libs.zaxxer.hikaricp) + compileOnly(libs.h2) + compileOnly(libs.netty.all) + compileOnly(libs.mojang.authlib) + testImplementation(libs.junit.jupiter.api) + testImplementation(libs.junit.jupiter.engine) + testImplementation(libs.junit.jupiter.params) + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junit.jupiter) + testImplementation(kotlin("test")) +} + +paperweight { reobfArtifactConfiguration.set(ReobfArtifactConfiguration.MOJANG_PRODUCTION) } + +tasks.build { dependsOn(tasks.shadowJar) } + +tasks.shadowJar { + relocate("me.testaccount666.paperktx", "me.testaccount666.serversystem.libs.paperktx") + archiveFileName.set("ServerSystem.jar") + + val libsDirectory = layout.buildDirectory.path.resolve("libs") + + doFirst { + libsDirectory.toFile().listFiles().filter { it.name.endsWith(".jar") }.forEach(File::delete) + } + + doLast { + archiveFile.get().asFile.copyTo(libsDirectory.resolve("ServerSystem-${version}.jar").toFile(), true) + println(gitVersion()) + } +} + +tasks.processResources { + exclude("templates/**") + filter( + ReplaceTokens::class, + mapOf( + "tokens" to mapOf( + "PROJECT_VERSION" to project.version, + "CLEAN_VERSION" to cleanVersion, + "KOTLIN_VERSION" to libs.versions.kotlin.get() + ) + ) + ) +} + +tasks.withType(Test::useJUnitPlatform) diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..c9a5e6b3 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,6 @@ +# Generated by Maven-to-Gradle migration +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.caching=true +# Unsupported +org.gradle.configuration-cache=false diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..ef07e016 --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# 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 +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +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\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +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. + +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. +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 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and 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. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..db3a6ac2 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@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 ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +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 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +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 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index a48f48e8..00000000 --- a/pom.xml +++ /dev/null @@ -1,381 +0,0 @@ - - - 4.0.0 - - me.testaccount666 - ServerSystem - 4.1.0 - jar - - ServerSystem - - - 21 - 21 - 21 - 2.3.20-Beta1 - UTF-8 - ${project.version} - - ${git.commit.id.describe} - yyyy-MM-dd--HH-mm - - - - scm:git:${project.basedir} - scm:git:${project.basedir} - HEAD - - - - - - bytecode.space - https://repo.bytecode.space/repository/maven-public/ - - - - - clean package - - - maven-antrun-plugin - 3.2.0 - - - cleanup-jars - prepare-package - - run - - - - - - - - - - - copy-version - package - - - - - - - run - - - - copy-version-hash - package - - - - - - - run - - - - - - - io.github.git-commit-id - git-commit-id-maven-plugin - 9.0.2 - - - get-the-git-infos - - revision - - initialize - - - - true - ${project.basedir}/git.properties - - full - 8 - - -${build.timestamp} - 8 - true - !* - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - ${java.version} - - ${project.basedir}/src/main/kotlin - - true - - - - - ca.bkaw - paper-nms-maven-plugin - 1.4.10 - - - - org.apache.maven.plugins - maven-jar-plugin - 3.5.0 - - - - mojang - - - - - - - maven-resources-plugin - 3.4.0 - - - filter-version-info - generate-sources - - copy-resources - - - - ${project.build.directory}/generated-sources/versioninfo/me/testaccount666/serversystem/utils - - - - src/main/resources/templates - true - - VersionInfo.kt - - - - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.6.1 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/versioninfo - - - - - - - - - - src/main/resources - true - - templates/** - - - - - - - - essentials-releases - https://repo.essentialsx.net/releases/ - - - papermc-repo - https://repo.papermc.io/repository/maven-public/ - - - sonatype - https://oss.sonatype.org/content/groups/public/ - - - placeholderapi - https://repo.extendedclip.com/content/repositories/placeholderapi/ - - - - jitpack - https://jitpack.io/ - - - - codemc-repo - https://repo.codemc.io/repository/maven-public/ - default - - - - - - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-reflect - ${kotlin.version} - - - - io.papermc.paper - paper-api - 1.21.8-R0.1-SNAPSHOT - provided - - - ca.bkaw - paper-nms - 1.21.8-SNAPSHOT - provided - - - - me.clip - placeholderapi - 2.11.7 - provided - - - - com.github.MilkBowl - VaultAPI - 1.7.1 - provided - - - net.essentialsx - EssentialsX - 2.21.2 - provided - - - ** - ** - - - - - de.tr7zw - item-nbt-api-plugin - 2.15.5 - provided - - - io.github.classgraph - classgraph - 4.8.184 - - - - net.bytebuddy - byte-buddy - 1.17.7 - provided - - - com.zaxxer - HikariCP - 7.0.2 - provided - - - com.h2database - h2 - 2.4.240 - provided - - - - org.junit.jupiter - junit-jupiter-api - 6.1.0-M1 - test - - - org.junit.jupiter - junit-jupiter-engine - 6.1.0-M1 - test - - - org.junit.jupiter - junit-jupiter-params - 6.1.0-M1 - test - - - org.mockito - mockito-core - 5.21.0 - test - - - org.mockito - mockito-junit-jupiter - 5.21.0 - test - - - io.netty - netty-all - 4.1.130.Final - provided - - - com.mojang - authlib - 3.13.56 - provided - - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..3461d7d7 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "ServerSystem" diff --git a/src/main/kotlin/me/testaccount666/migration/LegacyDataMigrator.kt b/src/main/kotlin/me/testaccount666/migration/LegacyDataMigrator.kt index 74b1753f..6e7f41e6 100644 --- a/src/main/kotlin/me/testaccount666/migration/LegacyDataMigrator.kt +++ b/src/main/kotlin/me/testaccount666/migration/LegacyDataMigrator.kt @@ -1,31 +1,25 @@ package me.testaccount666.migration +import me.testaccount666.paperktx.extensions.isAir +import me.testaccount666.paperktx.extensions.location import me.testaccount666.serversystem.ServerSystem.Companion.instance import me.testaccount666.serversystem.ServerSystem.Companion.log import me.testaccount666.serversystem.commands.executables.kit.manager.Kit import me.testaccount666.serversystem.commands.executables.kit.manager.KitManager import me.testaccount666.serversystem.commands.executables.waypoints.warp.manager.Warp import me.testaccount666.serversystem.commands.executables.waypoints.warp.manager.WarpManager -import me.testaccount666.serversystem.moderation.AbstractModeration -import me.testaccount666.serversystem.moderation.BanModeration -import me.testaccount666.serversystem.moderation.MuteModeration -import me.testaccount666.serversystem.userdata.ConsoleUser -import me.testaccount666.serversystem.userdata.OfflineUser -import me.testaccount666.serversystem.userdata.UserManager +import me.testaccount666.serversystem.extensions.getService +import me.testaccount666.serversystem.moderation.* +import me.testaccount666.serversystem.userdata.* import me.testaccount666.serversystem.userdata.home.Home -import me.testaccount666.serversystem.utils.ItemStackExtensions.Companion.isAir import me.testaccount666.serversystem.utils.Version import org.bukkit.Bukkit -import org.bukkit.Location import org.bukkit.Material import org.bukkit.configuration.file.FileConfiguration import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.inventory.ItemStack import java.io.File -import java.sql.Connection -import java.sql.DriverManager -import java.sql.ResultSet -import java.sql.SQLException +import java.sql.* import java.util.* import java.util.logging.Level @@ -42,8 +36,7 @@ class LegacyDataMigrator { * @return Optional containing the offline user if found, empty otherwise */ private fun getOfflineUser(uuid: UUID): OfflineUser? { - val userManager = instance.registry.getService() - val user = userManager.getUserOrNull(uuid) ?: run { + val user = getService().getUserOrNull(uuid) ?: run { log.warning("Could not find user with UUID: ${uuid}") return null } @@ -199,7 +192,7 @@ class LegacyDataMigrator { var migratedCount = 0 val defaultItem = ItemStack(Material.AIR) - val kitManager = instance.registry.getService() + val kitManager = getService() for (kitName in kitNames) try { val offhandItem = kitsSection.getItemStack("${kitName}.40", defaultItem) @@ -252,7 +245,7 @@ class LegacyDataMigrator { return } - val warpManager = instance.registry.getService() + val warpManager = getService() val warpSection = legacyWarpsConfig.getConfigurationSection("Warps") val warpNames = warpSection?.getKeys(false) ?: HashSet() var migratedCount = 0 @@ -263,8 +256,8 @@ class LegacyDataMigrator { val x = legacyWarpsConfig.getDouble("${prefix}.X") val y = legacyWarpsConfig.getDouble("${prefix}.Y") val z = legacyWarpsConfig.getDouble("${prefix}.Z") - val yaw = legacyWarpsConfig.getDouble("${prefix}.Yaw").toFloat() - val pitch = legacyWarpsConfig.getDouble("${prefix}.Pitch").toFloat() + val yaw = legacyWarpsConfig.getDouble("${prefix}.Yaw") + val pitch = legacyWarpsConfig.getDouble("${prefix}.Pitch") val worldName = legacyWarpsConfig.getString("${prefix}.World") ?: "" val world = Bukkit.getWorld(worldName) ?: run { @@ -272,7 +265,7 @@ class LegacyDataMigrator { continue } - val location = Location(world, x, y, z, yaw, pitch) + val location = location(x, y, z, world, yaw, pitch) val warp = Warp.of(warpName, location) ?: run { log(Level.WARNING, "Warp name '${warpName}' contains invalid characters, skipping") continue @@ -354,15 +347,15 @@ class LegacyDataMigrator { val legacyConfigFile = File(_legacyDataDirectory, "config.yml") val legacyConfig = YamlConfiguration.loadConfiguration(legacyConfigFile) - if (legacyConfig.getBoolean("mysql.use", false)) { + if (legacyConfig.getBoolean("mysql.use")) { log(Level.INFO, "Legacy MySQL configuration detected. Migrating...") migrateMySqlConfig(legacyConfig) } // Sqlite is handled below - if (legacyConfig.getBoolean("sqlite.use", false)) log(Level.INFO, "Legacy SQLite configuration detected. Migrating...") + if (legacyConfig.getBoolean("sqlite.use")) log(Level.INFO, "Legacy SQLite configuration detected. Migrating...") - if (legacyConfig.getBoolean("h2.use", false)) { + if (legacyConfig.getBoolean("h2.use")) { log(Level.INFO, "Legacy H2 configuration detected. Migrating...") migrateH2Config(legacyConfig) } @@ -406,10 +399,13 @@ class LegacyDataMigrator { // Use current time as issue time since we don't have that in the legacy database val issueTime = System.currentTimeMillis() - val banModeration = BanModeration.builder() - .issueTime(issueTime).expireTime(unbanTime) - .reason(reason).senderUuid(senderUuid) - .targetUuid(bannedUuid).build() + val banModeration = BanModeration.builder { + issueTime(issueTime) + expireTime(unbanTime) + reason(reason) + senderUuid(senderUuid) + targetUuid(bannedUuid) + } applyModeration(bannedUuid, banModeration) } } @@ -459,10 +455,14 @@ class LegacyDataMigrator { // Use current time as issue time since we don't have that in the legacy database val issueTime = System.currentTimeMillis() - val muteModeration = MuteModeration.builder() - .issueTime(issueTime).expireTime(unbanTime) - .reason(reason).senderUuid(senderUuid) - .targetUuid(bannedUuid).isShadowMute(isShadowMute).build() + val muteModeration = MuteModeration.builder { + issueTime(issueTime) + expireTime(unbanTime) + reason(reason) + senderUuid(senderUuid) + targetUuid(bannedUuid) + isShadowMute(isShadowMute) + } applyModeration(bannedUuid, muteModeration) } } diff --git a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/AbstractMigrator.kt b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/AbstractMigrator.kt index 44a59194..fbde7c4e 100644 --- a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/AbstractMigrator.kt +++ b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/AbstractMigrator.kt @@ -1,14 +1,14 @@ package me.testaccount666.migration.plugins.essentials import com.earth2me.essentials.Essentials -import me.testaccount666.serversystem.ServerSystem.Companion.instance +import me.testaccount666.serversystem.extensions.getService import me.testaccount666.serversystem.userdata.UserManager import org.bukkit.Bukkit import java.nio.file.Path import java.util.* abstract class AbstractMigrator { - val userManager by lazy { instance.registry.getService() } + val userManager by lazy { getService() } val essentials by lazy { Essentials.getPlugin(Essentials::class.java) } protected fun offlinePlayers() = Bukkit.getOfflinePlayers() diff --git a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/HomeMigrator.kt b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/HomeMigrator.kt index 6165bb29..66298226 100644 --- a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/HomeMigrator.kt +++ b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/HomeMigrator.kt @@ -27,7 +27,7 @@ class HomeMigrator : AbstractMigrator() { user.homeManager.addPoint(homeName, location) return@runCatching true }.onFailure { - log.log(Level.WARNING, "Couldn't migrate home '${homeName}' for user '${user.uuid}' (${user.getNameSafe()})", it) + log.log(Level.WARNING, "Couldn't migrate home '${homeName}' for user '${user.uuid}' (${user.nameSafe})", it) }.getOrDefault(false) } @@ -62,7 +62,7 @@ class HomeMigrator : AbstractMigrator() { essentialsUser.setHome(homeName, location) return@runCatching true }.onFailure { - log.log(Level.WARNING, "Couldn't migrate home '${home.displayName}' for user '${user.uuid}' (${user.getNameSafe()})", it) + log.log(Level.WARNING, "Couldn't migrate home '${home.displayName}' for user '${user.uuid}' (${user.nameSafe})", it) }.getOrDefault(false) } diff --git a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/MuteMigrator.kt b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/MuteMigrator.kt index bb5c8401..0d47433c 100644 --- a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/MuteMigrator.kt +++ b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/MuteMigrator.kt @@ -1,9 +1,9 @@ package me.testaccount666.migration.plugins.essentials import me.testaccount666.serversystem.ServerSystem.Companion.log +import me.testaccount666.serversystem.extensions.commandMsg import me.testaccount666.serversystem.moderation.MuteModeration import me.testaccount666.serversystem.userdata.UserManager.Companion.consoleUser -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.command import java.util.logging.Level class MuteMigrator : AbstractMigrator() { @@ -20,12 +20,12 @@ class MuteMigrator : AbstractMigrator() { if (!essentialsUser.isMuted) return@count false - val defaultReason = command("Moderation.DefaultReason", consoleUser) { + val defaultReason = consoleUser.commandMsg("Moderation.DefaultReason") { target(essentialsUser.name) prefix(false) send(false) blankError(true) - }.build() + } if (defaultReason.isEmpty()) { log.severe("(MuteMigrator) Default reason is empty! This should not happen!") @@ -42,9 +42,14 @@ class MuteMigrator : AbstractMigrator() { val targetUUID = user.uuid muteManager.addModeration( - MuteModeration.builder().isShadowMute(false) - .targetUuid(targetUUID).issueTime(issueTime).expireTime(expireTime) - .senderUuid(senderUUID).reason(reason).build() + MuteModeration.builder { + isShadowMute(false) + targetUuid(targetUUID) + issueTime(issueTime) + expireTime(expireTime) + senderUuid(senderUUID) + reason(reason) + } ) user.save() diff --git a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/WarpMigrator.kt b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/WarpMigrator.kt index 427a8874..96f6b4c3 100644 --- a/src/main/kotlin/me/testaccount666/migration/plugins/essentials/WarpMigrator.kt +++ b/src/main/kotlin/me/testaccount666/migration/plugins/essentials/WarpMigrator.kt @@ -1,12 +1,12 @@ package me.testaccount666.migration.plugins.essentials -import me.testaccount666.serversystem.ServerSystem.Companion.instance import me.testaccount666.serversystem.ServerSystem.Companion.log import me.testaccount666.serversystem.commands.executables.waypoints.warp.manager.WarpManager +import me.testaccount666.serversystem.extensions.getService import java.util.logging.Level class WarpMigrator : AbstractMigrator() { - val warpManager by lazy { instance.registry.getService() } + val warpManager by lazy { getService() } override fun migrateFrom(): Int { val essentials = essentials diff --git a/src/main/kotlin/me/testaccount666/serversystem/ServerSystem.kt b/src/main/kotlin/me/testaccount666/serversystem/ServerSystem.kt index 031370d1..028b4827 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/ServerSystem.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/ServerSystem.kt @@ -2,6 +2,8 @@ package me.testaccount666.serversystem import me.testaccount666.migration.LegacyDataMigrator import me.testaccount666.migration.plugins.MigratorRegistry +import me.testaccount666.paperktx.PaperKTX +import me.testaccount666.paperktx.scheduler.skedule.okkero.schedule import me.testaccount666.serversystem.clickablesigns.SignManager import me.testaccount666.serversystem.commands.executables.kit.manager.KitManager import me.testaccount666.serversystem.commands.executables.waypoints.warp.manager.WarpManager @@ -9,12 +11,8 @@ import me.testaccount666.serversystem.commands.management.CommandManager import me.testaccount666.serversystem.commands.management.CommandReplacer import me.testaccount666.serversystem.listener.management.ListenerManager import me.testaccount666.serversystem.managers.config.ConfigurationManager -import me.testaccount666.serversystem.managers.database.economy.EconomyDatabaseManager -import me.testaccount666.serversystem.managers.database.economy.MySqlEconomyDatabaseManager -import me.testaccount666.serversystem.managers.database.economy.SqliteEconomyDatabaseManager -import me.testaccount666.serversystem.managers.database.moderation.ModerationDatabaseManager -import me.testaccount666.serversystem.managers.database.moderation.MySqlModerationDatabaseManager -import me.testaccount666.serversystem.managers.database.moderation.SqliteModerationDatabaseManager +import me.testaccount666.serversystem.managers.database.economy.* +import me.testaccount666.serversystem.managers.database.moderation.* import me.testaccount666.serversystem.placeholderapi.PlaceholderApiSupport import me.testaccount666.serversystem.placeholderapi.PlaceholderManager import me.testaccount666.serversystem.updates.UpdateManager @@ -48,6 +46,7 @@ class ServerSystem : JavaPlugin() { } override fun onEnable() { + PaperKTX.plugin = this val migrator = LegacyDataMigrator() if (migrator.isLegacyDataPresent) { log.log(Level.INFO, "Legacy data detected. Attempting to migrate...") @@ -56,7 +55,7 @@ class ServerSystem : JavaPlugin() { val previousVersionFile = File(dataFolder, "previousVersion.yml") val previousVersionConfig = YamlConfiguration.loadConfiguration(previousVersionFile) - previousVersionConfig.set("previousVersion", CURRENT_VERSION.toString()) + previousVersionConfig["previousVersion"] = CURRENT_VERSION.toString() try { previousVersionConfig.save(previousVersionFile) } catch (exception: IOException) { @@ -74,14 +73,18 @@ class ServerSystem : JavaPlugin() { val configManager = registry.getService() registry.registerService(UpdateManager(this, configManager)).start() - Bukkit.getScheduler().runTaskLater(this, Runnable { migrator.migrateLegacyData() }, 1L) + schedule { + waitFor(1) + migrator.migrateLegacyData() + } - Bukkit.getScheduler().runTaskLater(this, Runnable { + schedule { + waitFor(2) registry.getServiceOrNull()?.registerCommands() registry.getServiceOrNull()?.registerListeners() registry.getServiceOrNull()?.registerPlaceholders() registry.getServiceOrNull()?.replaceCommands() - }, 2L) + } } private fun initialize() { @@ -134,27 +137,27 @@ class ServerSystem : JavaPlugin() { if (migratorCount > 0) log.info("Not hooking into Vault since we found data migrators!") - Bukkit.getScheduler().runTask(this, Runnable { + schedule { val warpFile = Path.of(dataFolder.path, "data", "warps.yml").toFile() val warpConfig = YamlConfiguration.loadConfiguration(warpFile) registry.registerService(WarpManager(warpConfig, warpFile)) registry.registerService(SignManager()).loadSignTypes() - }) + } } - override fun onDisable() { - registry.getServiceOrNull()?.run(::saveAllUsers) + override fun onDisable() = with(registry) { + getServiceOrNull()?.run(::saveAllUsers) - registry.getServiceOrNull()?.run(CommandManager::unregisterCommands) - registry.getServiceOrNull()?.run(ListenerManager::unregisterListeners) + getServiceOrNull()?.run(CommandManager::unregisterCommands) + getServiceOrNull()?.run(ListenerManager::unregisterListeners) PlaceholderApiSupport.unregisterPlaceholders() - registry.getServiceOrNull()?.shutdown() - registry.getServiceOrNull()?.shutdown() + getServiceOrNull()?.shutdown() + getServiceOrNull()?.shutdown() - registry.clearServices() + clearServices() } private fun saveAllUsers(userManager: UserManager) = userManager.cachedUsers.forEach { it.offlineUser.save() } diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignClickAction.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignClickAction.kt index c0eb38cf..83c674f6 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignClickAction.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignClickAction.kt @@ -2,10 +2,10 @@ package me.testaccount666.serversystem.clickablesigns import me.testaccount666.serversystem.clickablesigns.cost.CostHandler import me.testaccount666.serversystem.clickablesigns.util.SignUtils +import me.testaccount666.serversystem.extensions.generalMsg import me.testaccount666.serversystem.managers.PermissionManager.getPermission import me.testaccount666.serversystem.managers.PermissionManager.hasPermission import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.general import org.bukkit.block.Sign import org.bukkit.configuration.file.FileConfiguration @@ -23,25 +23,25 @@ abstract class AbstractSignClickAction : SignClickAction { /** * Executes the sign-specific action. * This method is called after permission and cost checks have passed. - * + * * @param user The user who clicked the sign * @param sign The sign that was clicked * @param config The sign configuration * @return true if the action was successful, false otherwise */ - protected abstract fun executeAction(user: User, sign: Sign, config: FileConfiguration): Boolean + protected abstract fun executeAction(user: User, sign: Sign, config: FileConfiguration, onSuccess: () -> Unit): Boolean override fun execute(user: User, sign: Sign) { if (!hasPermission(user, usePermissionNode, false)) { - general("NoPermission", user) { + user.generalMsg("NoPermission") { postModifier { it.replace("", getPermission(usePermissionNode)!!) } - }.build() + } return } val config = SignUtils.loadSignConfig(sign.location) - if (!CostHandler.deductCost(user, config)) return - if (!executeAction(user, sign, config)) CostHandler.refundCost(user, config) + if (!CostHandler.canAfford(user, config)) return + executeAction(user, sign, config) { CostHandler.deductCost(user, config) } } } \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignConfigurator.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignConfigurator.kt index d3826340..401f90b1 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignConfigurator.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/AbstractSignConfigurator.kt @@ -1,14 +1,12 @@ package me.testaccount666.serversystem.clickablesigns -import me.testaccount666.serversystem.ServerSystem.Companion.instance import me.testaccount666.serversystem.ServerSystem.Companion.log import me.testaccount666.serversystem.clickablesigns.cost.CostType import me.testaccount666.serversystem.clickablesigns.util.SignUtils +import me.testaccount666.serversystem.extensions.* import me.testaccount666.serversystem.managers.PermissionManager.getPermission import me.testaccount666.serversystem.managers.PermissionManager.hasPermission import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.general -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.sign import org.bukkit.block.Sign import org.bukkit.configuration.file.FileConfiguration import org.bukkit.configuration.file.YamlConfiguration @@ -22,14 +20,14 @@ import java.util.logging.Level abstract class AbstractSignConfigurator : SignConfigurator { /** * The permission node for the permission required to create this sign. - * + * * @return The permission node */ protected abstract val createPermissionNode: String /** * The sign type for this configurator. - * + * * @return The sign type */ protected abstract val signType: SignType @@ -37,7 +35,7 @@ abstract class AbstractSignConfigurator : SignConfigurator { /** * Validates the sign configuration. * This method is called before saving the configuration. - * + * * @param user The user who is configuring the sign * @param sign The sign being configured * @param config The sign configuration @@ -48,7 +46,7 @@ abstract class AbstractSignConfigurator : SignConfigurator { /** * Adds sign-specific configuration. * This method is called after basic configuration has been set. - * + * * @param user The user who is configuring the sign * @param sign The sign being configured * @param config The sign configuration @@ -57,26 +55,26 @@ abstract class AbstractSignConfigurator : SignConfigurator { /** * Gets the success message key for when the sign is successfully created. - * + * * @return The message key */ protected abstract val successMessageKey: String override fun execute(user: User, sign: Sign) { if (!hasPermission(user, createPermissionNode, false)) { - general("NoPermission", user) { + user.generalMsg("NoPermission") { postModifier { it.replace("", getPermission(createPermissionNode)!!) } - }.build() + } return } val signFile = SignUtils.getSignFile(sign.location) val config = YamlConfiguration.loadConfiguration(signFile) - config.set("Key", signType.name) + config["Key"] = signType.name - config.set("Cost.Type", CostType.NONE.name) - config.set("Cost.Amount", 0) + config["Cost.Type"] = CostType.NONE.name + config["Cost.Amount"] = 0 if (!validateConfiguration(user, sign, config)) return addSignSpecificConfiguration(user, sign, config) @@ -89,7 +87,7 @@ abstract class AbstractSignConfigurator : SignConfigurator { return } - instance.registry.getService().addSignType(sign.location, signType) - sign(successMessageKey, user).build() + getService().addSignType(sign.location, signType) + user.signMsg(successMessageKey) } } \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignClickAction.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignClickAction.kt index aabb5321..27dab678 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignClickAction.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignClickAction.kt @@ -8,14 +8,14 @@ interface SignClickAction { /** * The permission node for the permission required to use this sign. - * + * * @return The permission node */ val usePermissionNode: String /** * The permission node for the permission required to break this+ sign. - * + * * @return The permission node */ val destroyPermissionNode: String diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignManager.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignManager.kt index dbc56423..70e4e0ee 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignManager.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignManager.kt @@ -1,5 +1,6 @@ package me.testaccount666.serversystem.clickablesigns +import me.testaccount666.paperktx.extensions.location import me.testaccount666.serversystem.ServerSystem import org.bukkit.Bukkit import org.bukkit.Location @@ -33,10 +34,7 @@ class SignManager { val zString = locationSplit[3] val world = Bukkit.getWorld(worldName) ?: continue - val x = xString.toInt() - val y = yString.toInt() - val z = zString.toInt() - val location = Location(world, x.toDouble(), y.toDouble(), z.toDouble()) + val location = location(xString.toInt(), yString.toInt(), zString.toInt(), world) addSignType(location, signType) } } diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt index 5309db90..588d43bc 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/SignType.kt @@ -12,7 +12,7 @@ import me.testaccount666.serversystem.clickablesigns.executables.weather.ActionW import me.testaccount666.serversystem.clickablesigns.executables.weather.ConfiguratorWeatherSign enum class SignType(private val _key: String, val signName: String, val clickAction: SignClickAction, val configurator: SignConfigurator) { - GIVE("Give", "F3FD1[Give]", ActionGiveSign(), ConfiguratorGiveSign()), + GIVE("Give", "F3FD1[GIVE]", ActionGiveSign(), ConfiguratorGiveSign()), KIT("Kit", "F3FD1[KIT]", ActionKitSign(), ConfiguratorKitSign()), WARP("Warp", "F3FD1[WARP]", ActionWarpSign(), ConfiguratorWarpSign()), TIME("Time", "F3FD1[TIME]", ActionTimeSign(), ConfiguratorTimeSign()), diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/cost/CostHandler.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/cost/CostHandler.kt index 0ef2e4a9..07f4f722 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/cost/CostHandler.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/cost/CostHandler.kt @@ -1,9 +1,8 @@ package me.testaccount666.serversystem.clickablesigns.cost import me.testaccount666.serversystem.ServerSystem.Companion.log +import me.testaccount666.serversystem.extensions.* import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.general -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.sign import org.bukkit.configuration.file.FileConfiguration import java.util.logging.Level @@ -13,22 +12,33 @@ import java.util.logging.Level object CostHandler { /** * Checks if a user can afford the cost specified in the configuration. - * + * * @param user The user to check * @param config The configuration containing cost information * @return true if the user can afford the cost, false otherwise */ - fun canAfford(user: User, config: FileConfiguration): Boolean { + fun canAfford(user: User, config: FileConfiguration, sendMessage: Boolean = true): Boolean { val costType = getCostType(config) if (costType == CostType.NONE) return true val costAmount = config.getDouble("Cost.Amount") if (costAmount <= 0) return true - if (costType == CostType.EXP) return user.getPlayer()!!.calculateTotalExperiencePoints() >= costAmount - if (costType == CostType.ECONOMY) return user.bankAccount.balance >= costAmount.toBigDecimal() + val canAfford = when (costType) { + CostType.EXP -> user.getPlayer()!!.calculateTotalExperiencePoints() >= costAmount + CostType.ECONOMY -> user.bankAccount.balance >= costAmount.toBigDecimal() + } - return false + if (!canAfford && sendMessage) { + if (costType == CostType.EXP) user.signMsg("Cost.NotEnoughExp") { + postModifier { it.replace("", costAmount.toInt().toString()) } + } + else if (costType == CostType.ECONOMY) user.signMsg("Cost.NotEnoughMoney") { + postModifier { it.replace("", costAmount.toString()) } + } + } + + return canAfford } fun refundCost(user: User, config: FileConfiguration) { @@ -39,8 +49,8 @@ object CostHandler { if (costAmount <= 0) return if (costType == CostType.EXP) { - val player = user.getPlayer() - player!!.setExperienceLevelAndProgress(player.calculateTotalExperiencePoints() + costAmount.toInt()) + val player = user.getPlayer()!! + player.setExperienceLevelAndProgress(player.calculateTotalExperiencePoints() + costAmount.toInt()) return } if (costType == CostType.ECONOMY) { @@ -50,15 +60,15 @@ object CostHandler { bankAccount.balance += costAmount.toBigDecimal() bankAccount.save() } catch (exception: Exception) { - log.log(Level.SEVERE, "Failed to refund cost for '${user.getNameOrNull()}', failed to save bank account", exception) - general("ErrorOccurred", user).build() + log.log(Level.SEVERE, "Failed to refund cost for '${user.nameSafe}', failed to save bank account", exception) + user.generalMsg("ErrorOccurred") } } } /** * Deducts the cost from the user. - * + * * @param user The user to deduct from * @param config The configuration containing cost information * @return true if the cost was successfully deducted, false otherwise @@ -70,22 +80,14 @@ object CostHandler { val costAmount = config.getDouble("Cost.Amount") if (costAmount <= 0) return true - if (!canAfford(user, config)) { - if (costType == CostType.EXP) sign("Cost.NotEnoughExp", user) { - postModifier { it.replace("", costAmount.toInt().toString()) } - }.build() - else if (costType == CostType.ECONOMY) sign("Cost.NotEnoughMoney", user) { - postModifier { it.replace("", costAmount.toString()) } - }.build() - return false - } + if (!canAfford(user, config, false)) return false if (costType == CostType.EXP) { - val player = user.getPlayer() - player!!.setExperienceLevelAndProgress(player.calculateTotalExperiencePoints() - costAmount.toInt()) - sign("Cost.PaidExp", user) { + val player = user.getPlayer()!! + player.setExperienceLevelAndProgress(player.calculateTotalExperiencePoints() - costAmount.toInt()) + user.signMsg("Cost.PaidExp") { postModifier { it.replace("", costAmount.toInt().toString()) } - }.build() + } return true } if (costType == CostType.ECONOMY) { @@ -94,9 +96,9 @@ object CostHandler { try { bankAccount.balance -= costAmount.toBigDecimal() bankAccount.save() - sign("Cost.PaidMoney", user) { + user.signMsg("Cost.PaidMoney") { postModifier { it.replace("", costAmount.toString()) } - }.build() + } return true } catch (_: Exception) { return false @@ -108,16 +110,11 @@ object CostHandler { /** * Gets the cost type from the configuration. - * + * * @param config The configuration * @return The cost type */ fun getCostType(config: FileConfiguration): CostType { - val costTypeStr = config.getString("Cost.Type", "NONE")!! - return try { - CostType.valueOf(costTypeStr.uppercase()) - } catch (_: IllegalArgumentException) { - CostType.NONE - } + return config.getEnum("Cost.Type", CostType.NONE) } } \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/give/ActionGiveSign.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/give/ActionGiveSign.kt index 46fe3bef..457e99e4 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/give/ActionGiveSign.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/give/ActionGiveSign.kt @@ -1,9 +1,11 @@ package me.testaccount666.serversystem.clickablesigns.executables.give +import me.testaccount666.paperktx.extensions.ComponentExtensions.asComponent +import me.testaccount666.paperktx.extensions.isAir +import me.testaccount666.paperktx.extensions.set import me.testaccount666.serversystem.clickablesigns.AbstractSignClickAction +import me.testaccount666.serversystem.extensions.signMsg import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.ItemStackExtensions.Companion.isAir -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.sign import org.bukkit.Bukkit import org.bukkit.block.Sign import org.bukkit.configuration.file.FileConfiguration @@ -11,17 +13,17 @@ import org.bukkit.configuration.file.FileConfiguration class ActionGiveSign : AbstractSignClickAction() { override val basePermissionNode = "ClickableSigns.Give" - override fun executeAction(user: User, sign: Sign, config: FileConfiguration): Boolean { - val item = config.getItemStack("Item") - if (item.isAir()) { - sign("Give.NoItem", user).build() + override fun executeAction(user: User, sign: Sign, config: FileConfiguration, onSuccess: () -> Unit): Boolean { + val item = config.getItemStack("Item").takeUnless { it.isAir() } ?: run { + user.signMsg("Give.NoItem") return false } - val inventory = Bukkit.createInventory(null, 27, "Give Sign") - for (index in 0..().addSignType(sign.location, signType) + getService().addSignType(sign.location, signType) _CONFIGURATORS.removeByValue(sign) val front = sign.getSide(Side.FRONT) - front.line(0, translateToComponent(SignType.GIVE.signName)) - front.line(1, translateToComponent("&2${itemToGive.type.name}")) + front.line(0, SignType.GIVE.signName.asComponent()) + front.line(1, "&2${itemToGive.type.name}".asComponent()) val back = sign.getSide(Side.BACK) for (index in 0..3) back.line(index, front.line(index)) sign.update() @@ -91,17 +87,17 @@ class ConfiguratorGiveSign : AbstractSignConfigurator(), Listener { /** * Validates that the user has permission to create this sign. - * + * * @param user The user to check * @return true if the user has permission, false otherwise */ private fun validatePermission(user: User): Boolean { if (!hasPermission(user, createPermissionNode, false)) { - general("NoPermission", user) { + user.generalMsg("NoPermission") { postModifier { it.replace("", getPermission(createPermissionNode)!!) } - }.build() + } return false } return true diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ActionKitSign.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ActionKitSign.kt index 4a6850ca..dd737866 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ActionKitSign.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ActionKitSign.kt @@ -1,38 +1,51 @@ package me.testaccount666.serversystem.clickablesigns.executables.kit -import me.testaccount666.serversystem.ServerSystem.Companion.instance +import me.testaccount666.paperktx.colors.ChatColor.Companion.stripColor import me.testaccount666.serversystem.clickablesigns.AbstractSignClickAction import me.testaccount666.serversystem.commands.executables.kit.manager.KitManager +import me.testaccount666.serversystem.extensions.* import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.ChatColor.Companion.stripColor -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.sign +import me.testaccount666.serversystem.utils.DurationParser.parseDate import org.bukkit.block.Sign import org.bukkit.configuration.file.FileConfiguration class ActionKitSign : AbstractSignClickAction() { override val basePermissionNode = "ClickableSigns.Kit" - override fun executeAction(user: User, sign: Sign, config: FileConfiguration): Boolean { - val kitManager = instance.registry.getService() + override fun executeAction(user: User, sign: Sign, config: FileConfiguration, onSuccess: () -> Unit): Boolean { + val kitManager = getService() - var kitName = config.getString("KitName", sign.getLine(1)) - kitName = stripColor(kitName) - if (kitName.isEmpty()) { - sign("Kit.NoKitSpecified", user).build() + val kitName = stripColor(config.getString("KitName", sign.getLine(1))).takeUnless { it.isEmpty() } ?: run { + user.signMsg("Kit.NoKitSpecified") return false } - val kit = kitManager.getKit(kitName.lowercase()) ?: run { - sign("Kit.KitNotFound", user) { + val kit = kitManager.getKit(kitName) ?: run { + user.signMsg("Kit.KitNotFound") { postModifier { it.replace("", kitName) } - }.build() + } return false } + if (user.isOnKitCooldown(kit.name)) { + val cooldown = user.getKitCooldown(kitName) + + user.commandMsg("Kit.OnCooldown") { + postModifier { + it.replace("", kit.displayName) + .replace("", parseDate(cooldown, user)) + } + } + return false + } + + user.setKitCooldown(kit.name, kit.coolDown).also { user.save() } + kit.giveKit(user.getPlayer()!!) - sign("Kit.KitGiven", user) { + user.signMsg("Kit.KitGiven") { postModifier { it.replace("", kit.displayName) } - }.build() + } + onSuccess() return true } } \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ConfiguratorKitSign.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ConfiguratorKitSign.kt index dd9a68c4..24848d51 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ConfiguratorKitSign.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/kit/ConfiguratorKitSign.kt @@ -1,14 +1,14 @@ package me.testaccount666.serversystem.clickablesigns.executables.kit -import me.testaccount666.serversystem.ServerSystem.Companion.instance +import me.testaccount666.paperktx.colors.ChatColor.Companion.stripColor +import me.testaccount666.paperktx.extensions.ComponentExtensions.asComponent +import me.testaccount666.paperktx.extensions.ComponentExtensions.asString import me.testaccount666.serversystem.clickablesigns.AbstractSignConfigurator import me.testaccount666.serversystem.clickablesigns.SignType import me.testaccount666.serversystem.commands.executables.kit.manager.KitManager +import me.testaccount666.serversystem.extensions.getService +import me.testaccount666.serversystem.extensions.signMsg import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.ChatColor.Companion.stripColor -import me.testaccount666.serversystem.utils.ComponentColor.componentToString -import me.testaccount666.serversystem.utils.ComponentColor.translateToComponent -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.sign import org.bukkit.block.Sign import org.bukkit.block.sign.Side import org.bukkit.configuration.file.FileConfiguration @@ -20,24 +20,21 @@ class ConfiguratorKitSign : AbstractSignConfigurator() { override val signType = SignType.KIT override fun validateConfiguration(user: User, sign: Sign, config: YamlConfiguration): Boolean { - val kitManager = instance.registry.getService() - val front = sign.getSide(Side.FRONT) - val kitName = componentToString(front.line(1)) - if (kitName.isEmpty()) { - sign("Kit.NoKitSpecified", user).build() + val kitName = front.line(1).asString().takeUnless { it.isEmpty() } ?: run { + user.signMsg("Kit.NoKitSpecified") return false } - if (!kitManager.kitExists(kitName.lowercase())) { - sign("Kit.KitNotFound", user) { + if (!getService().kitExists(kitName)) { + user.signMsg("Kit.KitNotFound") { postModifier { it.replace("", kitName) } - }.build() + } return false } - front.line(0, translateToComponent(SignType.KIT.signName)) - front.line(1, translateToComponent("&2${kitName}")) + front.line(0, SignType.KIT.signName.asComponent()) + front.line(1, "&2${kitName}".asComponent()) val back = sign.getSide(Side.BACK) for (index in 0..3) back.line(index, front.line(index)) sign.update() @@ -47,6 +44,6 @@ class ConfiguratorKitSign : AbstractSignConfigurator() { override fun addSignSpecificConfiguration(user: User, sign: Sign, config: FileConfiguration) { var kitName = sign.getSide(Side.FRONT).getLine(1) kitName = stripColor(kitName) - config.set("KitName", kitName) + config["KitName"] = kitName } } \ No newline at end of file diff --git a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/time/ActionTimeSign.kt b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/time/ActionTimeSign.kt index 1fea8dff..882f48ea 100644 --- a/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/time/ActionTimeSign.kt +++ b/src/main/kotlin/me/testaccount666/serversystem/clickablesigns/executables/time/ActionTimeSign.kt @@ -1,46 +1,47 @@ package me.testaccount666.serversystem.clickablesigns.executables.time +import me.testaccount666.paperktx.colors.ChatColor.Companion.stripColor import me.testaccount666.serversystem.clickablesigns.AbstractSignClickAction +import me.testaccount666.serversystem.extensions.signMsg import me.testaccount666.serversystem.userdata.User -import me.testaccount666.serversystem.utils.ChatColor.Companion.stripColor -import me.testaccount666.serversystem.utils.MessageBuilder.Companion.sign import org.bukkit.block.Sign import org.bukkit.configuration.file.FileConfiguration class ActionTimeSign : AbstractSignClickAction() { override val basePermissionNode = "ClickableSigns.Time" - override fun executeAction(user: User, sign: Sign, config: FileConfiguration): Boolean { - var timeType = config.getString("TimeType", sign.getLine(1))?.lowercase() + override fun executeAction(user: User, sign: Sign, config: FileConfiguration, onSuccess: () -> Unit): Boolean { + var timeType = config.getString("TimeType", sign.getLine(1))!!.lowercase() timeType = stripColor(timeType) if (timeType.isEmpty()) { - sign("Time.NoTimeSpecified", user).build() + user.signMsg("Time.NoTimeSpecified") return false } - val world = user.getPlayer()?.world ?: return false + val world = user.getPlayer()!!.world val time = when (timeType) { - "day" -> 1000 - "noon" -> 6000 - "night" -> 13000 - "midnight" -> 18000 + "day" -> 1000L + "noon" -> 6000L + "night" -> 13000L + "midnight" -> 18000L else -> { try { timeType.toLong() } catch (_: NumberFormatException) { - sign("Time.InvalidTime", user) { + user.signMsg("Time.InvalidTime") { postModifier { it.replace("