diff --git a/.editorconfig b/.editorconfig
index 095d8c6ef..3788965bf 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -76,7 +76,7 @@ ij_java_case_statement_on_separate_line = true
ij_java_catch_on_new_line = false
ij_java_class_annotation_wrap = split_into_lines
ij_java_class_brace_style = end_of_line
-ij_java_class_count_to_use_import_on_demand = 5
+ij_java_class_count_to_use_import_on_demand = 999
ij_java_class_names_in_javadoc = 1
ij_java_deconstruction_list_wrap = normal
ij_java_do_not_indent_top_level_class_members = false
@@ -153,7 +153,7 @@ ij_java_method_parameters_right_paren_on_new_line = false
ij_java_method_parameters_wrap = off
ij_java_modifier_list_wrap = false
ij_java_multi_catch_types_wrap = normal
-ij_java_names_count_to_use_import_on_demand = 3
+ij_java_names_count_to_use_import_on_demand = 999
ij_java_new_line_after_lparen_in_annotation = false
ij_java_new_line_after_lparen_in_deconstruction_pattern = true
ij_java_new_line_after_lparen_in_record_header = false
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..fe4b4c3d0
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,49 @@
+# This workflow uses actions that GitHub does not certify.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
+
+name: Java CI with Gradle
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ steps:
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0 # full history
+ fetch-tags: true # grab your tags
+ # Make sure we check out by branch name, not just SHA:
+ ref: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v5
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+
+ # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
+ # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+
+ - name: Build with Gradle Wrapper
+ run: ./gradlew clean build
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: Staging-Build
+ path: build/libs
+ compression-level: '9'
diff --git a/.gitignore b/.gitignore
index 621f439f7..11ea81483 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,34 +1,184 @@
-# Compiled class file
-*.class
-
-# Log file
-*.log
-
-# BlueJ files
-*.ctxt
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.nar
-*.ear
-*.zip
-*.tar.gz
-*.rar
-*.xml
+# Created by https://www.toptal.com/developers/gitignore/api/intellij,gradle,maven
+# Edit at https://www.toptal.com/developers/gitignore?templates=intellij,gradle,maven
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+.idea/artifacts
+.idea/compiler.xml
+.idea/jarRepositories.xml
+.idea/modules.xml
+.idea/*.iml
+.idea/modules
*.iml
+*.ipr
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
+# CMake
+cmake-build-*/
-# Maven
-.classpath
-.project
-.settings/
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+### Intellij Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+.idea/misc.xml
+# *.ipr
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+# Sonarlint plugin
+# https://plugins.jetbrains.com/plugin/7973-sonarlint
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator-enh.xml
+.idea/**/markdown-navigator/
+
+# Cache file creation bug
+# See https://youtrack.jetbrains.com/issue/JBR-2257
+.idea/$CACHE_FILE$
+
+# CodeStream plugin
+# https://plugins.jetbrains.com/plugin/12206-codestream
+.idea/codestream.xml
+
+# Azure Toolkit for IntelliJ plugin
+# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
+.idea/**/azureSettings.xml
+
+### Maven ###
target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+# https://github.com/takari/maven-wrapper#usage-without-binary-jar
+.mvn/wrapper/maven-wrapper.jar
+
+# Eclipse m2e generated files
+# Eclipse Core
+.project
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+### Gradle ###
+.gradle
+**/build/
+!src/**/build/
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Avoid ignore Gradle wrappper properties
+!gradle-wrapper.properties
+
+# Cache of project
+.gradletasknamecache
+
+# Eclipse Gradle plugin generated files
+# Eclipse Core
+# JDT-specific (Eclipse Java Development Tools)
+
+### Gradle Patch ###
+# Java heap dump
+*.hprof
+
+# End of https://www.toptal.com/developers/gitignore/api/intellij,gradle,maven
+
+# Created by https://www.toptal.com/developers/gitignore/api/git
+# Edit at https://www.toptal.com/developers/gitignore?templates=git
+
+### Git ###
+# Created by git for backups. To disable backups in Git:
+# $ git config --global mergetool.keepBackup false
+*.orig
+
+# Created by git when using merge tools for conflicts
+*.BACKUP.*
+*.BASE.*
+*.LOCAL.*
+*.REMOTE.*
+*_BACKUP_*.txt
+*_BASE_*.txt
+*_LOCAL_*.txt
+*_REMOTE_*.txt
+
+# End of https://www.toptal.com/developers/gitignore/api/git
+
+# Custom
-# .idea
-.idea/
\ No newline at end of file
+/.idea/git_toolbox_prj.xml
+/.idea/.name
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 000000000..3f22c8f34
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 000000000..35eb1ddfb
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
index dae462c79..2ff6e64f7 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,7 @@
MIT License
-Copyright (c) 2021 Alps BTE
+Copyright (c) Alps BTE
+Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 4dc8376fd..bc48c5b85 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
+
-
+
@@ -24,12 +26,9 @@
-
-
-
# About The Project
The Plot System is an essential part of any BuildTheEarth server system,
meant to run alongside the classic Terra servers to make participating a lot easier
@@ -49,15 +48,23 @@ The plugin is mostly developed by the Alps-BTE team and is intended for everyone
If you have any questions regarding the setup or contribution, please do not hesitate to contact us.
All used Libraries and APIs are listed below.
+
# Features
## Plot Types
-The focus mode is the old well-known mode that was also used by default before the release of v3.0. Build your plot on a floating island in an empty void world. Simple and straightforward, like in the good old days.
+
+The focus mode is the old well-known mode that was also used by default before the release of v3.0. Build your plot on a
+floating island in an empty void world. Simple and straightforward, like in the good old days.
➖ No Environment
➖ No Neighbouring Plots
- The inspiration mode feels like building in a normal world. By adding the surrounding area of your plot, you will see neighbouring buildings, streets and vegetation. In comparison to the focus mode, you will have a better orientation which helps you when building. This mode is selected as default, when using the Plot System for the first time.
+ 
+The inspiration mode feels like building in a normal world. By adding the surrounding area of your plot, you will see
+neighbouring buildings, streets and vegetation. In comparison to the focus mode, you will have a better orientation
+which helps you when building. This mode is selected as default, when using the Plot System for the first time.
➕ Environment
➖ No Neighbouring Plots
- The city inspiration mode will give you the full building experience by combining the inspiration mode with other players. Build with your friends and others in one world next to each other and see continuous progress.
+ 
+The city inspiration mode will give you the full building experience by combining the inspiration mode with other
+players. Build with your friends and others in one world next to each other and see continuous progress.
⚠️ This mode is not fully stable and still in BETA
➕ Environment
➕ Neighbouring Plots
@@ -69,17 +76,34 @@ Tutorial, which needs to be completed to use the Plot-System and other features,
building process to understand how it works.
-
## Other Features
-✔️ Support for **multiple cities** as well as for **continents** and **countries/states** ✔️ **User-friendly menus** and **commands** ✔️ Inbuilt **Get Started Tutorial** for beginners ✔️ **User-friendly menus** and **commands** ✔️ **Multi-Language** Support (currently up to 7 languages) ✔️ Plot **Group System** (Build together with up to 5 people on one plot) ✔️ **SFTP/FTP** Support ✔️ Detailed **review system** with individual feedback ✔️ Three plot **difficulty levels** (easy, medium and hard) ✔️ Building **Quality of Life tools** ✔️ Full **/tpll support** on plots ✔️ **Leaderboards** when using the Holograms extension ✔️ Automatic **abandoning of inactive plots** ✔️ Automatic **placement of completed plots** on the terra server ✔️ **Easy configuration** and **setup**
-# Installation
-💻 To use this system, you currently need at least two servers.One is running Terra+- with the **[Plot-System-Terra Plugin](https://github.com/AlpsBTE/Plot-System-Terra)** and the
-other one is a Spigot Vanilla server for the Plot-System itself.**For more information check out the [Wiki](https://github.com/AlpsBTE/Plot-System/wiki/Installation)**!
+✔️ Support for **multiple cities** as well as for **continents** and **countries/states**
+✔️ **User-friendly menus** and **commands**
+✔️ Inbuilt **Get Started Tutorial** for beginners
+✔️ **User-friendly menus** and **commands**
+✔️ **Multi-Language** Support
+✔️ Plot **Group System** (Build together with up to 5 people on one plot)
+✔️ Detailed **review system** with individual feedback
+✔️ Three plot **difficulty levels** (easy, medium and hard)
+✔️ Building **Quality of Life tools**
+✔️ Full **/tpll support** on plots
+✔️ **Leaderboards** when using the Holograms extension
+✔️ Automatic **abandoning of inactive plots**
+✔️ Automatic **placement of completed plots** on the terra server
+✔️ **Easy configuration** and **setup**
+# Installation
+💻 To use this system, you currently need at least two servers.
+One server runs [Terra++](https://github.com/BTE-Germany/TerraPlusMinus) together with the
+**[Plot-System-Terra](https://github.com/AlpsBTE/Plot-System-Terra)** plugin, while the other is a Paper server
+dedicated to the Plot-System itself.
+**For more information check out the [Wiki](https://github.com/AlpsBTE/Plot-System/wiki/Installation)**!
-
# Roadmap
-📋 Web Interface 📋 Discord Integration 📋 Statistics
+📋 Web Interface
+📋 Discord Integration
+📋 Statistics
+
# Contributing
🔨 Any contributions you make are greatly appreciated.
@@ -88,24 +112,20 @@ other one is a Spigot Vanilla server for the Plot-System itself.**For more
* Submitting a fix
* Proposing new features
-
-
# License
-
Distributed under the MIT License. See `LICENSE` for more information.
-
-
# Libraries & APIs
-* [Paper API](https://github.com/PaperMC/Paper)
-* [FAWE API](https://github.com/IntellectualSites/FastAsyncWorldEdit)
-* [WorldGuard API](https://github.com/EngineHub/WorldGuard)
-* [Multiverse-Core API](https://github.com/Multiverse/Multiverse-Core)
-* [Canvas Menu-Builder Library](https://github.com/IPVP-MC/canvas)
-* [Head-DB API](https://github.com/Arcaniax-Development/HeadDatabase-API)
-* [Holographic Displays API](https://github.com/filoghost/HolographicDisplays)
-* [Maria-DB Library](https://mariadb.com/kb/en/about-mariadb-connector-j/)
-* [Hikari-CP](https://github.com/brettwooldridge/HikariCP)
-* [Apache Common VFS API](https://commons.apache.org/proper/commons-vfs/commons-vfs2/apidocs/index.html)
-* [ProtocolLIB](https://github.com/dmulloy2/ProtocolLib)
+* [Paper](https://github.com/PaperMC/Paper)
+* [FAWE](https://github.com/IntellectualSites/FastAsyncWorldEdit)
+* [WorldGuard](https://github.com/EngineHub/WorldGuard)
+* [Multiverse Core](https://github.com/Multiverse/Multiverse-Core)
+* [Particle Native](https://github.com/Fierioziy/ParticleNativeAPI)
+* [Canvas](https://github.com/AlpsBTE/Canvas)
+* [HeadDatabase](https://github.com/Arcaniax-Development/HeadDatabase-API)
+* [DecentHolograms](https://github.com/DecentSoftware-eu/DecentHolograms)
+* [MariaDB](https://mariadb.com/kb/en/about-mariadb-connector-j/)
+* [HikariCP](https://github.com/brettwooldridge/HikariCP)
* [Fancy NPCs](https://github.com/FancyMcPlugins/FancyNpcs)
+* [AlpsLib](https://github.com/AlpsBTE/Alps-Lib)
+* [LangLibs](https://github.com/Cinnazeyy/LangLibs)
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 000000000..6013616a4
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,113 @@
+plugins {
+ java
+ id("com.palantir.git-version") version "4.0.0"
+ id("com.gradleup.shadow") version "9.0.2"
+}
+
+repositories {
+ // mavenLocal() // NEVER use in Production/Commits!
+ maven {
+ url = uri("https://jitpack.io")
+ }
+
+ maven {
+ url = uri("https://repo.papermc.io/repository/maven-public/")
+ }
+
+ maven {
+ url = uri("https://mvn.alps-bte.com/repository/alps-bte/")
+ }
+
+ maven {
+ url = uri("https://repo.fancyplugins.de/releases")
+ }
+
+ maven {
+ url = uri("https://maven.enginehub.org/repo/")
+ }
+
+ maven {
+ url = uri("https://repo.onarandombox.com/content/groups/public/")
+ }
+
+ maven {
+ url = uri("https://repo.codemc.io/repository/maven-public/")
+ }
+
+ maven {
+ url = uri("https://repo.maven.apache.org/maven2/")
+ }
+}
+
+dependencies {
+ implementation(libs.com.alpsbte.canvas)
+ implementation(libs.com.alpsbte.alpslib.alpslib.io)
+ implementation(libs.com.alpsbte.alpslib.alpslib.hologram)
+ implementation(libs.com.alpsbte.alpslib.alpslib.utils)
+ implementation(libs.org.mariadb.jdbc.mariadb.java.client)
+ implementation(libs.com.zaxxer.hikaricp)
+ compileOnly(libs.io.papermc.paper.paper.api)
+ implementation(platform(libs.com.intellectualsites.bom.bom.newest))
+ compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core")
+ compileOnly(libs.com.sk89q.worldguard.worldguard.bukkit)
+ compileOnly(libs.multiverse.core)
+ compileOnly(libs.com.github.fierioziy.particlenativeapi.particlenativeapi.plugin)
+ compileOnly(libs.com.arcaniax.headdatabase.api)
+ compileOnly(libs.com.github.decentsoftware.eu.decentholograms)
+ compileOnly(libs.de.oliver.fancynpcs)
+ compileOnly(libs.li.cinnazeyy.langlibs.api)
+ compileOnly(libs.commons.io.commons.io)
+}
+
+val versionDetails: groovy.lang.Closure by extra
+val details = versionDetails()
+
+group = "com.alpsbte"
+version = "5.0.0" + "-" + details.commitDistance + "-" + details.gitHash + "-SNAPSHOT"
+description = "An easy to use building system for the BuildTheEarth project."
+java.sourceCompatibility = JavaVersion.VERSION_21
+
+tasks.withType {
+ options.encoding = "UTF-8"
+}
+
+tasks.withType {
+ options.encoding = "UTF-8"
+}
+
+tasks.shadowJar {
+ // Exclude annotation classes (e.g. org.jetbrains.annotations)
+ exclude("org/jetbrains/annotations/**")
+ // Exclude slf4j classes
+ exclude("org/slf4j/**")
+ exclude("META-INF/**")
+ archiveClassifier = ""
+
+ val relocationPrefix = "alpsplotsystem.libs"
+ relocate("com.alpsbte.alpslib", "$relocationPrefix.com.alpsbte.alpslib")
+ relocate("org.mariadb.jdbc", "$relocationPrefix.org.mariadb.jdbc")
+ relocate("com.zaxxer.hikari", "$relocationPrefix.com.zaxxer.hikari")
+}
+
+tasks.assemble {
+ dependsOn(tasks.shadowJar) // Ensure that the shadowJar task runs before the build task
+}
+
+tasks.jar {
+ enabled = false // Disable the default jar task since we are using shadowJar
+}
+
+tasks.processResources {
+ // work around IDEA-296490
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+ with(copySpec {
+ from("src/main/resources/plugin.yml") {
+ expand(
+ mapOf(
+ "version" to project.version,
+ "description" to project.description
+ )
+ )
+ }
+ })
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 000000000..e19f37c1b
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,3 @@
+# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties
+org.gradle.configuration-cache=true
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 000000000..0af5093b9
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,38 @@
+# This file was generated by the Gradle 'init' task.
+# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
+
+[versions]
+com-alpsbte-alpslib-alpslib-hologram = "1.1.1"
+com-alpsbte-alpslib-alpslib-io = "1.2.0"
+com-alpsbte-alpslib-alpslib-utils = "1.3.6"
+com-alpsbte-canvas = "1.3"
+com-arcaniax-headdatabase-api = "1.3.2"
+com-github-decentsoftware-eu-decentholograms = "2.9.2"
+com-github-fierioziy-particlenativeapi-particlenativeapi-plugin = "3.3.2"
+multiverse-core = "5.3.0"
+com-sk89q-worldguard-worldguard-bukkit = "7.1.0-SNAPSHOT"
+com-zaxxer-hikaricp = "6.3.0"
+commons-io-commons-io = "2.20.0"
+de-oliver-fancynpcs = "2.7.0"
+io-papermc-paper-paper-api = "1.21.8-R0.1-SNAPSHOT"
+li-cinnazeyy-langlibs-api = "1.5.1"
+org-mariadb-jdbc-mariadb-java-client = "2.7.4"
+com-intellectualsites-bom-bom-newest = "1.55" # Ref: https://github.com/IntellectualSites/bom
+
+[libraries]
+com-alpsbte-alpslib-alpslib-hologram = { module = "com.alpsbte.alpslib:alpslib-hologram", version.ref = "com-alpsbte-alpslib-alpslib-hologram" }
+com-alpsbte-alpslib-alpslib-io = { module = "com.alpsbte.alpslib:alpslib-io", version.ref = "com-alpsbte-alpslib-alpslib-io" }
+com-alpsbte-alpslib-alpslib-utils = { module = "com.alpsbte.alpslib:alpslib-utils", version.ref = "com-alpsbte-alpslib-alpslib-utils" }
+com-alpsbte-canvas = { module = "com.alpsbte:canvas", version.ref = "com-alpsbte-canvas" }
+com-arcaniax-headdatabase-api = { module = "com.arcaniax:HeadDatabase-API", version.ref = "com-arcaniax-headdatabase-api" }
+com-github-decentsoftware-eu-decentholograms = { module = "com.github.decentsoftware-eu:decentholograms", version.ref = "com-github-decentsoftware-eu-decentholograms" }
+com-github-fierioziy-particlenativeapi-particlenativeapi-plugin = { module = "com.github.fierioziy.particlenativeapi:ParticleNativeAPI-plugin", version.ref = "com-github-fierioziy-particlenativeapi-particlenativeapi-plugin" }
+multiverse-core = { module = "org.mvplugins.multiverse.core:multiverse-core", version.ref = "multiverse-core" }
+com-sk89q-worldguard-worldguard-bukkit = { module = "com.sk89q.worldguard:worldguard-bukkit", version.ref = "com-sk89q-worldguard-worldguard-bukkit" }
+com-zaxxer-hikaricp = { module = "com.zaxxer:HikariCP", version.ref = "com-zaxxer-hikaricp" }
+commons-io-commons-io = { module = "commons-io:commons-io", version.ref = "commons-io-commons-io" }
+de-oliver-fancynpcs = { module = "de.oliver:FancyNpcs", version.ref = "de-oliver-fancynpcs" }
+io-papermc-paper-paper-api = { module = "io.papermc.paper:paper-api", version.ref = "io-papermc-paper-paper-api" }
+li-cinnazeyy-langlibs-api = { module = "li.cinnazeyy:LangLibs-API", version.ref = "li-cinnazeyy-langlibs-api" }
+org-mariadb-jdbc-mariadb-java-client = { module = "org.mariadb.jdbc:mariadb-java-client", version.ref = "org-mariadb-jdbc-mariadb-java-client" }
+com-intellectualsites-bom-bom-newest = { module = "com.intellectualsites.bom:bom-newest", version.ref = "com-intellectualsites-bom-bom-newest" }
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..1b33c55ba
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..2a84e188b
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 000000000..342f59614
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,233 @@
+#!/bin/sh
+
+##############################################################################
+#
+# 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 000000000..db3a6ac20
--- /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
index 680e26dd8..bbcc0a996 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,27 +1,4 @@
-
com.alpsbte
PlotSystem
- 4.1.4
+ 5.0.0
+ An easy to use building system for the BuildTheEarth project.
@@ -64,16 +42,11 @@
OnARandomBox
https://repo.onarandombox.com/content/groups/public/
-
+
codemc-repo
https://repo.codemc.io/repository/maven-public/
-
-
- dmulloy2-repo
- https://repo.dmulloy2.net/repository/public/
-
@@ -81,7 +54,7 @@
io.papermc.paper
paper-api
- 1.21.4-R0.1-SNAPSHOT
+ 1.21.8-R0.1-SNAPSHOT
provided
@@ -99,9 +72,9 @@
- com.onarandombox.multiversecore
- Multiverse-Core
- 4.3.1
+ org.mvplugins.multiverse.core
+ multiverse-core
+ 5.3.0
provided
@@ -115,7 +88,7 @@
com.alpsbte
canvas
- 1.1
+ 1.3
compile
@@ -129,14 +102,14 @@
com.github.decentsoftware-eu
decentholograms
- 2.8.12
+ 2.9.2
provided
com.alpsbte.alpslib
alpslib-io
- 1.0.38
+ 1.2.0
com.alpsbte.alpslib
@@ -147,7 +120,7 @@
com.alpsbte.alpslib
alpslib-utils
- 1.3.4
+ 1.3.6
compile
@@ -161,48 +134,39 @@
com.zaxxer
HikariCP
- 4.0.3
- compile
-
-
-
- org.apache.commons
- commons-vfs2
- 2.4
- compile
-
-
-
- commons-net
- commons-net
- 3.11.0
- compile
-
-
-
- com.jcraft
- jsch
- 0.1.55
+ 6.3.0
+
+
+ org.slf4j
+ slf4j-api
+
+
compile
- com.comphenix.protocol
+ net.dmulloy2
ProtocolLib
- 5.1.0
+ 5.4.0
provided
de.oliver
FancyNpcs
- 2.4.0
+ 2.7.0
provided
li.cinnazeyy
- LangLibs
- 1.5
+ LangLibs-API
+ 1.5.1
+ provided
+
+
+ commons-io
+ commons-io
+ 2.17.0
provided
@@ -226,6 +190,16 @@
${basedir}/src/main/resources
false
+
+ plugin.yml
+
+
+
+ ${basedir}/src/main/resources
+ true
+
+ plugin.yml
+
./lang
@@ -246,7 +220,7 @@
src/main/java/
- ${project.artifactId}-${project.version}-${build.number}
+ ${project.artifactId}-${project.version}${build.number}
org.apache.maven.plugins
@@ -292,7 +266,7 @@
UTF-8
UTF-8
-
+
21
-
+
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 000000000..22487c716
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1 @@
+rootProject.name = "PlotSystem"
diff --git a/src/main/java/com/alpsbte/plotsystem/PlotSystem.java b/src/main/java/com/alpsbte/plotsystem/PlotSystem.java
index 011bf1480..201a59126 100644
--- a/src/main/java/com/alpsbte/plotsystem/PlotSystem.java
+++ b/src/main/java/com/alpsbte/plotsystem/PlotSystem.java
@@ -1,37 +1,14 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem;
import com.alpsbte.alpslib.hologram.DecentHologramDisplay;
import com.alpsbte.alpslib.io.YamlFileFactory;
import com.alpsbte.alpslib.io.config.ConfigNotImplementedException;
+import com.alpsbte.alpslib.io.database.DatabaseConfigPaths;
+import com.alpsbte.alpslib.io.database.DatabaseConnection;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.alpslib.utils.head.AlpsHeadEventListener;
import com.alpsbte.plotsystem.commands.CommandManager;
import com.alpsbte.plotsystem.core.EventListener;
-import com.alpsbte.plotsystem.core.database.DatabaseConnection;
import com.alpsbte.plotsystem.core.holograms.HologramRegister;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.Plot;
@@ -42,76 +19,52 @@
import com.alpsbte.plotsystem.core.system.tutorial.TutorialEventListener;
import com.alpsbte.plotsystem.core.system.tutorial.utils.TutorialNPCTurnTracker;
import com.alpsbte.plotsystem.core.system.tutorial.utils.TutorialUtils;
-import com.alpsbte.plotsystem.utils.PacketListener;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.utils.io.ConfigUtil;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.ProtocolManager;
-import com.onarandombox.MultiverseCore.MultiverseCore;
-import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
+import com.google.common.io.CharStreams;
import de.oliver.fancynpcs.api.FancyNpcsPlugin;
import net.kyori.adventure.text.Component;
-import org.apache.maven.artifact.versioning.ComparableVersion;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.ipvp.canvas.MenuFunctionListener;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.*;
-import java.util.function.Consumer;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.UUID;
-import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
+import static net.kyori.adventure.text.format.NamedTextColor.YELLOW;
public class PlotSystem extends JavaPlugin {
- private static final String VERSION = "4.1.3";
-
private static PlotSystem plugin;
- private CommandManager commandManager;
-
private boolean pluginEnabled = false;
@Override
public void onEnable() {
- System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); // Disable Logging
YamlFileFactory.registerPlugin(this);
plugin = this;
Component successPrefix = text("[", DARK_GRAY).append(text("✔", DARK_GREEN)).append(text("]", DARK_GRAY)).append(text(" ", GRAY));
Component errorPrefix = text("[", DARK_GRAY).append(text("X", RED)).append(text("]", DARK_GRAY)).append(text(" ", GRAY));
- Bukkit.getConsoleSender().sendMessage(text("------------------ Plot-System V" + VERSION + " ------------------", GOLD));
- Bukkit.getConsoleSender().sendMessage(text("Starting plugin...", DARK_GREEN));
- Bukkit.getConsoleSender().sendMessage(empty());
-
- // Check for required dependencies, if it returns false disable plugin
- if (!DependencyManager.checkForRequiredDependencies()) {
- Bukkit.getConsoleSender().sendMessage(errorPrefix.append(text("Could not load required dependencies.")));
- Bukkit.getConsoleSender().sendMessage(text("Missing Dependencies:", YELLOW));
- DependencyManager.missingDependencies.forEach(dependency -> Bukkit.getConsoleSender().sendMessage(text(" - " + dependency, YELLOW)));
-
- this.getServer().getPluginManager().disablePlugin(this);
- return;
- }
- Bukkit.getConsoleSender().sendMessage(successPrefix.append(text("Successfully loaded required dependencies.")));
-
// Load config, if it throws an exception disable plugin
try {
ConfigUtil.init();
- Bukkit.getConsoleSender().sendMessage(successPrefix.append(text("Successfully loaded configuration files.")));
+ getComponentLogger().info(successPrefix.append(text("Successfully loaded configuration files.")));
} catch (ConfigNotImplementedException ex) {
- Bukkit.getConsoleSender().sendMessage(errorPrefix.append(text("Could not load configuration file.")));
- Bukkit.getConsoleSender().sendMessage(text("The config file must be configured!", YELLOW));
-
+ getComponentLogger().error(errorPrefix.append(text("Could not load configuration file.")));
+ getComponentLogger().info(text("The config file must be configured!", YELLOW));
this.getServer().getPluginManager().disablePlugin(this);
return;
}
@@ -120,7 +73,7 @@ public void onEnable() {
// Load language files
try {
LangUtil.init();
- Bukkit.getConsoleSender().sendMessage(successPrefix.append(text("Successfully loaded language files.")));
+ getComponentLogger().info(successPrefix.append(text("Successfully loaded language files.")));
} catch (Exception ex) {
PlotSystem.getPlugin().getComponentLogger().error(text("Could not load language file."), ex);
this.getServer().getPluginManager().disablePlugin(this);
@@ -129,12 +82,10 @@ public void onEnable() {
// Initialize database connection
try {
- DatabaseConnection.InitializeDatabase();
- Bukkit.getConsoleSender().sendMessage(successPrefix.append(text("Successfully initialized database connection.")));
+ initDatabase();
+ getComponentLogger().info(successPrefix.append(text("Successfully initialized database connection.")));
} catch (Exception ex) {
- Bukkit.getConsoleSender().sendMessage(errorPrefix.append(text("Could not initialize database connection.")));
- PlotSystem.getPlugin().getComponentLogger().error(text(ex.getMessage()), ex);
-
+ getComponentLogger().error(errorPrefix.append(text("Could not initialize database connection.")), ex);
this.getServer().getPluginManager().disablePlugin(this);
return;
}
@@ -146,62 +97,30 @@ public void onEnable() {
this.getServer().getPluginManager().registerEvents(new AlpsHeadEventListener(), this);
if (getConfig().getBoolean(ConfigPaths.TUTORIAL_ENABLE))
this.getServer().getPluginManager().registerEvents(new TutorialEventListener(), this);
- Bukkit.getConsoleSender().sendMessage(successPrefix.append(text("Successfully registered event listeners.")));
+ getComponentLogger().info(successPrefix.append(text("Successfully registered event listeners.")));
} catch (Exception ex) {
- Bukkit.getConsoleSender().sendMessage(errorPrefix.append(text("Could not register event listeners.")));
- PlotSystem.getPlugin().getComponentLogger().error(text(ex.getMessage()), ex);
-
+ getComponentLogger().error(errorPrefix.append(text("Could not register event listeners.")), ex);
this.getServer().getPluginManager().disablePlugin(this);
return;
}
// Register commands
try {
- commandManager = new CommandManager();
+ CommandManager commandManager = new CommandManager();
commandManager.init();
- Bukkit.getConsoleSender().sendMessage(successPrefix.append(text("Successfully registered commands.")));
+ getComponentLogger().info(successPrefix.append(text("Successfully registered commands.")));
} catch (Exception ex) {
- Bukkit.getConsoleSender().sendMessage(errorPrefix.append(text("Could not register commands.")));
- PlotSystem.getPlugin().getComponentLogger().error(text(ex.getMessage()), ex);
-
+ getComponentLogger().error(errorPrefix.append(text("Could not register commands.")), ex);
this.getServer().getPluginManager().disablePlugin(this);
return;
}
- if (!DependencyManager.isWorldGuardExtraFlagsEnabled()) PlotSystem.getPlugin().getComponentLogger().warn(text("WorldGuardExtraFlags is not enabled!"));
-
- // Check for updates
- Bukkit.getConsoleSender().sendMessage(empty());
- Bukkit.getConsoleSender().sendMessage(text("Update-Checker:", GOLD));
-
- UpdateChecker.getVersion(version -> {
- if (new ComparableVersion(VERSION).compareTo(new ComparableVersion(version)) >= 0) {
- Bukkit.getConsoleSender().sendMessage(text("You are using the latest stable version.", YELLOW));
- } else {
- UpdateChecker.isUpdateAvailable = true;
- Bukkit.getConsoleSender().sendMessage(text("You are using a outdated version!", RED));
- Bukkit.getConsoleSender().sendMessage(text("Latest version: ", GRAY).append(text(version, GREEN)).append(text(" | Your version: ", GRAY)).append(text(VERSION, RED)));
- Bukkit.getConsoleSender().sendMessage(text("Update here: ", GRAY).append(text("https://github.com/AlpsBTE/Plot-System/releases", AQUA)));
- }
- });
-
DecentHologramDisplay.registerPlugin(this);
HologramRegister.init();
PlotUtils.checkPlotsForLastActivity();
- PlotUtils.syncPlotSchematicFiles();
Utils.ChatUtils.checkForChatInputExpiry();
PlotUtils.Effects.startTimer();
- try {
- new PacketListener();
- } catch (NoClassDefFoundError ex) {
- Bukkit.getConsoleSender().sendMessage(empty());
- Bukkit.getConsoleSender().sendMessage(text("Could not find Protocol-Lib! Consider installing it to avoid issues.", RED));
- }
-
- // Cache and register custom heads
- Bukkit.getScheduler().runTaskAsynchronously(this, Utils::registerCustomHeads);
-
// Register tutorials
if (getConfig().getBoolean(ConfigPaths.TUTORIAL_ENABLE)) {
AbstractTutorial.registerTutorials(Collections.singletonList(BeginnerTutorial.class));
@@ -209,29 +128,31 @@ public void onEnable() {
}
pluginEnabled = true;
- Bukkit.getConsoleSender().sendMessage(empty());
- Bukkit.getConsoleSender().sendMessage(text("Enabled Plot-System plugin.", DARK_GREEN));
- Bukkit.getConsoleSender().sendMessage(text("------------------------------------------------------", GOLD));
- Bukkit.getConsoleSender().sendMessage(text("> ", DARK_GRAY).append(text("Made by ", GRAY)).append(text("Alps BTE (AT/CH/LI)", RED)));
- Bukkit.getConsoleSender().sendMessage(text("> ", DARK_GRAY).append(text("GitHub: ", GRAY)).append(text("https://github.com/AlpsBTE/Plot-System", WHITE)));
- Bukkit.getConsoleSender().sendMessage(text("------------------------------------------------------", GOLD));
+ getComponentLogger().info(text("Enabled Plot-System plugin.", DARK_GREEN));
+ getComponentLogger().info(text("------------------------------------------------------", GOLD));
+ getComponentLogger().info(text("> ", DARK_GRAY).append(text("Made by ", GRAY)).append(text("Alps BTE (AT/CH/LI)", RED)));
+ getComponentLogger().info(text("> ", DARK_GRAY).append(text("GitHub: ", GRAY)).append(text("https://github.com/AlpsBTE/Plot-System", WHITE)));
+ getComponentLogger().info(text("------------------------------------------------------", GOLD));
}
@Override
public void onDisable() {
if (!pluginEnabled) {
- Bukkit.getConsoleSender().sendMessage(empty());
- Bukkit.getConsoleSender().sendMessage(text("Disabling plugin...", RED));
- Bukkit.getConsoleSender().sendMessage(text("------------------------------------------------------", GOLD));
- Bukkit.getConsoleSender().sendMessage(text("> ", DARK_GRAY).append(text("Made by ", GRAY)).append(text("Alps BTE (AT/CH/LI)", RED)));
- Bukkit.getConsoleSender().sendMessage(text("> ", DARK_GRAY).append(text("GitHub: ", GRAY)).append(text("https://github.com/AlpsBTE/Plot-System", WHITE)));
- Bukkit.getConsoleSender().sendMessage(text("------------------------------------------------------", GOLD));
+ getComponentLogger().info(text("Disabling plugin...", RED));
+ getComponentLogger().info(text("------------------------------------------------------", GOLD));
+ getComponentLogger().info(text("> ", DARK_GRAY).append(text("Made by ", GRAY)).append(text("Alps BTE (AT/CH/LI)", RED)));
+ getComponentLogger().info(text("> ", DARK_GRAY).append(text("GitHub: ", GRAY)).append(text("https://github.com/AlpsBTE/Plot-System", WHITE)));
+ getComponentLogger().info(text("------------------------------------------------------", GOLD));
DecentHologramDisplay.activeDisplays.forEach(DecentHologramDisplay::delete);
} else {
+ // Close database connection
+ DatabaseConnection.shutdown();
+
// Unload plots
for (UUID player : PlotUtils.Cache.getCachedInProgressPlots().keySet()) {
- for (Plot plot : PlotUtils.Cache.getCachedInProgressPlots(Builder.byUUID(player))) {
+ Builder builder = Builder.byUUID(player);
+ for (Plot plot : PlotUtils.Cache.getCachedInProgressPlots(builder)) {
if (plot != null) plot.getWorld().unloadWorld(true);
}
}
@@ -268,140 +189,11 @@ public static PlotSystem getPlugin() {
return plugin;
}
- public CommandManager getCommandManager() {
- return commandManager;
- }
-
-
- public static class DependencyManager {
-
- // List with all missing dependencies
- private static final List missingDependencies = new ArrayList<>();
-
- /**
- * Check for all required dependencies and inform in console about missing dependencies
- *
- * @return True if all dependencies are present
- */
- private static boolean checkForRequiredDependencies() {
- PluginManager pluginManager = plugin.getServer().getPluginManager();
- if (!pluginManager.isPluginEnabled("DecentHolograms")) {
- missingDependencies.add("DecentHolograms");
- }
-
- if (!pluginManager.isPluginEnabled("Multiverse-Core")) {
- missingDependencies.add("Multiverse-Core");
- }
-
- if (!pluginManager.isPluginEnabled("FastAsyncWorldEdit")) {
- missingDependencies.add("FastAsyncWorldEdit");
- }
-
- if (!pluginManager.isPluginEnabled("WorldGuard")) {
- missingDependencies.add("WorldGuard");
- }
-
- if (!pluginManager.isPluginEnabled("HeadDatabase")) {
- missingDependencies.add("HeadDatabase");
- }
-
- if (!pluginManager.isPluginEnabled("VoidGen")) {
- missingDependencies.add("VoidGen");
- }
-
- if (!pluginManager.isPluginEnabled("LangLibs")) {
- missingDependencies.add("LangLibs");
- }
-
- if (!pluginManager.isPluginEnabled("FancyNpcs")) {
- missingDependencies.add("FancyNpcs");
- }
-
- return missingDependencies.isEmpty();
- }
-
- /**
- * @return True if ParticleNativeAPI is present
- */
- public static boolean isParticleNativeAPIEnabled() {
- return plugin.getServer().getPluginManager().isPluginEnabled("ParticleNativeAPI");
- }
-
- public static boolean isMultiverseInventoriesEnabled() {
- return plugin.getServer().getPluginManager().isPluginEnabled("Multiverse-Inventories");
- }
-
- public static boolean isWorldGuardExtraFlagsEnabled() {
- return plugin.getServer().getPluginManager().isPluginEnabled("WorldGuardExtraFlags");
- }
-
- /**
- * @param worldName Name of the world
- * @return Config path for the world
- */
- public static String getMultiverseInventoriesConfigPath(String worldName) {
- return PlotSystem.DependencyManager.isMultiverseInventoriesEnabled() ? Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("Multiverse-Inventories")).getDataFolder() + "/worlds/" + worldName : "";
- }
-
- /**
- * @return Multiverse-Core instance
- */
- public static MultiverseCore getMultiverseCore() {
- return (MultiverseCore) plugin.getServer().getPluginManager().getPlugin("Multiverse-Core");
- }
-
- /**
- * @return World Edit instance
- */
- public static WorldEdit getWorldEdit() {
- return WorldEdit.getInstance();
- }
-
- /**
- * @return World Guard instance
- */
- public static WorldGuardPlugin getWorldGuard() {
- return WorldGuardPlugin.inst();
- }
-
- /**
- * @param worldName Name of the world
- * @return Config path for the world
- */
- public static String getWorldGuardConfigPath(String worldName) {
- return Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("WorldGuard")).getDataFolder() + "/worlds/" + worldName;
- }
-
- /**
- * @return Protocol Lib Instance
- */
- public static ProtocolManager getProtocolManager() {return ProtocolLibrary.getProtocolManager();}
- }
-
- public static class UpdateChecker {
- private static final int RESOURCE_ID = 95757;
- private static boolean isUpdateAvailable = false;
-
- /**
- * Get the latest plugin version from SpigotMC
- *
- * @param version Returns latest stable version
- */
- public static void getVersion(final Consumer version) {
- try (InputStream inputStream = new URI("https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).toURL().openStream(); Scanner scanner = new Scanner(inputStream)) {
- if (scanner.hasNext()) {
- version.accept(scanner.next());
- }
- } catch (IOException | URISyntaxException ex) {
- PlotSystem.getPlugin().getComponentLogger().warn(text("Cannot look for new updates:" + ex.getMessage()));
- }
- }
-
- /**
- * @return True if an update is available
- */
- public static boolean updateAvailable() {
- return isUpdateAvailable;
+ public void initDatabase() throws IOException, SQLException, ClassNotFoundException {
+ DatabaseConnection.initializeDatabase(DatabaseConfigPaths.getConfig(getConfig()), true);
+ var initScript = CharStreams.toString(Objects.requireNonNull(getTextResource("DATABASE.sql")));
+ try (var con = DatabaseConnection.getConnection(); var s = con.createStatement()) {
+ s.execute(initScript);
}
}
}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/BaseCommand.java b/src/main/java/com/alpsbte/plotsystem/commands/BaseCommand.java
index b308ac4cb..9f696a6dd 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/BaseCommand.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/BaseCommand.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
import com.alpsbte.plotsystem.utils.Utils;
@@ -99,7 +75,7 @@ public List getSubCommands() {
* @return null if sender is not a player
*/
protected Player getPlayer(CommandSender sender) {
- return sender instanceof Player ? (Player) sender : null;
+ return sender instanceof Player p ? p : null;
}
/**
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Companion.java b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Companion.java
index cd7087899..006d06a77 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Companion.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Companion.java
@@ -1,30 +1,5 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.core.menus.companion.CompanionMenu;
import com.alpsbte.plotsystem.core.menus.tutorial.TutorialStagesMenu;
import com.alpsbte.plotsystem.core.menus.tutorial.TutorialsMenu;
@@ -33,19 +8,13 @@
import com.alpsbte.plotsystem.core.system.tutorial.Tutorial;
import com.alpsbte.plotsystem.core.system.tutorial.TutorialCategory;
import com.alpsbte.plotsystem.utils.Utils;
-import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
-import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
-
-import static net.kyori.adventure.text.Component.text;
-
public class CMD_Companion extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
@@ -54,20 +23,15 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @N
return true;
}
- if (getPlayer(sender) == null) return true;
+ Player player = getPlayer(sender);
+ if (player == null) return true;
- try {
- FileConfiguration config = PlotSystem.getPlugin().getConfig();
- Tutorial tutorial = AbstractTutorial.getActiveTutorial(getPlayer(sender).getUniqueId());
- if (tutorial != null) {
- new TutorialStagesMenu(getPlayer(sender), tutorial.getId());
- } else if (config.getBoolean(ConfigPaths.TUTORIAL_ENABLE) && config.getBoolean(ConfigPaths.TUTORIAL_REQUIRE_BEGINNER_TUTORIAL) &&
- !TutorialPlot.isPlotCompleted(getPlayer(sender), TutorialCategory.BEGINNER.getId()) && getPlayer(sender).hasPermission("plotsystem.tutorial")) {
- new TutorialsMenu(getPlayer(sender));
- } else CompanionMenu.open((Player) sender);
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ Tutorial tutorial = AbstractTutorial.getActiveTutorial(player.getUniqueId());
+ if (tutorial != null) {
+ new TutorialStagesMenu(player, tutorial.getId());
+ } else if (TutorialPlot.isRequiredAndInProgress(TutorialCategory.BEGINNER.getId(), player.getUniqueId()) && player.hasPermission("plotsystem.tutorial")) {
+ new TutorialsMenu(player);
+ } else CompanionMenu.open((Player) sender);
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Plots.java b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Plots.java
index 302425b8f..4d8955826 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Plots.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Plots.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
import com.alpsbte.plotsystem.PlotSystem;
@@ -30,6 +6,7 @@
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
+import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
@@ -37,42 +14,40 @@
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
-
-import static net.kyori.adventure.text.Component.text;
+import java.util.concurrent.CompletableFuture;
public class CMD_Plots extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
- if (!sender.hasPermission(getPermission())) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", NamedTextColor.RED));
return true;
}
- if (getPlayer(sender) == null) {
- Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ if (!sender.hasPermission(getPermission())) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
return true;
}
- Player player = (Player) sender;
-
- try {
- if (args.length < 1) {
- new PlayerPlotsMenu(player, Builder.byUUID(player.getUniqueId()));
- return true;
- }
+ if (args.length < 1) {
+ CompletableFuture.runAsync(() -> {
+ Builder builder = Builder.byUUID(player.getUniqueId());
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new PlayerPlotsMenu(player, builder));
+ });
+ }
- Builder builder = Builder.getBuilderByName(args[0]);
- if (builder == null) {
- player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_NOT_FOUND)));
- return true;
- }
+ CompletableFuture.runAsync(() -> {
+ Builder builder = Builder.byName(args[0]);
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ if (builder == null) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_NOT_FOUND)));
+ return;
+ }
- new PlayerPlotsMenu(player, builder);
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ new PlayerPlotsMenu(player, builder);
+ });
+ });
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tpll.java b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tpll.java
index 78bbeccb2..de91f1e79 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tpll.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tpll.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
import com.alpsbte.plotsystem.PlotSystem;
@@ -46,7 +22,6 @@
import java.io.IOException;
import java.math.RoundingMode;
-import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -74,78 +49,87 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @N
return true;
}
- try {
- if (args == null || args.length < 2 || args.length > 3) {
- sendInfo(sender);
- return true;
- }
+ if (args == null || args.length < 2 || args.length > 3) {
+ sendInfo(sender);
+ return true;
+ }
- String[] splitCoords = args[0].split(",");
- if (splitCoords.length == 2) {
- args = splitCoords;
- }
+ String[] splitCoords = args[0].split(",");
+ if (splitCoords.length == 2) {
+ args = splitCoords;
+ }
- if (args[0].endsWith(",")) {
- args[0] = args[0].substring(0, args[0].length() - 1);
- }
- if (args[1].endsWith(",")) {
- args[1] = args[1].substring(0, args[1].length() - 1);
- }
+ if (args[0].endsWith(",")) {
+ args[0] = args[0].substring(0, args[0].length() - 1);
+ }
+ if (args[1].endsWith(",")) {
+ args[1] = args[1].substring(0, args[1].length() - 1);
+ }
+
+ // Parse coordinates to doubles
+ double lat;
+ double lon;
+ try {
+ lat = Double.parseDouble(args[0]);
+ lon = Double.parseDouble(args[1]);
+ } catch (Exception ignore) {
+ sendInfo(sender);
+ return true;
+ }
- // Parse coordinates to doubles
- double lat;
- double lon;
+ CompletableFuture.runAsync(() -> {
try {
- lat = Double.parseDouble(args[0]);
- lon = Double.parseDouble(args[1]);
- } catch (Exception ignore) {
- sendInfo(sender);
- return true;
- }
+ // Get the terra coordinates from the irl coordinates
+ double[] terraCoords = CoordinateConversion.convertFromGeo(lon, lat);
- // Get the terra coordinates from the irl coordinates
- double[] terraCoords = CoordinateConversion.convertFromGeo(lon, lat);
+ // Get plot, that the player is in
+ AbstractPlot plot = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished, Status.unreviewed, Status.completed);
- // Get plot, that the player is in
- AbstractPlot plot = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished, Status.unreviewed, Status.completed);
+ // Convert terra coordinates to plot relative coordinates
+ CompletableFuture plotCoordsFuture = plot != null ? PlotUtils.convertTerraToPlotXZ(plot, terraCoords) : null;
- // Convert terra coordinates to plot relative coordinates
- CompletableFuture plotCoords = plot != null ? PlotUtils.convertTerraToPlotXZ(plot, terraCoords) : null;
+ if (plotCoordsFuture == null) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.CANNOT_TELEPORT_OUTSIDE_PLOT)));
+ return;
+ }
- if (plotCoords == null) {
- player.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.CANNOT_TELEPORT_OUTSIDE_PLOT)));
- return true;
- }
+ double[] plotCoordinates = plotCoordsFuture.get();
- // Get Highest Y
- int highestY = 0;
- Location block = new Location(playerWorld, plotCoords.get()[0], 0, plotCoords.get()[1]);
- for (int i = 1; i < 256; i++) {
- block.add(0, 1, 0);
- if (!block.getBlock().isEmpty()) {
- highestY = i;
- }
- }
- if (highestY < PlotWorld.MIN_WORLD_HEIGHT) {
- highestY = PlotWorld.MIN_WORLD_HEIGHT;
- }
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ int highestY = getHighestY(playerWorld, plotCoordinates);
- player.teleport(new Location(playerWorld, plotCoords.get()[0], highestY + 1, plotCoords.get()[1], player.getLocation().getYaw(), player.getLocation().getPitch()));
+ player.teleport(new Location(playerWorld, plotCoordinates[0], highestY + 1f, plotCoordinates[1], player.getLocation().getYaw(), player.getLocation().getPitch()));
- DecimalFormat df = new DecimalFormat("##.#####");
- df.setRoundingMode(RoundingMode.FLOOR);
- player.sendMessage(Utils.ChatUtils.getInfoFormat(langUtil.get(sender, LangPaths.Message.Info.TELEPORTING_TPLL, df.format(lat), df.format(lon))));
+ DecimalFormat df = new DecimalFormat("##.#####");
+ df.setRoundingMode(RoundingMode.FLOOR);
+ player.sendMessage(Utils.ChatUtils.getInfoFormat(langUtil.get(sender, LangPaths.Message.Info.TELEPORTING_TPLL, df.format(lat), df.format(lon))));
+ });
+ } catch (IOException | OutOfProjectionBoundsException ex) {
+ PlotSystem.getPlugin().getComponentLogger().error(text("A coordinate conversion error occurred!"), ex);
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
+ } catch (InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ sendInfo(sender);
+ } catch (ExecutionException ex) {
+ sendInfo(sender);
+ }
+ });
+ return true;
+ }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- } catch (IOException | OutOfProjectionBoundsException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A coordinate conversion error occurred!"), ex);
- player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- } catch (InterruptedException | ExecutionException ex) {
- sendInfo(sender);
+ private static int getHighestY(World playerWorld, double[] plotCoordinates) {
+ int highestY = 0;
+ Location block = new Location(playerWorld, plotCoordinates[0], 0, plotCoordinates[1]);
+ for (int i = 1; i < 256; i++) {
+ block.add(0, 1, 0);
+ if (!block.getBlock().isEmpty()) {
+ highestY = i;
+ }
}
- return true;
+ if (highestY < PlotWorld.MIN_WORLD_HEIGHT) {
+ highestY = PlotWorld.MIN_WORLD_HEIGHT;
+ }
+ return highestY;
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tutorial.java b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tutorial.java
index a98b526f2..595ce97b5 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tutorial.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/CMD_Tutorial.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
@@ -47,29 +23,30 @@ public class CMD_Tutorial extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
- if (sender.hasPermission(getPermission())) {
- if (getPlayer(sender) != null) {
- if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.TUTORIAL_ENABLE)) {
- if (args.length == 0) {
- Tutorial tutorial = AbstractTutorial.getActiveTutorial(getPlayer(sender).getUniqueId());
- if (tutorial != null) {
- new TutorialStagesMenu(tutorial.getPlayer(), tutorial.getId());
- } else {
- new TutorialsMenu(getPlayer(sender));
- }
- } else if (args.length == 1 && AlpsUtils.tryParseInt(args[0]) != null) {
- int tutorialId = Integer.parseInt(args[0]);
- if (TutorialCategory.byId(tutorialId) == null) return true;
- AbstractTutorial.loadTutorial(getPlayer(sender), tutorialId);
- }
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.TUTORIAL_DISABLED)));
- }
+ if (!sender.hasPermission(getPermission())) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return true;
+ }
+ if (getPlayer(sender) == null) {
+ Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", NamedTextColor.RED));
+ return true;
+ }
+ if (!PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.TUTORIAL_ENABLE)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.TUTORIAL_DISABLED)));
+ return true;
+ }
+
+ if (args.length == 0) {
+ Tutorial tutorial = AbstractTutorial.getActiveTutorial(getPlayer(sender).getUniqueId());
+ if (tutorial != null) {
+ new TutorialStagesMenu(tutorial.getPlayer(), tutorial.getId());
} else {
- Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", NamedTextColor.RED));
+ new TutorialsMenu(getPlayer(sender));
}
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ } else if (args.length == 1 && AlpsUtils.tryParseInt(args[0]) != null) {
+ int tutorialId = Integer.parseInt(args[0]);
+ if (TutorialCategory.byId(tutorialId) == null) return true;
+ AbstractTutorial.loadTutorial(getPlayer(sender), tutorialId);
}
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/CommandManager.java b/src/main/java/com/alpsbte/plotsystem/commands/CommandManager.java
index 373e55c15..95b4634ff 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/CommandManager.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/CommandManager.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
import com.alpsbte.plotsystem.PlotSystem;
@@ -30,9 +6,9 @@
import com.alpsbte.plotsystem.commands.admin.CMD_SetLeaderboard;
import com.alpsbte.plotsystem.commands.admin.setup.CMD_Setup;
import com.alpsbte.plotsystem.commands.plot.CMD_Plot;
+import com.alpsbte.plotsystem.commands.review.CMD_EditFeedback;
import com.alpsbte.plotsystem.commands.review.CMD_EditPlot;
import com.alpsbte.plotsystem.commands.review.CMD_Review;
-import com.alpsbte.plotsystem.commands.review.CMD_EditFeedback;
import com.alpsbte.plotsystem.commands.review.CMD_UndoReview;
import java.util.ArrayList;
@@ -40,32 +16,33 @@
import java.util.Objects;
public class CommandManager {
-
- public final List baseCommands = new ArrayList() {{
+ public final List baseCommands = new ArrayList<>();
+
+ public CommandManager() {
// Default Commands
- add(new CMD_CancelChat());
- add(new CMD_Companion());
- add(new CMD_Plots());
- add(new CMD_Tpll());
+ baseCommands.add(new CMD_CancelChat());
+ baseCommands.add(new CMD_Companion());
+ baseCommands.add(new CMD_Plots());
+ baseCommands.add(new CMD_Tpll());
// Plot Commands
- add(new CMD_Plot());
+ baseCommands.add(new CMD_Plot());
// Review Commands
- add(new CMD_Review());
- add(new CMD_UndoReview());
- add(new CMD_EditFeedback());
- add(new CMD_EditPlot());
+ baseCommands.add(new CMD_Review());
+ baseCommands.add(new CMD_UndoReview());
+ baseCommands.add(new CMD_EditFeedback());
+ baseCommands.add(new CMD_EditPlot());
// Admin Commands
- add(new CMD_DeletePlot());
- add(new CMD_SetLeaderboard());
- add(new CMD_PReload());
+ baseCommands.add(new CMD_DeletePlot());
+ baseCommands.add(new CMD_SetLeaderboard());
+ baseCommands.add(new CMD_PReload());
// Admin Setup Commands
- add(new CMD_Setup());
- add(new CMD_Tutorial());
- }};
+ baseCommands.add(new CMD_Setup());
+ baseCommands.add(new CMD_Tutorial());
+ }
public void init() {
for (BaseCommand baseCmd : baseCommands) {
@@ -74,8 +51,4 @@ public void init() {
}
}
}
-
- public List getBaseCommands() {
- return baseCommands;
- }
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/ICommand.java b/src/main/java/com/alpsbte/plotsystem/commands/ICommand.java
index 391484098..803126079 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/ICommand.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/ICommand.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2021, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
import org.bukkit.command.CommandSender;
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/SubCommand.java b/src/main/java/com/alpsbte/plotsystem/commands/SubCommand.java
index 4250fc4e5..ae6fbd9a8 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/SubCommand.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/SubCommand.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands;
import com.alpsbte.plotsystem.utils.io.LangUtil;
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_DeletePlot.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_DeletePlot.java
index 2f460d6dc..35775b98a 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_DeletePlot.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_DeletePlot.java
@@ -1,38 +1,19 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin;
import com.alpsbte.alpslib.utils.AlpsUtils;
+import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
import com.alpsbte.plotsystem.utils.Utils;
+import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
+import java.util.concurrent.CompletableFuture;
+
public class CMD_DeletePlot extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
@@ -41,22 +22,33 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @N
return true;
}
- if (!(args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null)) {
+ if (args.length == 0) {
sendInfo(sender);
return true;
}
- int plotID = Integer.parseInt(args[0]);
- if (!PlotUtils.plotExists(plotID)) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find plot with ID #" + plotID + "!"));
+ Integer plotID = AlpsUtils.tryParseInt(args[0]);
+
+ if (plotID == null) {
+ sendInfo(sender);
return true;
}
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Deleting plot..."));
- if (PlotUtils.Actions.deletePlot(new Plot(plotID))) {
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully deleted plot with the ID §6#" + plotID + "§a!"));
- if (getPlayer(sender) != null) getPlayer(sender).playSound(getPlayer(sender).getLocation(), Utils.SoundUtils.DONE_SOUND, 1f, 1f);
- } else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An unexpected error has occurred!"));
+ CompletableFuture.runAsync(() -> {
+ Plot plot = DataProvider.PLOT.getPlotById(plotID);
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find plot with ID #" + plotID + "!"));
+ return;
+ }
+
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("Deleting plot..."));
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ if (PlotUtils.Actions.deletePlot(plot)) {
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully deleted plot with the ID §6#" + plotID + "§a!"));
+ if (getPlayer(sender) != null) getPlayer(sender).playSound(getPlayer(sender).getLocation(), Utils.SoundUtils.DONE_SOUND, 1f, 1f);
+ } else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An unexpected error has occurred!"));
+ });
+ });
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_PReload.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_PReload.java
index 4c09f0b17..409a60e4c 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_PReload.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_PReload.java
@@ -1,36 +1,12 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin;
import com.alpsbte.alpslib.hologram.DecentHologramDisplay;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
-import com.alpsbte.plotsystem.core.database.DatabaseConnection;
import com.alpsbte.plotsystem.core.holograms.HologramConfiguration;
import com.alpsbte.plotsystem.core.holograms.HologramRegister;
import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.io.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@@ -41,24 +17,25 @@ public class CMD_PReload extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
+ PlotSystem plugin = PlotSystem.getPlugin();
if (!sender.hasPermission(getPermission())) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat("You don't have permission to use this command!"));
return true;
}
try {
- PlotSystem.getPlugin().reloadConfig();
+ plugin.reloadConfig();
+ LangUtil.getInstance().reloadFiles();
sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully reloaded config!"));
DecentHologramDisplay.activeDisplays.forEach(leaderboard -> leaderboard.setLocation(HologramRegister
.getLocation((HologramConfiguration) leaderboard)));
HologramRegister.reload();
sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully reloaded leaderboards!"));
-
- DatabaseConnection.InitializeDatabase();
+ plugin.initDatabase();
} catch (Exception ex) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ plugin.getComponentLogger().error(text("An error occurred!"), ex);
}
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_SetLeaderboard.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_SetLeaderboard.java
index a35a2cfc0..f2d18813b 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_SetLeaderboard.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/CMD_SetLeaderboard.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin;
import com.alpsbte.alpslib.hologram.DecentHologramDisplay;
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup.java
index 7d49fce12..05b64e36d 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2021, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin.setup;
import com.alpsbte.plotsystem.commands.BaseCommand;
@@ -33,11 +9,11 @@ public class CMD_Setup extends BaseCommand {
public CMD_Setup() {
registerSubCommand(new CMD_Setup_BuildTeam(this));
- registerSubCommand(new CMD_Setup_FTP(this));
registerSubCommand(new CMD_Setup_Server(this));
registerSubCommand(new CMD_Setup_Country(this));
registerSubCommand(new CMD_Setup_City(this));
registerSubCommand(new CMD_Setup_Difficulty(this));
+ registerSubCommand(new CMD_Setup_ReviewCriteria(this));
}
@Override
@@ -68,16 +44,4 @@ public String[] getParameter() {
public String getPermission() {
return null;
}
-
- public static String appendArgs(String[] args, int startIndex) {
- StringBuilder name = new StringBuilder();
- for (int i = startIndex; i < args.length; i++) {
- name.append(args[i]);
- // Add space between words
- if (i != args.length - 1) {
- name.append(" ");
- }
- }
- return name.toString();
- }
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_BuildTeam.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_BuildTeam.java
index ace57dde0..d80acb731 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_BuildTeam.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_BuildTeam.java
@@ -1,44 +1,23 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin.setup;
import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.BuildTeam;
import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.Country;
+import com.alpsbte.plotsystem.core.system.review.ToggleCriteria;
import com.alpsbte.plotsystem.utils.Utils;
import org.bukkit.command.CommandSender;
-import java.sql.SQLException;
import java.util.List;
+import java.util.Optional;
import java.util.StringJoiner;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
public class CMD_Setup_BuildTeam extends SubCommand {
public CMD_Setup_BuildTeam(BaseCommand baseCommand) {
@@ -51,10 +30,11 @@ private void register() {
registerSubCommand(new CMD_Setup_BuildTeam_Add(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_BuildTeam_Remove(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_BuildTeam_SetName(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_BuildTeam_AddCountry(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_BuildTeam_RemoveCountry(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_BuildTeam_AddReviewer(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_BuildTeam_RemoveReviewer(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_BuildTeam_Criteria(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_BuildTeam_AssignCriteria(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_BuildTeam_RemoveCriteria(getBaseCommand(), this));
}
@Override
@@ -90,27 +70,25 @@ public CMD_Setup_BuildTeam_List(BaseCommand baseCommand, SubCommand subCommand)
@Override
public void onCommand(CommandSender sender, String[] args) {
- List buildTeams = BuildTeam.getBuildTeams();
+ List buildTeams = DataProvider.BUILD_TEAM.getBuildTeams();
if (buildTeams.isEmpty()) {
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no build teams registered in the database!"));
return;
}
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + buildTeams.size() + " build teams registered in the database:"));
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
for (BuildTeam b : buildTeams) {
- try {
- StringJoiner countriesAsString = new StringJoiner(", ");
- StringJoiner reviewersAsString = new StringJoiner(", ");
- b.getCountries().forEach(c -> countriesAsString.add(String.valueOf(c.getID())));
- b.getReviewers().forEach(r -> {try {reviewersAsString.add(r.getName());} catch (SQLException ex) {PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);}});
- sender.sendMessage(" §6> §b" + b.getID() + " (" + b.getName() + ") §f- Country IDs: " + (countriesAsString.length() == 0 ? "No Countries" : countriesAsString) + " - Reviewers: " + (reviewersAsString.length() == 0 ? "No Reviewers" : reviewersAsString));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ StringJoiner citiesAsString = new StringJoiner(", ");
+ StringJoiner reviewersAsString = new StringJoiner(", ");
+ b.getCityProjects().forEach(c -> citiesAsString.add(c.getId()));
+ b.getReviewers().forEach(r -> reviewersAsString.add(r.getName()));
+ sender.sendMessage(text(" » ", DARK_GRAY)
+ .append(text(b.getId() + " (" + b.getName() + ") ", AQUA))
+ .append(text("- City Project IDs: " + (citiesAsString.length() == 0 ? "No City Projects" : citiesAsString)
+ + " - Reviewers: " + (reviewersAsString.length() == 0 ? "No Reviewers" : reviewersAsString), WHITE)));
}
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
}
@Override
@@ -142,19 +120,16 @@ public CMD_Setup_BuildTeam_Add(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
if (args.length <= 1) {sendInfo(sender); return;}
- if (args[1].length() > 45) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team name cannot be longer than 45 characters!"));
+
+ String name = args[1];
+ if (name.length() > 255) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team name cannot be longer than 255 characters!"));
return;
}
- try {
- String name = CMD_Setup.appendArgs(args, 1);
- BuildTeam.addBuildTeam(name);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added build team with name '" + name + "'!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ boolean successful = DataProvider.BUILD_TEAM.addBuildTeam(name);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added build team with name '" + name + "'!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -185,21 +160,23 @@ public CMD_Setup_BuildTeam_Remove(BaseCommand baseCommand, SubCommand subCommand
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 1 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 1) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ Optional buildTeam = DataProvider.BUILD_TEAM.getBuildTeam(input);
// Check if build team exists
- try {
- if (BuildTeam.getBuildTeams().stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any build team with ID " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- BuildTeam.removeBuildTeam(Integer.parseInt(args[1]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed build team with ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (buildTeam.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any build team with ID " + args[1] + "!"));
+ sendInfo(sender);
+ return;
}
+
+ boolean successful = DataProvider.BUILD_TEAM.removeBuildTeam(buildTeam.get().getId());
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed build team with ID " + args[1] + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -230,23 +207,28 @@ public CMD_Setup_BuildTeam_SetName(BaseCommand baseCommand, SubCommand subComman
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
-
- // Check if build team exits
- try {
- if (BuildTeam.getBuildTeams().stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) return;
- String name = CMD_Setup.appendArgs(args, 2);
- if (name.length() > 45) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team name cannot be longer than 45 characters!"));
- return;
- }
-
- BuildTeam.setBuildTeamName(Integer.parseInt(args[1]), name);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully changed name of build team with ID " + args[1] + " to '" + name + "'!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (args.length <= 2) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ Optional buildTeam = DataProvider.BUILD_TEAM.getBuildTeam(input);
+
+ // Check if build team exists
+ if (buildTeam.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team could not be found!"));
+ return;
+ }
+
+ String name = args[2];
+ if (name.length() > 255) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team name cannot be longer than 255 characters!"));
+ return;
}
+
+ boolean successful = buildTeam.get().setName(name);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully changed name of build team with ID " + args[1] + " to '" + name + "'!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -270,37 +252,38 @@ public String getPermission() {
}
}
- public static class CMD_Setup_BuildTeam_AddCountry extends SubCommand {
- public CMD_Setup_BuildTeam_AddCountry(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_BuildTeam_AddReviewer extends SubCommand {
+ public CMD_Setup_BuildTeam_AddReviewer(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null || AlpsUtils.tryParseInt(args[2]) == null) {
- sendInfo(sender);
+ if (args.length <= 2) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ // Check if build team exists
+ Optional buildTeam = DataProvider.BUILD_TEAM.getBuildTeam(input);
+ if (buildTeam.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team could not be found!"));
return;
}
- // Check if build team and country exists
- try {
- if (BuildTeam.getBuildTeams().stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) return;
- if (Country.getCountries().stream().noneMatch(c -> c.getID() == Integer.parseInt(args[2]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Country could not be found or is already added to the build team!"));
- return;
- }
- Country country = new Country(Integer.parseInt(args[2]));
- BuildTeam.addCountry(Integer.parseInt(args[1]), country.getID());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added country '" + country.getName() + "' to build team with ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ Builder builder = Builder.byName(args[2]);
+ if (builder == null || DataProvider.BUILD_TEAM.getBuildTeamsByReviewer(builder.getUUID()).stream().anyMatch(b -> b.getId() == buildTeam.get().getId())) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Player could not be found or is already reviewer for this build team!"));
+ return;
}
+ boolean successful = buildTeam.get().addReviewer(builder);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added '" + builder.getName() + "' as reviewer to build team with ID " + buildTeam.get().getName() + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
public String[] getNames() {
- return new String[]{"addcountry"};
+ return new String[]{"addreviewer"};
}
@Override
@@ -310,46 +293,49 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"BuildTeam-ID", "Country-ID"};
+ return new String[]{"BuildTeam-ID", "Name"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.buildteam.addcountry";
+ return "plotsystem.admin.pss.buildteam.addreviewer";
}
}
- public static class CMD_Setup_BuildTeam_RemoveCountry extends SubCommand {
- public CMD_Setup_BuildTeam_RemoveCountry(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_BuildTeam_RemoveReviewer extends SubCommand {
+ public CMD_Setup_BuildTeam_RemoveReviewer(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null || AlpsUtils.tryParseInt(args[2]) == null) {
- sendInfo(sender);
+ if (args.length <= 2) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ // Check if build team exists
+ Optional buildTeam = DataProvider.BUILD_TEAM.getBuildTeam(input);
+
+ if (buildTeam.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team could not be found!"));
return;
}
- // Check if build team and country exists
- try {
- if (BuildTeam.getBuildTeams().stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) return;
- if (Country.getCountries().stream().noneMatch(c -> c.getID() == Integer.parseInt(args[2]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Country could not be found or is not added to the build team!"));
- return;
- }
- Country country = new Country(Integer.parseInt(args[2]));
- BuildTeam.removeCountry(Integer.parseInt(args[1]), country.getID());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed country '" + country.getName() + "' from build team with ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ Builder builder = Builder.byName(args[2]);
+ if (builder == null || DataProvider.BUILD_TEAM.getBuildTeamsByReviewer(builder.getUUID()).stream().noneMatch(b -> b.getId() == buildTeam.get().getId())) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Player could not be found or is not a reviewer for this build team!"));
+ return;
}
+
+ boolean successful = buildTeam.get().removeReviewer(builder.getUUID().toString());
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed '" + builder.getName() + "' as reviewer from build team with ID " + args[1] + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
public String[] getNames() {
- return new String[]{"removecountry"};
+ return new String[]{"removereviewer"};
}
@Override
@@ -359,46 +345,45 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"BuildTeam-ID", "Country-ID"};
+ return new String[]{"BuildTeam-ID", "Name"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.buildteam.removecountry";
+ return "plotsystem.admin.pss.buildteam.removereviewer";
}
}
- public static class CMD_Setup_BuildTeam_AddReviewer extends SubCommand {
- public CMD_Setup_BuildTeam_AddReviewer(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_BuildTeam_Criteria extends SubCommand {
+ public CMD_Setup_BuildTeam_Criteria(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {
- sendInfo(sender);
+ if (args.length <= 1) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ List criteria = DataProvider.REVIEW.getBuildTeamToggleCriteria(input);
+ if (criteria.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no toggle criteria assigned to the build team " + args[1] + " in the database!"));
return;
}
- // Check if build team exits
- try {
- if (BuildTeam.getBuildTeams().stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) return;
- Builder builder = Builder.getBuilderByName(args[2]);
- if (builder == null || BuildTeam.getBuildTeamsByReviewer(builder.getUUID()).stream().anyMatch(b -> b.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Player could not be found or is already reviewer for this build team!"));
- return;
- }
- BuildTeam.addReviewer(Integer.parseInt(args[1]), builder.getUUID().toString());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added '" + builder.getName() + "' as reviewer to build team with ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + criteria.size() + " toggle criteria associated to this build team:"));
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
+ for (ToggleCriteria c : criteria) {
+ sender.sendMessage(text(" » ", DARK_GRAY)
+ .append(text(c.criteriaName() + " (" + (c.isOptional() ? "optional" : "required") + ")")));
}
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
}
@Override
public String[] getNames() {
- return new String[]{"addreviewer"};
+ return new String[]{"criteria"};
}
@Override
@@ -408,44 +393,49 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"BuildTeam-ID", "Name"};
+ return new String[]{"Build-Team-ID"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.buildteam.addreviewer";
+ return "plotsystem.admin.pss.buildteam.criteria";
}
}
- public static class CMD_Setup_BuildTeam_RemoveReviewer extends SubCommand {
- public CMD_Setup_BuildTeam_RemoveReviewer(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_BuildTeam_AssignCriteria extends SubCommand {
+ public CMD_Setup_BuildTeam_AssignCriteria(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
-
- // Check if build team exits
- try {
- if (BuildTeam.getBuildTeams().stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) return;
-
- Builder builder = Builder.getBuilderByName(args[2]);
- if (builder == null || BuildTeam.getBuildTeamsByReviewer(builder.getUUID()).stream().noneMatch(b -> b.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Player could not be found or is not a reviewer for this build team!"));
- return;
- }
- BuildTeam.removeReviewer(Integer.parseInt(args[1]), builder.getUUID().toString());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed '" + builder.getName() + "' as reviewer from build team with ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (args.length <= 2) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ // Check if build team exists
+ Optional buildTeam = DataProvider.BUILD_TEAM.getBuildTeam(input);
+ if (buildTeam.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team could not be found!"));
+ return;
+ }
+
+ // Check if toggle criteria exists
+ Optional criteria = DataProvider.REVIEW.getToggleCriteria(args[2]);
+ if (criteria.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Toggle criteria could not be found!"));
+ return;
}
+
+ boolean successful = DataProvider.REVIEW.assignBuildTeamToggleCriteria(buildTeam.get().getId(), criteria.get());
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully assigned criteria '" + criteria.get().criteriaName() + "' to build team with ID '" + args[1] + "'!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
public String[] getNames() {
- return new String[]{"removereviewer"};
+ return new String[]{"assigncriteria"};
}
@Override
@@ -455,12 +445,65 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"BuildTeam-ID", "Name"};
+ return new String[]{"Build-Team-ID", "Criteria-Name"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.buildteam.removereviewer";
+ return "plotsystem.admin.pss.buildteam.assigncriteria";
+ }
+ }
+
+ public static class CMD_Setup_BuildTeam_RemoveCriteria extends SubCommand {
+ public CMD_Setup_BuildTeam_RemoveCriteria(BaseCommand baseCommand, SubCommand subCommand) {
+ super(baseCommand, subCommand);
+ }
+
+ @Override
+ public void onCommand(CommandSender sender, String[] args) {
+ if (args.length <= 2) {sendInfo(sender); return;}
+
+ Integer input = AlpsUtils.tryParseInt(args[1]);
+ if (input == null) {sendInfo(sender); return;}
+
+ // Check if build team exists
+ Optional buildTeam = DataProvider.BUILD_TEAM.getBuildTeam(input);
+ if (buildTeam.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team could not be found!"));
+ return;
+ }
+
+ // Check if toggle criteria exists
+ Optional criteria = DataProvider.REVIEW.getBuildTeamToggleCriteria(buildTeam.get().getId())
+ .stream().filter(t -> t.criteriaName().equalsIgnoreCase(args[2])).findFirst();
+ if (criteria.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Toggle criteria could not be found or is not assigned!"));
+ return;
+ }
+
+ boolean successful = DataProvider.REVIEW.removeBuildTeamToggleCriteria(buildTeam.get().getId(), criteria.get());
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed criteria '" + criteria.get().criteriaName() + "' from build team with ID '" + args[1] + "'!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
+ }
+
+ @Override
+ public String[] getNames() {
+ return new String[]{"removecriteria"};
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public String[] getParameter() {
+ return new String[]{"Build-Team-ID", "Criteria-Name"};
+ }
+
+ @Override
+ public String getPermission() {
+ return "plotsystem.admin.pss.buildteam.removecriteria";
}
}
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_City.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_City.java
index 41d925de9..34e6b5b1c 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_City.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_City.java
@@ -1,42 +1,22 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin.setup;
import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.CityProject;
import com.alpsbte.plotsystem.core.system.Country;
import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.io.LangPaths;
import org.bukkit.command.CommandSender;
-import java.sql.SQLException;
import java.util.List;
+import java.util.Optional;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
public class CMD_Setup_City extends SubCommand {
@@ -49,8 +29,8 @@ private void register() {
registerSubCommand(new CMD_Setup_City_List(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_City_Add(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_City_Remove(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_City_SetName(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_City_SetDescription(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_City_SetServer(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_City_SetBuildTeam(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_City_SetVisible(getBaseCommand(), this));
}
@@ -87,23 +67,23 @@ public CMD_Setup_City_List(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- List cities = CityProject.getCityProjects(false);
+ List cities = DataProvider.CITY_PROJECT.get(false);
if (cities.isEmpty()) {
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no City Projects registered in the database!"));
return;
}
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + cities.size() + " City Projects registered in the database:"));
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
for (CityProject c : cities) {
- try {
- sender.sendMessage(" §6> §b" + c.getID() + " (" + c.getName() + ") §f- Description: " + c.getDescription() + " - Country: " + c.getCountry().getName() + " - Visible: " + c.isVisible());
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ sender.sendMessage(text(" » ", DARK_GRAY)
+ .append(text(c.getId(), AQUA))
+ .append(text(" - Country: " + c.getCountry().getCode()
+ + " - Server: " + c.getServerName()
+ + " - Build Team: " + c.getBuildTeam().getName()
+ + " - Visible: " + c.isVisible(), WHITE)));
}
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
}
@Override
@@ -134,27 +114,47 @@ public CMD_Setup_City_Add(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 4) {sendInfo(sender); return;}
- Country country = Country.getCountries().stream().filter(c -> c.getID() == Integer.parseInt(args[1])).findFirst().orElse(null);
- if (country == null) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any country with ID " + args[1] + "!"));
+ String cityProjectId = args[1].toLowerCase();
+ String countryCode = args[2];
+ Optional country = DataProvider.COUNTRY.getCountryByCode(countryCode);
+ if (country.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any country with code " + countryCode + "!"));
sender.sendMessage(Utils.ChatUtils.getAlertFormat("Type to see all countries!"));
return;
}
- String name = CMD_Setup.appendArgs(args, 2);
- if (name.length() > 45) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("City Project name cannot be longer than 45 characters!"));
+ String serverName = args[3];
+ if (serverName.length() > 255) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Server name cannot be longer than 255 characters!"));
+ return;
+ }
+ // Check if server exists
+ if (!DataProvider.SERVER.serverExists(serverName)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any server with Name " + serverName + "!"));
+ sendInfo(sender);
+ return;
+ }
+
+ Integer buildTeamId = AlpsUtils.tryParseInt(args[4]);
+ if (buildTeamId == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build Team ID must be a number!"));
+ sendInfo(sender);
+ return;
+ }
+ if (DataProvider.BUILD_TEAM.getBuildTeam(buildTeamId).isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any build team with ID " + buildTeamId + "!"));
+ sendInfo(sender);
return;
}
- try {
- CityProject.addCityProject(country, name);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added City Project with name '" + name + "' in country with the ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ boolean added = DataProvider.CITY_PROJECT.add(cityProjectId, buildTeamId, country.get().getCode(), serverName);
+ if (!added) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while adding City Project! Check console for any exceptions."));
+ return;
}
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added City Project with Name '" + cityProjectId + "' under country with the code " + countryCode + "!"));
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Edit the " + LangPaths.Database.CITY_PROJECT + "." + cityProjectId + " language config setting, otherwise the name will be undefined!"));
}
@Override
@@ -169,7 +169,7 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"Country-ID", "Name"};
+ return new String[]{"City-Project-Name", "Country-Code", "Server-Name", "Build-Team-ID"};
}
@Override
@@ -185,21 +185,20 @@ public CMD_Setup_City_Remove(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 1 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 1) {sendInfo(sender); return;}
+ String cityProjectId = args[1];
// Check if City Project exists
- try {
- if (CityProject.getCityProjects(false).stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any City Project with ID " + args[1] + "!"));
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Type to see all City Projects!"));
- return;
- }
- CityProject.removeCityProject(Integer.parseInt(args[1]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed City Project with ID " + args[1] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ Optional cityProject = DataProvider.CITY_PROJECT.getById(cityProjectId);
+ if (cityProject.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any City Project with ID " + cityProjectId + "!"));
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Type to see all City Projects!"));
+ return;
}
+
+ boolean removed = DataProvider.CITY_PROJECT.remove(cityProjectId);
+ if (removed) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed City Project with ID " + cityProjectId + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while removing city project! Check console for any exceptions."));
}
@Override
@@ -223,37 +222,39 @@ public String getPermission() {
}
}
- public static class CMD_Setup_City_SetName extends SubCommand {
- public CMD_Setup_City_SetName(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_City_SetServer extends SubCommand {
+ public CMD_Setup_City_SetServer(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 2) {sendInfo(sender); return;}
// Check if City Project exits
- try {
- if (CityProject.getCityProjects(false).stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) return;
-
- String name = CMD_Setup.appendArgs(args, 2);
- if (name.length() > 45) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("City Project name cannot be longer than 45 characters!"));
- return;
- }
+ Optional cityProject = DataProvider.CITY_PROJECT.getById(args[1]);
+ if (cityProject.isEmpty()) return;
- CityProject.setCityProjectName(Integer.parseInt(args[1]), name);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully changed name of City Project with ID " + args[1] + " to '" + name + "'!"));
-
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ String serverName = args[2];
+ if (serverName.length() > 255) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Server name cannot be longer than 255 characters!"));
+ return;
+ }
+ // Check if server exists
+ if (!DataProvider.SERVER.serverExists(serverName)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any server with ID " + serverName + "!"));
+ sendInfo(sender);
+ return;
}
+
+ boolean successful = cityProject.get().setServer(serverName);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully changed server of City Project with ID " + args[1] + " to '" + serverName + "'!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while updating city project server! Check console for any exceptions."));
}
@Override
public String[] getNames() {
- return new String[]{"setname"};
+ return new String[]{"setserver"};
}
@Override
@@ -263,44 +264,41 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"City-ID", "Name"};
+ return new String[]{"City-ID", "Server-Name"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.city.setname";
+ return "plotsystem.admin.pss.city.setserver";
}
}
- public static class CMD_Setup_City_SetDescription extends SubCommand {
- public CMD_Setup_City_SetDescription(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_City_SetBuildTeam extends SubCommand {
+ public CMD_Setup_City_SetBuildTeam(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 2) {sendInfo(sender); return;}
// Check if City Project exits
- try {
- if (CityProject.getCityProjects(false).stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) return;
-
- String description = CMD_Setup.appendArgs(args, 2);
- if (description.length() > 255) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("City Project description cant be longer than 255 characters!"));
- return;
- }
- CityProject.setCityProjectDescription(Integer.parseInt(args[1]), description);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set description of City Project with ID " + args[1] + " to '" + description + "'!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ Optional cityProject = DataProvider.CITY_PROJECT.getById(args[1]);
+ if (cityProject.isEmpty()) return;
+
+ // Check if Build Team exists
+ int buildTeamId = Integer.parseInt(args[2]);
+ if (DataProvider.BUILD_TEAM.getBuildTeam(buildTeamId).isEmpty()) return;
+
+ boolean successful = cityProject.get().setBuildTeam(buildTeamId);
+
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set Build Team of City Project with ID " + args[1] + " to " + buildTeamId + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while updating city project build team! Check console for any exceptions."));
}
@Override
public String[] getNames() {
- return new String[]{"setdescription"};
+ return new String[]{"setbuildteam"};
}
@Override
@@ -310,12 +308,12 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"City-ID", "Description"};
+ return new String[]{"City-ID", "Build-Team-ID"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.city.setdescription";
+ return "plotsystem.admin.pss.city.setbuildteam";
}
}
@@ -326,19 +324,19 @@ public CMD_Setup_City_SetVisible(BaseCommand baseCommand, SubCommand subCommand)
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 2) {sendInfo(sender); return;}
+ String id = args[1];
// Check if City Project exits
- try {
- if (CityProject.getCityProjects(false).stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) return;
- if (!args[2].equalsIgnoreCase("true") && !args[2].equalsIgnoreCase("false")) return;
-
- CityProject.setCityProjectVisibility(Integer.parseInt(args[1]), args[2].equalsIgnoreCase("true"));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set visibility of City Project with ID " + args[1] + " to " + args[2].toUpperCase() + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ Optional cityProject = DataProvider.CITY_PROJECT.getById(id);
+ if (cityProject.isEmpty()) return;
+ if (!args[2].equalsIgnoreCase("true") && !args[2].equalsIgnoreCase("false")) return;
+
+ boolean isVisible = args[2].equalsIgnoreCase("true");
+ boolean successful = cityProject.get().setVisible(isVisible);
+
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set visibility of City Project with ID " + id + " to " + args[2].toUpperCase() + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while updating city project visibility! Check console for any exceptions."));
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Country.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Country.java
index 20353fe42..bd23d1257 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Country.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Country.java
@@ -1,43 +1,21 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin.setup;
-import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Country;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Continent;
+import com.alpsbte.plotsystem.utils.io.LangPaths;
import org.bukkit.command.CommandSender;
-import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
+import java.util.Optional;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
public class CMD_Setup_Country extends SubCommand {
@@ -50,7 +28,7 @@ private void register() {
registerSubCommand(new CMD_Setup_Country_List(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_Country_Add(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_Country_Remove(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_Country_SetHead(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_Country_SetMaterial(getBaseCommand(), this));
}
@Override
@@ -86,22 +64,18 @@ public CMD_Setup_Country_List(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- List countries = Country.getCountries();
+ List countries = DataProvider.COUNTRY.getCountries();
if (countries.isEmpty()) {
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no countries registered in the database!"));
return;
}
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + countries.size() + " Countries registered in the database:"));
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
for (Country c : countries) {
- try {
- sender.sendMessage(" §6> §b" + c.getID() + " (" + c.getName() + ") §f- Server: " + c.getServer().getID() + " (" + c.getServer().getName() + ")");
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ sender.sendMessage(text(" » ", DARK_GRAY).append(text(c.getCode(), AQUA)));
}
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
}
@Override
@@ -132,27 +106,35 @@ public CMD_Setup_Country_Add(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 3 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 3) {sendInfo(sender); return;}
- if (args[2].length() > 45) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Country name cannot be longer than 45 characters!"));
+ String code = args[1];
+ if (code.length() > 2) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Country code cannot be longer than 2 characters!"));
return;
}
Continent continent;
try {
- continent = Continent.valueOf(args[3].toUpperCase());
+ continent = Continent.fromDatabase(args[2].toUpperCase());
+ if (continent == null) {
+ continent = Continent.valueOf(args[2].toUpperCase());
+ }
} catch (IllegalArgumentException e) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat("Unknown continent! " + Arrays.toString(Continent.values())));
return;
}
- try {
- Country.addCountry(Integer.parseInt(args[1]), args[2], continent);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added country!"));
- } catch (SQLException ex) {
+
+ String material = args[3];
+ String customModelData = args.length > 4 ? args[4] : null;
+
+ boolean successful = DataProvider.COUNTRY.addCountry(code, continent, material, customModelData);
+ if (!successful) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ return;
}
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added country!"));
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Edit the " + LangPaths.Database.COUNTRY + "." + code + " language config setting, otherwise name & id will be undefined!"));
}
@Override
@@ -167,7 +149,7 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"Server-ID", "Name", "Continent"};
+ return new String[]{"Code", "Continent", "Material", "CustomModelData?"};
}
@Override
@@ -183,21 +165,18 @@ public CMD_Setup_Country_Remove(BaseCommand baseCommand, SubCommand subCommand)
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 1 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 1) {sendInfo(sender); return;}
+ String code = args[1];
// Check if country exists
- try {
- if (Country.getCountries().stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any country with ID " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- Country.removeCountry(Integer.parseInt(args[1]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed country!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (DataProvider.COUNTRY.getCountryByCode(code).isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any country with code " + code + "!"));
+ sendInfo(sender);
+ return;
}
+ boolean successful = DataProvider.COUNTRY.removeCountry(code);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed country!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -212,7 +191,7 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"Country-ID"};
+ return new String[]{"Country-Code"};
}
@Override
@@ -221,36 +200,38 @@ public String getPermission() {
}
}
- public static class CMD_Setup_Country_SetHead extends SubCommand {
- public CMD_Setup_Country_SetHead(BaseCommand baseCommand, SubCommand subCommand) {
+ public static class CMD_Setup_Country_SetMaterial extends SubCommand {
+ public CMD_Setup_Country_SetMaterial(BaseCommand baseCommand, SubCommand subCommand) {
super(baseCommand, subCommand);
}
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null || AlpsUtils.tryParseInt(args[2]) == null) {
+ if (args.length <= 2) {
sendInfo(sender);
return;
}
+ String code = args[1];
+ String material = args[2];
+ String customModelData = args.length > 3 ? args[3] : null;
+
// Check if country exists
- try {
- if (Country.getCountries().stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any country with name " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- Country.setHeadID(Integer.parseInt(args[1]), Integer.parseInt(args[2]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set head id of country " + args[1] + " to " + args[2] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ Optional country = DataProvider.COUNTRY.getCountryByCode(code);
+ if (country.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any country with code " + code + "!"));
+ sendInfo(sender);
+ return;
}
+
+ boolean successful = country.get().setMaterialAndModelData(material, customModelData);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully updated country with code " + code + "! Material: " + material + " CustomModelData: " + (customModelData == null ? "NULL" : customModelData)));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
public String[] getNames() {
- return new String[]{"sethead"};
+ return new String[]{"setmaterial"};
}
@Override
@@ -260,12 +241,12 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"Country-ID", "Head-ID"};
+ return new String[]{"Country-Code", "Material", "CustomModelData?"};
}
@Override
public String getPermission() {
- return "plotsystem.admin.pss.country.sethead";
+ return "plotsystem.admin.pss.country.setmaterial";
}
}
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Difficulty.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Difficulty.java
index b790aa701..a040cd3a3 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Difficulty.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Difficulty.java
@@ -1,41 +1,20 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin.setup;
import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Difficulty;
import com.alpsbte.plotsystem.utils.Utils;
import org.bukkit.command.CommandSender;
-import java.sql.SQLException;
import java.util.List;
+import java.util.Optional;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
public class CMD_Setup_Difficulty extends SubCommand {
@@ -83,13 +62,15 @@ public CMD_Setup_Difficulty_List(BaseCommand baseCommand, SubCommand subCommand)
@Override
public void onCommand(CommandSender sender, String[] args) {
- List difficulties = Difficulty.getDifficulties();
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + difficulties.size() + " Difficulties registered in the database:"));
- sender.sendMessage("§8--------------------------");
+ List difficulties = DataProvider.DIFFICULTY.getDifficulties();
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
for (Difficulty d : difficulties) {
- sender.sendMessage(" §6> §b" + d.getID() + " (" + d.getDifficulty().name() + ") §f- Multiplier: " + d.getMultiplier() + " - Score Requirement: " + d.getScoreRequirement());
+ sender.sendMessage(text(" » ", DARK_GRAY)
+ .append(text(d.getID(), AQUA))
+ .append(text("Multiplier: " + d.getMultiplier(), WHITE))
+ .append(text(" - Score Requirement: " + d.getScoreRequirement(), WHITE)));
}
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
}
@Override
@@ -120,20 +101,18 @@ public CMD_Setup_Difficulty_SetMultiplier(BaseCommand baseCommand, SubCommand su
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null || AlpsUtils.tryParseDouble(args[2]) == null) {
+ if (args.length <= 2 || AlpsUtils.tryParseDouble(args[2]) == null) {
sendInfo(sender);
return;
}
// Check if difficulty exists
- try {
- if (Difficulty.getDifficulties().stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) return;
- Difficulty.setMultiplier(Integer.parseInt(args[1]), Double.parseDouble(args[2]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set multiplier of Difficulty with ID " + args[1] + " to " + args[2] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ Optional difficulty = DataProvider.DIFFICULTY.getDifficultyById(args[1]);
+ if (difficulty.isEmpty()) return;
+
+ boolean successful = difficulty.get().setMultiplier(Double.parseDouble(args[2]));
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set multiplier of Difficulty with ID " + args[1] + " to " + args[2] + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -164,20 +143,18 @@ public CMD_Setup_Difficulty_SetRequirement(BaseCommand baseCommand, SubCommand s
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null || AlpsUtils.tryParseInt(args[2]) == null) {
+ if (args.length <= 2 || AlpsUtils.tryParseInt(args[2]) == null) {
sendInfo(sender);
return;
}
// Check if difficulty exists
- try {
- if (Difficulty.getDifficulties().stream().noneMatch(c -> c.getID() == Integer.parseInt(args[1]))) return;
- Difficulty.setScoreRequirement(Integer.parseInt(args[1]), Integer.parseInt(args[2]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set score requirement of Difficulty with ID " + args[1] + " to " + args[2] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ Optional difficulty = DataProvider.DIFFICULTY.getDifficultyById(args[1]);
+ if (difficulty.isEmpty()) return;
+
+ boolean successful = difficulty.get().setScoreRequirement(Integer.parseInt(args[2]));
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set score requirement of Difficulty with ID " + args[1] + " to " + args[2] + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_FTP.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_FTP.java
deleted file mode 100644
index 8dfee205e..000000000
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_FTP.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.alpsbte.plotsystem.commands.admin.setup;
-
-import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.commands.BaseCommand;
-import com.alpsbte.plotsystem.commands.SubCommand;
-import com.alpsbte.plotsystem.core.system.FTPConfiguration;
-import com.alpsbte.plotsystem.utils.Utils;
-import org.bukkit.command.CommandSender;
-
-import java.sql.SQLException;
-import java.util.List;
-
-import static net.kyori.adventure.text.Component.text;
-
-public class CMD_Setup_FTP extends SubCommand {
-
- public CMD_Setup_FTP(BaseCommand baseCommand) {
- super(baseCommand);
- register();
- }
-
- private void register() {
- registerSubCommand(new CMD_Setup_FTP_List(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_FTP_Add(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_FTP_Remove(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_FTP_SetPath(getBaseCommand(), this));
- }
-
- @Override
- public void onCommand(CommandSender sender, String[] args) {
- sendInfo(sender);
- }
-
- @Override
- public String[] getNames() {
- return new String[]{"ftp"};
- }
-
- @Override
- public String getDescription() {
- return "Configure SFTP/FTP configurations";
- }
-
- @Override
- public String[] getParameter() {
- return new String[0];
- }
-
- @Override
- public String getPermission() {
- return "plotsystem.admin.pss.ftp";
- }
-
-
- public static class CMD_Setup_FTP_List extends SubCommand {
- public CMD_Setup_FTP_List(BaseCommand baseCommand, SubCommand subCommand) {
- super(baseCommand, subCommand);
- }
-
- @Override
- public void onCommand(CommandSender sender, String[] args) {
- List ftpConfigs = FTPConfiguration.getFTPConfigurations();
- if (ftpConfigs.isEmpty()) {
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no FTP Configurations registered in the database!"));
- return;
- }
-
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + ftpConfigs.size() + " FTP-Configurations registered in the database:"));
- sender.sendMessage("§8--------------------------");
- for (FTPConfiguration ftp : ftpConfigs) {
- sender.sendMessage(" §6> §b" + ftp.getID() + " §f- Address: " + ftp.getAddress() + " - Port: " + ftp.getPort() + " - SFTP: " + (ftp.isSFTP() ? "True" : "False") + " - Username: " + getCensorString(ftp.getUsername().length()) + " - Password: " + getCensorString(ftp.getPassword().length()) + " - Path: " + ftp.getSchematicPath());
- }
- sender.sendMessage("§8--------------------------");
- }
-
- @Override
- public String[] getNames() {
- return new String[]{"list"};
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public String[] getParameter() {
- return new String[0];
- }
-
- @Override
- public String getPermission() {
- return "plotsystem.admin.pss.ftp.list";
- }
-
- public String getCensorString(int length) {
- StringBuilder output = new StringBuilder();
- for (int i = 0; i < length; i++) {
- output.append("*");
- }
- return output.toString();
- }
- }
-
- public static class CMD_Setup_FTP_Add extends SubCommand {
- public CMD_Setup_FTP_Add(BaseCommand baseCommand, SubCommand subCommand) {
- super(baseCommand, subCommand);
- }
-
- @Override
- public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 5 || AlpsUtils.tryParseInt(args[2]) == null) {sendInfo(sender); return;}
- if (!args[3].equalsIgnoreCase("true") && !args[3].equalsIgnoreCase("false")) return;
- if (args[1].toLowerCase().startsWith("sftp:") || args[1].toLowerCase().startsWith("ftp:")) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Please remove the protocol URL from the host address!"));
- return;
- }
- try {
- FTPConfiguration.addFTPConfiguration(args[1], Integer.parseInt(args[2]), args[3].equalsIgnoreCase("true"), args[4], args[5]);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added FTP-Configuration!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- }
-
- @Override
- public String[] getNames() {
- return new String[]{"add"};
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public String[] getParameter() {
- return new String[]{"Address", "Port", "isSFTP (True/False)", "Username", "Password"};
- }
-
- @Override
- public String getPermission() {
- return "plotsystem.admin.pss.ftp.add";
- }
- }
-
- public static class CMD_Setup_FTP_Remove extends SubCommand {
- public CMD_Setup_FTP_Remove(BaseCommand baseCommand, SubCommand subCommand) {
- super(baseCommand, subCommand);
- }
-
- @Override
- public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 1 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
-
- // Check if ftp config exists
- try {
- if (FTPConfiguration.getFTPConfigurations().stream().noneMatch(f -> f.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any FTP-Configurations with ID " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- FTPConfiguration.removeFTPConfiguration(Integer.parseInt(args[1]));
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed FTP-Configuration!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- }
-
- @Override
- public String[] getNames() {
- return new String[]{"remove"};
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public String[] getParameter() {
- return new String[]{"FTP-ID"};
- }
-
- @Override
- public String getPermission() {
- return "plotsystem.admin.pss.ftp.remove";
- }
- }
-
- public static class CMD_Setup_FTP_SetPath extends SubCommand {
- public CMD_Setup_FTP_SetPath(BaseCommand baseCommand, SubCommand subCommand) {
- super(baseCommand, subCommand);
- }
-
- @Override
- public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
-
- // Check if ftp config exists
- try {
- if (FTPConfiguration.getFTPConfigurations().stream().noneMatch(f -> f.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any FTP-Configurations with ID " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- FTPConfiguration.setSchematicPath(Integer.parseInt(args[1]), args[2]);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set path of FTP-Configuration " + args[1] + " to " + args[2] + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- }
-
- @Override
- public String[] getNames() {
- return new String[]{"setpath"};
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public String[] getParameter() {
- return new String[]{"FTP-ID", "Path"};
- }
-
- @Override
- public String getPermission() {
- return "plotsystem.admin.pss.ftp.setpath";
- }
- }
-}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_ReviewCriteria.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_ReviewCriteria.java
new file mode 100644
index 000000000..ef05a1f04
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_ReviewCriteria.java
@@ -0,0 +1,233 @@
+package com.alpsbte.plotsystem.commands.admin.setup;
+
+import com.alpsbte.plotsystem.commands.BaseCommand;
+import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.system.review.ToggleCriteria;
+import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.io.LangPaths;
+import org.bukkit.command.CommandSender;
+
+import java.util.List;
+import java.util.Optional;
+
+import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+
+public class CMD_Setup_ReviewCriteria extends SubCommand {
+ public CMD_Setup_ReviewCriteria(BaseCommand baseCommand) {
+ super(baseCommand);
+ registerSubCommand(new CMD_Setup_ReviewCriteria_List(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_ReviewCriteria_Add(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_ReviewCriteria_Remove(getBaseCommand(), this));
+ registerSubCommand(new CMD_Setup_ReviewCriteria_SetOptional(getBaseCommand(), this));
+ }
+
+ @Override
+ public void onCommand(CommandSender sender, String[] args) {
+ sendInfo(sender);
+ }
+
+ @Override
+ public String[] getNames() {
+ return new String[]{"review"};
+ }
+
+ @Override
+ public String getDescription() {
+ return "Configure review criteria";
+ }
+
+ @Override
+ public String[] getParameter() {
+ return new String[0];
+ }
+
+ @Override
+ public String getPermission() {
+ return "plotsystem.admin.pss.review";
+ }
+
+ public static class CMD_Setup_ReviewCriteria_List extends SubCommand {
+
+ public CMD_Setup_ReviewCriteria_List(BaseCommand baseCommand, SubCommand subCommand) {
+ super(baseCommand, subCommand);
+ }
+
+ @Override
+ public void onCommand(CommandSender sender, String[] args) {
+ List criteria = DataProvider.REVIEW.getAllToggleCriteria();
+ if (criteria.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no toggle criteria registered in the database!"));
+ return;
+ }
+
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + criteria.size() + " toggle criteria registered in the database:"));
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
+ for (ToggleCriteria c : criteria) {
+ sender.sendMessage(text(" » ", DARK_GRAY)
+ .append(text(c.criteriaName() + " (" + (c.isOptional() ? "optional" : "required") + ")")));
+ }
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
+ }
+
+ @Override
+ public String[] getNames() {
+ return new String[]{"list"};
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public String[] getParameter() {
+ return new String[0];
+ }
+
+ @Override
+ public String getPermission() {
+ return "plotsystem.admin.pss.review.list";
+ }
+ }
+
+ public static class CMD_Setup_ReviewCriteria_Add extends SubCommand {
+ public CMD_Setup_ReviewCriteria_Add(BaseCommand baseCommand, SubCommand subCommand) {
+ super(baseCommand, subCommand);
+ }
+
+ @Override
+ public void onCommand(CommandSender sender, String[] args) {
+ if (args.length <= 2) {sendInfo(sender); return;}
+
+ String name = args[1];
+ if (name.length() > 255) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Toggle criteria name cannot be longer than 255 characters!"));
+ return;
+ }
+
+ boolean isOptional = args[2].equalsIgnoreCase("true");
+
+ boolean successful = DataProvider.REVIEW.addToggleCriteria(name, isOptional);
+ if (!successful) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
+ return;
+ }
+
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added country!"));
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Edit the " + LangPaths.Database.TOGGLE_CRITERIA + "." + name + " language config setting, otherwise the name will be the ID of the Toggle Criteria & no description will be present!"));
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added toggle criteria with name '" + name + "'!"));
+ }
+
+ @Override
+ public String[] getNames() {
+ return new String[]{"add"};
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public String[] getParameter() {
+ return new String[]{"Name","Is-Optional"};
+ }
+
+ @Override
+ public String getPermission() {
+ return "plotsystem.admin.pss.review.add";
+ }
+ }
+
+ public static class CMD_Setup_ReviewCriteria_Remove extends SubCommand {
+ public CMD_Setup_ReviewCriteria_Remove(BaseCommand baseCommand, SubCommand subCommand) {
+ super(baseCommand, subCommand);
+ }
+
+ @Override
+ public void onCommand(CommandSender sender, String[] args) {
+ if (args.length <= 1) {sendInfo(sender); return;}
+ String name = args[1];
+
+ // Check if criteria exists
+ Optional criteria = DataProvider.REVIEW.getToggleCriteria(name);
+ if (criteria.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any toggle criteria with name " + name + "!"));
+ sendInfo(sender);
+ return;
+ }
+
+ boolean successful = DataProvider.REVIEW.removeToggleCriteria(criteria.get().criteriaName());
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed toggle criteria with name " + name + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
+ }
+
+ @Override
+ public String[] getNames() {
+ return new String[]{"remove"};
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public String[] getParameter() {
+ return new String[]{"Name"};
+ }
+
+ @Override
+ public String getPermission() {
+ return "plotsystem.admin.pss.review.remove";
+ }
+ }
+
+ public static class CMD_Setup_ReviewCriteria_SetOptional extends SubCommand {
+ public CMD_Setup_ReviewCriteria_SetOptional(BaseCommand baseCommand, SubCommand subCommand) {
+ super(baseCommand, subCommand);
+ }
+
+ @Override
+ public void onCommand(CommandSender sender, String[] args) {
+ if (args.length <= 2) {sendInfo(sender); return;}
+ String name = args[1];
+
+ // Check if criteria exits
+ Optional criteria = DataProvider.REVIEW.getToggleCriteria(name);
+ if (criteria.isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Toggle criteria could not be found!"));
+ return;
+ }
+
+
+ boolean isOptional = args[2].equalsIgnoreCase("true");
+
+ boolean successful = DataProvider.REVIEW.setToggleCriteriaOptional(name, isOptional);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully changed optionality of toggle criteria with name " + name + " to '" + isOptional + "'!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
+ }
+
+ @Override
+ public String[] getNames() {
+ return new String[]{"setoptional"};
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public String[] getParameter() {
+ return new String[]{"Name", "Is-Optional"};
+ }
+
+ @Override
+ public String getPermission() {
+ return "plotsystem.admin.pss.buildteam.setoptional";
+ }
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Server.java b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Server.java
index 16cfb6bb3..f80821133 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Server.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/admin/setup/CMD_Setup_Server.java
@@ -1,47 +1,17 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.admin.setup;
import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
-import com.alpsbte.plotsystem.core.system.FTPConfiguration;
-import com.alpsbte.plotsystem.core.system.Server;
-import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.utils.Utils;
-import org.apache.commons.io.FileUtils;
import org.bukkit.command.CommandSender;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.sql.SQLException;
import java.util.List;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
public class CMD_Setup_Server extends SubCommand {
@@ -54,7 +24,6 @@ private void register() {
registerSubCommand(new CMD_Setup_Server_List(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_Server_Add(getBaseCommand(), this));
registerSubCommand(new CMD_Setup_Server_Remove(getBaseCommand(), this));
- registerSubCommand(new CMD_Setup_Server_SetFTP(getBaseCommand(), this));
}
@Override
@@ -90,22 +59,18 @@ public CMD_Setup_Server_List(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- List servers = Server.getServers();
+ List servers = DataProvider.SERVER.getServers();
if (servers.isEmpty()) {
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently no Servers registered in the database!"));
return;
}
sender.sendMessage(Utils.ChatUtils.getInfoFormat("There are currently " + servers.size() + " Servers registered in the database:"));
- sender.sendMessage("§8--------------------------");
- for (Server s : servers) {
- try {
- sender.sendMessage(" §6> §b" + s.getID() + " (" + s.getName() + ") §f- FTP-Configuration: " + (s.getFTPConfiguration() == null ? "None" : s.getFTPConfiguration().getID()));
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ for (String server : servers) {
+ sender.sendMessage(text(" » ", DARK_GRAY).append(text(server, AQUA)));
}
- sender.sendMessage("§8--------------------------");
+ sender.sendMessage(text("--------------------------", DARK_GRAY));
}
@Override
@@ -136,23 +101,24 @@ public CMD_Setup_Server_Add(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 1) {sendInfo(sender); return;}
- if (args[1].length() > 45) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Server name cannot be longer than 45 characters!"));
+ if (args.length <= 2 || AlpsUtils.tryParseInt(args[2]) == null) {sendInfo(sender); return;}
+
+ String serverName = args[1];
+ if (serverName.length() > 255) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Server name cannot be longer than 255 characters!"));
sendInfo(sender);
return;
}
- try {
- Server server = Server.addServer(args[1]);
- Path serverPath = Paths.get(PlotUtils.getDefaultSchematicPath(), String.valueOf(server.getID()));
- if (serverPath.toFile().exists()) FileUtils.deleteDirectory(serverPath.toFile());
- if (!serverPath.toFile().mkdirs()) throw new IOException();
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added server!"));
- } catch (SQLException | IOException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ int buildTeamId = AlpsUtils.tryParseInt(args[2]);
+ if (DataProvider.BUILD_TEAM.getBuildTeam(buildTeamId).isEmpty()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Build team with id " + buildTeamId + " could not be found!"));
+ return;
}
+
+ boolean successful = DataProvider.SERVER.addServer(serverName, buildTeamId);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully added server!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -167,7 +133,7 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"Name"};
+ return new String[]{"Name", "BuildTeamId"};
}
@Override
@@ -183,23 +149,19 @@ public CMD_Setup_Server_Remove(BaseCommand baseCommand, SubCommand subCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 1 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
+ if (args.length <= 1) {sendInfo(sender); return;}
+ String name = args[1];
// Check if server exists
- try {
- if (Server.getServers().stream().noneMatch(s -> s.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any server with ID " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- Server.removeServer(Integer.parseInt(args[1]));
- Path serverPath = Paths.get(PlotUtils.getDefaultSchematicPath(), args[1]);
- if (serverPath.toFile().exists()) FileUtils.deleteDirectory(serverPath.toFile());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed server with ID " + args[1] + "!"));
- } catch (SQLException | IOException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (!DataProvider.SERVER.serverExists(name)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any server with name " + name + "!"));
+ sendInfo(sender);
+ return;
}
+
+ boolean successful = DataProvider.SERVER.removeServer(name);
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully removed server with name " + name + "!"));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command! Check console for any exceptions."));
}
@Override
@@ -214,7 +176,7 @@ public String getDescription() {
@Override
public String[] getParameter() {
- return new String[]{"Server-ID"};
+ return new String[]{"Name"};
}
@Override
@@ -222,55 +184,4 @@ public String getPermission() {
return "plotsystem.admin.pss.server.remove";
}
}
-
- public static class CMD_Setup_Server_SetFTP extends SubCommand {
- public CMD_Setup_Server_SetFTP(BaseCommand baseCommand, SubCommand subCommand) {
- super(baseCommand, subCommand);
- }
-
- @Override
- public void onCommand(CommandSender sender, String[] args) {
- if (args.length <= 2 || AlpsUtils.tryParseInt(args[1]) == null) {sendInfo(sender); return;}
-
- // Check if server exists
- try {
- if (Server.getServers().stream().noneMatch(s -> s.getID() == Integer.parseInt(args[1]))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any server with ID " + args[1] + "!"));
- sendInfo(sender);
- return;
- }
- if (!args[2].equalsIgnoreCase("none") && (AlpsUtils.tryParseInt(args[2]) == null || FTPConfiguration.getFTPConfigurations().stream().noneMatch(f -> f.getID() == Integer.parseInt(args[2])))) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("Could not find any ftp configurations with ID " + args[2] + "!"));
- sendInfo(sender);
- return;
- }
- int ftpID = AlpsUtils.tryParseInt(args[2]) != null ? Integer.parseInt(args[2]) : -1;
- Server.setFTP(Integer.parseInt(args[1]), ftpID);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat("Successfully set FTP Configuration of server with ID " + args[1] + " to " + (ftpID == -1 ? "None" : ftpID) + "!"));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- }
-
- @Override
- public String[] getNames() {
- return new String[]{"setftp"};
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public String[] getParameter() {
- return new String[]{"Server-ID", "FTP-ID/None"};
- }
-
- @Override
- public String getPermission() {
- return "plotsystem.admin.pss.server.setftp";
- }
- }
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot.java
index 825ba9eb0..37935dbcb 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot.java
@@ -1,30 +1,8 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2021, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
+import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
+import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@@ -37,10 +15,12 @@ public CMD_Plot() {
registerSubCommand(new CMD_Plot_Links(this));
registerSubCommand(new CMD_Plot_Submit(this));
registerSubCommand(new CMD_Plot_Abandon(this));
- registerSubCommand(new CMD_Plot_Invite(this));
+ if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.ENABLE_GROUP_SUPPORT)) {
+ registerSubCommand(new CMD_Plot_Invite(this));
+ registerSubCommand(new CMD_Plot_Members(this));
+ }
registerSubCommand(new CMD_Plot_Feedback(this));
registerSubCommand(new CMD_Plot_UndoSubmit(this));
- registerSubCommand(new CMD_Plot_Members(this));
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Abandon.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Abandon.java
index 75b4490da..7dd10f9a1 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Abandon.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Abandon.java
@@ -1,33 +1,10 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
@@ -35,14 +12,12 @@
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
import com.alpsbte.plotsystem.utils.io.LangPaths;
+import com.alpsbte.plotsystem.utils.io.LangUtil;
+import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.jetbrains.annotations.Nullable;
-
-import java.sql.SQLException;
-import java.util.Objects;
-import static net.kyori.adventure.text.Component.text;
+import java.util.concurrent.CompletableFuture;
public class CMD_Plot_Abandon extends SubCommand {
@@ -52,42 +27,52 @@ public CMD_Plot_Abandon(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- @Nullable Player player = getPlayer(sender);
- try {
+ CompletableFuture.runAsync(() -> {
Plot plot;
+ if (!(sender instanceof Player player)) {
+ sendInfo(sender);
+ return;
+ }
+
if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- if (PlotUtils.plotExists(plotID)) {
- plot = new Plot(plotID);
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return;
- }
- } else if (player != null && PlotUtils.isPlotWorld(player.getWorld())) {
+ plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ } else if (PlotUtils.isPlotWorld(player.getWorld())) {
AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished);
- if (p instanceof Plot) {
- plot = (Plot) p;
- } else {
+ if (!(p instanceof Plot)) {
sendInfo(sender);
return;
}
+ plot = (Plot) p;
} else {
sendInfo(sender);
return;
}
- if (Objects.requireNonNull(plot).getStatus() == Status.unfinished) {
- if (Utils.isOwnerOrReviewer(sender, player, plot) && PlotUtils.Actions.abandonPlot(plot)) {
- sender.sendMessage(Utils.ChatUtils.getInfoFormat(langUtil.get(sender, LangPaths.Message.Info.ABANDONED_PLOT, plot.getID() + "")));
- if (player != null) player.playSound(player.getLocation(), Utils.SoundUtils.ABANDON_PLOT_SOUND, 1, 1);
- }
- } else {
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
+ if (!Utils.isOwnerOrReviewer(sender, player, plot)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_IS_NOT_ALLOWED)));
+ return;
+ }
+ if (plot.getStatus() != Status.unfinished) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.CAN_ONLY_ABANDON_UNFINISHED_PLOTS)));
+ return;
}
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.CANNOT_MODIFY_LEGACY_PLOT)));
+ return;
+ }
+
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ if (PlotUtils.Actions.abandonPlot(plot)) {
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat(langUtil.get(sender, LangPaths.Message.Info.ABANDONED_PLOT, plot.getId() + "")));
+ player.playSound(player.getLocation(), Utils.SoundUtils.ABANDON_PLOT_SOUND, 1, 1);
+ }
+ });
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Feedback.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Feedback.java
index 0af9373da..1c298ed39 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Feedback.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Feedback.java
@@ -1,33 +1,10 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.FeedbackMenu;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
@@ -39,9 +16,9 @@
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
-import java.sql.SQLException;
-import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
@@ -53,46 +30,44 @@ public CMD_Plot_Feedback(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- try {
- if (getPlayer(sender) != null) {
- Plot plot;
- if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- if (PlotUtils.plotExists(plotID)) {
- plot = new Plot(plotID);
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return;
- }
- } else if (PlotUtils.isPlotWorld(getPlayer(sender).getWorld())) {
- AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(getPlayer(sender).getUniqueId()), Status.completed);
- if (p instanceof Plot) {
- plot = (Plot) p;
- } else {
- sendInfo(sender);
- return;
- }
- } else {
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
+
+ CompletableFuture.runAsync(() -> {
+ Plot plot;
+ if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
+ plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ } else if (PlotUtils.isPlotWorld(player.getWorld())) {
+ AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished);
+ if (!(p instanceof Plot)) {
sendInfo(sender);
return;
}
-
- if (Objects.requireNonNull(plot).getPlotOwner().getUUID().equals(getPlayer(sender).getUniqueId()) || plot.getPlotMembers().stream().anyMatch(m -> m.getUUID().equals(getPlayer(sender).getUniqueId())) || getPlayer(sender).hasPermission("plotsystem.plot.review")) {
- if (plot.isReviewed()) {
- new FeedbackMenu(getPlayer(sender), plot.getID());
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_HAS_NOT_YET_REVIEWED)));
- }
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
- }
+ plot = (Plot) p;
} else {
- Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ sendInfo(sender);
+ return;
}
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
+ if (!plot.getPlotOwner().getUUID().equals(player.getUniqueId())
+ && plot.getPlotMembers().stream().noneMatch(m -> m.getUUID().equals(player.getUniqueId())) && !player.hasPermission("plotsystem.plot.review")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
+ if (!plot.isReviewed()) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_HAS_NOT_YET_REVIEWED)));
+ return;
+ }
+
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new FeedbackMenu(player, plot.getId()));
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Invite.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Invite.java
index 6c7ad6236..402b0578e 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Invite.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Invite.java
@@ -1,40 +1,14 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
-import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.utils.PlotMemberInvitation;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
-import org.bukkit.configuration.file.FileConfiguration;
-
-import java.sql.SQLException;
+import org.bukkit.entity.Player;
import static net.kyori.adventure.text.Component.text;
@@ -46,40 +20,43 @@ public CMD_Plot_Invite(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- if (args.length > 0) {
- FileConfiguration config = PlotSystem.getPlugin().getConfig();
- if (getPlayer(sender) != null && config.getBoolean(ConfigPaths.ENABLE_GROUP_SUPPORT)) {
- PlotMemberInvitation invite = null;
- for (PlotMemberInvitation item : PlotMemberInvitation.invitationsList) {
- if (item.invitee.getUniqueId().toString().equals(getPlayer(sender).getUniqueId().toString())) {
- invite = item;
- try {
- switch (args[0]) {
- case "accept":
- item.acceptInvite();
- break;
- case "reject":
- item.rejectInvite();
- break;
- default:
- sendInfo(sender);
- break;
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- }
- }
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
- if (invite != null) {
- PlotMemberInvitation.invitationsList.remove(invite);
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_INVITATIONS)));
- }
- }
- } else {
+ if (args.length == 0) {
sendInfo(sender);
+ return;
+ }
+
+ PlotMemberInvitation invite = null;
+ for (PlotMemberInvitation item : PlotMemberInvitation.invitationsList) {
+ if (!item.invitee.getUniqueId().toString().equals(player.getUniqueId().toString())) {
+ continue;
+ }
+
+ invite = item;
+ switch (args[0]) {
+ case "accept":
+ item.acceptInvite();
+ break;
+ case "reject":
+ item.rejectInvite();
+ break;
+ default:
+ sendInfo(sender);
+ break;
+ }
}
+
+ if (invite == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_INVITATIONS)));
+ return;
+ }
+
+ PlotMemberInvitation.invitationsList.remove(invite);
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Links.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Links.java
index 955eec374..b3dfddaeb 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Links.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Links.java
@@ -1,33 +1,9 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
@@ -37,8 +13,9 @@
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
-import java.sql.SQLException;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
@@ -50,26 +27,35 @@ public CMD_Plot_Links(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- try {
- if (getPlayer(sender) != null) {
- if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- if (PlotUtils.plotExists(plotID)) {
- PlotUtils.ChatFormatting.sendLinkMessages(new Plot(plotID), getPlayer(sender));
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- }
- } else if (PlotUtils.isPlotWorld(getPlayer(sender).getWorld())) {
- PlotUtils.ChatFormatting.sendLinkMessages(PlotUtils.getCurrentPlot(Builder.byUUID(getPlayer(sender).getUniqueId()), Status.unfinished, Status.unreviewed), getPlayer(sender));
- } else {
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
+
+ CompletableFuture.runAsync(() -> {
+ Builder builder = Builder.byUUID(player.getUniqueId());
+ if (args.length == 0) {
+ if (!PlotUtils.isPlotWorld(player.getWorld())) {
sendInfo(sender);
+ return;
}
- } else {
- Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ PlotUtils.ChatFormatting.sendLinkMessages(PlotUtils.getCurrentPlot(builder, Status.unfinished, Status.unreviewed), player);
+ return;
}
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ if (AlpsUtils.tryParseInt(args[0]) == null) {
+ sendInfo(sender);
+ return;
+ }
+ Plot plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
+
+ PlotUtils.ChatFormatting.sendLinkMessages(plot, player);
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Members.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Members.java
index e60229fb5..3b61e769c 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Members.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Members.java
@@ -1,33 +1,10 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.PlotMemberMenu;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
@@ -35,12 +12,14 @@
import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
+import com.alpsbte.plotsystem.utils.io.LangPaths;
+import com.alpsbte.plotsystem.utils.io.LangUtil;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
-import java.sql.SQLException;
-import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
@@ -52,45 +31,60 @@ public CMD_Plot_Members(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- try {
- if (getPlayer(sender) != null) {
- Plot plot;
- // Get Plot
- if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- //plot members
- int plotID = Integer.parseInt(args[0]);
- if (PlotUtils.plotExists(plotID)) {
- plot = new Plot(plotID);
- } else {
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
+
+ CompletableFuture.runAsync(() -> {
+ Plot plot;
+
+ // Use tryParseInt result (avoids double parsing) and handle null safely
+ if (args.length > 0) {
+ Integer id = AlpsUtils.tryParseInt(args[0]);
+ if (id != null) {
+ plot = DataProvider.PLOT.getPlotById(id);
+ if (plot == null) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat("This plot does not exist!"));
return;
}
- } else if (PlotUtils.isPlotWorld(getPlayer(sender).getWorld())) {
- //plot members
- AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(getPlayer(sender).getUniqueId()), Status.unfinished, Status.unreviewed);
- if (p instanceof Plot) {
- plot = (Plot) p;
- } else {
- sendInfo(sender);
- return;
- }
} else {
- sendInfo(sender);
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("Invalid plot ID."));
return;
}
-
- if (Objects.requireNonNull(plot).getPlotOwner().getUUID().equals(getPlayer(sender).getUniqueId()) || getPlayer(sender).hasPermission("plotsystem.admin")) {
- new PlotMemberMenu(plot, getPlayer(sender));
+ } else if (PlotUtils.isPlotWorld(player.getWorld())) {
+ AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished, Status.unreviewed);
+ if (p instanceof Plot pl) {
+ plot = pl;
} else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("You don't have permission to manage this plot's members!"));
+ sendInfo(sender);
+ return;
}
} else {
- Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ sendInfo(sender);
+ return;
}
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat("An error occurred while executing command!"));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ // Guard against missing owner data
+ if (plot.getPlotOwner() == null || plot.getPlotOwner().getUUID() == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("This plot has no owner assigned. Contact an admin."));
+ return;
+ }
+
+ if (!plot.getPlotOwner().getUUID().equals(player.getUniqueId()) && !player.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat("You don't have permission to manage this plot's members!"));
+ return;
+ }
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.CANNOT_MODIFY_LEGACY_PLOT)));
+ return;
+ }
+
+ // Switch to main thread for menu creation (GUI operations must be on main thread)
+ Plot finalPlot = plot;
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new PlotMemberMenu(finalPlot, player));
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Submit.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Submit.java
index 9b992572d..dd24a910f 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Submit.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Submit.java
@@ -1,33 +1,10 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
@@ -35,12 +12,15 @@
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
import com.alpsbte.plotsystem.utils.io.LangPaths;
+import com.alpsbte.plotsystem.utils.io.LangUtil;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.jetbrains.annotations.Nullable;
-import java.sql.SQLException;
+import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
@@ -52,58 +32,68 @@ public CMD_Plot_Submit(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- try {
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
+
+ CompletableFuture.runAsync(() -> {
Plot plot;
- @Nullable Player player = getPlayer(sender);
if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- if (PlotUtils.plotExists(plotID)) {
- plot = new Plot(plotID);
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return;
- }
- } else if (player != null && PlotUtils.isPlotWorld(player.getWorld())) {
- AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()));
- if (p instanceof Plot) {
- plot = (Plot) p;
- } else {
+ plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ } else if (PlotUtils.isPlotWorld(player.getWorld())) {
+ AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished);
+ if (!(p instanceof Plot)) {
sendInfo(sender);
return;
}
+ plot = (Plot) p;
} else {
sendInfo(sender);
return;
}
- if (Utils.isOwnerOrReviewer(sender, player, plot)) {
- if (Objects.requireNonNull(plot).getStatus() == Status.unfinished) {
- PlotUtils.Actions.submitPlot(plot);
-
- if (plot.getPlotMembers().isEmpty()) {
- // Plot was made alone
- langUtil.broadcast(LangPaths.Message.Info.FINISHED_PLOT, String.valueOf(plot.getID()), plot.getPlotOwner().getName());
- } else {
- // Plot was made in a group
- StringBuilder sb = new StringBuilder(plot.getPlotOwner().getName() + ", ");
-
- for (int i = 0; i < plot.getPlotMembers().size(); i++) {
- sb.append(i == plot.getPlotMembers().size() - 1 ?
- plot.getPlotMembers().get(i).getName() :
- plot.getPlotMembers().get(i).getName() + ", ");
- }
- langUtil.broadcast(LangPaths.Message.Info.FINISHED_PLOT, String.valueOf(plot.getID()), sb.toString());
- }
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
+ if (!Utils.isOwnerOrReviewer(sender, player, plot)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_IS_NOT_ALLOWED)));
+ return;
+ }
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_MODIFY_LEGACY_PLOT)));
+ return;
+ }
+ if (plot.getStatus() != Status.unfinished) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.CAN_ONLY_SUBMIT_UNFINISHED_PLOTS)));
+ return;
+ }
+
+ List plotMembers = plot.getPlotMembers();
+
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
- if (player != null) player.playSound(player.getLocation(), Utils.SoundUtils.FINISH_PLOT_SOUND, 1, 1);
+ PlotUtils.Actions.submitPlot(plot);
+ if (plotMembers.isEmpty()) {
+ // Plot was made alone
+ langUtil.broadcast(LangPaths.Message.Info.FINISHED_PLOT, String.valueOf(plot.getId()), plot.getPlotOwner().getName());
} else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.CAN_ONLY_SUBMIT_UNFINISHED_PLOTS)));
+ // Plot was made in a group
+ StringBuilder sb = new StringBuilder(plot.getPlotOwner().getName() + ", ");
+
+ for (int i = 0; i < plotMembers.size(); i++) {
+ sb.append(i == plotMembers.size() - 1 ?
+ plotMembers.get(i).getName() :
+ plotMembers.get(i).getName() + ", ");
+ }
+ langUtil.broadcast(LangPaths.Message.Info.FINISHED_PLOT, String.valueOf(plot.getId()), sb.toString());
}
- }
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ Objects.requireNonNull(player).playSound(player.getLocation(), Utils.SoundUtils.FINISH_PLOT_SOUND, 1, 1);
+ });
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Teleport.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Teleport.java
index 0ce04f455..b4c9033bc 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Teleport.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_Teleport.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
@@ -29,20 +5,22 @@
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.ICommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.core.system.plot.generator.DefaultPlotGenerator;
-import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
import com.alpsbte.plotsystem.utils.io.LangPaths;
+import com.alpsbte.plotsystem.utils.io.LangUtil;
+import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
-import java.sql.SQLException;
-
-import static net.kyori.adventure.text.Component.text;
+import java.util.concurrent.CompletableFuture;
public class CMD_Plot_Teleport extends SubCommand implements ICommand {
@@ -52,30 +30,45 @@ public CMD_Plot_Teleport(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- try {
- if (getPlayer(sender) != null) {
- if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- Plot plot;
- if (PlotUtils.plotExists(plotID) && (plot = new Plot(plotID)).getStatus() != Status.unclaimed) {
- plot.getWorld().teleportPlayer(getPlayer(sender));
- } else {
- if (sender.hasPermission("plotsystem.admin") && PlotUtils.plotExists(plotID)) {
- new DefaultPlotGenerator(new Plot(plotID), Builder.byUUID(getPlayer(sender).getUniqueId()));
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- }
- }
- } else {
- sendInfo(sender);
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
+
+ if (args.length == 0 || AlpsUtils.tryParseInt(args[0]) == null) {
+ sendInfo(sender);
+ return;
+ }
+
+ int plotID = Integer.parseInt(args[0]);
+
+ CompletableFuture.runAsync(() -> {
+ Plot plot = DataProvider.PLOT.getPlotById(plotID);
+
+ if (plot != null && plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_LOAD_LEGACY_PLOT)));
+ return;
+ }
+
+ if (plot == null || plot.getStatus() == Status.unclaimed) {
+ if (!sender.hasPermission("plotsystem.admin") || plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
+
+ Builder builder = Builder.byUUID(player.getUniqueId());
+ if (builder == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
+ return;
}
- } else {
- Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new DefaultPlotGenerator(plot, builder));
+ return;
}
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> plot.getWorld().teleportPlayer(player));
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_UndoSubmit.java b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_UndoSubmit.java
index a284bb2ee..a9b89bb9c 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_UndoSubmit.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/plot/CMD_Plot_UndoSubmit.java
@@ -1,33 +1,10 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.plot;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
import com.alpsbte.plotsystem.commands.SubCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
@@ -35,12 +12,13 @@
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
import com.alpsbte.plotsystem.utils.io.LangPaths;
+import com.alpsbte.plotsystem.utils.io.LangUtil;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import org.jetbrains.annotations.Nullable;
-import java.sql.SQLException;
-import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
@@ -52,43 +30,51 @@ public CMD_Plot_UndoSubmit(BaseCommand baseCommand) {
@Override
public void onCommand(CommandSender sender, String[] args) {
- try {
+ if (!(sender instanceof Player player)) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ return;
+ }
+
+ CompletableFuture.runAsync(() -> {
Plot plot;
- @Nullable Player player = getPlayer(sender);
if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- if (PlotUtils.plotExists(plotID)) {
- plot = new Plot(plotID);
- } else {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return;
- }
- } else if (player != null && PlotUtils.isPlotWorld(player.getWorld())) {
- AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unreviewed);
- if (p instanceof Plot) {
- plot = (Plot) p;
- } else {
+ plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ } else if (PlotUtils.isPlotWorld(player.getWorld())) {
+ AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished);
+ if (!(p instanceof Plot)) {
sendInfo(sender);
return;
}
+ plot = (Plot) p;
} else {
sendInfo(sender);
return;
}
- if (Objects.requireNonNull(plot).getStatus() == Status.unreviewed) {
- if (Utils.isOwnerOrReviewer(sender, player, plot)) {
- PlotUtils.Actions.undoSubmit(plot);
- sender.sendMessage(Utils.ChatUtils.getInfoFormat(langUtil.get(sender, LangPaths.Message.Info.UNDID_SUBMISSION, plot.getID() + "")));
- if (player != null) player.playSound(player.getLocation(), Utils.SoundUtils.FINISH_PLOT_SOUND, 1, 1);
- }
- } else {
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
+ if (!Utils.isOwnerOrReviewer(sender, player, plot)) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLAYER_IS_NOT_ALLOWED)));
+ return;
+ }
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_MODIFY_LEGACY_PLOT)));
+ return;
+ }
+ if (plot.getStatus() != Status.unreviewed) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.CAN_ONLY_UNDO_SUBMISSIONS_UNREVIEWED_PLOTS)));
+ return;
}
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ PlotUtils.Actions.undoSubmit(plot);
+
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat(langUtil.get(sender, LangPaths.Message.Info.UNDID_SUBMISSION, plot.getId() + "")));
+ player.playSound(player.getLocation(), Utils.SoundUtils.FINISH_PLOT_SOUND, 1, 1);
+ });
+ });
}
@Override
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditFeedback.java b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditFeedback.java
index 14a4d4c97..d90819163 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditFeedback.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditFeedback.java
@@ -1,85 +1,83 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.review;
import com.alpsbte.alpslib.utils.AlpsUtils;
-import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
+import com.alpsbte.plotsystem.core.system.review.PlotReview;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
+import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
public class CMD_EditFeedback extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
- if (!sender.hasPermission(getPermission())) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", RED));
return true;
}
- if (args.length <= 1 || AlpsUtils.tryParseInt(args[0]) == null) {sendInfo(sender); return true;}
- int plotID = Integer.parseInt(args[0]);
+ CompletableFuture.runAsync(() -> {
+ if (!DataProvider.BUILD_TEAM.isAnyReviewer(player.getUniqueId()) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
- if (!PlotUtils.plotExists(plotID)) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return true;
- }
+ if (args.length < 1) {
+ sendInfo(sender);
+ return;
+ }
+
+ Integer plotId = AlpsUtils.tryParseInt(args[0]);
- Plot plot = new Plot(plotID);
- try {
- if (!plot.isReviewed() && !plot.isRejected()) {
+ if (plotId == null) {
+ sendInfo(sender);
+ return;
+ }
+
+ Plot plot = DataProvider.PLOT.getPlotById(plotId);
+
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_MODIFY_LEGACY_PLOT)));
+ return;
+ }
+
+ Optional review = plot.getLatestReview();
+ if (review.isEmpty()) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLOT_EITHER_UNCLAIMED_OR_UNREVIEWED)));
- return true;
+ return;
}
- if (getPlayer(sender) != null && !sender.hasPermission("plotsystem.admin") && !plot.getReview().getReviewer().getUUID().equals(((Player) sender).getUniqueId())) {
+
+ Builder builder = DataProvider.BUILDER.getBuilderByUUID(player.getUniqueId());
+ if (DataProvider.BUILDER.canNotReviewPlot(builder.getUUID(), plot) && !sender.hasPermission("plotsystem.admin")) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_SEND_FEEDBACK)));
- return true;
+ return;
}
StringBuilder feedback = new StringBuilder();
for (int i = 2; i <= args.length; i++) {
feedback.append(args.length == 2 ? "" : " ").append(args[i - 1]);
}
- plot.getReview().setFeedback(feedback.toString());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.UPDATED_PLOT_FEEDBACK, plot.getID() + "")));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ boolean successful = review.get().updateFeedback(feedback.toString());
+ if (successful) sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.UPDATED_PLOT_FEEDBACK, plot.getId() + "")));
+ else sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
+ });
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditPlot.java b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditPlot.java
index 2c01c1eb1..595904d1b 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditPlot.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_EditPlot.java
@@ -1,117 +1,97 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.review;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
+import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
+import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
import com.alpsbte.plotsystem.utils.io.ConfigPaths;
-import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.ConfigUtil;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
+import java.util.concurrent.CompletableFuture;
-import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
public class CMD_EditPlot extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
- if (getPlayer(sender) == null) {
- Bukkit.getConsoleSender().sendMessage(text("This command can only be used as a player!", NamedTextColor.RED));
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", RED));
return true;
}
+ // TODO: don't register command if this config value is false
if (!ConfigUtil.getInstance().configs[1].getBoolean(ConfigPaths.EDITPLOT_ENABLED)) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.COMMAND_DISABLED)));
return true;
}
- if (!sender.hasPermission(getPermission())) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
- return true;
- }
+ CompletableFuture.runAsync(() -> {
+ if (!DataProvider.BUILD_TEAM.isAnyReviewer(player.getUniqueId()) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
- try {
Plot plot;
if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) != null) {
- int plotID = Integer.parseInt(args[0]);
- if (!PlotUtils.plotExists(plotID)) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return true;
- }
- plot = new Plot(plotID);
- } else if (getPlayer(sender) != null && PlotUtils.isPlotWorld(getPlayer(sender).getWorld())) {
- AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(getPlayer(sender).getUniqueId()), Status.unfinished, Status.unreviewed);
- if (p instanceof Plot) {
- plot = (Plot) p;
- } else {
+ plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ } else if (PlotUtils.isPlotWorld(player.getWorld())) {
+ AbstractPlot p = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unfinished);
+ if (!(p instanceof Plot)) {
sendInfo(sender);
- return true;
+ return;
}
+ plot = (Plot) p;
} else {
sendInfo(sender);
- return true;
+ return;
}
+ if (plot == null) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
+ }
if (plot.getStatus() == Status.completed) {
sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_IS_NOT_ALLOWED)));
- return true;
+ return;
}
- Builder builder = Builder.byUUID(getPlayer(sender).getUniqueId());
- int countryID = plot.getCity().getCountry().getID();
- if (!builder.isReviewer() || builder.getAsReviewer().getCountries().stream().noneMatch(c -> c.getID() == countryID) || plot.getPlotOwner().getUUID() == builder.getUUID() || plot.getPlotMembers().stream().anyMatch(b -> b.getUUID() == builder.getUUID())) {
- return true;
+ Builder builder = Builder.byUUID(player.getUniqueId());
+ if (DataProvider.BUILDER.canNotReviewPlot(builder.getUUID(), plot) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
}
- if (!plot.getPermissions().hasBuildingPerms(builder.getUUID())) {
- plot.getPermissions().addBuilderPerms(builder.getUUID()).save();
- sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.ENABLED_PLOT_PERMISSIONS, plot.getID() + "")));
- return true;
- }
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+
+ if (!plot.getPermissions().hasBuildingPerms(builder.getUUID())) {
+ plot.getPermissions().addBuilderPerms(builder.getUUID()).save();
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.ENABLED_PLOT_PERMISSIONS, plot.getId() + "")));
+ return;
+ }
+
+ plot.getPermissions().removeBuilderPerms(builder.getUUID()).save();
+ sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.DISABLED_PLOT_PERMISSIONS, plot.getId() + "")));
+ });
+ });
+
- plot.getPermissions().removeBuilderPerms(builder.getUUID()).save();
- sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.DISABLED_PLOT_PERMISSIONS, plot.getID() + "")));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_Review.java b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_Review.java
index 98d4a10cf..01b234dbf 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_Review.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_Review.java
@@ -1,34 +1,11 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.review;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
-import com.alpsbte.plotsystem.core.menus.ReviewMenu;
-import com.alpsbte.plotsystem.core.menus.ReviewPlotMenu;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.menus.review.ReviewMenu;
+import com.alpsbte.plotsystem.core.menus.review.ReviewPlotMenu;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
@@ -45,7 +22,7 @@
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
+import java.util.concurrent.CompletableFuture;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.RED;
@@ -53,85 +30,103 @@
public class CMD_Review extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
- if (getPlayer(sender) == null) {
+ Player player = getPlayer(sender);
+ if (player == null) {
Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", RED));
return true;
}
- if (!sender.hasPermission(getPermission())) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
- return true;
- }
+ CompletableFuture.runAsync(() -> {
+ if (!DataProvider.BUILD_TEAM.isAnyReviewer(player.getUniqueId()) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
- if (args.length > 0 && AlpsUtils.tryParseInt(args[0]) == null) {
- sendInfo(sender);
- return true;
- }
+ Builder builder = DataProvider.BUILDER.getBuilderByUUID(player.getUniqueId());
+ AbstractPlot currentPlot = PlotUtils.getCurrentPlot(builder);
- Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getPlugin(), () -> {
- Plot plot = null;
- if (args.length > 0) {
- int plotId = Integer.parseInt(args[0]);
- if (!PlotUtils.plotExists(plotId)) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender,
- LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return;
- }
- plot = new Plot(plotId);
+ if (args.length == 0 && !(currentPlot instanceof Plot)) {
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new ReviewMenu(player));
+ return;
}
- try {
- Builder.Reviewer builder = Builder.byUUID(getPlayer(sender).getUniqueId()).getAsReviewer();
- Player player = (Player) sender;
-
- // Check if the given plot is valid
- if (plot != null && plot.getStatus() != Status.unreviewed) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender,
- LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ Plot plotToReview;
+ if (args.length == 0) plotToReview = (Plot) currentPlot;
+ else {
+ Integer id = AlpsUtils.tryParseInt(args[0]);
+ if (id == null) {
+ sendInfo(sender);
return;
}
- // Check if the reviewer is on the plot
- AbstractPlot currentPlot = PlotUtils.getCurrentPlot(Builder.byUUID(player.getUniqueId()), Status.unreviewed);
- boolean teleportPlayer = false;
- if (currentPlot instanceof Plot cp) {
- if (plot != null && plot.getID() != currentPlot.getID()) teleportPlayer = true;
- else plot = cp;
- } else if (plot == null) {
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new ReviewMenu(player));
- return;
- } else teleportPlayer = true;
-
- // If the reviewer is not on the plot, teleport the player
- if (teleportPlayer) {
- Plot finalPlot = plot;
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> finalPlot.getWorld().teleportPlayer(player));
+ plotToReview = DataProvider.PLOT.getPlotById(id);
+ if (plotToReview == null || plotToReview.getStatus() != Status.unreviewed) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
return;
}
+ }
- // Check if player is allowed to review this plot (cannot be the owner or a member of this plot)
- if ((plot.getPlotOwner().getUUID().toString().equals(player.getUniqueId().toString()) ||
- (!plot.getPlotMembers().isEmpty() && plot.getPlotMembers().stream()
- .anyMatch(b -> b.getUUID().toString().equals(player.getUniqueId().toString())))) &&
- !PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE)) {
- player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player,
- LangPaths.Message.Error.CANNOT_REVIEW_OWN_PLOT)));
- return;
- }
+ if (plotToReview.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.CANNOT_LOAD_LEGACY_PLOT)));
+ return;
+ }
- // Check if the reviewer is allowed to review this plot in this city project
- int countryID = plot.getCity().getCountry().getID();
- if (builder.getCountries().stream().anyMatch(c -> c.getID() == countryID)) {
- Plot finalPlot = plot;
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new ReviewPlotMenu(player, finalPlot));
- return;
+ if (DataProvider.BUILDER.canNotReviewPlot(builder.getUUID(), plotToReview) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
+
+ // Players cannot review their own plots
+ boolean isParticipant = plotToReview.getPlotOwner().getUUID().equals(player.getUniqueId()) || plotToReview.getPlotMembers().stream().anyMatch(b -> b.getUUID().equals(player.getUniqueId()));
+ if (!PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE) && isParticipant) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.CANNOT_REVIEW_OWN_PLOT)));
+ return;
+ }
+
+ // Check if the reviewer is on the plot
+ boolean teleportPlayer = false;
+ if (currentPlot instanceof Plot currentPlotCast) {
+ if (plotToReview.getId() != currentPlotCast.getId()) {
+ teleportPlayer = true;
+ if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE)) {
+ PlotSystem.getPlugin().getComponentLogger().info(text("Review: Player on different plot, will teleport. Current: " + currentPlotCast.getId() + ", Target: " + plotToReview.getId()));
+ }
+ } else {
+ if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE)) {
+ PlotSystem.getPlugin().getComponentLogger().info(text("Review: Player on target plot " + plotToReview.getId() + ", opening menu directly"));
+ }
}
+ } else {
+ teleportPlayer = true;
+ if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE)) {
+ PlotSystem.getPlugin().getComponentLogger().info(text("Review: Player not on any plot, will teleport to plot " + plotToReview.getId()));
+ }
+ }
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> new ReviewMenu(player));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(langUtil.get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ Plot finalPlotToReview = plotToReview;
+
+ // If the reviewer is not on the plot, teleport the player first
+ if (teleportPlayer) {
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ plotToReview.getWorld().teleportPlayer(player);
+ if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE)) {
+ PlotSystem.getPlugin().getComponentLogger().info(text("Review: Teleported player, scheduling menu open in 20 ticks"));
+ }
+ });
+ return;
}
+
+ // Player is already on the plot, open menu on main thread
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
+ if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE)) {
+ PlotSystem.getPlugin().getComponentLogger().info(text("Review: Opening ReviewPlotMenu for plot if status is unreviewed" + finalPlotToReview.getId() + " (no teleport needed)"));
+ }
+ if (finalPlotToReview.getStatus() == Status.unreviewed) {
+ new ReviewPlotMenu(player, finalPlotToReview);
+ } else {
+ new ReviewMenu(player);
+ }
+ });
});
return true;
}
@@ -153,6 +148,6 @@ public String[] getParameter() {
@Override
public String getPermission() {
- return "plotsystem.review";
+ return "";
}
}
diff --git a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_UndoReview.java b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_UndoReview.java
index 1224e274b..f0c47b016 100644
--- a/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_UndoReview.java
+++ b/src/main/java/com/alpsbte/plotsystem/commands/review/CMD_UndoReview.java
@@ -1,83 +1,85 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.commands.review;
import com.alpsbte.alpslib.utils.AlpsUtils;
import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.commands.BaseCommand;
-import com.alpsbte.plotsystem.core.system.Review;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
+import com.alpsbte.plotsystem.core.system.review.PlotReview;
import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.enums.Status;
+import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
+import net.kyori.adventure.text.Component;
+import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
-import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
public class CMD_UndoReview extends BaseCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) {
- if (!sender.hasPermission(getPermission())) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ Player player = getPlayer(sender);
+ if (player == null) {
+ Bukkit.getConsoleSender().sendMessage(Component.text("This command can only be used as a player!", RED));
return true;
}
- if (args.length == 0 || AlpsUtils.tryParseInt(args[0]) == null) {
- sendInfo(sender);
- return true;
- }
+ CompletableFuture.runAsync(() -> {
+ if (!DataProvider.BUILD_TEAM.isAnyReviewer(player.getUniqueId()) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
- int plotID = Integer.parseInt(args[0]);
- if (!PlotUtils.plotExists(plotID)) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
- return true;
- }
+ if (args.length < 1 || AlpsUtils.tryParseInt(args[0]) == null) {
+ sendInfo(sender);
+ return;
+ }
- try {
- Plot plot = new Plot(plotID);
- if (!plot.isReviewed()) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLOT_EITHER_UNCLAIMED_OR_UNREVIEWED)));
- return true;
+ Plot plot = DataProvider.PLOT.getPlotById(Integer.parseInt(args[0]));
+ if (plot == null || plot.getStatus() != Status.completed) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender,
+ LangPaths.Message.Error.PLOT_DOES_NOT_EXIST)));
+ return;
}
- if (getPlayer(sender) != null && !sender.hasPermission("plotsystem.admin") && !plot.getReview().getReviewer().getUUID().equals(getPlayer(sender).getUniqueId())) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_UNDO_REVIEW)));
- return true;
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.CANNOT_MODIFY_LEGACY_PLOT)));
+ return;
}
- Review.undoReview(plot.getReview());
- sender.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Info.UNDID_REVIEW, plot.getID() + "", plot.getPlotOwner().getName())));
- } catch (SQLException ex) {
- sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ Builder builder = DataProvider.BUILDER.getBuilderByUUID(player.getUniqueId());
+ if (DataProvider.BUILDER.canNotReviewPlot(builder.getUUID(), plot) && !sender.hasPermission("plotsystem.admin")) {
+ sender.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(sender, LangPaths.Message.Error.PLAYER_HAS_NO_PERMISSIONS)));
+ return;
+ }
+
+ // Players cannot review their own plots
+ boolean isParticipant = plot.getPlotOwner().getUUID() == player.getUniqueId() || plot.getPlotMembers().stream().anyMatch(b -> b.getUUID() == player.getUniqueId());
+ if (!PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DEV_MODE) && isParticipant) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.CANNOT_REVIEW_OWN_PLOT)));
+ return;
+ }
+
+ Optional review = plot.getLatestReview();
+ if (review.isEmpty()) {
+ player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.REVIEW_NOT_FOUND)));
+ return;
+ }
+
+ boolean successful = review.get().undoReview();
+ if (successful) player.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(player, LangPaths.Message.Info.UNDID_REVIEW, plot.getId() + "", plot.getPlotOwner().getName())));
+ else player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.ERROR_OCCURRED)));
+ });
return true;
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/EventListener.java b/src/main/java/com/alpsbte/plotsystem/core/EventListener.java
index 6087f7005..0d38d00c0 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/EventListener.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/EventListener.java
@@ -1,52 +1,32 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core;
import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.companion.CompanionMenu;
+import com.alpsbte.plotsystem.core.menus.review.ReviewMenu;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.CityProject;
+import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.core.system.plot.TutorialPlot;
+import com.alpsbte.plotsystem.core.system.plot.generator.DefaultPlotGenerator;
import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
import com.alpsbte.plotsystem.core.system.plot.world.PlotWorld;
+import com.alpsbte.plotsystem.core.system.review.ReviewNotification;
import com.alpsbte.plotsystem.core.system.tutorial.AbstractPlotTutorial;
import com.alpsbte.plotsystem.core.system.tutorial.AbstractTutorial;
import com.alpsbte.plotsystem.core.system.tutorial.Tutorial;
import com.alpsbte.plotsystem.core.system.tutorial.TutorialCategory;
+import com.alpsbte.plotsystem.utils.DependencyManager;
import com.alpsbte.plotsystem.utils.PlotMemberInvitation;
+import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.chat.ChatInput;
-import com.alpsbte.plotsystem.utils.chat.PlayerInviteeChatInput;
import com.alpsbte.plotsystem.utils.chat.PlayerFeedbackChatInput;
+import com.alpsbte.plotsystem.utils.chat.PlayerInviteeChatInput;
+import com.alpsbte.plotsystem.utils.enums.Status;
import com.alpsbte.plotsystem.utils.io.ConfigPaths;
-import com.alpsbte.plotsystem.core.menus.ReviewMenu;
-import com.alpsbte.plotsystem.core.database.DatabaseConnection;
-import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.plot.generator.DefaultPlotGenerator;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.Utils;
-import com.alpsbte.plotsystem.utils.enums.Status;
+import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.flags.Flags;
@@ -54,7 +34,9 @@
import com.sk89q.worldguard.protection.regions.RegionQuery;
import io.papermc.paper.event.player.AsyncChatEvent;
import li.cinnazeyy.langlibs.core.event.LanguageChangeEvent;
+import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
@@ -68,125 +50,56 @@
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
-import org.bukkit.event.player.*;
+import org.bukkit.event.player.PlayerChangedWorldEvent;
+import org.bukkit.event.player.PlayerDropItemEvent;
+import org.bukkit.event.player.PlayerInteractAtEntityEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.player.PlayerSwapHandItemsEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
+import java.time.Duration;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
+import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
+import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class EventListener implements Listener {
@EventHandler
public void onPlayerJoinEvent(PlayerJoinEvent event) {
- // User has joined for the first time
- // Adding user to the database
- Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getPlugin(), () -> {
- // Add Items
- Utils.updatePlayerInventorySlots(event.getPlayer());
-
- // Check if player even exists in database.
- try (ResultSet rs = DatabaseConnection.createStatement("SELECT * FROM plotsystem_builders WHERE uuid = ?")
- .setValue(event.getPlayer().getUniqueId().toString()).executeQuery()) {
-
- if (!rs.first()) {
- DatabaseConnection.createStatement("INSERT INTO plotsystem_builders (uuid, name) VALUES (?, ?)")
- .setValue(event.getPlayer().getUniqueId().toString())
- .setValue(event.getPlayer().getName())
- .executeUpdate();
- }
+ Player player = event.getPlayer();
- DatabaseConnection.closeResultSet(rs);
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
-
- // Inform player about update
- if (event.getPlayer().hasPermission("plotsystem.admin") && PlotSystem.UpdateChecker.updateAvailable() && PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.CHECK_FOR_UPDATES)) {
- event.getPlayer().sendMessage(Utils.ChatUtils.getInfoFormat("There is a new update for the Plot-System available. Check your console for more information!"));
- event.getPlayer().playSound(event.getPlayer().getLocation(), Utils.SoundUtils.NOTIFICATION_SOUND, 1f, 1f);
- }
-
- // Check if player has changed his name
- Builder builder = Builder.byUUID(event.getPlayer().getUniqueId());
- try {
- if (!builder.getName().equals(event.getPlayer().getName())) {
- DatabaseConnection.createStatement("UPDATE plotsystem_builders SET name = ? WHERE uuid = ?")
- .setValue(event.getPlayer().getName()).setValue(event.getPlayer().getUniqueId().toString()).executeUpdate();
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
-
- // Informing player about new feedback
- try {
- List plots = Plot.getPlots(builder, Status.completed, Status.unfinished);
- List reviewedPlots = new ArrayList<>();
-
- for (Plot plot : plots) {
- if (plot.isReviewed() && !plot.getReview().isFeedbackSent()) {
- reviewedPlots.add(plot);
- plot.getReview().setFeedbackSent(true);
- }
- }
-
- if (!reviewedPlots.isEmpty()) {
- PlotUtils.ChatFormatting.sendFeedbackMessage(reviewedPlots, event.getPlayer());
- event.getPlayer().sendTitle("", "§6§l" + reviewedPlots.size() + " §a§lPlot" + (reviewedPlots.size() == 1 ? " " : "s ") + (reviewedPlots.size() == 1 ? "has" : "have") + " been reviewed!", 20, 150, 20);
- }
- } catch (Exception ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("An error occurred while trying to inform the player about his plot feedback!"), ex);
- }
+ // Add Items
+ Utils.updatePlayerInventorySlots(player);
- // Informing player about unfinished plots
- try {
- List plots = Plot.getPlots(builder, Status.unfinished);
- if (!plots.isEmpty()) {
- PlotUtils.ChatFormatting.sendUnfinishedPlotReminderMessage(plots, event.getPlayer());
- event.getPlayer().sendMessage("");
- }
- } catch (Exception ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("An error occurred while trying to inform the player about his unfinished plots!"), ex);
- }
+ // User has joined for the first time
+ // Adding user to the database
- // Informing reviewer about new reviews
- try {
- if (event.getPlayer().hasPermission("plotsystem.review") && builder.isReviewer()) {
- List unreviewedPlots = Plot.getPlots(builder.getAsReviewer().getCountries(), Status.unreviewed);
+ // Create builder if it does not exist in database.
+ boolean successful = DataProvider.BUILDER.addBuilderIfNotExists(player.getUniqueId(), player.getName());
+ if (!successful) PlotSystem.getPlugin().getComponentLogger().error(text("BUILDER COULD NOT BE CREATED!!", RED));
- if (!unreviewedPlots.isEmpty()) {
- PlotUtils.ChatFormatting.sendUnreviewedPlotsReminderMessage(unreviewedPlots, event.getPlayer());
- }
- }
- } catch (Exception ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("An error occurred while trying to inform the player about unreviewed plots!"), ex);
- }
+ // Check if player has changed their name
+ Builder builder = Builder.byUUID(player.getUniqueId());
+ if (!builder.getName().equals(player.getName())) {
+ successful = builder.setName(player.getName());
+ if (!successful) PlotSystem.getPlugin().getComponentLogger().error(text("Builder name could not be updated!", RED));
+ }
- // Start or notify the player if he has not completed the beginner tutorial yet (only if required)
- try {
- if (PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.TUTORIAL_REQUIRE_BEGINNER_TUTORIAL) &&
- !TutorialPlot.isPlotCompleted(event.getPlayer(), TutorialCategory.BEGINNER.getId())) {
- if (!event.getPlayer().hasPlayedBefore()) {
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(),
- () -> event.getPlayer().performCommand("tutorial " + TutorialCategory.BEGINNER.getId()));
- } else {
- AbstractPlotTutorial.sendTutorialRequiredMessage(event.getPlayer(), TutorialCategory.BEGINNER.getId());
- event.getPlayer().playSound(event.getPlayer().getLocation(), Utils.SoundUtils.NOTIFICATION_SOUND, 1f, 1f);
- }
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- });
+ Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getPlugin(), () -> sendNotices(event.getPlayer(), builder));
}
@EventHandler
- public void onPlayerInteractEvent(PlayerInteractEvent event) {
+ public void onPlayerInteractEvent(@NotNull PlayerInteractEvent event) {
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) || event.getAction().equals(Action.RIGHT_CLICK_AIR)) {
if (event.getItem() != null && event.getItem().equals(CompanionMenu.getMenuItem(event.getPlayer()))) {
event.getPlayer().performCommand("companion");
@@ -196,40 +109,18 @@ public void onPlayerInteractEvent(PlayerInteractEvent event) {
}
// Open/Close iron trap door when right-clicking
- if (event.getAction().equals(Action.RIGHT_CLICK_AIR) || event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
- if (event.getHand() != EquipmentSlot.OFF_HAND) {
- if (!event.getPlayer().isSneaking()) {
- if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.IRON_TRAPDOOR) {
- RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer();
- RegionQuery query = regionContainer.createQuery();
-
- if (query.testBuild(BukkitAdapter.adapt(event.getPlayer().getLocation()), PlotSystem.DependencyManager.getWorldGuard().wrapPlayer(event.getPlayer()), Flags.INTERACT)) {
- BlockState state = event.getClickedBlock().getState();
- Openable tp = (Openable) state.getBlockData();
- if (!tp.isOpen()) {
- tp.setOpen(true);
- event.getPlayer().playSound(event.getClickedBlock().getLocation(), "block.iron_trapdoor.open", 1f, 1f);
- } else {
- tp.setOpen(false);
- event.getPlayer().playSound(event.getClickedBlock().getLocation(), "block.iron_trapdoor.close", 1f, 1f);
- }
- state.update();
- }
- }
- }
- }
- }
+ handleIronTrapdoorClick(event);
}
@EventHandler
- public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) throws SQLException {
+ public void onPlayerInteractAtEntity(@NotNull PlayerInteractAtEntityEvent event) {
if (event.getRightClicked().getType().equals(EntityType.PLAYER) && event.getHand() == EquipmentSlot.HAND) {
event.getPlayer().performCommand("plots " + Builder.byUUID(event.getRightClicked().getUniqueId()).getName());
}
}
@EventHandler
- public void onPlayerQuitEvent(PlayerQuitEvent event) {
+ public void onPlayerQuitEvent(@NotNull PlayerQuitEvent event) {
final World w = event.getPlayer().getWorld();
DefaultPlotGenerator.playerPlotGenerationHistory.remove(event.getPlayer().getUniqueId());
@@ -249,10 +140,13 @@ public void onPlayerQuitEvent(PlayerQuitEvent event) {
if (plotWorld != null && !plotWorld.getWorldName().toLowerCase(Locale.ROOT).startsWith("t-"))
plotWorld.unloadWorld(false);
}, 60L);
+
+ PlotUtils.plotReminder.get(event.getPlayer().getUniqueId()).cancel();
+ PlotUtils.plotReminder.remove(event.getPlayer().getUniqueId());
}
@EventHandler
- public void onPlayerChangedWorldEvent(PlayerChangedWorldEvent event) {
+ public void onPlayerChangedWorldEvent(@NotNull PlayerChangedWorldEvent event) {
Bukkit.getScheduler().scheduleSyncDelayedTask(PlotSystem.getPlugin(), () -> {
PlotWorld plotWorld = PlotWorld.getPlotWorldByName(event.getFrom().getName());
if (plotWorld != null) plotWorld.unloadWorld(false);
@@ -262,24 +156,21 @@ public void onPlayerChangedWorldEvent(PlayerChangedWorldEvent event) {
}
@EventHandler
- public void onInventoryClickEvent(InventoryClickEvent event) {
- if (event.getCurrentItem() != null && event.getCurrentItem().equals(CompanionMenu.getMenuItem((Player) event.getWhoClicked()))) {
- event.setCancelled(true);
- } else if (event.getCurrentItem() != null && event.getCurrentItem().equals(ReviewMenu.getMenuItem(((Player) event.getWhoClicked()).getPlayer()))) {
+ public void onInventoryClickEvent(@NotNull InventoryClickEvent event) {
+ if (event.getCurrentItem() != null && (event.getCurrentItem().equals(CompanionMenu.getMenuItem((Player) event.getWhoClicked())) || event.getCurrentItem().equals(ReviewMenu.getMenuItem(((Player) event.getWhoClicked()))))) {
event.setCancelled(true);
}
- if (event.getWhoClicked().getGameMode() == GameMode.CREATIVE) {
- if (event.getCursor().isSimilar(CompanionMenu.getMenuItem((Player) event.getWhoClicked())) ||
- event.getCursor().isSimilar(ReviewMenu.getMenuItem((Player) event.getWhoClicked()))) {
- event.setCursor(ItemStack.empty());
- event.setCancelled(true);
- }
+ if (event.getWhoClicked().getGameMode() == GameMode.CREATIVE && (event.getCursor().isSimilar(CompanionMenu.getMenuItem((Player) event.getWhoClicked())) ||
+ event.getCursor().isSimilar(ReviewMenu.getMenuItem((Player) event.getWhoClicked())))) {
+ event.getView().setCursor(ItemStack.empty());
+ event.setCancelled(true);
}
+
}
@EventHandler
- public void onlPlayerItemDropEvent(PlayerDropItemEvent event) {
+ public void onlPlayerItemDropEvent(@NotNull PlayerDropItemEvent event) {
if (event.getItemDrop().getItemStack().equals(CompanionMenu.getMenuItem(event.getPlayer())) ||
event.getItemDrop().getItemStack().equals(ReviewMenu.getMenuItem(event.getPlayer()))) {
event.setCancelled(true);
@@ -287,7 +178,7 @@ public void onlPlayerItemDropEvent(PlayerDropItemEvent event) {
}
@EventHandler
- public void onPlayerSwapHandItemsEvent(PlayerSwapHandItemsEvent event) {
+ public void onPlayerSwapHandItemsEvent(@NotNull PlayerSwapHandItemsEvent event) {
if (event.getMainHandItem().equals(CompanionMenu.getMenuItem(event.getPlayer())) ||
event.getMainHandItem().equals(ReviewMenu.getMenuItem(event.getPlayer()))) event.setCancelled(true);
if (event.getOffHandItem().equals(CompanionMenu.getMenuItem(event.getPlayer())) ||
@@ -295,7 +186,7 @@ public void onPlayerSwapHandItemsEvent(PlayerSwapHandItemsEvent event) {
}
@EventHandler(priority = EventPriority.LOWEST)
- public void onPlayerChatEvent(AsyncChatEvent event) throws SQLException {
+ public void onPlayerChatEvent(@NotNull AsyncChatEvent event) {
UUID playerUUID = event.getPlayer().getUniqueId();
if (ChatInput.awaitChatInput.containsKey(playerUUID)) {
event.setCancelled(true);
@@ -303,17 +194,17 @@ public void onPlayerChatEvent(AsyncChatEvent event) throws SQLException {
ChatInput input = ChatInput.awaitChatInput.get(playerUUID);
if (input instanceof PlayerFeedbackChatInput feedbackInput) {
- feedbackInput.getReview().setFeedback(messageComp.content());
+ feedbackInput.getReview().updateFeedback(messageComp.content());
ChatInput.awaitChatInput.remove(playerUUID);
event.getPlayer().sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(event.getPlayer(),
- LangPaths.Message.Info.UPDATED_PLOT_FEEDBACK, String.valueOf(feedbackInput.getReview().getPlotID()))));
+ LangPaths.Message.Info.UPDATED_PLOT_FEEDBACK, String.valueOf(feedbackInput.getReview().getPlot().getId()))));
} else if (input instanceof PlayerInviteeChatInput inviteeInput) {
Player player = Bukkit.getPlayer(messageComp.content());
if (player == null) {
event.getPlayer().sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance()
.get(event.getPlayer(), LangPaths.Message.Error.PLAYER_NOT_FOUND)));
- } else if (!player.isOnline() || !TutorialPlot.isPlotCompleted(player, TutorialCategory.BEGINNER.getId())) {
+ } else if (!player.isOnline()) {
event.getPlayer().sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance()
.get(event.getPlayer(), LangPaths.Message.Error.PLAYER_IS_NOT_ONLINE)));
} else if (inviteeInput.getPlot().getPlotMembers().contains(Builder.byUUID(player.getUniqueId()))) {
@@ -322,6 +213,9 @@ public void onPlayerChatEvent(AsyncChatEvent event) throws SQLException {
} else if (inviteeInput.getPlot().getPlotOwner().getUUID().toString().equals(player.getUniqueId().toString())) {
event.getPlayer().sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance()
.get(event.getPlayer(), LangPaths.Message.Error.PLAYER_IS_PLOT_OWNER)));
+ } else if (TutorialPlot.isRequiredAndInProgress(TutorialCategory.BEGINNER.getId(), player.getUniqueId())) {
+ event.getPlayer().sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance()
+ .get(event.getPlayer(), LangPaths.Message.Error.PLAYER_MISSING_TUTORIAL)));
} else {
new PlotMemberInvitation(Bukkit.getPlayer(messageComp.content()), inviteeInput.getPlot());
ChatInput.awaitChatInput.remove(playerUUID);
@@ -334,7 +228,80 @@ public void onPlayerChatEvent(AsyncChatEvent event) throws SQLException {
}
@EventHandler
- public void onLanguageChange(LanguageChangeEvent event) {
+ public void onLanguageChange(@NotNull LanguageChangeEvent event) {
Utils.updatePlayerInventorySlots(event.getPlayer());
}
+
+ @EventHandler
+ public void onPlayerClientOptionsChange(@NotNull PlayerClientOptionsChangeEvent e) {
+ Utils.updatePlayerInventorySlots(e.getPlayer());
+ }
+
+ private void handleIronTrapdoorClick(@NotNull PlayerInteractEvent event) {
+ if (!event.getAction().equals(Action.RIGHT_CLICK_AIR) && !event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) return;
+ if (event.getHand() == EquipmentSlot.OFF_HAND) return;
+ if (event.getPlayer().isSneaking()) return;
+ if (event.getClickedBlock() == null || event.getClickedBlock().getType() != Material.IRON_TRAPDOOR) return;
+
+ RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer();
+ RegionQuery query = regionContainer.createQuery();
+
+ if (!query.testBuild(BukkitAdapter.adapt(event.getPlayer().getLocation()), DependencyManager.getWorldGuard().wrapPlayer(event.getPlayer()), Flags.INTERACT)) return;
+
+ BlockState state = event.getClickedBlock().getState();
+ Openable tp = (Openable) state.getBlockData();
+ if (!tp.isOpen()) {
+ tp.setOpen(true);
+ event.getPlayer().playSound(event.getClickedBlock().getLocation(), "block.iron_trapdoor.open", 1f, 1f);
+ } else {
+ tp.setOpen(false);
+ event.getPlayer().playSound(event.getClickedBlock().getLocation(), "block.iron_trapdoor.close", 1f, 1f);
+ }
+ state.update();
+ }
+
+ private void sendNotices(@NotNull Player player, Builder builder) {
+ sendReviewNotices(player, builder);
+
+ // Start or notify the player if he has not completed the beginner tutorial yet (only if required)
+ if (TutorialPlot.isRequiredAndInProgress(TutorialCategory.BEGINNER.getId(), player.getUniqueId())) {
+ if (!player.hasPlayedBefore()) {
+ Bukkit.getScheduler().runTask(PlotSystem.getPlugin(),
+ () -> player.performCommand("tutorial " + TutorialCategory.BEGINNER.getId()));
+ } else {
+ AbstractPlotTutorial.sendTutorialRequiredMessage(player, TutorialCategory.BEGINNER.getId());
+ player.playSound(player.getLocation(), Utils.SoundUtils.NOTIFICATION_SOUND, 1f, 1f);
+ }
+ }
+ }
+
+ private void sendReviewNotices(@NotNull Player player, Builder builder) {
+ // Informing player about new feedback
+ List notifications = DataProvider.REVIEW.getReviewNotifications(player.getUniqueId());
+ if (!notifications.isEmpty()) {
+ PlotUtils.ChatFormatting.sendFeedbackMessage(notifications, player);
+ Component subtitleComp = LangUtil.getInstance().getComponent(player.getUniqueId(),
+ notifications.size() == 1
+ ? LangPaths.Message.Info.PLOTS_REVIEWED_SINGULAR
+ : LangPaths.Message.Info.PLOTS_REVIEWED_PLURAL,
+ GREEN, text(notifications.size(), GOLD).decoration(BOLD, true));
+ player.showTitle(Title.title(
+ empty(),
+ subtitleComp,
+ Title.Times.times(Duration.ofSeconds(1), Duration.ofSeconds(8), Duration.ofSeconds(1)))
+ );
+ }
+ PlotUtils.informPlayerAboutUnfinishedPlots(player, builder);
+ PlotUtils.startUnfinishedPlotReminderTimer(player);
+
+ // Informing reviewer about new reviews
+ if (player.hasPermission("plotsystem.admin") || DataProvider.BUILD_TEAM.isAnyReviewer(builder.getUUID())) {
+ List reviewerCityProjects = DataProvider.BUILD_TEAM.getReviewerCities(builder.getUUID());
+ List unreviewedPlots = DataProvider.PLOT.getPlots(reviewerCityProjects, Status.unreviewed);
+
+ if (!unreviewedPlots.isEmpty()) {
+ PlotUtils.ChatFormatting.sendUnreviewedPlotsReminderMessage(unreviewedPlots, player);
+ }
+ }
+ }
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/DataProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/DataProvider.java
new file mode 100644
index 000000000..2e557d18c
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/DataProvider.java
@@ -0,0 +1,25 @@
+package com.alpsbte.plotsystem.core.database;
+
+import com.alpsbte.plotsystem.core.database.providers.BuildTeamProvider;
+import com.alpsbte.plotsystem.core.database.providers.BuilderProvider;
+import com.alpsbte.plotsystem.core.database.providers.CityProjectProvider;
+import com.alpsbte.plotsystem.core.database.providers.CountryProvider;
+import com.alpsbte.plotsystem.core.database.providers.DifficultyProvider;
+import com.alpsbte.plotsystem.core.database.providers.PlotProvider;
+import com.alpsbte.plotsystem.core.database.providers.ReviewProvider;
+import com.alpsbte.plotsystem.core.database.providers.ServerProvider;
+import com.alpsbte.plotsystem.core.database.providers.TutorialPlotProvider;
+
+public final class DataProvider {
+ public static final BuilderProvider BUILDER = new BuilderProvider();
+ public static final PlotProvider PLOT = new PlotProvider();
+ public static final DifficultyProvider DIFFICULTY = new DifficultyProvider();
+ public static final CityProjectProvider CITY_PROJECT = new CityProjectProvider();
+ public static final CountryProvider COUNTRY = new CountryProvider();
+ public static final ServerProvider SERVER = new ServerProvider();
+ public static final TutorialPlotProvider TUTORIAL_PLOT = new TutorialPlotProvider();
+ public static final ReviewProvider REVIEW = new ReviewProvider();
+ public static final BuildTeamProvider BUILD_TEAM = new BuildTeamProvider(BUILDER, CITY_PROJECT); // has to be initialized after builder and city project providers
+
+ private DataProvider() {}
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/DatabaseConnection.java b/src/main/java/com/alpsbte/plotsystem/core/database/DatabaseConnection.java
deleted file mode 100644
index 88daf8317..000000000
--- a/src/main/java/com/alpsbte/plotsystem/core/database/DatabaseConnection.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2021-2022, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.alpsbte.plotsystem.core.database;
-
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.utils.io.ConfigPaths;
-import com.zaxxer.hikari.HikariConfig;
-import com.zaxxer.hikari.HikariDataSource;
-import org.bukkit.configuration.file.FileConfiguration;
-
-import java.sql.*;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-import static net.kyori.adventure.text.Component.text;
-
-public class DatabaseConnection {
-
- private final static HikariConfig config = new HikariConfig();
- private static HikariDataSource dataSource;
-
- private static String URL;
- private static String name;
- private static String username;
- private static String password;
-
- private static int connectionClosed, connectionOpened;
-
- public static void InitializeDatabase() throws ClassNotFoundException, SQLException {
- Class.forName("org.mariadb.jdbc.Driver");
-
- FileConfiguration configFile = PlotSystem.getPlugin().getConfig();
- URL = configFile.getString(ConfigPaths.DATABASE_URL);
- name = configFile.getString(ConfigPaths.DATABASE_NAME);
- username = configFile.getString(ConfigPaths.DATABASE_USERNAME);
- password = configFile.getString(ConfigPaths.DATABASE_PASSWORD);
-
- createDatabase();
-
- config.setJdbcUrl(URL + name);
- config.setUsername(username);
- config.setPassword(password);
- config.addDataSourceProperty("cachePrepStmts", "true");
- config.addDataSourceProperty("prepStmtCacheSize", "250");
- config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
-
- dataSource = new HikariDataSource(config);
-
- createTables();
- }
-
- @Deprecated
- public static Connection getConnection() {
- int retries = 3;
- while (retries > 0) {
- try {
- return dataSource.getConnection();
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("Database connection failed!"), ex);
- }
- retries--;
- }
- return null;
- }
-
- public static StatementBuilder createStatement(String sql) {
- return new StatementBuilder(sql);
- }
-
- public static void closeResultSet(ResultSet resultSet) throws SQLException {
- if (resultSet.isClosed()
- && resultSet.getStatement().isClosed()
- && resultSet.getStatement().getConnection().isClosed())
- return;
-
- resultSet.close();
- resultSet.getStatement().close();
- resultSet.getStatement().getConnection().close();
-
- connectionClosed++;
-
- if (connectionOpened > connectionClosed + 5) {
- PlotSystem.getPlugin().getComponentLogger().error(text("There are multiple database connections opened. Please report this issue."));
- PlotSystem.getPlugin().getComponentLogger().error(text("Connections Open: " + (connectionOpened - connectionClosed)));
- }
- }
-
- private static void createDatabase() throws SQLException {
- try (Connection con = DriverManager.getConnection(URL, username, password)) {
- try (Statement statement = con.createStatement()) {
- statement.executeUpdate("CREATE DATABASE IF NOT EXISTS `" + name + "`");
- }
- }
- }
-
- private static void createTables() {
- try (Connection con = dataSource.getConnection()) {
- for (String table : Tables.getTables()) {
- Objects.requireNonNull(con).prepareStatement(table).executeUpdate();
- }
-
- try (ResultSet rs = con.prepareStatement("SELECT COUNT(id) FROM plotsystem_difficulties").executeQuery()) {
- if (rs.next()) {
- if (rs.getInt(1) == 0) {
- con.prepareStatement("INSERT INTO plotsystem_difficulties (id, name) VALUES (1, 'EASY')").executeUpdate();
- con.prepareStatement("INSERT INTO plotsystem_difficulties (id, name, multiplier) VALUES (2, 'MEDIUM', 1.5)").executeUpdate();
- con.prepareStatement("INSERT INTO plotsystem_difficulties (id, name, multiplier) VALUES (3, 'HARD', 2)").executeUpdate();
- }
- }
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("An error occurred while creating á database table"), ex);
- }
- }
-
- /**
- * Returns a missing auto increment id
- *
- * @param table in the database
- * @return smallest missing auto increment id in the table
- */
- public static int getTableID(String table) {
- try {
- String query = "SELECT id + 1 available_id FROM $table t WHERE NOT EXISTS (SELECT * FROM $table WHERE $table.id = t.id + 1) ORDER BY id LIMIT 1"
- .replace("$table", table);
- try (ResultSet rs = DatabaseConnection.createStatement(query).executeQuery()) {
- if (rs.next()) {
- int i = rs.getInt(1);
- DatabaseConnection.closeResultSet(rs);
- return i;
- }
-
- DatabaseConnection.closeResultSet(rs);
- return 1;
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- return 1;
- }
- }
-
- public static class StatementBuilder {
- private final String sql;
- private final List values = new ArrayList<>();
-
- public StatementBuilder(String sql) {
- this.sql = sql;
- }
-
- public StatementBuilder setValue(Object value) {
- values.add(value instanceof Boolean ? ((boolean) value ? 1 : 0) : value);
- return this;
- }
-
- public ResultSet executeQuery() throws SQLException {
- Connection con = dataSource.getConnection();
- PreparedStatement ps = Objects.requireNonNull(con).prepareStatement(sql);
- ResultSet rs = iterateValues(ps).executeQuery();
-
- connectionOpened++;
-
- return rs;
- }
-
- public void executeUpdate() throws SQLException {
- try (Connection con = dataSource.getConnection()) {
- try (PreparedStatement ps = Objects.requireNonNull(con).prepareStatement(sql)) {
- iterateValues(ps).executeUpdate();
- }
- }
- }
-
- private PreparedStatement iterateValues(PreparedStatement ps) throws SQLException {
- for (int i = 0; i < values.size(); i++) {
- ps.setObject(i + 1, values.get(i));
- }
- return ps;
- }
- }
-
- private static class Tables {
- private final static List tables;
-
- public static List getTables() {
- return tables;
- }
-
- static {
- tables = Arrays.asList(
- // FTP Configurations
- "CREATE TABLE IF NOT EXISTS `plotsystem_ftp_configurations`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `address` varchar(255) NOT NULL ," +
- " `port` int NOT NULL ," +
- " `isSFTP` tinyint NOT NULL DEFAULT 1 ," +
- " `username` varchar(255) NOT NULL ," +
- " `password` varchar(255) NOT NULL ," +
- " `schematics_path` varchar(255) NULL ," +
- "PRIMARY KEY (`id`)" +
- ");",
-
- // Servers
- "CREATE TABLE IF NOT EXISTS `plotsystem_servers`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `ftp_configuration_id` int NULL ," +
- " `name` varchar(45) NOT NULL ," +
- "PRIMARY KEY (`id`)," +
- "KEY `fkIdx_30` (`ftp_configuration_id`)," +
- "CONSTRAINT `FK_29` FOREIGN KEY `fkIdx_30` (`ftp_configuration_id`) REFERENCES `plotsystem_ftp_configurations` (`id`)" +
- ");",
-
- // Countries
- "CREATE TABLE IF NOT EXISTS `plotsystem_countries`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `server_id` int NOT NULL ," +
- " `name` varchar(45) NOT NULL ," +
- " `head_id` varchar(10) NULL ," +
- "PRIMARY KEY (`id`)," +
- "KEY `fkIdx_38` (`server_id`)," +
- "CONSTRAINT `FK_37` FOREIGN KEY `fkIdx_38` (`server_id`) REFERENCES `plotsystem_servers` (`id`)" +
- ");",
- "ALTER TABLE plotsystem_countries ADD COLUMN IF NOT EXISTS `continent` enum('europe', 'asia', 'africa', 'oceania', 'south america', 'north america') NOT NULL;",
-
- // City Projects
- "CREATE TABLE IF NOT EXISTS `plotsystem_city_projects`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `country_id` int NOT NULL ," +
- " `name` varchar(45) NOT NULL ," +
- " `description` varchar(255) NOT NULL ," +
- " `visible` tinyint DEFAULT 0 ," +
- "PRIMARY KEY (`id`)," +
- "KEY `fkIdx_44` (`country_id`)," +
- "CONSTRAINT `FK_43` FOREIGN KEY `fkIdx_44` (`country_id`) REFERENCES `plotsystem_countries` (`id`)" +
- ");",
-
- // Builders
- "CREATE TABLE IF NOT EXISTS `plotsystem_builders`" +
- "(" +
- " `uuid` varchar(36) NOT NULL COLLATE 'utf8mb4_general_ci'," +
- " `name` varchar(16) NOT NULL ," +
- " `score` int DEFAULT 0 ," +
- " `completed_plots` int DEFAULT 0 ," +
- " `first_slot` int NULL ," +
- " `second_slot` int NULL ," +
- " `third_slot` int NULL ," +
- "PRIMARY KEY (`uuid`)" +
- ");",
- "ALTER TABLE plotsystem_builders ADD COLUMN IF NOT EXISTS lang varchar(5) NULL;",
- "ALTER TABLE plotsystem_builders ADD COLUMN IF NOT EXISTS setting_plot_type int DEFAULT 1;",
-
- // Reviews
- "CREATE TABLE IF NOT EXISTS `plotsystem_reviews`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `reviewer_uuid` varchar(36) NOT NULL COLLATE 'utf8mb4_general_ci'," +
- " `rating` varchar(45) NOT NULL ," +
- " `feedback` varchar(420) NOT NULL ," +
- " `review_date` datetime NOT NULL ," +
- " `sent` tinyint DEFAULT 0 ," +
- "PRIMARY KEY (`id`)," +
- "KEY `fkIdx_73` (`reviewer_uuid`)," +
- "CONSTRAINT `FK_72` FOREIGN KEY `fkIdx_73` (`reviewer_uuid`) REFERENCES `plotsystem_builders` (`uuid`)" +
- ");",
-
- // Difficulties
- "CREATE TABLE IF NOT EXISTS `plotsystem_difficulties`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `name` varchar(45) NOT NULL ," +
- " `multiplier` double DEFAULT 1 ," +
- " `score_requirment` int DEFAULT 0 ," +
- "PRIMARY KEY (`id`)" +
- ");",
-
- // Plots
- "CREATE TABLE IF NOT EXISTS `plotsystem_plots`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `city_project_id` int NOT NULL ," +
- " `difficulty_id` int NOT NULL ," +
- " `review_id` int NULL ," +
- " `owner_uuid` varchar(36) NULL COLLATE 'utf8mb4_general_ci'," +
- " `member_uuids` varchar(110) NULL ," +
- " `status` enum ('unclaimed', 'unfinished', 'unreviewed', 'completed') NOT NULL DEFAULT 'unclaimed' ," +
- " `mc_coordinates` varchar(255) NOT NULL ," +
- " `score` int NULL ," +
- " `last_activity` datetime NULL ," +
- " `create_date` datetime NOT NULL ," +
- " `create_player` varchar(36) NOT NULL ," +
- " `pasted` tinyint DEFAULT 0 ," +
- "PRIMARY KEY (`id`)," +
- "KEY `fkIdx_57` (`city_project_id`)," +
- "CONSTRAINT `FK_56` FOREIGN KEY `fkIdx_57` (`city_project_id`) REFERENCES `plotsystem_city_projects` (`id`)," +
- "KEY `fkIdx_60` (`owner_uuid`)," +
- "CONSTRAINT `FK_59` FOREIGN KEY `fkIdx_60` (`owner_uuid`) REFERENCES `plotsystem_builders` (`uuid`)," +
- "KEY `fkIdx_70` (`review_id`)," +
- "CONSTRAINT `FK_69` FOREIGN KEY `fkIdx_70` (`review_id`) REFERENCES `plotsystem_reviews` (`id`)," +
- "KEY `fkIdx_82` (`difficulty_id`)," +
- "CONSTRAINT `FK_81` FOREIGN KEY `fkIdx_82` (`difficulty_id`) REFERENCES `plotsystem_difficulties` (`id`)" +
- ");",
- "ALTER TABLE plotsystem_plots ADD COLUMN IF NOT EXISTS outline longtext NULL DEFAULT NULL;",
- "ALTER TABLE plotsystem_plots ADD COLUMN IF NOT EXISTS type int NOT NULL DEFAULT 1;",
- "ALTER TABLE plotsystem_plots ADD COLUMN IF NOT EXISTS version DOUBLE NULL DEFAULT NULL;",
-
- // API Keys
- "CREATE TABLE IF NOT EXISTS `plotsystem_api_keys`" +
- "(" +
- " `id` int NOT NULL AUTO_INCREMENT ," +
- " `api_key` varchar(32) NOT NULL ," +
- " `created_at` timestamp NOT NULL DEFAULT current_timestamp()," +
- "PRIMARY KEY (`id`)" +
- ");",
-
- // Build-Teams
- "CREATE TABLE IF NOT EXISTS `plotsystem_buildteams` (" +
- "`id` INT(11) NOT NULL AUTO_INCREMENT," +
- "`name` VARCHAR(45) NOT NULL COLLATE 'utf8mb4_general_ci'," +
- "`api_key_id` INT(11) NULL DEFAULT NULL," +
- "PRIMARY KEY (`id`) USING BTREE," +
- "KEY `FK_132` (`api_key_id`)," +
- "CONSTRAINT `FK_130` FOREIGN KEY `FK_132` (`api_key_id`) REFERENCES `plotsystem_api_keys` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
- ")" +
- "COLLATE='utf8mb4_general_ci'" +
- "ENGINE=InnoDB" +
- ";",
-
- // Build-Team has Countries
- "CREATE TABLE IF NOT EXISTS `plotsystem_buildteam_has_countries` (" +
- "`id` INT(11) NOT NULL AUTO_INCREMENT," +
- "`country_id` INT(11) NOT NULL," +
- "`buildteam_id` INT(11) NOT NULL," +
- "PRIMARY KEY (`id`) USING BTREE," +
- "KEY `FK_115` (`buildteam_id`)," +
- "KEY `FK_118` (`country_id`)," +
- "CONSTRAINT `FK_113` FOREIGN KEY `FK_115` (`buildteam_id`) REFERENCES `plotsystem_buildteams` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT," +
- "CONSTRAINT `FK_116` FOREIGN KEY `FK_118` (`country_id`) REFERENCES `plotsystem_countries` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
- ")" +
- "COLLATE='utf8mb4_general_ci'" +
- "ENGINE=InnoDB" +
- ";",
-
- // Builder Is Reviewer
- "CREATE TABLE IF NOT EXISTS `plotsystem_builder_is_reviewer` (" +
- "`id` INT(11) NOT NULL AUTO_INCREMENT," +
- "`builder_uuid` VARCHAR(36) NOT NULL COLLATE 'utf8mb4_general_ci'," +
- "`buildteam_id` INT(11) NOT NULL," +
- "PRIMARY KEY (`id`) USING BTREE," +
- "INDEX `FK_138` (`builder_uuid`) USING BTREE," +
- "INDEX `FK_141` (`buildteam_id`) USING BTREE," +
- "CONSTRAINT `FK_136` FOREIGN KEY (`builder_uuid`) REFERENCES `plotsystem_builders` (`uuid`) ON UPDATE RESTRICT ON DELETE RESTRICT," +
- "CONSTRAINT `FK_139` FOREIGN KEY (`buildteam_id`) REFERENCES `plotsystem_buildteams` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
- ")" +
- "COLLATE='utf8mb4_general_ci'" +
- "ENGINE=InnoDB" +
- ";",
-
- // Payouts
- "CREATE TABLE IF NOT EXISTS `plotsystem_payouts` (" +
- "`id` INT(11) NOT NULL AUTO_INCREMENT," +
- "`timeframe` ENUM('DAILY','WEEKLY','MONTHLY','YEARLY') NOT NULL COLLATE 'utf8mb4_general_ci'," +
- "`position` INT(11) NOT NULL COMMENT 'position on the leaderboard for this timeframe'," +
- "`payout_amount` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_general_ci'," +
- "PRIMARY KEY (`id`) USING BTREE" +
- ")" +
- "COLLATE='utf8mb4_general_ci'" +
- "ENGINE=InnoDB" +
- ";",
-
- // Tutorial Plots
- "CREATE TABLE IF NOT EXISTS `plotsystem_plots_tutorial` (" +
- "`id` INT(11) NOT NULL AUTO_INCREMENT," +
- "`player_uuid` VARCHAR(36) NOT NULL COLLATE 'utf8mb4_general_ci'," +
- "`tutorial_id` INT(11) NOT NULL," +
- "`stage_id` INT(11) NOT NULL DEFAULT '0'," +
- "`is_completed` TINYINT(4) NOT NULL DEFAULT '0'," +
- "`create_date` DATETIME NOT NULL DEFAULT current_timestamp()," +
- "`last_stage_complete_date` DATETIME NULL DEFAULT NULL," +
- "`complete_date` DATETIME NULL DEFAULT NULL," +
- "PRIMARY KEY (`id`) USING BTREE," +
- "INDEX `FK_142` (`player_uuid`) USING BTREE," +
- "CONSTRAINT `FK_12` FOREIGN KEY (`player_uuid`) REFERENCES `plotsystem_builders` (`uuid`) ON UPDATE RESTRICT ON DELETE RESTRICT" +
- ")" +
- "COLLATE='utf8mb4_general_ci'" +
- "ENGINE=InnoDB" +
- ";"
- );
- }
- }
-}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/BuildTeamProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/BuildTeamProvider.java
new file mode 100644
index 000000000..f9ebdec22
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/BuildTeamProvider.java
@@ -0,0 +1,145 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.system.BuildTeam;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.CityProject;
+import com.alpsbte.plotsystem.utils.Utils;
+import org.jetbrains.annotations.NotNull;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+public class BuildTeamProvider {
+ private static final List BUILD_TEAMS = new ArrayList<>();
+ private final CityProjectProvider cityProjectProvider;
+
+ public BuildTeamProvider(BuilderProvider builderProvider, CityProjectProvider cityProjectProvider) {
+ this.cityProjectProvider = cityProjectProvider;
+
+ String qBuildTeams = "SELECT build_team_id, name FROM build_team;";
+ // cache all build teams
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qBuildTeams, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ int buildTeamId = rs.getInt(1);
+ List cityProjects = cityProjectProvider.getCityProjectsByBuildTeam(buildTeamId);
+ List reviewers = builderProvider.getReviewersByBuildTeam(buildTeamId);
+ BUILD_TEAMS.add(new BuildTeam(buildTeamId, rs.getString(2), cityProjects, reviewers));
+ }
+ }));
+ }
+
+ public Optional getBuildTeam(int id) {
+ return BUILD_TEAMS.stream().filter(b -> b.getId() == id).findFirst();
+ }
+
+ public List getBuildTeamsByReviewer(@NotNull UUID reviewerUUID) {
+ var l = BUILD_TEAMS.stream()
+ .filter(b -> b.getReviewers().stream()
+ .anyMatch(r -> r.getUUID().equals(reviewerUUID)))
+ .toList();
+ if (!l.isEmpty()) return l;
+
+ String qIdByUuid = "SELECT build_team_id FROM build_team_has_reviewer WHERE uuid = ?;";
+ return Utils.handleSqlException(new ArrayList<>(), () -> SqlHelper.runQuery(qIdByUuid, ps -> {
+ ps.setString(1, reviewerUUID.toString());
+ ResultSet rs = ps.executeQuery();
+ List buildTeams = new ArrayList<>();
+ while (rs.next()) {
+ Optional buildTeam = getBuildTeam(rs.getInt(1));
+ if (buildTeam.isEmpty()) continue;
+ buildTeams.add(buildTeam.get());
+ }
+ return buildTeams;
+ }));
+ }
+
+ public List getBuildTeams() {
+ return BUILD_TEAMS;
+ }
+
+ public boolean addBuildTeam(String name) {
+ if (BUILD_TEAMS.stream().anyMatch(b -> b.getName().equals(name))) return false;
+
+ String qInsert = "INSERT INTO build_team (name) VALUES (?);";
+ String qByName = "SELECT build_team_id FROM build_team WHERE name = ?;";
+ // get the last inserted build team id
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsert, ps -> {
+ ps.setString(1, name);
+ boolean result = ps.executeUpdate() > 0;
+
+ if (result) {
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qByName, ps.getConnection(), ps2 -> {
+ ps2.setString(1, name);
+ ResultSet rs = ps2.executeQuery();
+ rs.next(); // get the last inserted build team id
+ BUILD_TEAMS.add(new BuildTeam(rs.getInt(1), name));
+ return null; // no need to return anything
+ }));
+ }
+ return result;
+ })));
+ }
+
+ public boolean removeBuildTeam(int id) {
+ Optional cachedBuildTeam = getBuildTeam(id);
+ if (cachedBuildTeam.isEmpty()) return false;
+
+ String qDeleteById = "DELETE FROM build_team WHERE build_team_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDeleteById, ps -> {
+ ps.setInt(1, id);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) BUILD_TEAMS.remove(cachedBuildTeam.get());
+ return result;
+ })));
+ }
+
+ public boolean setBuildTeamName(int id, String newName) {
+ String qSetNameById = "UPDATE build_team SET name = ? WHERE build_team_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetNameById, ps -> {
+ ps.setString(1, newName);
+ ps.setInt(2, id);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean addReviewer(int id, String reviewerUUID) {
+ String qInsertReviewer = "INSERT INTO build_team_has_reviewer (build_team_id, uuid) VALUES (?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runInsertQuery(qInsertReviewer, ps -> {
+ ps.setInt(1, id);
+ ps.setString(2, reviewerUUID);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean removeReviewer(int id, String reviewerUUID) {
+ String qDeleteReviewer = "DELETE FROM build_team_has_reviewer WHERE build_team_id = ? AND uuid = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDeleteReviewer, ps -> {
+ ps.setInt(1, id);
+ ps.setString(2, reviewerUUID);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean isAnyReviewer(@NotNull UUID reviewerUUID) {
+ return BUILD_TEAMS.stream()
+ .anyMatch(bt -> bt.getReviewers().stream()
+ .anyMatch(r -> r.getUUID().equals(reviewerUUID))
+ );
+ }
+
+ public List getReviewerCities(UUID reviewerUUID) {
+ List buildTeams = BUILD_TEAMS.stream().filter(b
+ -> b.getReviewers().stream().anyMatch(r -> r.getUUID().equals(reviewerUUID))).toList();
+ List cities = new ArrayList<>();
+
+ for (BuildTeam buildTeam : buildTeams) {
+ cities.addAll(cityProjectProvider.getCityProjectsByBuildTeam(buildTeam.getId()));
+ }
+ return cities;
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/BuilderProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/BuilderProvider.java
new file mode 100644
index 000000000..ad2d65780
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/BuilderProvider.java
@@ -0,0 +1,253 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.holograms.leaderboards.LeaderboardTimeframe;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.Plot;
+import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.enums.Slot;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class BuilderProvider {
+ protected static final Map BUILDERS = new HashMap<>();
+ private static final String Q_SLOTS_BY_UUID = "SELECT first_slot, second_slot, third_slot FROM builder WHERE uuid = ?;";
+
+ public Builder getBuilderByUUID(UUID uuid) {
+ if (BUILDERS.containsKey(uuid)) return BUILDERS.get(uuid);
+
+ String qByUuid = "SELECT name, score, first_slot, second_slot, third_slot, plot_type FROM builder WHERE uuid = ?;";
+ return Utils.handleSqlException(null, () -> SqlHelper.runQuery(qByUuid, ps -> {
+ ps.setString(1, uuid.toString());
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) {
+ Builder builder = new Builder(uuid, rs.getString(1), rs.getInt(2), rs.getInt(3),
+ rs.getInt(4), rs.getInt(5), rs.getInt(6));
+ BUILDERS.put(uuid, builder); // cache the builder
+ return builder;
+ }
+ return null;
+ }));
+ }
+
+ public Builder getBuilderByName(String name) {
+ for (var i : BUILDERS.values()) {
+ if (i.getName().equalsIgnoreCase(name)) {
+ return i; // return cached builder if name matches
+ }
+ }
+
+ String qUuidByName = "SELECT uuid FROM builder WHERE name = ?;";
+ return Utils.handleSqlException(null, () -> SqlHelper.runQuery(qUuidByName, ps -> {
+ ps.setString(1, name);
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) {
+ String uuid = rs.getString(1);
+ if (uuid != null) return getBuilderByUUID(UUID.fromString(uuid));
+ }
+ return null;
+ }));
+ }
+
+ public boolean addBuilderIfNotExists(UUID uuid, String name) {
+ if (BUILDERS.containsKey(uuid)) return true;
+
+ String qExistsByUuid = "SELECT 1 FROM builder WHERE uuid = ?;";
+ String qInsert = "INSERT INTO builder (uuid, name, plot_type) VALUES (?, ?, 1);";
+ // builder already exists
+ // insert new builder
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qExistsByUuid, ps -> {
+ ps.setString(1, uuid.toString());
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) return true; // builder already exists
+
+ return SqlHelper.runQuery(qInsert, ps.getConnection(), insertStmt -> {
+ insertStmt.setString(1, uuid.toString());
+ insertStmt.setString(2, name);
+ return insertStmt.executeUpdate() > 0; // insert new builder
+ });
+ })));
+ }
+
+ public boolean setName(@NotNull UUID uuid, String name) {
+ String qSetNameByUuid = "UPDATE builder SET name = ? WHERE uuid = ?;";
+ // update builder name
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetNameByUuid, ps -> {
+ ps.setString(1, name);
+ ps.setString(2, uuid.toString());
+ return ps.executeUpdate() > 0; // update builder name
+ })));
+ }
+
+ public boolean addScore(@NotNull UUID uuid, int score) {
+ String qIncreaseScoreByUuid = "UPDATE builder b SET score = (b.score + ?) WHERE uuid = ?;";
+ // increase score by given value
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qIncreaseScoreByUuid, ps -> {
+ ps.setInt(1, score);
+ ps.setString(2, uuid.toString());
+ return ps.executeUpdate() > 0; // increase score by given value
+ })));
+ }
+
+ public boolean setSlot(UUID uuid, int plotID, @NotNull Slot slot) {
+ String qBuilderSetSlotByUuid = "UPDATE builder b SET " + slot.name().toLowerCase() + "_slot = " + (plotID > 0 ? "?" : "DEFAULT(first_slot)") + " WHERE uuid = ?;";
+ // update builder slot
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qBuilderSetSlotByUuid, ps -> {
+ if (plotID > 0) ps.setInt(1, plotID);
+ ps.setString(plotID > 0 ? 2 : 1, uuid.toString());
+ return ps.executeUpdate() > 0; // update builder slot
+ })));
+ }
+
+ public boolean setPlotType(@NotNull UUID uuid, int plotTypeId) {
+ String qSetPlotTypeByUuid = "UPDATE builder b SET plot_type = ? WHERE uuid = ?;";
+ // update plot type
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetPlotTypeByUuid, ps -> {
+ ps.setInt(1, plotTypeId);
+ ps.setString(2, uuid.toString());
+ return ps.executeUpdate() > 0; // update plot type
+ })));
+ }
+
+ public int getCompletedBuildsCount(@NotNull UUID uuid) {
+ String qBuilderCompletedBuildsCountByUuid = "SELECT COUNT(p.plot_id) AS completed_plots FROM plot p INNER JOIN builder_is_plot_member " +
+ "bipm ON p.plot_id = bipm.plot_id WHERE p.status = 'completed' AND (p.owner_uuid = ? OR bipm.uuid = ?);";
+ Integer result = Utils.handleSqlException(0, () -> SqlHelper.runQuery(qBuilderCompletedBuildsCountByUuid, ps -> {
+ ps.setString(1, uuid.toString());
+ ps.setString(2, uuid.toString());
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) return rs.getInt(1);
+ return 0;
+ }));
+ return result != null ? result : 0;
+ }
+
+ public Slot getFreeSlot(@NotNull UUID uuid) {
+ return Utils.handleSqlException(null, () -> SqlHelper.runQuery(Q_SLOTS_BY_UUID, ps -> {
+ ps.setString(1, uuid.toString());
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) return null; // no slots found
+ for (int i = 1; i <= 3; i++) {
+ if (rs.getString(i) == null) return Slot.values()[i - 1]; // return first free slot
+ }
+ return null; // no free slots found
+ }));
+ }
+
+ public Slot getSlot(@NotNull UUID uuid, int plotId) {
+ return Utils.handleSqlException(null, () -> SqlHelper.runQuery(Q_SLOTS_BY_UUID, ps -> {
+ ps.setString(1, uuid.toString());
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) return null; // no slots found
+ if (rs.getInt(1) == plotId) return Slot.FIRST; // first slot
+ if (rs.getInt(2) == plotId) return Slot.SECOND; // second slot
+ if (rs.getInt(3) == plotId) return Slot.THIRD; // third slot
+ return null; // no matching slot found
+ }));
+ }
+
+ public boolean canNotReviewPlot(@NotNull UUID uuid, Plot plot) {
+ return DataProvider.BUILD_TEAM.getReviewerCities(uuid).stream().noneMatch(c -> c.getId().equals(plot.getCityProject().getId()));
+ }
+
+ public List getReviewersByBuildTeam(int buildTeamId) {
+ String qReviewerUuidByBtId = "SELECT uuid FROM build_team_has_reviewer WHERE build_team_id = ?;";
+ return Utils.handleSqlException(new ArrayList<>(), () -> SqlHelper.runQuery(qReviewerUuidByBtId, ps -> {
+ ps.setInt(1, buildTeamId);
+ ResultSet rs = ps.executeQuery();
+ List builders = new ArrayList<>();
+ while (rs.next()) {
+ Builder builder = getBuilderByUUID(UUID.fromString(rs.getString(1)));
+ if (builder != null) builders.add(builder);
+ }
+ return builders;
+ }));
+ }
+
+ /**
+ * Retrieves the leaderboard entries for all players within a specified timeframe, including their names and scores.
+ *
+ * @param sortBy the timeframe used to filter leaderboard data (e.g., daily, weekly, etc.).
+ * @return provides a map of player names and their scores, or an empty map if no data is found.
+ */
+ public Map getLeaderboardEntries(LeaderboardTimeframe sortBy) {
+ return Utils.handleSqlException(new LinkedHashMap<>(), () -> SqlHelper.runQuery(getLeaderboardQuery(sortBy), ps -> {
+ ResultSet rs = ps.executeQuery();
+ LinkedHashMap playerEntries = new LinkedHashMap<>();
+ while (rs.next()) {
+ playerEntries.put(rs.getString(1), rs.getInt(2));
+ }
+ return playerEntries;
+ }));
+ }
+
+ /**
+ * Constructs a SQL query to retrieve leaderboard data by sorting based on a given timeframe.
+ *
+ * This query returns the top leaderboard entries ordered by the score
+ * within the specified timeframe.
+ *
+ * @param sortBy the timeframe used to filter entries. Determines the minimum date for reviews
+ * (e.g., daily, weekly, monthly, yearly).
+ * @return the constructed SQL query as a {@code String}.
+ */
+ @Contract(pure = true)
+ private static @NotNull String getLeaderboardQuery(@NotNull LeaderboardTimeframe sortBy) {
+ String minimumDate = switch (sortBy) {
+ case DAILY -> "(NOW() - INTERVAL 1 DAY)";
+ case WEEKLY -> "(NOW() - INTERVAL 1 WEEK)";
+ case MONTHLY -> "(NOW() - INTERVAL 1 MONTH)";
+ case YEARLY -> "(NOW() - INTERVAL 1 YEAR)";
+ default -> null;
+ };
+
+ return "WITH latest_reviews AS ( "
+ + " SELECT pr.* "
+ + " FROM plot_review pr "
+ + " INNER JOIN ( "
+ + " SELECT plot_id, MAX(review_date) AS latest_review_date "
+ + " FROM plot_review "
+ + " GROUP BY plot_id "
+ + " ) latest ON pr.plot_id = latest.plot_id AND pr.review_date = latest.latest_review_date "
+ + "), "
+ + "plot_member_counts AS ( "
+ + " SELECT plot_id, COUNT(*) AS member_count "
+ + " FROM builder_is_plot_member "
+ + " GROUP BY plot_id "
+ + "), "
+ + "all_builders AS ( "
+ + " SELECT "
+ + " p.owner_uuid AS builder_uuid, "
+ + " p.plot_id "
+ + " FROM plot p "
+ + " WHERE p.status = 'completed' "
+ + " UNION ALL "
+ + " SELECT "
+ + " bipm.uuid AS builder_uuid, "
+ + " bipm.plot_id "
+ + " FROM builder_is_plot_member bipm "
+ + " JOIN plot p ON p.plot_id = bipm.plot_id "
+ + " WHERE p.status = 'completed' "
+ + ") "
+ + "SELECT b.name, SUM( "
+ + " IF(pmc.member_count IS NULL OR pmc.member_count = 0, lr.score, FLOOR(lr.score / (pmc.member_count + 1))) "
+ + ") AS total_score "
+ + "FROM all_builders ab "
+ + "JOIN builder b ON b.uuid = ab.builder_uuid "
+ + "JOIN latest_reviews lr ON lr.plot_id = ab.plot_id "
+ + "LEFT JOIN plot_member_counts pmc ON pmc.plot_id = ab.plot_id "
+ + (minimumDate != null ? "WHERE lr.review_date BETWEEN " + minimumDate + " AND NOW() " : "")
+ + "GROUP BY b.name "
+ + "ORDER BY total_score DESC, b.name "
+ + "LIMIT 10;";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/CityProjectProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/CityProjectProvider.java
new file mode 100644
index 000000000..2030e3dee
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/CityProjectProvider.java
@@ -0,0 +1,105 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.system.CityProject;
+import com.alpsbte.plotsystem.utils.Utils;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+public class CityProjectProvider {
+ protected static final List CITY_PROJECTS = new ArrayList<>();
+
+ public CityProjectProvider() {
+ String qCityProjects = "SELECT city_project_id, country_code, server_name, is_visible, build_team_id FROM city_project;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qCityProjects, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ CITY_PROJECTS.add(new CityProject(rs.getString(1), // cache all city projects
+ rs.getString(2), rs.getString(3), rs.getBoolean(4), rs.getInt(5)));
+ }
+ }));
+ }
+
+ public Optional getById(String id) {
+ return CITY_PROJECTS.stream().filter(c -> c.getId().equals(id)).findFirst();
+ }
+
+ public List getByCountryCode(String countryCode, boolean onlyVisible) {
+ return CITY_PROJECTS.stream().filter(c -> (!onlyVisible || c.isVisible()) &&
+ c.getCountry().getCode().equals(countryCode)).toList();
+ }
+
+ public List get(boolean onlyVisible) {
+ return CITY_PROJECTS.stream().filter(c -> !onlyVisible || c.isVisible()).toList();
+ }
+
+ public List getCityProjectsByBuildTeam(int buildTeamId) {
+ String qIdByBtId = "SELECT city_project_id FROM city_project WHERE build_team_id = ?;";
+ return Utils.handleSqlException(new ArrayList<>(), () -> SqlHelper.runQuery(qIdByBtId, ps -> {
+ ps.setInt(1, buildTeamId);
+ ResultSet rs = ps.executeQuery();
+ List cityProjects = new ArrayList<>();
+ while (rs.next()) {
+ Optional city = getById(rs.getString(1));
+ city.ifPresent(cityProjects::add);
+ }
+ return cityProjects;
+ }));
+ }
+
+ public boolean add(String id, int buildTeamId, String countryCode, String serverName) {
+ if (getById(id).isPresent()) return true;
+
+ String qInsert = "INSERT INTO city_project (city_project_id, build_team_id, country_code, server_name) VALUES (?, ?, ?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsert, ps -> {
+ ps.setString(1, id);
+ ps.setInt(2, buildTeamId);
+ ps.setString(3, countryCode);
+ ps.setString(4, serverName);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) CITY_PROJECTS.add(new CityProject(id, countryCode, serverName, true, buildTeamId));
+ return result;
+ })));
+ }
+
+ public boolean remove(String id) {
+ Optional cityProject = getById(id);
+ String qDelete = "DELETE FROM city_project WHERE city_project_id = ?;";
+ return cityProject.filter(project -> Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDelete, ps -> {
+ ps.setString(1, id);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) CITY_PROJECTS.remove(project);
+ return result;
+ })))).isPresent();
+ }
+
+ public boolean setVisibility(String id, boolean isVisible) {
+ String qUpdateVisible = "UPDATE city_project SET is_visible = ? WHERE city_project_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qUpdateVisible, ps -> {
+ ps.setBoolean(1, isVisible);
+ ps.setString(2, id);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setServer(String id, String serverName) {
+ String qUpdateServerName = "UPDATE city_project SET server_name = ? WHERE city_project_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qUpdateServerName, ps -> {
+ ps.setString(1, serverName);
+ ps.setString(2, id);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setBuildTeam(String id, int buildTeamId) {
+ String qUpdateBuildTeamId = "UPDATE city_project SET build_team_id = ? WHERE city_project_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qUpdateBuildTeamId, ps -> {
+ ps.setInt(1, buildTeamId);
+ ps.setString(2, id);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/CountryProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/CountryProvider.java
new file mode 100644
index 000000000..df759ce1c
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/CountryProvider.java
@@ -0,0 +1,79 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.system.Country;
+import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.enums.Continent;
+import org.jetbrains.annotations.Nullable;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+public class CountryProvider {
+ protected static final List COUNTRIES = new ArrayList<>();
+
+ public CountryProvider() {
+ String qAll = "SELECT country_code, continent, material, custom_model_data FROM country;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qAll, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ Continent continent = Continent.fromDatabase(rs.getString(2));
+ Country country = new Country(rs.getString(1), continent, rs.getString(3),
+ rs.getString(4));
+ COUNTRIES.add(country); // cache all countries
+ }
+ }));
+ }
+
+ public List getCountries() {
+ return COUNTRIES;
+ }
+
+ public List getCountriesByContinent(Continent continent) {
+ return COUNTRIES.stream().filter(c -> c.getContinent() == continent).toList();
+ }
+
+ public Optional getCountryByCode(String code) {
+ return COUNTRIES.stream().filter(c -> c.getCode().equals(code)).findFirst();
+ }
+
+ public boolean setMaterialAndCustomModelData(String code, String material, @Nullable String customModelData) {
+ String qSetItem = "UPDATE country SET material = ?, custom_model_data = ? WHERE country_code = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetItem, ps -> {
+ ps.setString(1, material);
+ ps.setString(2, customModelData);
+ ps.setString(3, code);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean addCountry(String code, Continent continent, String material, @Nullable String customModelData) {
+ if (getCountryByCode(code).isPresent()) return true;
+
+ String qInsert = "INSERT INTO country (country_code, continent, material, custom_model_data) VALUES (?, ?, ?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsert, ps -> {
+ ps.setString(1, code);
+ ps.setString(2, continent.databaseEnum);
+ ps.setString(3, material);
+ ps.setString(4, customModelData);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) COUNTRIES.add(new Country(code, continent, material, customModelData));
+ return result;
+ })));
+ }
+
+ public boolean removeCountry(String code) {
+ Optional cachedCountry = getCountryByCode(code);
+ if (cachedCountry.isEmpty()) return false;
+
+ String qDelete = "DELETE FROM country WHERE country_code = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDelete, ps -> {
+ ps.setString(1, code);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) COUNTRIES.remove(cachedCountry.get());
+ return result;
+ })));
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/DifficultyProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/DifficultyProvider.java
new file mode 100644
index 000000000..95d6d2914
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/DifficultyProvider.java
@@ -0,0 +1,79 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.Difficulty;
+import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.enums.PlotDifficulty;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static net.kyori.adventure.text.Component.text;
+
+public class DifficultyProvider {
+ protected static final List DIFFICULTIES = new ArrayList<>();
+
+ public DifficultyProvider() {
+ // cache all difficulties
+ String qAll = "SELECT difficulty_id, multiplier, score_requirement FROM plot_difficulty;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qAll, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ String id = rs.getString(1);
+ double multiplier = rs.getDouble(2);
+ int scoreRequirement = rs.getInt(3);
+
+ Difficulty difficulty = new Difficulty(PlotDifficulty.valueOf(id), id, multiplier, scoreRequirement);
+ DIFFICULTIES.add(difficulty); // cache all difficulties
+ }
+ }));
+ }
+
+ public List getDifficulties() {
+ return DIFFICULTIES;
+ }
+
+ public Optional getDifficultyById(String id) {
+ return DIFFICULTIES.stream().filter(d -> d.getID().equalsIgnoreCase(id)).findAny();
+ }
+
+ public Optional getDifficultyByEnum(PlotDifficulty difficulty) {
+ if (difficulty == null) return Optional.empty();
+ return DIFFICULTIES.stream().filter(d -> d.getID().equalsIgnoreCase(difficulty.name())).findFirst();
+ }
+
+ public boolean setMultiplier(String id, double multiplier) {
+ String qSetMulti = "UPDATE plot_difficulty SET multiplier = ? WHERE difficulty_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetMulti, ps -> {
+ ps.setDouble(1, multiplier);
+ ps.setString(2, id);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setScoreRequirement(String id, int scoreRequirement) {
+ String qSetScoreRequirement = "UPDATE plot_difficulty SET score_requirement = ? WHERE difficulty_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetScoreRequirement, ps -> {
+ ps.setInt(1, scoreRequirement);
+ ps.setString(2, id);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean builderMeetsRequirements(Builder builder, PlotDifficulty plotDifficulty) {
+ Optional cachedDifficulty = getDifficultyByEnum(plotDifficulty);
+ if (cachedDifficulty.isEmpty()) {
+ PlotSystem.getPlugin().getComponentLogger().error(text("No database entry for difficulty "
+ + plotDifficulty.toString() + " was found!"));
+ return false;
+ }
+
+ int playerScore = builder.getScore();
+ int scoreRequirement = cachedDifficulty.get().getScoreRequirement();
+ return playerScore >= scoreRequirement;
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/PlotProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/PlotProvider.java
new file mode 100644
index 000000000..c06507f41
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/PlotProvider.java
@@ -0,0 +1,268 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.CityProject;
+import com.alpsbte.plotsystem.core.system.plot.Plot;
+import com.alpsbte.plotsystem.core.system.plot.utils.PlotType;
+import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.enums.PlotDifficulty;
+import com.alpsbte.plotsystem.utils.enums.Status;
+import org.bukkit.Bukkit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class PlotProvider {
+ private static final String PLOT_SQL_COLUMNS = "plot.plot_id, plot.city_project_id, plot.difficulty_id, " +
+ "plot.owner_uuid, plot.status, plot.outline_bounds, plot.last_activity_date, " +
+ "plot.plot_version, plot.plot_type";
+
+ public Plot getPlotById(int plotId) {
+ String qGet = "SELECT " + PLOT_SQL_COLUMNS + " FROM plot WHERE plot_id = ?;";
+ return Utils.handleSqlException(null, () -> SqlHelper.runQuery(qGet, ps -> {
+ ps.setInt(1, plotId);
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) return null; // No plot found
+ return extractPlot(rs);
+ }));
+ }
+
+ public List getPlots(@NotNull Status status) {
+ String qAllByStatus = "SELECT " + PLOT_SQL_COLUMNS + " FROM plot WHERE status = ?;";
+ return Utils.handleSqlException(List.of(), () -> SqlHelper.runQuery(qAllByStatus, ps -> {
+ ps.setString(1, status.name());
+ ResultSet rs = ps.executeQuery();
+ List plots = new ArrayList<>();
+ while (rs.next()) {
+ plots.add(extractPlot(rs));
+ }
+ return plots;
+ }));
+ }
+
+ public List getPlots(@NotNull CityProject city, Status @NotNull ... statuses) {
+ String query = "SELECT " + PLOT_SQL_COLUMNS + " FROM plot WHERE city_project_id = ?";
+ query += statuses.length > 0 ? " AND status IN (" + "?,".repeat(statuses.length - 1) + "?);" : ";";
+ String qPlotsWithCityAndStatuses = query;
+ return Utils.handleSqlException(List.of(), () -> SqlHelper.runQuery(qPlotsWithCityAndStatuses, ps -> {
+ ps.setString(1, city.getId());
+ for (int i = 0; i < statuses.length; i++) ps.setString(i + 2, statuses[i].name());
+ ResultSet rs = ps.executeQuery();
+ List plots = new ArrayList<>();
+ while (rs.next()) plots.add(extractPlot(rs));
+ return plots;
+ }));
+ }
+
+ public List getPlots(@NotNull CityProject city, @NotNull PlotDifficulty plotDifficulty, @NotNull Status status) {
+ String qAllByCityDifficultyStatus = "SELECT " + PLOT_SQL_COLUMNS + " FROM plot WHERE city_project_id = ? AND difficulty_id = ? AND status = ?;";
+ return Utils.handleSqlException(List.of(), () -> SqlHelper.runQuery(qAllByCityDifficultyStatus, ps -> {
+ ps.setString(1, city.getId());
+ ps.setString(2, plotDifficulty.name());
+ ps.setString(3, status.name());
+ ResultSet rs = ps.executeQuery();
+ List plots = new ArrayList<>();
+ while (rs.next()) plots.add(extractPlot(rs));
+ return plots;
+ }));
+ }
+
+ public List getPlots(@NotNull List cities, Status... statuses) {
+ if (cities.isEmpty()) return List.of();
+
+ String cityPlaceholders = "?,".repeat(cities.size() - 1) + "?";
+ String query = "SELECT " + PLOT_SQL_COLUMNS + " FROM plot WHERE city_project_id IN (" + cityPlaceholders + ")";
+ query += statuses.length > 0 ? " AND status IN (" + "?,".repeat(statuses.length - 1) + "?) ORDER BY plot.plot_id;" : ";";
+ String qPlotsWithCitiesAndStatuses = query;
+
+ return Utils.handleSqlException(List.of(), () -> SqlHelper.runQuery(qPlotsWithCitiesAndStatuses, ps -> {
+ int index = 1;
+ for (CityProject city : cities) ps.setString(index++, city.getId());
+ for (Status status : statuses) ps.setString(index++, status.name());
+
+ ResultSet rs = ps.executeQuery();
+ List plots = new ArrayList<>();
+ while (rs.next()) plots.add(extractPlot(rs));
+ return plots;
+ }));
+ }
+
+ public List getPlots(@NotNull Builder builder, Status @NotNull ... statuses) {
+ String query = "SELECT " + PLOT_SQL_COLUMNS + " FROM plot LEFT JOIN builder_is_plot_member pm ON " +
+ "plot.plot_id = pm.plot_id WHERE (plot.owner_uuid = ? OR pm.uuid = ?)";
+ query += statuses.length > 0 ? "AND plot.status IN (" + "?,".repeat(statuses.length - 1) + "?);" : ";";
+ String qPlotsWithBuilderAndStatuses = query;
+ return Utils.handleSqlException(List.of(), () -> SqlHelper.runQuery(qPlotsWithBuilderAndStatuses, ps -> {
+ String builderUUID = builder.getUUID().toString();
+ ps.setString(1, builderUUID);
+ ps.setString(2, builderUUID);
+ for (int i = 0; i < statuses.length; i++) ps.setString(i + 3, statuses[i].name());
+
+ ResultSet rs = ps.executeQuery();
+ List plots = new ArrayList<>();
+ while (rs.next()) plots.add(extractPlot(rs));
+ return plots;
+ }));
+ }
+
+ private @NotNull Plot extractPlot(@NotNull ResultSet rs) throws SQLException {
+ int plotId = rs.getInt("plot_id");
+ CityProject cityProject = DataProvider.CITY_PROJECT.getById(rs.getString("city_project_id")).orElseThrow();
+ PlotDifficulty difficulty = DataProvider.DIFFICULTY.getDifficultyById(rs.getString("difficulty_id")).orElseThrow().getDifficulty();
+
+ String ownerUUIDString = rs.getString("owner_uuid");
+ UUID ownerUUID = ownerUUIDString != null ? UUID.fromString(ownerUUIDString) : null;
+
+ Status status = Status.valueOf(rs.getString("status"));
+ String outlineBounds = rs.getString("outline_bounds");
+ Date lastActivity = rs.getDate("last_activity_date");
+
+ double version = rs.getDouble("plot_version");
+ PlotType type = PlotType.byId(rs.getInt("plot_type"));
+
+ return new Plot(
+ plotId,
+ cityProject,
+ difficulty,
+ ownerUUID,
+ status,
+ outlineBounds,
+ lastActivity != null ? lastActivity.toLocalDate() : null,
+ version,
+ type,
+ getPlotMembers(plotId));
+ }
+
+ public List getPlotMembers(int plotId) {
+ String qAllMembers = "SELECT uuid FROM builder_is_plot_member WHERE plot_id = ?;";
+ return Utils.handleSqlException(new ArrayList<>(), () -> SqlHelper.runQuery(qAllMembers, ps -> {
+ ps.setInt(1, plotId);
+ ResultSet rs = ps.executeQuery();
+ List members = new ArrayList<>();
+ while (rs.next()) {
+ members.add(Builder.byUUID(UUID.fromString(rs.getString(1))));
+ }
+ return members;
+ }));
+ }
+
+ public byte[] getInitialSchematic(int plotId) {
+ return getSchematic(plotId, "initial_schematic");
+ }
+
+ public byte[] getCompletedSchematic(int plotId) {
+ return getSchematic(plotId, "complete_schematic");
+ }
+
+ private byte @Nullable [] getSchematic(int plotId, String name) {
+ String qName = "SELECT " + name + " FROM plot WHERE plot_id = ?;";
+ return Utils.handleSqlException(null, () -> SqlHelper.runQuery(qName, ps -> {
+ ps.setInt(1, plotId);
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) return null;
+ return rs.getBytes(1);
+ }));
+ }
+
+ public boolean setCompletedSchematic(int plotId, byte[] completedSchematic) {
+ String qSetCompleteSchematic = "UPDATE plot SET complete_schematic = ? WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetCompleteSchematic, ps -> {
+ ps.setBytes(1, completedSchematic);
+ ps.setInt(2, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setPlotOwner(int plotId, UUID ownerUUID) {
+ String qSetOwner = "UPDATE plot SET owner_uuid = " + (ownerUUID == null ? "DEFAULT(owner_uuid)" : "?") + " WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetOwner, ps -> {
+ if (ownerUUID == null) {
+ ps.setInt(1, plotId);
+ } else {
+ ps.setString(1, ownerUUID.toString());
+ ps.setInt(2, plotId);
+ }
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setLastActivity(int plotId, LocalDate activityDate) {
+ String qSetLastActivityDate = "UPDATE plot SET last_activity_date = ? WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetLastActivityDate, ps -> {
+ ps.setDate(1, activityDate == null ? null : Date.valueOf(activityDate));
+ ps.setInt(2, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setStatus(int plotId, @NotNull Status status) {
+ String qSetStatus = "UPDATE plot SET status = ? WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetStatus, ps -> {
+ ps.setString(1, status.name());
+ ps.setInt(2, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setMcVersion(int plotId) {
+ String qSetMcVersion = "UPDATE plot SET mc_version = ? WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetMcVersion, ps -> {
+ ps.setString(1, Bukkit.getMinecraftVersion());
+ ps.setInt(2, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setPlotType(int plotId, @NotNull PlotType type) {
+ String qSetType = "UPDATE plot SET plot_type = ? WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetType, ps -> {
+ ps.setInt(1, type.getId());
+ ps.setInt(2, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setPasted(int plotId, boolean pasted) {
+ String qSetPasted = "UPDATE plot SET is_pasted = ? WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetPasted, ps -> {
+ ps.setBoolean(1, pasted);
+ ps.setInt(2, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean deletePlot(int plotId) {
+ String qDelete = "DELETE FROM plot WHERE plot_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDelete, ps -> {
+ ps.setInt(1, plotId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean addPlotMember(int id, Builder member) {
+ String qInsertPlotMember = "INSERT INTO builder_is_plot_member (plot_id, uuid) VALUES (?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsertPlotMember, ps -> {
+ ps.setInt(1, id);
+ ps.setString(2, member.getUUID().toString());
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean removePlotMember(int id, Builder member) {
+ String qDeletePlotMember = "DELETE FROM builder_is_plot_member WHERE plot_id = ? AND uuid = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDeletePlotMember, ps -> {
+ ps.setInt(1, id);
+ ps.setString(2, member.getUUID().toString());
+ return ps.executeUpdate() > 0;
+ })));
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/ReviewProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/ReviewProvider.java
new file mode 100644
index 000000000..f5656fff1
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/ReviewProvider.java
@@ -0,0 +1,345 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.Plot;
+import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
+import com.alpsbte.plotsystem.core.system.review.BuildTeamToggleCriteria;
+import com.alpsbte.plotsystem.core.system.review.PlotReview;
+import com.alpsbte.plotsystem.core.system.review.ReviewNotification;
+import com.alpsbte.plotsystem.core.system.review.ReviewRating;
+import com.alpsbte.plotsystem.core.system.review.ToggleCriteria;
+import com.alpsbte.plotsystem.utils.Utils;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+public class ReviewProvider {
+ protected static final List NOTIFICATIONS = new ArrayList<>();
+ protected static final List TOGGLE_CRITERIA = new ArrayList<>();
+ protected static final List BUILD_TEAM_TOGGLE_CRITERIA = new ArrayList<>();
+
+ public ReviewProvider() {
+ // cache all review notifications
+ String qAllNotifys = "SELECT review_id, uuid FROM builder_has_review_notification;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qAllNotifys, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ NOTIFICATIONS.add(new ReviewNotification(rs.getInt(1), UUID.fromString(rs.getString(2))));
+ }
+ }));
+
+ // cache all toggle criteria
+ String qAllToggleCriterias = "SELECT criteria_name, is_optional FROM review_toggle_criteria;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qAllToggleCriterias, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ TOGGLE_CRITERIA.add(new ToggleCriteria(rs.getString(1), rs.getBoolean(2)));
+ }
+ }));
+
+ // cache all build team toggle criteria
+ String qAllBuildteamCriteria = "SELECT criteria_name, build_team_id FROM build_team_uses_toggle_criteria;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qAllBuildteamCriteria, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ String criteriaName = rs.getString(1);
+ ToggleCriteria toggle = TOGGLE_CRITERIA.stream().filter(c -> c.criteriaName().equals(criteriaName)).findFirst().orElseThrow();
+ BUILD_TEAM_TOGGLE_CRITERIA.add(new BuildTeamToggleCriteria(rs.getInt(2), toggle));
+ }
+ }));
+ }
+
+ public Optional getReview(int reviewId) {
+ String qById = "SELECT plot_id, rating, score, feedback, reviewed_by FROM plot_review WHERE review_id = ?;";
+ return Utils.handleSqlException(Optional.empty(), () -> SqlHelper.runQuery(qById, ps -> {
+ ps.setInt(1, reviewId);
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) return Optional.empty();
+
+ int plotId = rs.getInt(1);
+ ReviewRating rating = getReviewRating(reviewId, rs.getString(2));
+ int score = rs.getInt(3);
+ String feedback = rs.getString(4);
+ UUID reviewedBy = UUID.fromString(rs.getString(5));
+
+ return Optional.of(new PlotReview(reviewId, plotId, rating, score, feedback, reviewedBy));
+ }));
+ }
+
+ public Optional getLatestReview(int plotId) {
+ String qLatestByPlotId = "SELECT review_id, rating, score, feedback, reviewed_by FROM plot_review WHERE plot_id = ? ORDER BY review_date DESC LIMIT 1;";
+ return Utils.handleSqlException(Optional.empty(), () -> SqlHelper.runQuery(qLatestByPlotId, ps -> {
+ ps.setInt(1, plotId);
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) return Optional.empty();
+
+ int reviewId = rs.getInt(1);
+ ReviewRating rating = getReviewRating(reviewId, rs.getString(2));
+ int score = rs.getInt(3);
+ String feedback = rs.getString(4);
+ UUID reviewedBy = UUID.fromString(rs.getString(5));
+
+ return Optional.of(new PlotReview(reviewId, plotId, rating, score, feedback, reviewedBy));
+ }));
+ }
+
+ public List getPlotReviewHistory(int plotId) {
+ String qByPlotId = "SELECT review_id, rating, score, feedback, reviewed_by FROM plot_review WHERE plot_id = ?;";
+ return Utils.handleSqlException(new ArrayList<>(), () -> SqlHelper.runQuery(qByPlotId, ps -> {
+ ps.setInt(1, plotId);
+ ResultSet rs = ps.executeQuery();
+ List reviews = new ArrayList<>();
+ while (rs.next()) {
+ int reviewId = rs.getInt(1);
+ ReviewRating rating = getReviewRating(reviewId, rs.getString(2));
+ int score = rs.getInt(3);
+ String feedback = rs.getString(4);
+ UUID reviewedBy = UUID.fromString(rs.getString(5));
+
+ reviews.add(new PlotReview(reviewId, plotId, rating, score, feedback, reviewedBy));
+ }
+ return reviews;
+ }));
+ }
+
+ private @NotNull ReviewRating getReviewRating(int reviewId, @NotNull String ratingString) {
+ int accuracyPoints = Integer.parseInt(ratingString.split(",")[0]);
+ int blockPalettePoints = Integer.parseInt(ratingString.split(",")[1]);
+ Map toggleCriteria = getReviewToggleCriteria(reviewId);
+ return new ReviewRating(accuracyPoints, blockPalettePoints, toggleCriteria);
+ }
+
+ public boolean updateFeedback(int reviewId, String newFeedback) {
+ String qSetFeedback = "UPDATE plot_review SET feedback = ? WHERE review_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetFeedback, ps -> {
+ ps.setString(1, newFeedback);
+ ps.setInt(2, reviewId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public PlotReview createReview(@NotNull Plot plot, ReviewRating rating, int score, UUID reviewerUUID) {
+ boolean result = DataProvider.PLOT.setMcVersion(plot.getId());
+ if (!result) return null;
+
+ // Create Review
+ String qInsert = "INSERT INTO plot_review (plot_id, rating, score, reviewed_by) VALUES (?, ?, ?, ?);";
+ result = Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsert, ps -> {
+ ps.setInt(1, plot.getId());
+ ps.setString(2, rating.getRatingDatabaseString());
+ ps.setInt(3, score);
+ ps.setString(4, reviewerUUID.toString());
+ return ps.executeUpdate() > 0;
+ })));
+
+ if (!result) return null;
+
+ PlotReview review = plot.getLatestReview().orElseThrow();
+ Map allToggles = rating.getAllToggles();
+ for (Map.Entry criteriaEntry : allToggles.entrySet()) {
+ if (!addReviewToggleCriteria(review.getReviewId(), criteriaEntry.getKey(), criteriaEntry.getValue()))
+ return null;
+ }
+
+
+ // create feedback notifications
+ createReviewNotification(review.getReviewId(), plot.getPlotOwner().getUUID());
+ for (Builder builder : plot.getPlotMembers()) {
+ createReviewNotification(review.getReviewId(), builder.getUUID());
+ }
+ return review;
+ }
+
+ public boolean removeReview(int reviewId) {
+ // remove all review notifications
+ List notifications = getReviewNotifications(reviewId);
+ for (ReviewNotification notification : notifications) {
+ removeReviewNotification(notification.reviewId(), notification.uuid());
+ }
+
+ // remove checked toggle criteria
+ removeCheckedToggleCriteria(reviewId);
+
+ // remove review
+ String qDelete = "DELETE FROM plot_review WHERE review_id = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDelete, ps -> {
+ ps.setInt(1, reviewId);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean removeAllReviewsOfPlot(int plotId) {
+ String qIdsByPlotId = "SELECT review_id FROM plot_review WHERE plot_id = ?;";
+ List reviewIds = new ArrayList<>();
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qIdsByPlotId, ps -> {
+ ps.setInt(1, plotId);
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ reviewIds.add(rs.getInt(1));
+ }
+ }));
+
+ boolean successful = true;
+ for (int reviewId : reviewIds) {
+ successful = successful && removeReview(reviewId);
+ }
+ return successful;
+ }
+
+ // --- Toggle Criteria ---
+ public Optional getToggleCriteria(String criteriaName) {
+ return TOGGLE_CRITERIA.stream().filter(c -> c.criteriaName().equals(criteriaName)).findFirst();
+ }
+
+ public boolean addToggleCriteria(String criteriaName, boolean isOptional) {
+ Optional criteria = TOGGLE_CRITERIA.stream().filter(t -> t.criteriaName().equals(criteriaName)).findFirst();
+ if (criteria.isPresent()) return false;
+
+ String qInsertToggleCriteria = "INSERT INTO review_toggle_criteria (criteria_name, is_optional) VALUES (?, ?);";
+ if (!Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsertToggleCriteria, ps -> {
+ ps.setString(1, criteriaName);
+ ps.setBoolean(2, isOptional);
+ return ps.executeUpdate() > 0;
+ })))) return false;
+ TOGGLE_CRITERIA.add(new ToggleCriteria(criteriaName, isOptional));
+ return true;
+ }
+
+ public boolean removeToggleCriteria(String criteriaName) {
+ Optional criteria = TOGGLE_CRITERIA.stream().filter(t -> t.criteriaName().equals(criteriaName)).findFirst();
+ if (criteria.isEmpty()) return false;
+
+ String qDeleteToggleCriteria = "DELETE FROM review_toggle_criteria WHERE criteria_name = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDeleteToggleCriteria, ps -> {
+ ps.setString(1, criteriaName);
+ boolean successful = ps.executeUpdate() > 0;
+ if (successful) TOGGLE_CRITERIA.remove(criteria.get());
+ return successful;
+ })));
+ }
+
+ public boolean setToggleCriteriaOptional(String criteriaName, boolean isOptional) {
+ Optional criteria = TOGGLE_CRITERIA.stream().filter(t -> t.criteriaName().equals(criteriaName)).findFirst();
+ if (criteria.isEmpty()) return false;
+
+ String qSetToggleCriteriaOptional = "UPDATE review_toggle_criteria SET is_optional = ? WHERE criteria_name = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetToggleCriteriaOptional, ps -> {
+ ps.setBoolean(1, isOptional);
+ ps.setString(2, criteriaName);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public List getAllToggleCriteria() {return TOGGLE_CRITERIA.stream().toList();}
+
+ public List getBuildTeamToggleCriteria(int buildTeamId) {
+ return BUILD_TEAM_TOGGLE_CRITERIA.stream().filter(c -> c.buildTeamId() == buildTeamId).map(BuildTeamToggleCriteria::criteria).toList();
+ }
+
+ public boolean assignBuildTeamToggleCriteria(int buildTeamId, ToggleCriteria criteria) {
+ Optional existingCriteria = getBuildTeamToggleCriteria(buildTeamId).stream().filter(t ->
+ t.criteriaName().equals(criteria.criteriaName())).findFirst();
+ if (existingCriteria.isPresent()) return false;
+ String qInsertCriteriaToBuildteam = "INSERT INTO build_team_uses_toggle_criteria (build_team_id, criteria_name) VALUES (?, ?);";
+ if (!Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsertCriteriaToBuildteam, ps -> {
+ ps.setInt(1, buildTeamId);
+ ps.setString(2, criteria.criteriaName());
+ return ps.executeUpdate() > 0;
+ })))) return false;
+ BUILD_TEAM_TOGGLE_CRITERIA.add(new BuildTeamToggleCriteria(buildTeamId, criteria));
+ return true;
+ }
+
+ public boolean removeBuildTeamToggleCriteria(int buildTeamId, ToggleCriteria criteria) {
+ Optional existingCriteria = BUILD_TEAM_TOGGLE_CRITERIA.stream().filter(btc ->
+ btc.buildTeamId() == buildTeamId && btc.criteria().criteriaName().equals(criteria.criteriaName())).findFirst();
+ if (existingCriteria.isEmpty()) return false;
+ String qDeleteCriteriaToBuildteam = "DELETE FROM build_team_uses_toggle_criteria WHERE build_team_id = ? AND criteria_name = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDeleteCriteriaToBuildteam, ps -> {
+ ps.setInt(1, buildTeamId);
+ ps.setString(2, criteria.criteriaName());
+ boolean successful = ps.executeUpdate() > 0;
+ if (successful) BUILD_TEAM_TOGGLE_CRITERIA.remove(existingCriteria.get());
+ return successful;
+ })));
+ }
+
+ public Map getReviewToggleCriteria(int reviewId) {
+ String qReviewToggleCriteriasByReviewId = "SELECT criteria_name, is_checked FROM review_contains_toggle_criteria WHERE review_id = ?;";
+ return Utils.handleSqlException(new HashMap<>(), () -> SqlHelper.runQuery(qReviewToggleCriteriasByReviewId, ps -> {
+ ps.setInt(1, reviewId);
+ ResultSet rs = ps.executeQuery();
+ HashMap toggleCriteriaList = new HashMap<>();
+ while (rs.next()) {
+ boolean isChecked = rs.getBoolean(2);
+ toggleCriteriaList.put(getToggleCriteria(rs.getString(1)).orElseThrow(), isChecked);
+ }
+ return toggleCriteriaList;
+ }));
+ }
+
+ public boolean addReviewToggleCriteria(int reviewId, @NotNull ToggleCriteria toggle, boolean isChecked) {
+ String qInsertToggleCriteriaToReview = "INSERT INTO review_contains_toggle_criteria (review_id, criteria_name, is_checked) VALUES (?, ?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsertToggleCriteriaToReview, ps -> {
+ ps.setInt(1, reviewId);
+ ps.setString(2, toggle.criteriaName());
+ ps.setBoolean(3, isChecked);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public void removeCheckedToggleCriteria(int reviewId) {
+ String qDeleteToggleCriteriaToReview = "DELETE FROM review_contains_toggle_criteria WHERE review_id = ?;";
+ Utils.handleSqlException(() -> SqlHelper.runStatement(qDeleteToggleCriteriaToReview, ps -> ps.setInt(1, reviewId)));
+ }
+
+ // --- Review Notification ---
+ public Optional getReviewNotification(int reviewId, UUID uuid) {
+ return NOTIFICATIONS.stream().filter(n -> n.reviewId() == reviewId && n.uuid() == uuid).findFirst();
+ }
+
+ public List getReviewNotifications(int reviewId) {
+ return NOTIFICATIONS.stream().filter(n -> n.reviewId() == reviewId).toList();
+ }
+
+ public List getReviewNotifications(UUID uuid) {
+ return NOTIFICATIONS.stream().filter(n -> n.uuid() == uuid).toList();
+ }
+
+ public void removeReviewNotification(int reviewId, UUID uuid) {
+ Optional notification = getReviewNotification(reviewId, uuid);
+ if (notification.isEmpty()) return;
+
+ String qDeleteReviewNotify = "DELETE FROM builder_has_review_notification WHERE review_id = ? AND uuid = ?;";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qDeleteReviewNotify, ps -> {
+ ps.setInt(1, reviewId);
+ ps.setString(2, uuid.toString());
+ if (ps.executeUpdate() > 0) NOTIFICATIONS.remove(notification.get());
+ }));
+ }
+
+ public void createReviewNotification(int reviewId, UUID uuid) {
+ Player player = Bukkit.getPlayer(uuid);
+ if (player != null && player.isOnline()) {
+ PlotUtils.ChatFormatting.sendFeedbackMessage(List.of(new ReviewNotification(reviewId, uuid)), player);
+ return;
+ }
+
+ String qInsertReviewNotify = "INSERT INTO builder_has_review_notification (review_id, uuid) VALUES (?, ?);";
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qInsertReviewNotify, ps -> {
+ ps.setInt(1, reviewId);
+ ps.setString(2, uuid.toString());
+ if (ps.executeUpdate() > 0) NOTIFICATIONS.add(new ReviewNotification(reviewId, uuid));
+ }));
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/ServerProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/ServerProvider.java
new file mode 100644
index 000000000..6da3f21a6
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/ServerProvider.java
@@ -0,0 +1,56 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.utils.Utils;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ServerProvider {
+ protected static final List SERVERS = new ArrayList<>();
+
+ public ServerProvider() {
+ String qAll = "SELECT server_name FROM server;";
+
+ Utils.handleSqlException(() -> SqlHelper.runQuery(qAll, ps -> {
+ ResultSet rs = ps.executeQuery();
+ while (rs.next()) {
+ SERVERS.add(rs.getString(1)); // cache all servers
+ }
+ }));
+ }
+
+ public boolean serverExists(String serverName) {
+ return SERVERS.stream().anyMatch(s -> s.equals(serverName));
+ }
+
+ public List getServers() {
+ return SERVERS;
+ }
+
+ public boolean addServer(String name, int buildTeamId) {
+ if (serverExists(name)) return true;
+
+ String qInsert = "INSERT INTO server (server_name, build_team_id) VALUES (?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsert, ps -> {
+ ps.setString(1, name);
+ ps.setInt(2, buildTeamId);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) SERVERS.add(name);
+ return result;
+ })));
+ }
+
+ public boolean removeServer(String name) {
+ if (!serverExists(name)) return false;
+
+ String qDelete = "DELETE FROM server WHERE server_name = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qDelete, ps -> {
+ ps.setString(1, name);
+ boolean result = ps.executeUpdate() > 0;
+ if (result) SERVERS.remove(name);
+ return result;
+ })));
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/database/providers/TutorialPlotProvider.java b/src/main/java/com/alpsbte/plotsystem/core/database/providers/TutorialPlotProvider.java
new file mode 100644
index 000000000..ae9e46601
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/database/providers/TutorialPlotProvider.java
@@ -0,0 +1,85 @@
+package com.alpsbte.plotsystem.core.database.providers;
+
+import com.alpsbte.alpslib.io.database.SqlHelper;
+import com.alpsbte.plotsystem.core.system.plot.TutorialPlot;
+import com.alpsbte.plotsystem.utils.Utils;
+
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Optional;
+
+public class TutorialPlotProvider {
+ public static final Map tutorialPlots = new HashMap<>();
+ public static final Deque freeTutorialPlotIds = new LinkedList<>();
+
+ public Optional getById(int id) {
+ return tutorialPlots.keySet().stream().filter(t -> tutorialPlots.get(t) == id).findFirst();
+ }
+
+ public Optional getByTutorialId(int tutorialId, String playerUUID) {
+ Optional tutorialPlot = tutorialPlots.keySet().stream()
+ .filter(t -> t.getTutorialID() == tutorialId && t.getUUID().toString().equals(playerUUID)).findFirst();
+
+ if (tutorialPlot.isPresent()) return tutorialPlot;
+
+ String qGet = "SELECT stage_id, is_complete, last_stage_complete_date FROM tutorial WHERE tutorial_id = ? AND uuid = ?;";
+ return Utils.handleSqlException(tutorialPlot, () -> SqlHelper.runQuery(qGet, ps -> {
+ ps.setInt(1, tutorialId);
+ ps.setString(2, playerUUID);
+ ResultSet rs = ps.executeQuery();
+ if (rs.next()) {
+ int plotId = freeTutorialPlotIds.isEmpty() ? 0 : freeTutorialPlotIds.poll();
+ int stageId = rs.getInt(1);
+ boolean isComplete = rs.getBoolean(2);
+ Date lastStageCompleteDate = rs.getDate(3);
+ TutorialPlot newTutorialPlot = new TutorialPlot(plotId, tutorialId, playerUUID, stageId,
+ isComplete, lastStageCompleteDate != null ? lastStageCompleteDate.toLocalDate() : null);
+ tutorialPlots.put(newTutorialPlot, plotId);
+
+ return Optional.of(newTutorialPlot);
+ }
+ return Optional.empty();
+ }));
+
+ }
+
+ public boolean add(int tutorialId, String playerUUID) {
+ if (getByTutorialId(tutorialId, playerUUID).isPresent()) return false;
+
+ String qInsert = "INSERT INTO tutorial (tutorial_id, uuid) VALUES (?, ?);";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qInsert, ps -> {
+ ps.setInt(1, tutorialId);
+ ps.setString(2, playerUUID);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setStageId(int tutorialId, String playerUUID, int stageId) {
+ String qSetStage = "UPDATE tutorial SET stage_id = ?, last_stage_complete_date = ? WHERE tutorial_id = ? AND uuid = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetStage, ps -> {
+ ps.setInt(1, stageId);
+ ps.setObject(2, LocalDate.now());
+ ps.setInt(3, tutorialId);
+ ps.setString(4, playerUUID);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+
+ public boolean setComplete(int tutorialId, String playerUUID) {
+ String qSetComplete = "UPDATE tutorial SET is_complete = ?, last_stage_complete_date = ? WHERE tutorial_id = ? AND uuid = ?;";
+ return Boolean.TRUE.equals(Utils.handleSqlException(false, () -> SqlHelper.runQuery(qSetComplete, ps -> {
+ ps.setBoolean(1, true);
+ ps.setObject(2, Timestamp.valueOf(LocalDateTime.now()));
+ ps.setInt(3, tutorialId);
+ ps.setString(4, playerUUID);
+ return ps.executeUpdate() > 0;
+ })));
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramConfiguration.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramConfiguration.java
index 8d2d313ac..b42cbccad 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramConfiguration.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramConfiguration.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.holograms;
public interface HologramConfiguration {
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramRegister.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramRegister.java
index d8b92f732..72652253b 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramRegister.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/holograms/HologramRegister.java
@@ -2,6 +2,7 @@
import com.alpsbte.alpslib.hologram.DecentHologramDisplay;
import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.holograms.leaderboards.ScoreLeaderboard;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.ConfigUtil;
import org.bukkit.Bukkit;
@@ -12,13 +13,14 @@
import java.util.Objects;
public final class HologramRegister {
+ private HologramRegister() {}
+
/**
- * Registers the {@link ScoreLeaderboard}, {@link PlotsLeaderboard} and adds
+ * Registers the {@link ScoreLeaderboard} and adds
* them to {@link DecentHologramDisplay#activeDisplays}.
*/
public static void init() {
new ScoreLeaderboard();
- new PlotsLeaderboard();
}
public static void reload() {
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotTutorialHologram.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotTutorialHologram.java
index 5e729f947..9ed7dd9cc 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotTutorialHologram.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotTutorialHologram.java
@@ -1,32 +1,8 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.holograms;
import com.alpsbte.plotsystem.core.system.tutorial.AbstractTutorialHologram;
-import com.alpsbte.plotsystem.core.system.tutorial.utils.TutorialUtils;
import com.alpsbte.plotsystem.core.system.tutorial.stage.tasks.message.ChatMessageTask;
+import com.alpsbte.plotsystem.core.system.tutorial.utils.TutorialUtils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import net.kyori.adventure.text.Component;
@@ -35,7 +11,12 @@
import org.bukkit.Sound;
import org.bukkit.entity.Player;
-import static org.bukkit.ChatColor.*;
+import static org.bukkit.ChatColor.BOLD;
+import static org.bukkit.ChatColor.DARK_GRAY;
+import static org.bukkit.ChatColor.GOLD;
+import static org.bukkit.ChatColor.GRAY;
+import static org.bukkit.ChatColor.GREEN;
+import static org.bukkit.ChatColor.YELLOW;
public class PlotTutorialHologram extends AbstractTutorialHologram {
public PlotTutorialHologram(Player player, int plotTutorialId, int holoId, String content) {
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotsLeaderboard.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotsLeaderboard.java
deleted file mode 100644
index 51d4e1e0c..000000000
--- a/src/main/java/com/alpsbte/plotsystem/core/holograms/PlotsLeaderboard.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.alpsbte.plotsystem.core.holograms;
-
-import com.alpsbte.alpslib.hologram.DecentHologramDisplay;
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.utils.io.ConfigPaths;
-import com.alpsbte.plotsystem.utils.items.BaseItems;
-import org.bukkit.inventory.ItemStack;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.logging.Level;
-
-public class PlotsLeaderboard extends DecentHologramDisplay implements HologramConfiguration {
- protected PlotsLeaderboard() {
- super(ConfigPaths.PLOTS_LEADERBOARD, null, false);
- setLocation(HologramRegister.getLocation(this));
- setEnabled(PlotSystem.getPlugin().getConfig().getBoolean(getEnablePath()));
- }
-
- @Override
- public ItemStack getItem() {
- return new ItemStack(BaseItems.LEADERBOARD_PLOT.getItem());
- }
-
- @Override
- public String getTitle(UUID playerUUID) {
- return "§b§lCOMPLETED PLOTS §6§l[Lifetime]";
- }
-
- @Override
- public List> getContent(UUID playerUUID) {
- try {
- ArrayList> lines = new ArrayList<>();
-
- List> entries = Builder.getBuildersByCompletedBuilds(10);
- for (int i = 0; i < 10; i++) {
- Builder.DatabaseEntry entry = i < entries.size() && entries.get(i).getValue() != 0 ? entries.get(i) : null;
- lines.add(new HologramRegister.LeaderboardPositionLine(i + 1, entry != null ? entry.getKey() : null, entry != null ? entry.getValue() : 0));
- }
-
- return lines;
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getLogger().log(Level.SEVERE, "An error occurred while reading leaderboard content", ex);
- }
- return new ArrayList<>();
- }
-
- @Override
- public boolean hasViewPermission(UUID uuid) {
- return true;
- }
-
- @Override
- public String getEnablePath() {
- return ConfigPaths.PLOTS_LEADERBOARD_ENABLE;
- }
-
- @Override
- public String getXPath() {
- return ConfigPaths.PLOTS_LEADERBOARD_X;
- }
-
- @Override
- public String getYPath() {
- return ConfigPaths.PLOTS_LEADERBOARD_Y;
- }
-
- @Override
- public String getZPath() {
- return ConfigPaths.PLOTS_LEADERBOARD_Z;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/ScoreLeaderboard.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/ScoreLeaderboard.java
deleted file mode 100644
index 4625c69f0..000000000
--- a/src/main/java/com/alpsbte/plotsystem/core/holograms/ScoreLeaderboard.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.alpsbte.plotsystem.core.holograms;
-
-import com.alpsbte.alpslib.hologram.DecentHologramPagedDisplay;
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.Payout;
-import com.alpsbte.plotsystem.core.system.tutorial.AbstractTutorial;
-import com.alpsbte.plotsystem.utils.io.ConfigPaths;
-import com.alpsbte.plotsystem.utils.io.ConfigUtil;
-import com.alpsbte.plotsystem.utils.io.LangPaths;
-import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.BaseItems;
-import eu.decentsoftware.holograms.api.DHAPI;
-import eu.decentsoftware.holograms.api.holograms.Hologram;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.TextComponent;
-import net.kyori.adventure.text.format.NamedTextColor;
-import net.kyori.adventure.text.format.TextDecoration;
-import org.bukkit.Bukkit;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.scheduler.BukkitRunnable;
-
-import java.sql.SQLException;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.stream.Collectors;
-
-public class ScoreLeaderboard extends DecentHologramPagedDisplay implements HologramConfiguration {
- private final DecimalFormat df = new DecimalFormat("#.##");
- private LeaderboardTimeframe sortByLeaderboard;
-
- protected ScoreLeaderboard() {
- super("score-leaderboard", null, false, PlotSystem.getPlugin());
- setEnabled(PlotSystem.getPlugin().getConfig().getBoolean(getEnablePath()));
- setLocation(HologramRegister.getLocation(this));
-
- new BukkitRunnable() {
- @Override
- public void run() {
- for (Player player : getPlayersInRadiusForRanking()) {
- if (AbstractTutorial.getActiveTutorial(player.getUniqueId()) != null) continue;
- player.sendActionBar(getRankingString(player));
- }
- }
- }.runTaskTimerAsynchronously(PlotSystem.getPlugin(), 0L, 20L);
- }
-
- @Override
- public List getPages() {
- if (ConfigUtil.getInstance() == null) return new ArrayList<>();
- FileConfiguration config = PlotSystem.getPlugin().getConfig();
- return Arrays.stream(LeaderboardTimeframe.values())
- .filter(p -> config.getBoolean(p.configPath)).map(LeaderboardTimeframe::toString).collect(Collectors.toList());
- }
-
- @Override
- public void create(Player player) {
- if (getPages().isEmpty()) {
- PlotSystem.getPlugin().getLogger().log(Level.WARNING, "Unable to initialize Score-Leaderboard - No display pages enabled! Check config for display-options.");
- return;
- }
-
- super.create(player);
- }
-
- @Override
- public boolean hasViewPermission(UUID uuid) {
- return true;
- }
-
- @Override
- public ItemStack getItem() {
- return new ItemStack(BaseItems.LEADERBOARD_SCORE.getItem());
- }
-
- @Override
- public String getTitle(UUID playerUUID) {
- return "§b§lTOP SCORE §6§l[" + (sortByLeaderboard.toString().charAt(0) +
- sortByLeaderboard.toString().toLowerCase().substring(1)) + "]";
- }
-
- @Override
- public List> getHeader(UUID playerUUID) {
- sortByLeaderboard = LeaderboardTimeframe.valueOf(currentPage);
- return super.getHeader(playerUUID);
- }
-
- @Override
- public List> getContent(UUID playerUUID) {
- try {
- ArrayList> lines = new ArrayList<>();
-
- for (int index = 0; index < 10; index++) {
- lines.add(new LeaderboardPositionLineWithPayout(index + 1, null, 0));
- }
-
- int index = 0;
- for (Builder.DatabaseEntry entry : Builder.getBuildersByScore(sortByLeaderboard)) {
- lines.set(index, new LeaderboardPositionLineWithPayout(index + 1, entry.getKey(), entry.getValue()));
- index++;
- }
-
- return lines;
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getLogger().log(Level.SEVERE, "An error occurred while reading leaderboard content", ex);
- }
- return new ArrayList<>();
- }
-
- private Component getRankingString(Player player) {
- int position, rows, myScore;
- try {
- position = Builder.getBuilderScorePosition(player.getUniqueId(), sortByLeaderboard);
- rows = Builder.getBuildersInSort(sortByLeaderboard);
- myScore = Builder.getBuilderScore(player.getUniqueId(), sortByLeaderboard);
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(Component.text("A SQL error occurred!"), ex);
- return Component.empty();
- }
-
- // Start building the component
- TextComponent.Builder builder = Component.text()
- .append(Component.text(" " + LangUtil.getInstance().get(player, sortByLeaderboard.langPath))
- .color(NamedTextColor.GOLD)
- .decorate(TextDecoration.BOLD)
- )
- .append(Component.text(" ➜ ")
- .color(NamedTextColor.DARK_GRAY)
- .decorate(TextDecoration.BOLD)
- );
-
- if (position == -1) {
- builder.append(Component.text(LangUtil.getInstance().get(player, LangPaths.Leaderboards.NOT_ON_LEADERBOARD))
- .color(NamedTextColor.RED)
- .decoration(TextDecoration.BOLD, false)
- );
- } else if (position < 50) {
- builder.append(Component.text(
- LangUtil.getInstance().get(player, LangPaths.Leaderboards.ACTIONBAR_POSITION, String.valueOf(position)))
- .color(NamedTextColor.GREEN)
- .decoration(TextDecoration.BOLD, false)
- );
- } else {
- String topPercentage = df.format(position * 1.0 / rows);
- builder.append(Component.text(
- LangUtil.getInstance().get(player, LangPaths.Leaderboards.ACTIONBAR_PERCENTAGE, topPercentage))
- .decoration(TextDecoration.BOLD, false)
- );
- }
-
- if (myScore != -1) {
- builder.append(
- Component.text(" (", NamedTextColor.DARK_GRAY)
- .append(Component.text(myScore + " points", NamedTextColor.AQUA))
- .append(Component.text(")", NamedTextColor.DARK_GRAY))
- );
- }
-
- return builder.build();
- }
-
- private List getPlayersInRadiusForRanking() {
- FileConfiguration config = PlotSystem.getPlugin().getConfig();
- boolean actionBarEnabled = config.getBoolean(ConfigPaths.DISPLAY_OPTIONS_ACTION_BAR_ENABLE, true);
- int actionBarRadius = config.getInt(ConfigPaths.DISPLAY_OPTIONS_ACTION_BAR_RADIUS, 30);
- List players = new ArrayList<>();
- if (!actionBarEnabled) return players;
- for (Player player : Bukkit.getOnlinePlayers()) {
- Hologram holo = DHAPI.getHologram(player.getUniqueId() + "-" + getId());
- if (holo == null) continue;
- if (player.getWorld().getName().equals(holo.getLocation().getWorld().getName()) &&
- holo.getLocation().distance(player.getLocation()) <= actionBarRadius) {
- players.add(player);
- }
- }
- return players;
- }
-
- @Override
- public long getInterval() {
- return PlotSystem.getPlugin().getConfig().getInt(ConfigPaths.DISPLAY_OPTIONS_INTERVAL) * 20L;
- }
-
- @Override
- public String getEnablePath() {
- return ConfigPaths.SCORE_LEADERBOARD_ENABLE;
- }
-
- @Override
- public String getXPath() {
- return ConfigPaths.SCORE_LEADERBOARD_X;
- }
-
- @Override
- public String getYPath() {
- return ConfigPaths.SCORE_LEADERBOARD_Y;
- }
-
- @Override
- public String getZPath() {
- return ConfigPaths.SCORE_LEADERBOARD_Z;
- }
-
- public enum LeaderboardTimeframe {
- DAILY(ConfigPaths.DISPLAY_OPTIONS_SHOW_DAILY),
- WEEKLY(ConfigPaths.DISPLAY_OPTIONS_SHOW_WEEKLY),
- MONTHLY(ConfigPaths.DISPLAY_OPTIONS_SHOW_MONTHLY),
- YEARLY(ConfigPaths.DISPLAY_OPTIONS_SHOW_YEARLY),
- LIFETIME(ConfigPaths.DISPLAY_OPTIONS_SHOW_LIFETIME);
-
- public final String configPath;
- public final String langPath;
-
- LeaderboardTimeframe(String configPath) {
- this.configPath = configPath;
- this.langPath = LangPaths.Leaderboards.PAGES + name();
- }
- }
-
- private class LeaderboardPositionLineWithPayout extends HologramRegister.LeaderboardPositionLine {
- private final int position;
-
- public LeaderboardPositionLineWithPayout(int position, String username, int score) {
- super(position, username, score);
- this.position = position;
- }
-
- @Override
- public String getLine() {
- try {
- String line = super.getLine();
- Payout payout = sortByLeaderboard != LeaderboardTimeframe.LIFETIME ? Payout.getPayout(sortByLeaderboard, position) : null;
- if (payout == null) return line;
- String payoutAmount = payout.getPayoutAmount();
- try {
- // if payout amount can be number, prefix with dollar sign
- Integer.valueOf(payoutAmount);
- payoutAmount = "$" + payoutAmount;
- } catch (NumberFormatException ignored) {}
-
- return line + " §7- §e§l" + payoutAmount;
- } catch (SQLException e) {
- return super.getLine() + " §7- §cSQL ERR";
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/leaderboards/LeaderboardTimeframe.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/leaderboards/LeaderboardTimeframe.java
new file mode 100644
index 000000000..dc722dd0b
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/holograms/leaderboards/LeaderboardTimeframe.java
@@ -0,0 +1,20 @@
+package com.alpsbte.plotsystem.core.holograms.leaderboards;
+
+import com.alpsbte.plotsystem.utils.io.ConfigPaths;
+import com.alpsbte.plotsystem.utils.io.LangPaths;
+
+public enum LeaderboardTimeframe {
+ DAILY(ConfigPaths.DISPLAY_OPTIONS_SHOW_DAILY),
+ WEEKLY(ConfigPaths.DISPLAY_OPTIONS_SHOW_WEEKLY),
+ MONTHLY(ConfigPaths.DISPLAY_OPTIONS_SHOW_MONTHLY),
+ YEARLY(ConfigPaths.DISPLAY_OPTIONS_SHOW_YEARLY),
+ LIFETIME(ConfigPaths.DISPLAY_OPTIONS_SHOW_LIFETIME);
+
+ public final String configPath;
+ public final String langPath;
+
+ LeaderboardTimeframe(String configPath) {
+ this.configPath = configPath;
+ this.langPath = LangPaths.Leaderboards.PAGES + name();
+ }
+}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/holograms/leaderboards/ScoreLeaderboard.java b/src/main/java/com/alpsbte/plotsystem/core/holograms/leaderboards/ScoreLeaderboard.java
new file mode 100644
index 000000000..e4ec49e28
--- /dev/null
+++ b/src/main/java/com/alpsbte/plotsystem/core/holograms/leaderboards/ScoreLeaderboard.java
@@ -0,0 +1,112 @@
+package com.alpsbte.plotsystem.core.holograms.leaderboards;
+
+import com.alpsbte.alpslib.hologram.DecentHologramPagedDisplay;
+import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.database.DataProvider;
+import com.alpsbte.plotsystem.core.holograms.HologramConfiguration;
+import com.alpsbte.plotsystem.core.holograms.HologramRegister;
+import com.alpsbte.plotsystem.utils.io.ConfigPaths;
+import com.alpsbte.plotsystem.utils.io.ConfigUtil;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.logging.Level;
+
+public class ScoreLeaderboard extends DecentHologramPagedDisplay implements HologramConfiguration {
+ private LeaderboardTimeframe sortByLeaderboard;
+
+ public ScoreLeaderboard() {
+ super("score-leaderboard", null, false, PlotSystem.getPlugin());
+ setEnabled(PlotSystem.getPlugin().getConfig().getBoolean(getEnablePath()));
+ setLocation(HologramRegister.getLocation(this));
+ }
+
+ @Override
+ public List getPages() {
+ if (ConfigUtil.getInstance() == null) return new ArrayList<>();
+ FileConfiguration config = PlotSystem.getPlugin().getConfig();
+ return Arrays.stream(LeaderboardTimeframe.values())
+ .filter(p -> config.getBoolean(p.configPath)).map(LeaderboardTimeframe::toString).toList();
+ }
+
+ @Override
+ public void create(Player player) {
+ if (getPages().isEmpty()) {
+ PlotSystem.getPlugin().getLogger().log(Level.WARNING, "Unable to initialize Score-Leaderboard - No display pages enabled! Check config for display-options.");
+ return;
+ }
+
+ super.create(player);
+ }
+
+ @Override
+ public boolean hasViewPermission(UUID uuid) {
+ return true;
+ }
+
+ @Override
+ public ItemStack getItem() {
+ return new ItemStack(BaseItems.LEADERBOARD_SCORE.getItem());
+ }
+
+ @Override
+ public String getTitle(UUID playerUUID) {
+ return "§b§lTOP SCORE §6§l[" + (sortByLeaderboard.toString().charAt(0) +
+ sortByLeaderboard.toString().toLowerCase().substring(1)) + "]";
+ }
+
+ @Override
+ public List> getHeader(UUID playerUUID) {
+ sortByLeaderboard = LeaderboardTimeframe.valueOf(currentPage);
+ return super.getHeader(playerUUID);
+ }
+
+ @Override
+ public List> getContent(UUID playerUUID) {
+ ArrayList> lines = new ArrayList<>();
+
+ for (int index = 0; index < 10; index++) {
+ lines.add(new HologramRegister.LeaderboardPositionLine(index + 1, null, 0));
+ }
+
+ Map playerRankings = DataProvider.BUILDER.getLeaderboardEntries(sortByLeaderboard);
+ int i = 0;
+ for (Map.Entry entry : playerRankings.entrySet()) {
+ lines.set(i, new HologramRegister.LeaderboardPositionLine(i + 1, entry.getKey(), entry.getValue()));
+ i++;
+ }
+ return lines;
+ }
+
+ @Override
+ public long getInterval() {
+ return PlotSystem.getPlugin().getConfig().getInt(ConfigPaths.DISPLAY_OPTIONS_INTERVAL) * 20L;
+ }
+
+ @Override
+ public String getEnablePath() {
+ return ConfigPaths.SCORE_LEADERBOARD_ENABLE;
+ }
+
+ @Override
+ public String getXPath() {
+ return ConfigPaths.SCORE_LEADERBOARD_X;
+ }
+
+ @Override
+ public String getYPath() {
+ return ConfigPaths.SCORE_LEADERBOARD_Y;
+ }
+
+ @Override
+ public String getZPath() {
+ return ConfigPaths.SCORE_LEADERBOARD_Z;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractMenu.java
index 0dfc4ce4a..0b3c2f21f 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractMenu.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.plotsystem.PlotSystem;
@@ -38,11 +14,11 @@ public abstract class AbstractMenu {
private final Player menuPlayer;
private final String title;
- public AbstractMenu(int rows, String title, Player menuPlayer) {
+ protected AbstractMenu(int rows, String title, Player menuPlayer) {
this(rows, title, menuPlayer, true);
}
- public AbstractMenu(int rows, String title, Player menuPlayer, boolean reload) {
+ protected AbstractMenu(int rows, String title, Player menuPlayer, boolean reload) {
this.title = title;
this.menuPlayer = menuPlayer;
this.menu = ChestMenu.builder(rows).title(text(title)).redraw(true).build();
@@ -53,12 +29,16 @@ public AbstractMenu(int rows, String title, Player menuPlayer, boolean reload) {
/**
* Places items asynchronously in the menu after it is opened
*/
- protected abstract void setMenuItemsAsync();
+ protected void setMenuItemsAsync() {
+ // Default just does nothing, for use-cases which doesn't need it.
+ }
/**
* Sets click events for the items placed in the menu async after it is opened
*/
- protected abstract void setItemClickEventsAsync();
+ protected void setItemClickEventsAsync() {
+ // Default just does nothing, for use-cases which doesn't need it.
+ }
/**
* Places pre-defined items in the menu before it is opened
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractPaginatedMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractPaginatedMenu.java
index 8c52640e2..57231c609 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractPaginatedMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/AbstractPaginatedMenu.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2021-2022, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.plotsystem.PlotSystem;
@@ -36,7 +12,7 @@ public abstract class AbstractPaginatedMenu extends AbstractMenu {
private int totalItemsAmount;
private int currentPage = 0;
- public AbstractPaginatedMenu(int rows, int pagedRows, String title, Player menuPlayer) {
+ protected AbstractPaginatedMenu(int rows, int pagedRows, String title, Player menuPlayer) {
super(rows, title, menuPlayer, false);
this.maxItemsPerPage = pagedRows * 9;
reloadMenuAsync();
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/BuilderUtilitiesMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/BuilderUtilitiesMenu.java
index 8f0e74b96..1c3f26ac4 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/BuilderUtilitiesMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/BuilderUtilitiesMenu.java
@@ -1,35 +1,12 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
-import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
+import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
import com.alpsbte.plotsystem.utils.items.MenuItems;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
@@ -100,9 +77,9 @@ protected void setItemClickEventsAsync() {
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
- .pattern("111111111")
- .pattern("000000000")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
.pattern("111101111")
.build();
}
@@ -111,7 +88,7 @@ protected Mask getMask() {
* @return Menu item
*/
public static ItemStack getMenuItem(Player player) {
- return new ItemBuilder(Material.GOLDEN_AXE)
+ return new ItemBuilder(BaseItems.BUILDER_UTILITIES.getItem())
.setName(Component.text(LangUtil.getInstance().get(player, LangPaths.MenuTitle.BUILDER_UTILITIES), AQUA, BOLD))
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(player, LangPaths.MenuDescription.BUILDER_UTILITIES), true).build())
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/FeedbackMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/FeedbackMenu.java
index 6c97e3cd2..88a162a69 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/FeedbackMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/FeedbackMenu.java
@@ -1,62 +1,42 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.core.database.DatabaseConnection;
-import com.alpsbte.plotsystem.core.system.Review;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.plot.Plot;
+import com.alpsbte.plotsystem.core.system.review.PlotReview;
+import com.alpsbte.plotsystem.core.system.review.ToggleCriteria;
import com.alpsbte.plotsystem.utils.Utils;
-import com.alpsbte.plotsystem.utils.enums.Category;
-import com.alpsbte.plotsystem.utils.items.MenuItems;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
+import com.alpsbte.plotsystem.utils.items.MenuItems;
import org.bukkit.Material;
import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class FeedbackMenu extends AbstractMenu {
- private Review review = null;
+ private PlotReview review = null;
private final Plot plot;
- public FeedbackMenu(Player player, int plotID) throws SQLException {
+ public FeedbackMenu(Player player, int plotID) {
super(3, LangUtil.getInstance().get(player, LangPaths.MenuTitle.FEEDBACK, String.valueOf(plotID)), player);
- this.plot = new Plot(plotID);
+ this.plot = DataProvider.PLOT.getPlotById(plotID);
}
@Override
@@ -68,84 +48,91 @@ protected void setPreviewItems() {
@Override
protected void setMenuItemsAsync() {
// Get review id from plot
- try (ResultSet rs = DatabaseConnection.createStatement("SELECT review_id FROM plotsystem_plots WHERE id = ?")
- .setValue(plot.getID()).executeQuery()) {
-
- if (rs.next()) this.review = new Review(rs.getInt(1));
- DatabaseConnection.closeResultSet(rs);
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ plot.getLatestReview().ifPresent(value -> this.review = value);
// Set score item
- try {
- getMenu().getSlot(10).setItem(new ItemBuilder(Material.NETHER_STAR)
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.SCORE), AQUA, BOLD))
- .setLore(new LoreBuilder()
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.TOTAL_SCORE) + ": ", GRAY).append(text(plot.getTotalScore(), WHITE)))
- .emptyLine()
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.ACCURACY) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating(Category.ACCURACY))
- .append(text("/", DARK_GRAY))
- .append(text("5", GREEN))))
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.BLOCK_PALETTE) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating(Category.BLOCKPALETTE)))
- .append(text("/", DARK_GRAY))
- .append(text("5", GREEN)))
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.DETAILING) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating(Category.DETAILING)))
- .append(text("/", DARK_GRAY))
- .append(text("5", GREEN)))
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.TECHNIQUE) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating(Category.TECHNIQUE)))
- .append(text("/", DARK_GRAY))
- .append(text("5", GREEN)))
- .emptyLine()
- .addLine(plot.isRejected()
- ? text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.REJECTED), RED, BOLD)
- : text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.ACCEPTED), GREEN, BOLD))
- .build())
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(10).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
+ getMenu().getSlot(10).setItem(new ItemBuilder(BaseItems.REVIEW_SCORE.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.SCORE), AQUA, BOLD))
+ .setLore(new LoreBuilder()
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.TOTAL_SCORE) + ": ", GRAY).append(text(review.getScore(), WHITE)))
+ .emptyLine()
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.ACCURACY) + ": ", GRAY)
+ .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating().getAccuracyPoints(), 5)
+ .append(text("/", DARK_GRAY))
+ .append(text("5", GREEN))))
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.BLOCK_PALETTE) + ": ", GRAY)
+ .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating().getBlockPalettePoints(), 5))
+ .append(text("/", DARK_GRAY))
+ .append(text("5", GREEN)))
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.TOGGLE_POINTS) + ": ", GRAY)
+ .append(Utils.ItemUtils.getColoredPointsComponent(review.getRating().getTogglePoints(), 10))
+ .append(text("/", DARK_GRAY))
+ .append(text("10", GREEN)))
+ .emptyLine()
+ .addLine(plot.isRejected()
+ ? text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.REJECTED), RED, BOLD)
+ : text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.ACCEPTED), GREEN, BOLD))
+ .build())
+ .build());
+
+ // Set toggles item
+ getMenu().getSlot(12).setItem(getTogglesItem());
// Set feedback text item
- try {
- getMenu().getSlot(13).setItem(new ItemBuilder(Material.WRITABLE_BOOK)
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.FEEDBACK), AQUA, BOLD))
- .setLore(new LoreBuilder()
- .addLine(plot.getReview().getFeedback().replaceAll("//", " "), true)
- .build())
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(13).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
+ String feedbackText = review.getFeedback() == null ? LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.NO_FEEDBACK) : review.getFeedback();
+ getMenu().getSlot(14).setItem(new ItemBuilder(BaseItems.REVIEW_FEEDBACK.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.FEEDBACK), AQUA, BOLD))
+ .setLore(new LoreBuilder()
+ .addLine(feedbackText.replace("//", " "), true)
+ .build())
+ .build());
// Set reviewer item
- try {
- getMenu().getSlot(16).setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(review.getReviewer().getUUID()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.REVIEWER), AQUA, BOLD))
- .setLore(new LoreBuilder().addLine(review.getReviewer().getName()).build())
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(13).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
+ getMenu().getSlot(16).setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(review.getReviewerUUID()))
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.REVIEWER), AQUA, BOLD))
+ .setLore(new LoreBuilder().addLine(review.getReviewer().getName()).build())
+ .build());
}
- @Override
- protected void setItemClickEventsAsync() {}
-
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(empty()).build())
- .pattern("111111111")
- .pattern("000000000")
- .pattern("111111111")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
+ .pattern(Utils.FULL_MASK)
.build();
}
-}
+
+ private ItemStack getTogglesItem() {
+ ItemBuilder itemBuilder = new ItemBuilder(BaseItems.REVIEW_TOGGLE_CHECKED.getItem())
+ .setName(text("Toggle Criteria", AQUA, BOLD));
+
+
+ int totalCheckCriteriaCount = review.getRating().getAllToggles().size();
+ int checkedCount = review.getRating().getCheckedToggles().size();
+ LoreBuilder loreBuilder = new LoreBuilder()
+ .addLine(text(checkedCount + "/" + totalCheckCriteriaCount, GRAY));
+
+ if (!review.getRating().getUncheckedToggles().isEmpty()) {
+ loreBuilder.emptyLine();
+ loreBuilder.addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.CRITERIA_NOT_FULFILLED) + ":", RED, BOLD));
+ for (ToggleCriteria unchecked : review.getRating().getUncheckedToggles()) {
+ loreBuilder.addLine(text("• ", DARK_GRAY).append(text(unchecked.getDisplayName(getMenuPlayer()), GRAY)
+ .append(unchecked.isOptional()
+ ? empty()
+ : text(" - ").append(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.REQUIRED), GOLD)))));
+ }
+ }
+
+ if (!review.getRating().getCheckedToggles().isEmpty()) {
+ loreBuilder.emptyLine();
+ loreBuilder.addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.CRITERIA_FULFILLED) + ":", GREEN, BOLD));
+ for (ToggleCriteria unchecked : review.getRating().getCheckedToggles()) {
+ loreBuilder.addLine(text("• ", DARK_GRAY).append(text(unchecked.getDisplayName(getMenuPlayer()), GRAY)));
+ }
+ }
+
+ return itemBuilder.setLore(loreBuilder.build()).build();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/PlayerPlotsMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/PlayerPlotsMenu.java
index 75b5bd7ce..09b11c689 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/PlayerPlotsMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/PlayerPlotsMenu.java
@@ -1,53 +1,37 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
+import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
-import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.alpslib.utils.item.ItemBuilder;
+import com.alpsbte.plotsystem.core.system.review.PlotReview;
+import com.alpsbte.plotsystem.core.system.review.ReviewRating;
import com.alpsbte.plotsystem.utils.Utils;
-import com.alpsbte.plotsystem.utils.enums.Category;
-import com.alpsbte.plotsystem.utils.items.BaseItems;
-import com.alpsbte.plotsystem.utils.items.MenuItems;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
+import com.alpsbte.plotsystem.utils.items.MenuItems;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
+import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
import java.util.List;
+import java.util.Optional;
-import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class PlayerPlotsMenu extends AbstractMenu {
@@ -56,7 +40,7 @@ public class PlayerPlotsMenu extends AbstractMenu {
private int plotDisplayCount = 0;
- public PlayerPlotsMenu(Player menuPlayer, Builder builder) throws SQLException {
+ public PlayerPlotsMenu(Player menuPlayer, @NotNull Builder builder) {
super(6, LangUtil.getInstance().get(menuPlayer.getPlayer(), LangPaths.MenuTitle.PLAYER_PLOTS, builder.getName() + "'"), menuPlayer);
this.builder = builder;
}
@@ -75,48 +59,34 @@ protected void setPreviewItems() {
@Override
protected void setMenuItemsAsync() {
// Set player stats item
- try {
- getMenu().getSlot(4)
- .setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(builder.getUUID()))
- .setName(text(builder.getName(), GOLD).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.SCORE) + ": ", GRAY)
- .append(text(builder.getScore(), WHITE)))
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.COMPLETED_PLOTS) + ": ", GRAY)
- .append(text(builder.getCompletedBuilds(), WHITE)))
- .build())
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(4).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
+ getMenu().getSlot(4)
+ .setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(builder.getUUID()))
+ .setName(text(builder.getName(), GOLD).decoration(BOLD, true))
+ .setLore(new LoreBuilder()
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.SCORE) + ": ", GRAY)
+ .append(text(builder.getScore(), WHITE)))
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.COMPLETED_PLOTS) + ": ", GRAY)
+ .append(text(builder.getCompletedBuildsCount(), WHITE)))
+ .build())
+ .build());
// Set player plot items
- try {
- plots = Plot.getPlots(builder);
-
- plotDisplayCount = Math.min(plots.size(), 36);
- for (int i = 0; i < plotDisplayCount; i++) {
- Plot plot = plots.get(i);
- try {
- ItemStack item = switch (plot.getStatus()) {
- case unfinished -> BaseItems.PLOT_UNFINISHED.getItem();
- case unreviewed -> BaseItems.PLOT_UNREVIEWED.getItem();
- default -> BaseItems.PLOT_COMPLETED.getItem();
- };
-
- getMenu().getSlot(9 + i)
- .setItem(new ItemBuilder(item)
- .setName(text(plot.getCity().getName() + " | " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.PLOT_NAME) + " #" + plot.getID(), AQUA).decoration(BOLD, true))
- .setLore(getLore(plot, getMenuPlayer()).build())
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(9 + i).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ plots = DataProvider.PLOT.getPlots(builder);
+
+ plotDisplayCount = Math.min(plots.size(), 36);
+ for (int i = 0; i < plotDisplayCount; i++) {
+ Plot plot = plots.get(i);
+ ItemStack item = switch (plot.getStatus()) {
+ case unfinished -> BaseItems.PLOT_UNFINISHED.getItem();
+ case unreviewed -> BaseItems.PLOT_UNREVIEWED.getItem();
+ default -> BaseItems.PLOT_COMPLETED.getItem();
+ };
+
+ getMenu().getSlot(9 + i)
+ .setItem(new ItemBuilder(item)
+ .setName(text(plot.getCityProject().getName(getMenuPlayer()) + " | " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.PLOT_NAME) + " #" + plot.getId(), AQUA).decoration(BOLD, true))
+ .setLore(getLore(plot, getMenuPlayer()).build())
+ .build());
}
}
@@ -126,12 +96,8 @@ protected void setItemClickEventsAsync() {
for (int i = 0; i < plotDisplayCount; i++) {
int itemSlot = i;
getMenu().getSlot(9 + i).setClickHandler((clickPlayer, clickInformation) -> {
- try {
- new PlotActionsMenu(clickPlayer, plots.get(itemSlot));
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- clickPlayer.closeInventory();
- }
+ if (plots.get(itemSlot).getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) return;
+ new PlotActionsMenu(clickPlayer, plots.get(itemSlot));
});
}
@@ -142,12 +108,12 @@ protected void setItemClickEventsAsync() {
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(empty()).build())
+ .item(Utils.DEFAULT_ITEM)
.pattern("111101111")
- .pattern("000000000")
- .pattern("000000000")
- .pattern("000000000")
- .pattern("000000000")
+ .pattern(Utils.EMPTY_MASK)
+ .pattern(Utils.EMPTY_MASK)
+ .pattern(Utils.EMPTY_MASK)
+ .pattern(Utils.EMPTY_MASK)
.pattern("111101111")
.build();
}
@@ -159,57 +125,67 @@ protected Mask getMask() {
* @param p player instance for language system
* @return description lore for plot item
*/
- private LoreBuilder getLore(Plot plot, Player p) throws SQLException {
- LoreBuilder builder = new LoreBuilder();
+ private @NotNull LoreBuilder getLore(@NotNull Plot plot, Player p) {
+ LoreBuilder loreBuilder = new LoreBuilder();
+
+ Optional review = plot.getLatestReview();
+ int score = (review.isEmpty() || plot.isRejected()) ? 0 : review.get().getScore();
if (plot.getPlotMembers().isEmpty()) {
// Plot is single player plot
- builder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.TOTAL_SCORE) + ": ", GRAY)
- .append(text((plot.getTotalScore() == -1 ? 0 : plot.getTotalScore()), WHITE)));
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.TOTAL_SCORE) + ": ", GRAY)
+ .append(text(score, WHITE)));
} else {
// Plot is multiplayer plot
- builder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.OWNER) + ": ", GRAY)
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.OWNER) + ": ", GRAY)
.append(text(plot.getPlotOwner().getName(), WHITE)));
- builder.emptyLine();
+ loreBuilder.emptyLine();
- int score = (plot.getTotalScore() == -1 ? 0 : plot.getTotalScore());
- builder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.TOTAL_SCORE) + ": ", GRAY)
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.TOTAL_SCORE) + ": ", GRAY)
.append(text(score + " ", WHITE))
- .append(text(LangUtil.getInstance().get(p, LangPaths.Plot.GroupSystem.SHARED_BY_MEMBERS, Integer.toString(plot.getPlotMembers().size() + 1)), DARK_GRAY)));
+ .append(text(LangUtil.getInstance().get(p, LangPaths.Plot.GroupSystem.SHARED_BY_MEMBERS,
+ Integer.toString(plot.getPlotMembers().size() + 1)), DARK_GRAY)));
}
- if (plot.isReviewed() || plot.isRejected()) {
- builder.emptyLine();
- builder.addLines(
+ if (review.isPresent()) {
+ ReviewRating rating = review.get().getRating();
+ loreBuilder.emptyLine();
+ loreBuilder.addLines(
text(LangUtil.getInstance().get(p, LangPaths.Review.Criteria.ACCURACY) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(plot.getReview().getRating(Category.ACCURACY)))
+ .append(Utils.ItemUtils.getColoredPointsComponent(rating.getAccuracyPoints(), 5))
.append(text("/", DARK_GRAY)).append(text("5", GREEN)),
text(LangUtil.getInstance().get(p, LangPaths.Review.Criteria.BLOCK_PALETTE) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(plot.getReview().getRating(Category.BLOCKPALETTE)))
- .append(text("/", DARK_GRAY)).append(text("5", GREEN)),
- text(LangUtil.getInstance().get(p, LangPaths.Review.Criteria.DETAILING) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(plot.getReview().getRating(Category.DETAILING)))
- .append(text("/", DARK_GRAY)).append(text("5", GREEN)),
- text(LangUtil.getInstance().get(p, LangPaths.Review.Criteria.TECHNIQUE) + ": ", GRAY)
- .append(Utils.ItemUtils.getColoredPointsComponent(plot.getReview().getRating(Category.TECHNIQUE)))
+ .append(Utils.ItemUtils.getColoredPointsComponent(rating.getBlockPalettePoints(), 5))
.append(text("/", DARK_GRAY)).append(text("5", GREEN))
);
- builder.emptyLine();
- builder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Review.FEEDBACK) + ":", GRAY));
- builder.addLine(text(plot.getReview().getFeedback().replaceAll("//", " "), WHITE), true);
+ if (plot.getVersion() > AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Review.TOGGLE_POINTS) + ": ", GRAY)
+ .append(Utils.ItemUtils.getColoredPointsComponent(rating.getTogglePoints(), 10))
+ .append(text("/", DARK_GRAY)).append(text("10", GREEN)));
+ }
+ loreBuilder.emptyLine();
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Review.FEEDBACK) + ":", GRAY));
+ String feedback = review.get().getFeedback() == null
+ ? LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.NO_FEEDBACK)
+ : review.get().getFeedback().replace("//", " ");
+ loreBuilder.addLine(text(feedback, WHITE), true);
}
- builder.emptyLine();
- if (plot.isReviewed() && plot.isRejected()) builder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Review.REJECTED), RED, BOLD));
- builder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.STATUS) + ": ", GRAY)
+ loreBuilder.emptyLine();
+ if (plot.isRejected()) loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Review.REJECTED), RED, BOLD));
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Plot.STATUS) + ": ", GRAY)
.append(text(plot.getStatus().name().substring(0, 1).toUpperCase() +
plot.getStatus().name().substring(1), WHITE)));
- return builder;
+
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ loreBuilder.addLine(text(LangUtil.getInstance().get(p, LangPaths.Note.LEGACY), RED).decoration(BOLD, true));
+ }
+ return loreBuilder;
}
/**
* @return Menu item
*/
- public static ItemStack getMenuItem(Player p) {
+ public static ItemStack getMenuItem(@NotNull Player p) {
return new ItemBuilder(AlpsHeadUtils.getPlayerHead(p.getUniqueId()))
.setName(text(LangUtil.getInstance().get(p, LangPaths.MenuTitle.SHOW_PLOTS), AQUA, BOLD))
.setLore(new LoreBuilder()
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/PlotActionsMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/PlotActionsMenu.java
index 7b0c8f652..d2924c14b 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/PlotActionsMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/PlotActionsMenu.java
@@ -1,104 +1,76 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
-import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.core.system.Builder;
+import com.alpsbte.plotsystem.core.system.plot.AbstractPlot;
import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Status;
+import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.CustomHeads;
-import com.alpsbte.plotsystem.utils.items.MenuItems;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Material;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
+import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
-
-import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class PlotActionsMenu extends AbstractMenu {
private final Plot plot;
- private final boolean hasFeedback;
+ private final boolean hasReview;
+ final FileConfiguration config;
- public PlotActionsMenu(Player menuPlayer, Plot plot) throws SQLException {
- super(3, LangUtil.getInstance().get(menuPlayer, LangPaths.Plot.PLOT_NAME) + " #" + plot.getID() + " | " + plot.getStatus().name().substring(0, 1).toUpperCase() + plot.getStatus().name().substring(1), menuPlayer);
+ public PlotActionsMenu(Player menuPlayer, @NotNull Plot plot) {
+ super(3, LangUtil.getInstance().get(menuPlayer, LangPaths.Plot.PLOT_NAME) + " #" + plot.getId() + " | " + plot.getStatus().name().substring(0, 1).toUpperCase() + plot.getStatus().name().substring(1), menuPlayer);
this.plot = plot;
- hasFeedback = plot.isReviewed() || plot.isRejected();
+ hasReview = plot.getLatestReview().isPresent();
+ config = PlotSystem.getPlugin().getConfig();
}
@Override
protected void setMenuItemsAsync() {
// Set plot submit or undo submit item
- try {
- if (plot.getStatus().equals(Status.unreviewed)) {
- getMenu().getSlot(10)
- .setItem(new ItemBuilder(Material.FIRE_CHARGE, 1)
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.UNDO_SUBMIT), RED).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.UNDO_SUBMIT), true).build())
- .build());
- } else {
- getMenu().getSlot(10)
- .setItem(new ItemBuilder(Material.NAME_TAG, 1)
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SUBMIT), GREEN).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SUBMIT_PLOT)).color(GRAY), true)
- .emptyLine()
- .addLine(Utils.ItemUtils.getNoteFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.WONT_BE_ABLE_CONTINUE_BUILDING)))
- .build())
- .build());
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(10).setItem(MenuItems.errorItem(getMenuPlayer()));
+ if (plot.getStatus().equals(Status.unreviewed)) {
+ getMenu().getSlot(10)
+ .setItem(new ItemBuilder(BaseItems.PLOT_UNDO_SUBMIT.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.UNDO_SUBMIT), RED).decoration(BOLD, true))
+ .setLore(new LoreBuilder()
+ .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.UNDO_SUBMIT), true).build())
+ .build());
+ } else {
+ getMenu().getSlot(10)
+ .setItem(new ItemBuilder(BaseItems.PLOT_SUBMIT.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SUBMIT), GREEN).decoration(BOLD, true))
+ .setLore(new LoreBuilder()
+ .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SUBMIT_PLOT)).color(GRAY), true)
+ .emptyLine()
+ .addLine(Utils.ItemUtils.getNoteFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.WONT_BE_ABLE_CONTINUE_BUILDING)))
+ .build())
+ .build());
}
// Set teleport to plot item
- getMenu().getSlot(hasFeedback ? 12 : 13)
- .setItem(new ItemBuilder(Material.COMPASS, 1)
+ getMenu().getSlot(hasReview ? 12 : 13)
+ .setItem(new ItemBuilder(BaseItems.PLOT_TELEPORT.getItem())
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.TELEPORT), GOLD).decoration(BOLD, true))
.setLore(new LoreBuilder().addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.TELEPORT)).color(GRAY), true).build())
.build());
// Set plot abandon item
- getMenu().getSlot(hasFeedback ? 14 : 16)
- .setItem(new ItemBuilder(Material.BARRIER, 1)
+ getMenu().getSlot(hasReview ? 14 : 16)
+ .setItem(new ItemBuilder(BaseItems.PLOT_ABANDON.getItem())
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.ABANDON), RED).decoration(BOLD, true))
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.ABANDON), true)
@@ -108,42 +80,39 @@ protected void setMenuItemsAsync() {
.build());
// Set plot feedback item
- if (hasFeedback) {
+ if (hasReview) {
getMenu().getSlot(16)
- .setItem(new ItemBuilder(Material.WRITABLE_BOOK)
+ .setItem(new ItemBuilder(BaseItems.REVIEW_FEEDBACK.getItem())
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.FEEDBACK), AQUA).decoration(BOLD, true))
.setLore(new LoreBuilder().addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.FEEDBACK), true).build())
.build());
}
-
+
// Set plot members item
- try {
- if (!plot.isReviewed()) {
- FileConfiguration config = PlotSystem.getPlugin().getConfig();
- if ((getMenuPlayer() == plot.getPlotOwner().getPlayer() || getMenuPlayer().hasPermission("plotsystem.admin")) && config.getBoolean(ConfigPaths.ENABLE_GROUP_SUPPORT)) {
- getMenu().getSlot(22)
- .setItem(new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.ADD_BUTTON.getId()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.MANAGE_MEMBERS), AQUA).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.MANAGE_MEMBERS), true)
- .emptyLine()
- .addLine(Utils.ItemUtils.getNoteFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.SCORE_WILL_BE_SPLIT)))
- .build())
- .build());
- } else if (plot.getPlotMembers().stream().anyMatch(m -> m.getUUID().equals(getMenuPlayer().getUniqueId()))) {
- getMenu().getSlot(22)
- .setItem(new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.REMOVE_BUTTON.getId()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.LEAVE_PLOT), AQUA).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.LEAVE_PLOT), true)
- .emptyLine()
- .addLine(Utils.ItemUtils.getNoteFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.WONT_BE_ABLE_CONTINUE_BUILDING)))
- .build())
- .build());
- }
+ if (!plot.isReviewed() && config.getBoolean(ConfigPaths.ENABLE_GROUP_SUPPORT)) {
+ if ((getMenuPlayer() == plot.getPlotOwner().getPlayer() || getMenuPlayer().hasPermission("plotsystem.admin"))) {
+ getMenu().getSlot(22)
+ .setItem(new ItemBuilder(BaseItems.MENU_ADD.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.MANAGE_MEMBERS), AQUA).decoration(BOLD, true))
+ .setLore(new LoreBuilder()
+ .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.MANAGE_MEMBERS), true)
+ .emptyLine()
+ .addLine(Utils.ItemUtils.getNoteFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.SCORE_WILL_BE_SPLIT)))
+ .build())
+ .build());
+ } else if (plot.getPlotMembers().stream().anyMatch(m -> m.getUUID().equals(getMenuPlayer().getUniqueId()))) {
+ getMenu().getSlot(22)
+ .setItem(new ItemBuilder(BaseItems.MENU_REMOVE.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.LEAVE_PLOT), AQUA).decoration(BOLD, true))
+ .setLore(new LoreBuilder()
+ .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.LEAVE_PLOT), true)
+ .emptyLine()
+ .addLine(Utils.ItemUtils.getNoteFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.WONT_BE_ABLE_CONTINUE_BUILDING)))
+ .build())
+ .build());
}
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ } else {
+ getMenu().getSlot(22).setItem(Utils.DEFAULT_ITEM);
}
}
@@ -152,36 +121,36 @@ protected void setItemClickEventsAsync() {
// Set click event for submit or undo submit plot item
getMenu().getSlot(10).setClickHandler((clickPlayer, clickInformation) -> {
clickPlayer.closeInventory();
- try {
- clickPlayer.performCommand("plot " + (plot.getStatus().equals(Status.unreviewed) ? "undosubmit " : "submit ") + plot.getID());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ clickPlayer.performCommand("plot " + (plot.getStatus().equals(Status.unreviewed) ? "undosubmit " : "submit ") + plot.getId());
});
// Set click event for teleport to plot item
- getMenu().getSlot(hasFeedback ? 12 : 13).setClickHandler((clickPlayer, clickInformation) -> {
+ getMenu().getSlot(hasReview ? 12 : 13).setClickHandler((clickPlayer, clickInformation) -> {
clickPlayer.closeInventory();
+ if (plot.getVersion() <= AbstractPlot.LEGACY_VERSION_THRESHOLD) {
+ clickPlayer.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(clickPlayer, LangPaths.Message.Error.CANNOT_LOAD_LEGACY_PLOT)));
+ return;
+ }
plot.getWorld().teleportPlayer(clickPlayer);
});
// Set click event for abandon plot item
- getMenu().getSlot(hasFeedback ? 14 : 16).setClickHandler((clickPlayer, clickInformation) -> {
+ getMenu().getSlot(hasReview ? 14 : 16).setClickHandler((clickPlayer, clickInformation) -> {
clickPlayer.closeInventory();
- clickPlayer.performCommand("plot abandon " + plot.getID());
+ clickPlayer.performCommand("plot abandon " + plot.getId());
});
// Set click event for feedback menu button
- if (hasFeedback) {
+ if (hasReview) {
getMenu().getSlot(16).setClickHandler((clickPlayer, clickInformation) -> {
clickPlayer.closeInventory();
- clickPlayer.performCommand("plot feedback " + plot.getID());
+ clickPlayer.performCommand("plot feedback " + plot.getId());
});
}
// Set click event for plot members item
- getMenu().getSlot(22).setClickHandler((clickPlayer, clickInformation) -> {
- try {
+ if (!plot.isReviewed() && config.getBoolean(ConfigPaths.ENABLE_GROUP_SUPPORT)) {
+ getMenu().getSlot(22).setClickHandler((clickPlayer, clickInformation) -> {
if (plot.isReviewed()) return;
if (plot.getStatus() != Status.unfinished) {
clickPlayer.closeInventory();
@@ -196,21 +165,19 @@ protected void setItemClickEventsAsync() {
// Leave Plot
clickPlayer.closeInventory();
plot.removePlotMember(Builder.byUUID(clickPlayer.getUniqueId()));
- clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.LEFT_PLOT, Integer.toString(plot.getID()))));
+ clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.LEFT_PLOT, Integer.toString(plot.getId()))));
}
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- });
+ });
+ }
}
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
- .pattern("111111111")
- .pattern("000000000")
- .pattern("111111111")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
+ .pattern(Utils.FULL_MASK)
.build();
}
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/PlotMemberMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/PlotMemberMenu.java
index 34992e0f1..1fc54affd 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/PlotMemberMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/PlotMemberMenu.java
@@ -1,27 +1,3 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
@@ -35,21 +11,23 @@
import com.alpsbte.plotsystem.utils.chat.PlayerInviteeChatInput;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.CustomHeads;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
import com.alpsbte.plotsystem.utils.items.MenuItems;
-import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.ItemStack;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
+import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
import java.util.List;
import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class PlotMemberMenu extends AbstractMenu {
@@ -58,9 +36,16 @@ public class PlotMemberMenu extends AbstractMenu {
private final ItemStack emptyMemberSlotItem = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE, 1).setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.GroupSystem.EMPTY_MEMBER_SLOTS), DARK_GREEN).decoration(BOLD, true)).build();
private List builders;
- public PlotMemberMenu(Plot plot, Player menuPlayer) {
- super(3, LangUtil.getInstance().get(menuPlayer, LangPaths.MenuTitle.MANAGE_MEMBERS) + " | " + LangUtil.getInstance().get(menuPlayer, LangPaths.Plot.PLOT_NAME) + " #" + plot.getID(), menuPlayer);
+ public PlotMemberMenu(@NotNull Plot plot, Player menuPlayer) {
+ // Avoid opening the menu before 'plot' is assigned
+ super(3,
+ LangUtil.getInstance().get(menuPlayer, LangPaths.MenuTitle.MANAGE_MEMBERS) + " | " +
+ LangUtil.getInstance().get(menuPlayer, LangPaths.Plot.PLOT_NAME) + " #" + plot.getId(),
+ menuPlayer,
+ false);
this.plot = plot;
+ // Now that 'plot' is set, we can safely load the menu
+ reloadMenuAsync();
}
@Override
@@ -69,23 +54,21 @@ protected void setPreviewItems() {
getMenu().getSlot(10).setItem(MenuItems.loadingItem(Material.PLAYER_HEAD, getMenuPlayer()));
// Set loading item for plot member items
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
- try {
- List plotMembers = plot.getPlotMembers();
- for (int i = 1; i <= 3; i++) {
- getMenu().getSlot(11 + i).setItem(plotMembers.size() >= i
- ? MenuItems.loadingItem(Material.PLAYER_HEAD, getMenuPlayer())
- : emptyMemberSlotItem);
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (plot != null) {
+ List plotMembers = plot.getPlotMembers();
+ for (int i = 1; i <= 3; i++) {
+ getMenu().getSlot(11 + i).setItem(plotMembers.size() >= i
+ ? MenuItems.loadingItem(Material.PLAYER_HEAD, getMenuPlayer())
+ : emptyMemberSlotItem);
}
- });
+ } else {
+ PlotSystem.getPlugin().getComponentLogger().warn(text("PlotMemberMenu: plot is null in setPreviewItems"));
+ }
// Set add plot member item
- ItemStack whitePlus = AlpsHeadUtils.getCustomHead(CustomHeads.ADD_BUTTON.getId());
+ ItemStack addItem = BaseItems.MENU_ADD.getItem();
getMenu().getSlot(16)
- .setItem(new ItemBuilder(whitePlus)
+ .setItem(new ItemBuilder(addItem)
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.ADD_MEMBER_TO_PLOT), GOLD, BOLD))
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.ADD_MEMBER_TO_PLOT), true)
@@ -102,55 +85,57 @@ protected void setPreviewItems() {
@Override
protected void setMenuItemsAsync() {
- // Set plot owner item
- try {
- getMenu().getSlot(10)
- .setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(plot.getPlotOwner().getUUID()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.OWNER), GOLD, BOLD))
- .setLore(new LoreBuilder()
- .addLine(plot.getPlotOwner().getName()).build())
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ if (plot == null) {
+ PlotSystem.getPlugin().getComponentLogger().error(text("PlotMemberMenu: plot is null in setMenuItemsAsync, cannot load menu items"));
+ return;
}
+ // Set plot owner item
+ getMenu().getSlot(10)
+ .setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(plot.getPlotOwner().getUUID()))
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.OWNER), GOLD, BOLD))
+ .setLore(new LoreBuilder()
+ .addLines(text(plot.getPlotOwner().getName()),
+ empty(),
+ text(Utils.ItemUtils.getActionFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.Action.CLICK_TO_OPEN_PLOTS_MENUE))))
+ .build())
+ .build());
+
// Set plot member items
- try {
- builders = plot.getPlotMembers();
- for (int i = 12; i < 15; i++) {
- if (builders.size() < (i - 11)) return;
-
- Builder builder = builders.get(i - 12);
- getMenu().getSlot(i)
- .setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(builder.getUUID()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.MEMBER), AQUA, BOLD))
- .setLore(new LoreBuilder()
- .addLines(text(builder.getName()),
- empty(),
- text(Utils.ItemUtils.getActionFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.Action.CLICK_TO_REMOVE_PLOT_MEMBER))))
- .build())
- .build());
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
+ builders = plot.getPlotMembers();
+ for (int i = 12; i < 15; i++) {
+ if (builders.size() < (i - 11)) return;
+
+ Builder builder = builders.get(i - 12);
+ getMenu().getSlot(i)
+ .setItem(new ItemBuilder(AlpsHeadUtils.getPlayerHead(builder.getUUID()))
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.MEMBER), AQUA, BOLD))
+ .setLore(new LoreBuilder()
+ .addLines(text(builder.getName()),
+ empty(),
+ text(Utils.ItemUtils.getActionFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Note.Action.CLICK_TO_REMOVE_PLOT_MEMBER))))
+ .build())
+ .build());
}
}
@Override
protected void setItemClickEventsAsync() {
+ // Set click event for owner slot
+ getMenu().getSlot(10).setClickHandler((clickPlayer, clickInformation) -> {
+ clickPlayer.closeInventory(InventoryCloseEvent.Reason.OPEN_NEW);
+ new PlayerPlotsMenu(clickPlayer, plot.getPlotOwner());
+ });
+
// Set click event for member slots
for (int i = 12; i < 15; i++) {
int itemSlot = i;
getMenu().getSlot(i).setClickHandler((clickPlayer, clickInformation) -> {
if (getMenu().getSlot(itemSlot).getItem(clickPlayer).equals(emptyMemberSlotItem)) return;
Builder builder = builders.get(itemSlot - 12);
- try {
- plot.removePlotMember(builder);
- clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(),
- LangPaths.Message.Info.REMOVED_PLOT_MEMBER, builder.getName(), Integer.toString(plot.getID()))));
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
+ plot.removePlotMember(builder);
+ clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(),
+ LangPaths.Message.Info.REMOVED_PLOT_MEMBER, builder.getName(), Integer.toString(plot.getId()))));
reloadMenuAsync();
});
}
@@ -163,22 +148,18 @@ protected void setItemClickEventsAsync() {
});
// Set click event for back item
- getMenu().getSlot(22).setClickHandler((clickPlayer, clickInformation) -> {
- try {
- new PlotActionsMenu(clickPlayer, plot);
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- });
+ getMenu().getSlot(22).setClickHandler((clickPlayer, clickInformation)
+ -> new PlotActionsMenu(clickPlayer, plot));
}
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(empty()).build())
- .pattern("111111111")
- .pattern("000000000")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
.pattern("111101111")
.build();
}
-}
\ No newline at end of file
+}
+
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/PlotTypeMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/PlotTypeMenu.java
index 114263d22..a44216cfa 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/PlotTypeMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/PlotTypeMenu.java
@@ -1,38 +1,15 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
-import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
+import com.alpsbte.plotsystem.PlotSystem;
import com.alpsbte.plotsystem.core.system.Builder;
import com.alpsbte.plotsystem.core.system.plot.utils.PlotType;
import com.alpsbte.plotsystem.utils.Utils;
+import com.alpsbte.plotsystem.utils.io.ConfigPaths;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.CustomHeads;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
import com.alpsbte.plotsystem.utils.items.MenuItems;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -41,7 +18,9 @@
import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class PlotTypeMenu extends AbstractMenu {
@@ -62,12 +41,12 @@ protected void setPreviewItems() {
protected void setMenuItemsAsync() {
// Set plot type items
getMenu().getSlot(11).setItem(
- new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.FOCUS_MODE_BUTTON.getId()))
+ new ItemBuilder(BaseItems.PLOT_FOCUS_MODE.getItem())
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SELECT_FOCUS_MODE), GOLD, BOLD))
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SELECT_FOCUS_MODE), true)
.build())
- .setEnchanted(builder.getPlotTypeSetting().getId() == PlotType.FOCUS_MODE.getId())
+ .setEnchanted(builder.getPlotType().getId() == PlotType.FOCUS_MODE.getId())
.build());
getMenu().getSlot(13).setItem(
@@ -76,28 +55,30 @@ protected void setMenuItemsAsync() {
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SELECT_INSPIRATION_MODE), true)
.build())
- .setEnchanted(builder.getPlotTypeSetting().getId() == PlotType.LOCAL_INSPIRATION_MODE.getId())
+ .setEnchanted(builder.getPlotType().getId() == PlotType.LOCAL_INSPIRATION_MODE.getId())
.build());
- getMenu().getSlot(15).setItem(
- new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.CITY_INSPIRATION_MODE_BUTTON.getId()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SELECT_CITY_INSPIRATION_MODE), GOLD, BOLD)
- .append(text(" [", DARK_GRAY).append(text("BETA", RED).append(text("]", DARK_GRAY))))) // temporary BETA tag
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SELECT_CITY_INSPIRATION_MODE), true)
- .build())
- .setEnchanted(builder.getPlotTypeSetting().getId() == PlotType.CITY_INSPIRATION_MODE.getId())
- .build());
+ boolean inspirationModeDisabled = PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DISABLE_CITY_INSPIRATION_MODE); // TODO remove or enhance as soon CIM is working again
+ getMenu().getSlot(15).setItem(!inspirationModeDisabled ?
+ new ItemBuilder(BaseItems.PLOT_CITY_INSPIRATION_MODE.getItem())
+ .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SELECT_CITY_INSPIRATION_MODE), GOLD, BOLD)
+ .append(text(" [", DARK_GRAY).append(text("BETA", RED).append(text("]", DARK_GRAY))))) // temporary BETA tag
+ .setLore(new LoreBuilder()
+ .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SELECT_CITY_INSPIRATION_MODE), true)
+ .build())
+ .setEnchanted(builder.getPlotType().getId() == PlotType.CITY_INSPIRATION_MODE.getId())
+ .build() : Utils.DEFAULT_ITEM);
+
+
// Set selected glass pane
int selectedPlotTypeSlot = 13;
- if (builder.getPlotTypeSetting() == PlotType.FOCUS_MODE)
+ if (builder.getPlotType() == PlotType.FOCUS_MODE)
selectedPlotTypeSlot = 11;
- if (builder.getPlotTypeSetting() == PlotType.CITY_INSPIRATION_MODE)
+ if (builder.getPlotType() == PlotType.CITY_INSPIRATION_MODE)
selectedPlotTypeSlot = 15;
getMenu().getSlot(selectedPlotTypeSlot - 9).setItem(new ItemBuilder(Material.LIME_STAINED_GLASS_PANE, 1).setName(empty()).build());
-
// Set back item
getMenu().getSlot(22).setItem(MenuItems.backMenuItem(getMenuPlayer()));
}
@@ -106,22 +87,28 @@ protected void setMenuItemsAsync() {
protected void setItemClickEventsAsync() {
// Set click event for plot type items
getMenu().getSlot(11).setClickHandler(((clickPlayer, clickInformation) -> {
- builder.setPlotTypeSetting(PlotType.FOCUS_MODE);
+ boolean successful = builder.setPlotType(PlotType.FOCUS_MODE);
+ if (!successful) return;
getMenuPlayer().playSound(getMenuPlayer().getLocation(), Utils.SoundUtils.DONE_SOUND, 1f, 1f);
reloadMenuAsync();
}));
getMenu().getSlot(13).setClickHandler(((clickPlayer, clickInformation) -> {
- builder.setPlotTypeSetting(PlotType.LOCAL_INSPIRATION_MODE);
+ boolean successful = builder.setPlotType(PlotType.LOCAL_INSPIRATION_MODE);
+ if (!successful) return;
getMenuPlayer().playSound(getMenuPlayer().getLocation(), Utils.SoundUtils.DONE_SOUND, 1f, 1f);
reloadMenuAsync();
}));
- getMenu().getSlot(15).setClickHandler(((clickPlayer, clickInformation) -> {
- builder.setPlotTypeSetting(PlotType.CITY_INSPIRATION_MODE);
- getMenuPlayer().playSound(getMenuPlayer().getLocation(), Utils.SoundUtils.DONE_SOUND, 1f, 1f);
- reloadMenuAsync();
- }));
+ boolean inspirationModeDisabled = PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.DISABLE_CITY_INSPIRATION_MODE); // TODO improve or remove when CIM ist working again
+ if (!inspirationModeDisabled) {
+ getMenu().getSlot(15).setClickHandler(((clickPlayer, clickInformation) -> {
+ boolean successful = builder.setPlotType(PlotType.CITY_INSPIRATION_MODE);
+ if (!successful) return;
+ getMenuPlayer().playSound(getMenuPlayer().getLocation(), Utils.SoundUtils.DONE_SOUND, 1f, 1f);
+ reloadMenuAsync();
+ }));
+ }
// Set click event for back item
getMenu().getSlot(22).setClickHandler((clickPlayer, clickInformation) -> new SettingsMenu(clickPlayer));
@@ -130,9 +117,9 @@ protected void setItemClickEventsAsync() {
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(empty()).build())
- .pattern("111111111")
- .pattern("000000000")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
.pattern("111101111")
.build();
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/ReviewMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/ReviewMenu.java
deleted file mode 100644
index 03b40ed77..000000000
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/ReviewMenu.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.alpsbte.plotsystem.core.menus;
-
-import com.alpsbte.alpslib.utils.item.ItemBuilder;
-import com.alpsbte.alpslib.utils.item.LegacyLoreBuilder;
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.Country;
-import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.plotsystem.utils.Utils;
-import com.alpsbte.plotsystem.utils.enums.Status;
-import com.alpsbte.plotsystem.utils.io.LangPaths;
-import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.BaseItems;
-import com.alpsbte.plotsystem.utils.items.MenuItems;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Material;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.ipvp.canvas.mask.BinaryMask;
-import org.ipvp.canvas.mask.Mask;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static net.kyori.adventure.text.Component.text;
-
-public class ReviewMenu extends AbstractPaginatedMenu {
- private List countries = new ArrayList<>();
- private Country filteredCountry = null;
-
- public ReviewMenu(Player player) {
- super(6, 4, LangUtil.getInstance().get(player, LangPaths.Review.MANAGE_AND_REVIEW_PLOTS), player);
- }
-
- @Override
- protected List> getSource() {
- List plots = new ArrayList<>();
- try {
- countries = Builder.byUUID(getMenuPlayer().getUniqueId()).getAsReviewer().getCountries();
- plots.addAll(Plot.getPlots(countries, Status.unreviewed));
- plots.addAll(Plot.getPlots(countries, Status.unfinished));
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- return plots;
- }
-
- @Override
- protected void setPreviewItems() {
- // Set close item
- getMenu().getSlot(49).setItem(MenuItems.closeMenuItem(getMenuPlayer()));
-
- super.setPreviewItems();
- }
-
- @Override
- protected void setPaginatedMenuItemsAsync(List> source) {
- // Set filter item
- getMenu().getSlot(7).setItem(getFilterItem(getMenuPlayer()));
-
- // Set unreviewed and unfinished plot items
- List plots = getFilteredPlots(source);
- for (int i = 0; i < plots.size(); i++) {
- try {
- Plot plot = plots.get(i);
- List lines = new ArrayList<>();
- lines.add("§7" + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.ID) + ": §f" + plot.getID());
- lines.add("");
- lines.add("§7" + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.OWNER) + ": §f" + plot.getPlotOwner().getName());
- if (!plot.getPlotMembers().isEmpty()) lines.add("§7" + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.MEMBERS) + ": §f" + plot.getPlotMembers().stream().map(m -> {
- try {return m.getName();} catch (SQLException ex) {PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);}
- return "";
- }).collect(Collectors.joining(", "))
- );
- lines.add("§7" + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.CITY) + ": §f" + plot.getCity().getName());
- lines.add("§7" + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.COUNTRY) + ": §f" + plot.getCity().getCountry().getName());
- lines.add("§7" + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.DIFFICULTY) + ": §f" + plot.getDifficulty().name().charAt(0) + plot.getDifficulty().name().substring(1).toLowerCase());
-
- getMenu().getSlot(i + 9).setItem(new ItemBuilder(plot.getStatus() == Status.unfinished ? Material.MAP : Material.FILLED_MAP, 1)
- .setName("§b§l" + LangUtil.getInstance().get(getMenuPlayer(), plot.getStatus() == Status.unfinished ? LangPaths.Review.MANAGE_PLOT : LangPaths.Review.REVIEW_PLOT))
- .setLore(lines)
- .build());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenu().getSlot(i).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
- }
- }
-
- @Override
- protected void setPaginatedItemClickEventsAsync(List> source) {
- // Set click event for unreviewed and unfinished plot items
- List plots = getFilteredPlots(source);
- for (int i = 0; i < plots.size(); i++) {
- Plot plot = plots.get(i);
- getMenu().getSlot(i + 9).setClickHandler((player, info) -> {
- try {
- if (plot.getStatus() == Status.unfinished) {
- new PlotActionsMenu(getMenuPlayer(), plot);
- return;
- }
-
- player.performCommand("review " + plot.getID());
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- getMenuPlayer().closeInventory();
- }
- });
- }
- }
-
- @Override
- protected void setMenuItemsAsync() {
- // Set previous page item
- if (hasPreviousPage()) getMenu().getSlot(46).setItem(MenuItems.previousPageItem(getMenuPlayer()));
-
- // Set next page item
- if (hasNextPage()) getMenu().getSlot(52).setItem(MenuItems.nextPageItem(getMenuPlayer()));
- }
-
- @Override
- protected void setItemClickEventsAsync() {
- // Set click event for filter item
- getMenu().getSlot(7).setClickHandler((clickPlayer, clickInformation) -> {
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
- if (countries.isEmpty()) return;
-
- if (filteredCountry == null) {
- filteredCountry = countries.get(0);
- } else {
- int index = countries.indexOf(filteredCountry);
- filteredCountry = index + 1 >= countries.size() ? null : countries.get(index + 1);
- }
-
- reloadMenuAsync(false);
- });
-
- // Set click event for previous page item
- getMenu().getSlot(46).setClickHandler((clickPlayer, clickInformation) -> {
- if (hasPreviousPage()) {
- previousPage();
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
- }
- });
-
- // Set click event for close item
- getMenu().getSlot(49).setClickHandler((clickPlayer, clickInformation) -> clickPlayer.closeInventory());
-
- // Set click event for next page item
- getMenu().getSlot(52).setClickHandler((clickPlayer, clickInformation) -> {
- if (hasNextPage()) {
- nextPage();
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
- }
- });
- }
-
- @Override
- protected Mask getMask() {
- return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
- .pattern("111111111")
- .pattern("000000000")
- .pattern("000000000")
- .pattern("000000000")
- .pattern("000000000")
- .pattern("111101111")
- .build();
- }
-
- private List getFilteredPlots(List> plots) {
- List filteredPlots = plots.stream().map(p -> (Plot) p).collect(Collectors.toList());
- if (filteredCountry != null) filteredPlots = filteredPlots.stream().filter(p -> {
- try {
- return p.getCity().getCountry().getID() == filteredCountry.getID();
- } catch (SQLException ex) {PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);}
- return false;
- }).collect(Collectors.toList());
- return filteredPlots;
- }
-
- private ItemStack getFilterItem(Player langPlayer) {
- LegacyLoreBuilder LegacyLoreBuilder = new LegacyLoreBuilder();
- LegacyLoreBuilder.addLine((filteredCountry == null ? "§b§l> §f§l" : "§7") + LangUtil.getInstance().get(langPlayer, LangPaths.MenuDescription.FILTER));
- LegacyLoreBuilder.emptyLine();
-
- countries.forEach(c -> {
- if (filteredCountry != null && filteredCountry.getID() == c.getID()) {
- LegacyLoreBuilder.addLine("§b§l> §f§l" + filteredCountry.getName());
- } else LegacyLoreBuilder.addLine("§7" + c.getName());
- });
-
- return new ItemBuilder(MenuItems.filterItem(getMenuPlayer()))
- .setLore(LegacyLoreBuilder.build())
- .setEnchanted(filteredCountry != null)
- .build();
- }
-
- /**
- * @return Menu item
- */
- public static ItemStack getMenuItem(Player player) {
- return new ItemBuilder(BaseItems.REVIEW_ITEM.getItem())
- .setName("§b§l" + LangUtil.getInstance().get(player, LangPaths.MenuTitle.REVIEW_PLOTS) + " §7(" + LangUtil.getInstance().get(player, LangPaths.Note.Action.RIGHT_CLICK) + ")")
- .setEnchanted(true)
- .build();
- }
-}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/ReviewPlotMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/ReviewPlotMenu.java
deleted file mode 100644
index e6a5b2913..000000000
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/ReviewPlotMenu.java
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package com.alpsbte.plotsystem.core.menus;
-
-import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
-import com.alpsbte.alpslib.utils.item.ItemBuilder;
-import com.alpsbte.alpslib.utils.item.LoreBuilder;
-import com.alpsbte.plotsystem.PlotSystem;
-import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.Review;
-import com.alpsbte.plotsystem.core.system.plot.Plot;
-import com.alpsbte.plotsystem.core.system.plot.utils.PlotUtils;
-import com.alpsbte.plotsystem.utils.Utils;
-import com.alpsbte.plotsystem.utils.chat.ChatInput;
-import com.alpsbte.plotsystem.utils.chat.PlayerFeedbackChatInput;
-import com.alpsbte.plotsystem.utils.enums.Status;
-import com.alpsbte.plotsystem.utils.io.LangPaths;
-import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.BaseItems;
-import com.alpsbte.plotsystem.utils.items.CustomHeads;
-import com.alpsbte.plotsystem.utils.items.MenuItems;
-import com.sk89q.worldedit.WorldEditException;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Bukkit;
-import org.bukkit.Material;
-import org.bukkit.enchantments.Enchantment;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.ipvp.canvas.mask.BinaryMask;
-import org.ipvp.canvas.mask.Mask;
-
-import java.io.IOException;
-import java.sql.SQLException;
-import java.util.Collections;
-import java.util.Objects;
-
-import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
-import static net.kyori.adventure.text.format.TextDecoration.BOLD;
-
-public class ReviewPlotMenu extends AbstractMenu {
- private final Plot plot;
-
- boolean sentWarning = false;
-
- public ReviewPlotMenu(Player player, Plot plot) {
- super(6, LangUtil.getInstance().get(player, LangPaths.MenuTitle.REVIEW_PLOT, Integer.toString(plot.getID())), player);
- this.plot = plot;
- }
-
- @Override
- protected void setPreviewItems() {
- final ItemStack[] itemPointZero = new ItemStack[4];
- final ItemStack[] itemPointOne = new ItemStack[4];
- final ItemStack[] itemPointTwo = new ItemStack[4];
- final ItemStack[] itemPointThree = new ItemStack[4];
- final ItemStack[] itemPointFour = new ItemStack[4];
- final ItemStack[] itemPointFive = new ItemStack[4];
-
- for (int i = 0; i < 54; i++) {
- int column = (i % 9) + 1;
- int row = (i - (i % 9)) / 9 + 1;
- int position = ((i + 1) - (i + 1) % 9) / 54;
- if (column > 2 && column < 9 && row > 1 && row < 6) {
- if ((i + 1) % 9 == 3) {
- itemPointZero[position] = getZeroPointItem();
-
- //Add Enchantment
- ItemMeta itemMeta = itemPointZero[position].getItemMeta();
- Objects.requireNonNull(itemMeta).addEnchant(Enchantment.POWER, 1, true);
- itemPointZero[position].setItemMeta(itemMeta);
- getMenu().getSlot(i).setItem(itemPointZero[(i - (i + 1) % 9) / 54]);
- } else if ((i + 1) % 9 == 4) {
- itemPointOne[position] = getOnePointItem();
- getMenu().getSlot(i).setItem(itemPointOne[(i - (i + 1) % 9) / 54]);
- } else if ((i + 1) % 9 == 5) {
- itemPointTwo[position] = getTwoPointItem();
- getMenu().getSlot(i).setItem(itemPointTwo[(i - (i + 1) % 9) / 54]);
- } else if ((i + 1) % 9 == 6) {
- itemPointThree[position] = getThreePointItem();
- getMenu().getSlot(i).setItem(itemPointThree[(i - (i + 1) % 9) / 54]);
- } else if ((i + 1) % 9 == 7) {
- itemPointFour[position] = getFourPointItem();
- getMenu().getSlot(i).setItem(itemPointFour[(i - (i + 1) % 9) / 54]);
- } else if ((i + 1) % 9 == 8) {
- itemPointFive[position] = getFivePointItem();
- getMenu().getSlot(i).setItem(itemPointFive[(i - (i + 1) % 9) / 54]);
- }
- }
- }
-
- getMenu().getSlot(4).setItem(MenuItems.loadingItem(Material.MAP, getMenuPlayer()));
-
- getMenu().getSlot(10).setItem(getAccuracyItem());
- getMenu().getSlot(19).setItem(getBlockPaletteItem());
- getMenu().getSlot(28).setItem(getDetailingItem());
- getMenu().getSlot(37).setItem(getTechniqueItem());
-
- getMenu().getSlot(48).setItem(getSubmitItem());
- getMenu().getSlot(50).setItem(getCancelItem());
-
- super.setPreviewItems();
- }
-
- @Override
- protected void setMenuItemsAsync() {
- // Set back item
- getMenu().getSlot(1).setItem(MenuItems.backMenuItem(getMenuPlayer()));
-
- // Set plot information item
- getMenu().getSlot(4).setItem(getPlotInfoItem());
-
- // Set review information item
- getMenu().getSlot(7).setItem(getReviewInfoItem());
- }
-
- @Override
- protected void setItemClickEventsAsync() {
- // Set click event for back item
- getMenu().getSlot(1).setClickHandler((clickPlayer, clickInformation) -> new ReviewMenu(getMenuPlayer()));
-
- // Set click event for close item
- getMenu().getSlot(50).setClickHandler((clickPlayer, clickInformation) -> clickPlayer.closeInventory());
-
- // Set click event for plot info item
- getMenu().getSlot(4).setClickHandler((clickPlayer, clickInformation) -> {
- try {
- new PlotActionsMenu(clickPlayer, plot);
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- });
-
- // Set click event for submit item
- getMenu().getSlot(48).setClickHandler((clickPlayer, clickInformation) -> {
- Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getPlugin(), () -> {
- try {
- StringBuilder score = new StringBuilder();
-
- int totalRating = 0;
- boolean isRejected = false;
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 6; j++) {
- if (Objects.requireNonNull(getMenu().getSlot(11 + (i * 9) + j).getItem(clickPlayer).getItemMeta()).hasEnchant(Enchantment.POWER)) {
- if (i == 3) {
- score.append(j);
- } else {
- score.append(j).append(",");
- }
- totalRating += j;
- if (j == 0) isRejected = true;
- }
- }
- }
- if (totalRating <= 8) isRejected = true;
-
- if (totalRating == 0 && !sentWarning) {
- clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.PLOT_WILL_GET_ABANDONED)));
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.CREATE_PLOT_SOUND, 1, 1);
- sentWarning = true;
- return;
- } else if (isRejected && !sentWarning) {
- clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.PLOT_WILL_GET_REJECTED)));
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.CREATE_PLOT_SOUND, 1, 1);
- sentWarning = true;
- return;
- } else if (totalRating == 0) {
- plot.setStatus(Status.unfinished);
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> clickPlayer.performCommand("plot abandon " + plot.getID()));
- return;
- }
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> clickPlayer.closeInventory());
-
- if (plot.isReviewed()) {
- plot.getReview().setRating(score.toString());
- plot.getReview().setReviewer(clickPlayer.getUniqueId());
- } else new Review(plot.getID(), clickPlayer.getUniqueId(), score.toString());
-
- double totalRatingWithMultiplier = totalRating * Plot.getMultiplierByDifficulty(plot.getDifficulty());
- totalRating = (int) Math.floor(totalRatingWithMultiplier);
- plot.setTotalScore(totalRating);
-
- Component reviewerConfirmationMessage;
-
- if (!isRejected) {
- clickPlayer.sendMessage(Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.SAVING_PLOT)));
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
- try {
- PlotSystem.getPlugin().getComponentLogger().warn(text("Saving plot schematic (ID: " + plot.getID() + ")..."));
- if (!PlotUtils.savePlotAsSchematic(plot)) {
- clickPlayer.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Error.ERROR_OCCURRED)));
- PlotSystem.getPlugin().getComponentLogger().warn(text("Could not save finished plot schematic (ID: " + plot.getID() + ")!"));
- }
- } catch (IOException | SQLException | WorldEditException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("Could not save finished plot schematic (ID: " + plot.getID() + ")!"), ex);
- }
- });
-
- plot.setStatus(Status.completed);
- plot.getReview().setFeedbackSent(false);
- plot.getReview().setFeedback("No Feedback");
- plot.getPlotOwner().addCompletedBuild(1);
-
- // Remove Plot from Owner
- plot.getPlotOwner().removePlot(plot.getSlot());
-
- if (plot.getPlotMembers().isEmpty()) {
- // Plot was made alone
- reviewerConfirmationMessage = Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.PLOT_MARKED_REVIEWED, Integer.toString(plot.getID()), plot.getPlotOwner().getName()));
-
- // Builder gets 100% of score
- plot.getPlotOwner().addScore(totalRating);
- } else {
- // Plot was made in a group
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < plot.getPlotMembers().size(); i++) {
- sb.append(i == plot.getPlotMembers().size() - 1 ?
- plot.getPlotMembers().get(i).getName() :
- plot.getPlotMembers().get(i).getName() + ", ");
- }
- reviewerConfirmationMessage = Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.PLOT_MARKED_REVIEWED, Integer.toString(plot.getID()), sb.toString()));
-
- // Score gets split between all participants
- plot.getPlotOwner().addScore(plot.getSharedScore());
-
- for (Builder builder : plot.getPlotMembers()) {
- // Score gets split between all participants
- builder.addScore(plot.getSharedScore());
- builder.addCompletedBuild(1);
-
- // Remove Slot from Member
- builder.removePlot(builder.getSlot(plot));
- }
- }
- } else {
- if (!plot.getPlotMembers().isEmpty()) {
- // Plot was made alone
- reviewerConfirmationMessage = Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.PLOT_REJECTED, Integer.toString(plot.getID()), plot.getPlotOwner().getName()));
- } else {
- // Plot was made in a group
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < plot.getPlotMembers().size(); i++) {
- sb.append(i == plot.getPlotMembers().size() - 1 ?
- plot.getPlotMembers().get(i).getName() :
- plot.getPlotMembers().get(i).getName() + ", ");
- }
- reviewerConfirmationMessage = Utils.ChatUtils.getInfoFormat(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Message.Info.PLOT_REJECTED, Integer.toString(plot.getID()), sb.toString()));
- }
-
- PlotUtils.Actions.undoSubmit(plot);
- }
-
- boolean finalIsRejected = isRejected;
- Bukkit.getScheduler().runTask(PlotSystem.getPlugin(), () -> {
- for (Player player : plot.getWorld().getBukkitWorld().getPlayers()) {
- player.teleport(Utils.getSpawnLocation());
- }
-
- // Delete plot world after reviewing
- try {
- if (!finalIsRejected && plot.getPlotType().hasOnePlotPerWorld())
- plot.getWorld().deleteWorld();
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
-
- clickPlayer.sendMessage(reviewerConfirmationMessage);
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.FINISH_PLOT_SOUND, 1f, 1f);
-
- try {
- ChatInput.awaitChatInput.put(clickPlayer.getUniqueId(),
- new PlayerFeedbackChatInput(clickPlayer.getUniqueId(), plot.getReview()));
- PlayerFeedbackChatInput.sendChatInputMessage(clickPlayer);
- } catch (SQLException ex) {PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);}
- });
-
- for (Builder member : plot.getPlotMembers()) {
- if (member.isOnline()) PlotUtils.ChatFormatting.sendFeedbackMessage(Collections.singletonList(plot), member.getPlayer());
- }
-
- if (plot.getPlotOwner().isOnline()) {
- PlotUtils.ChatFormatting.sendFeedbackMessage(Collections.singletonList(plot), plot.getPlotOwner().getPlayer());
- plot.getReview().setFeedbackSent(true);
- }
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- }
- });
- });
-
- // Set click event for point selection items
- for (int i = 0; i < 54; i++) {
- int slot = i;
-
- int column = (slot % 9) + 1;
- int row = (slot - (slot % 9)) / 9 + 1;
-
- ItemMeta meta = getMenu().getSlot(slot).getItem(getMenuPlayer()).getItemMeta();
-
- if (column > 2 && column < 9 && row > 1 && row < 6) {
- //Go through the whole points row
- getMenu().getSlot(i).setClickHandler((clickPlayer, clickInformation) -> {
- for (int j = 0; j < 6; j++) {
- if (!Objects.requireNonNull(getMenu().getSlot(slot - (column - 1) + j + 2).getItem(clickPlayer).getItemMeta()).hasEnchant(Enchantment.POWER)) continue;
-
- ItemStack itemPrevious = getMenu().getSlot(slot - (column - 1) + j + 2).getItem(clickPlayer);
- ItemMeta metaPrevious = itemPrevious.getItemMeta();
- assert metaPrevious != null;
- metaPrevious.removeEnchant(Enchantment.POWER);
- itemPrevious.setItemMeta(metaPrevious);
- getMenu().getSlot(slot - (column - 1) + j + 2).setItem(itemPrevious);
- }
-
- assert meta != null;
- meta.addEnchant(Enchantment.POWER, 1, true);
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
-
- ItemStack newItem = getMenu().getSlot(slot).getItem(clickPlayer);
- newItem.setItemMeta(meta);
- getMenu().getSlot(slot).setItem(newItem);
- sentWarning = false;
- });
- }
- }
- }
-
- @Override
- protected Mask getMask() {
- return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
- .pattern("101101101")
- .pattern("100000001")
- .pattern("100000001")
- .pattern("100000001")
- .pattern("100000001")
- .pattern("111010111")
- .build();
- }
-
- // --- Info Items ---
- private ItemStack getPlotInfoItem() {
- String plotOwner, city, country, difficulty;
- Player plotOwnerPlayer;
-
- try {
- plotOwner = plot.getPlotOwner().getName();
- city = plot.getCity().getName();
- country = plot.getCity().getCountry().getName();
- difficulty = plot.getDifficulty().name().charAt(0) + plot.getDifficulty().name().substring(1).toLowerCase();
-
- plotOwnerPlayer = plot.getPlotOwner().getPlayer();
- } catch (SQLException e) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), e);
- return MenuItems.errorItem(getMenuPlayer());
- }
-
-
- return new ItemBuilder(BaseItems.REVIEW_INFO_PLOT.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.REVIEW_PLOT))
- .color(AQUA)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.ID) + ": ", GRAY).append(text(plot.getID(), WHITE)))
- .emptyLine()
- .addLines(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.OWNER) + ": ", GRAY).append(text(plotOwner, WHITE)),
- text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.CITY) + ": ", GRAY).append(text(city, WHITE)),
- text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.COUNTRY) + ": ", GRAY).append(text(country, WHITE)),
- text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Plot.DIFFICULTY) + ": ", GRAY).append(text(difficulty, WHITE)))
- .emptyLine()
- .addLine(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.PLAYER_LANGUAGE) + ": ", GRAY).append(text(LangUtil.getInstance().get(plotOwnerPlayer, "lang.name"), WHITE)))
- .build())
- .build();
- }
-
- private ItemStack getReviewInfoItem() {
- String points = LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINTS);
-
- return new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.INFO_BUTTON.getId()))
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.INFORMATION), AQUA).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLines(true, LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.INFORMATION))
- .emptyLine()
- .addLines(text(points + " <= 0: ", WHITE).append(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.ABANDONED), RED)),
- text(points + " <= 8: ", WHITE).append(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.REJECTED), YELLOW)),
- text(points + " > 8: ", WHITE).append(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.ACCEPTED), GREEN)))
- .build())
- .build();
- }
-
- // --- Category Items ---
- private ItemStack getAccuracyItem() {
- return new ItemBuilder(BaseItems.REVIEW_ACCURACY.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.ACCURACY))
- .color(GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLines(true, LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.ACCURACY_DESC))
- .build())
- .build();
- }
-
- private ItemStack getBlockPaletteItem() {
- return new ItemBuilder(BaseItems.REVIEW_BLOCK_PALETTE.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.BLOCK_PALETTE))
- .color(GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLines(true, LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.BLOCK_PALETTE_DESC))
- .build())
- .build();
- }
-
- private ItemStack getDetailingItem() {
- return new ItemBuilder(BaseItems.REVIEW_DETAILING.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.DETAILING))
- .color(GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLines(true, LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.DETAILING_DESC))
- .build())
- .build();
- }
-
- private ItemStack getTechniqueItem() {
- return new ItemBuilder(BaseItems.REVIEW_TECHNIQUE.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.TECHNIQUE))
- .color(GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLines(true, LangUtil.getInstance().get(getMenuPlayer(), LangPaths.Review.Criteria.TECHNIQUE_DESC))
- .build())
- .build();
- }
-
- // --- Button Items ---
- private ItemStack getSubmitItem() {
- return new ItemBuilder(BaseItems.REVIEW_SUBMIT.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SUBMIT))
- .color(GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SUBMIT_REVIEW), true)
- .build())
- .build();
- }
-
- private ItemStack getCancelItem() {
- return new ItemBuilder(BaseItems.REVIEW_CANCEL.getItem())
- .setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.CANCEL))
- .color(RED)
- .decoration(BOLD, true))
- .build();
- }
-
- // --- Point Items ---
- private ItemStack getZeroPointItem() {
- return new ItemBuilder(BaseItems.REVIEW_POINT_ZERO.getItem())
- .setName(text("0 " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINTS))
- .color(GRAY)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.REVIEW_POINTS))
- .build())
- .build();
- }
-
- private ItemStack getOnePointItem() {
- return new ItemBuilder(BaseItems.REVIEW_POINT_ONE.getItem())
- .setName(text("1 " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINT))
- .color(RED)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.REVIEW_POINTS))
- .build())
- .build();
- }
-
- private ItemStack getTwoPointItem() {
- ItemStack item = BaseItems.REVIEW_POINT_TWO.getItem();
- item.setAmount(2);
-
- return new ItemBuilder(item)
- .setName(text("2 " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINTS))
- .color(GOLD)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.REVIEW_POINTS))
- .build())
- .build();
- }
-
- private ItemStack getThreePointItem() {
- ItemStack item = BaseItems.REVIEW_POINT_THREE.getItem();
- item.setAmount(3);
-
- return new ItemBuilder(item)
- .setName(text("3 " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINTS))
- .color(YELLOW)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.REVIEW_POINTS))
- .build())
- .build();
- }
-
- private ItemStack getFourPointItem() {
- ItemStack item = BaseItems.REVIEW_POINT_FOUR.getItem();
- item.setAmount(4);
-
- return new ItemBuilder(item)
- .setName(text("4 " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINTS))
- .color(DARK_GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.REVIEW_POINTS))
- .build())
- .build();
- }
-
- private ItemStack getFivePointItem() {
- ItemStack item = BaseItems.REVIEW_POINT_FIVE.getItem();
- item.setAmount(5);
-
- return new ItemBuilder(item)
- .setName(text("5 " + LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.REVIEW_POINTS))
- .color(GREEN)
- .decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.REVIEW_POINTS))
- .build())
- .build();
- }
-}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/SettingsMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/SettingsMenu.java
index 707d08784..546d61285 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/SettingsMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/SettingsMenu.java
@@ -1,50 +1,24 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
-import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
+import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
-import com.alpsbte.plotsystem.utils.items.CustomHeads;
+import com.alpsbte.plotsystem.utils.items.BaseItems;
import com.alpsbte.plotsystem.utils.items.MenuItems;
-import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
import java.util.function.Consumer;
-import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class SettingsMenu extends AbstractMenu {
- private Consumer onBack = (player) -> player.performCommand("companion");
+ private Consumer onBack = player -> player.performCommand("companion");
public SettingsMenu(Player player) {
super(3, LangUtil.getInstance().get(player, LangPaths.MenuTitle.SETTINGS), player);
@@ -59,7 +33,7 @@ public SettingsMenu(Player player, Consumer onBack) {
protected void setMenuItemsAsync() {
// Set language item
getMenu().getSlot(11).setItem(
- new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.GLOBE_HEAD.getId()))
+ new ItemBuilder(BaseItems.LANGUAGE_ITEM.getItem())
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SELECT_LANGUAGE), GOLD, BOLD))
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SELECT_LANGUAGE))
@@ -68,7 +42,7 @@ protected void setMenuItemsAsync() {
// Set Plot type item
getMenu().getSlot(15).setItem(
- new ItemBuilder(AlpsHeadUtils.getCustomHead(CustomHeads.PLOT_TYPE_BUTTON.getId()))
+ new ItemBuilder(BaseItems.PLOT_TYPE.getItem())
.setName(text(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuTitle.SELECT_PLOT_TYPE), GOLD, BOLD))
.setLore(new LoreBuilder()
.addLine(LangUtil.getInstance().get(getMenuPlayer(), LangPaths.MenuDescription.SELECT_PLOT_TYPE))
@@ -94,9 +68,9 @@ protected void setItemClickEventsAsync() {
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(empty()).build())
- .pattern("111111111")
- .pattern("000000000")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
.pattern("111101111")
.build();
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/SpecialToolsMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/SpecialToolsMenu.java
index 7b1f788e7..0db6c7885 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/SpecialToolsMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/SpecialToolsMenu.java
@@ -1,35 +1,11 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2023, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
+import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import com.alpsbte.plotsystem.utils.items.MenuItems;
-import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@@ -73,9 +49,9 @@ protected void setItemClickEventsAsync() {
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
- .pattern("111111111")
- .pattern("000000000")
+ .item(Utils.DEFAULT_ITEM)
+ .pattern(Utils.FULL_MASK)
+ .pattern(Utils.EMPTY_MASK)
.pattern("111101111")
.build();
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CityProjectMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CityProjectMenu.java
index 803c40edf..e9ab62abc 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CityProjectMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CityProjectMenu.java
@@ -1,31 +1,7 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus.companion;
-import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.AbstractPaginatedMenu;
import com.alpsbte.plotsystem.core.menus.tutorial.TutorialsMenu;
import com.alpsbte.plotsystem.core.system.Builder;
@@ -40,14 +16,12 @@
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import com.alpsbte.plotsystem.utils.items.MenuItems;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Unmodifiable;
-import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@@ -58,7 +32,7 @@ public class CityProjectMenu extends AbstractPaginatedMenu {
private PlotDifficulty selectedPlotDifficulty;
CityProjectMenu(Player player, @NotNull Country country, PlotDifficulty selectedPlotDifficulty) {
- super(6, 4, country.getName() + " → " + LangUtil.getInstance().get(player, LangPaths.MenuTitle.COMPANION_SELECT_CITY), player);
+ super(6, 4, country.getName(player) + " → " + LangUtil.getInstance().get(player, LangPaths.MenuTitle.COMPANION_SELECT_CITY), player);
this.country = country;
this.selectedPlotDifficulty = selectedPlotDifficulty;
}
@@ -68,31 +42,25 @@ protected void setPreviewItems() {
getMenu().getSlot(0).setItem(MenuItems.getRandomItem(getMenuPlayer())); // Set random selection item
getMenu().getSlot(1).setItem(MenuItems.backMenuItem(getMenuPlayer()));
- for (Map.Entry entry : CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, country.getContinent())).entrySet()) {
- getMenu().getSlot(entry.getKey()).setItem(entry.getValue().item);
- }
+ Map footerItems = CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, country.getContinent()));
+ footerItems.forEach((index, footerItem) -> getMenu().getSlot(index).setItem(footerItem.item()));
// Set loading item for plots difficulty item
getMenu().getSlot(6).setItem(CompanionMenu.getDifficultyItem(getMenuPlayer(), selectedPlotDifficulty));
// Set tutorial item
getMenu().getSlot(7).setItem(PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.TUTORIAL_ENABLE) ?
- TutorialsMenu.getTutorialItem(getMenuPlayer()) : new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build());
+ TutorialsMenu.getTutorialItem(getMenuPlayer()) : Utils.DEFAULT_ITEM);
// Set previous page item
- if (hasPreviousPage())
- getMenu().getSlot(45).setItem(MenuItems.previousPageItem(getMenuPlayer()));
+ getMenu().getSlot(45).setItem(hasPreviousPage() ? MenuItems.previousPageItem(getMenuPlayer()) : Utils.DEFAULT_ITEM);
// Set next page item
- if (hasNextPage())
- getMenu().getSlot(53).setItem(MenuItems.nextPageItem(getMenuPlayer()));
+ getMenu().getSlot(53).setItem(hasNextPage() ? MenuItems.nextPageItem(getMenuPlayer()) : Utils.DEFAULT_ITEM);
super.setPreviewItems();
}
- @Override
- protected void setMenuItemsAsync() {}
-
@Override
protected void setItemClickEventsAsync() {
getMenu().getSlot(0).setClickHandler((clickPlayer, clickInformation) ->
@@ -101,24 +69,24 @@ protected void setItemClickEventsAsync() {
getMenu().getSlot(1).setClickHandler((clickPlayer, clickInformation) -> new CountryMenu(clickPlayer, country.getContinent(), selectedPlotDifficulty));
// Set click event for previous page item
- getMenu().getSlot(45).setClickHandler((clickPlayer, clickInformation) -> {
- if (hasPreviousPage()) {
+ if (hasPreviousPage()) {
+ getMenu().getSlot(45).setClickHandler((clickPlayer, clickInformation) -> {
previousPage();
clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
- }
- });
+ });
+ }
// Set click event for next page item
- getMenu().getSlot(53).setClickHandler((clickPlayer, clickInformation) -> {
- if (!hasNextPage()) return;
- nextPage();
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
- });
-
- for (Map.Entry entry : CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, country.getContinent())).entrySet()) {
- getMenu().getSlot(entry.getKey()).setClickHandler(entry.getValue().clickHandler);
+ if (hasNextPage()) {
+ getMenu().getSlot(53).setClickHandler((clickPlayer, clickInformation) -> {
+ nextPage();
+ clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.INVENTORY_CLICK_SOUND, 1, 1);
+ });
}
+ Map footerItems = CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, country.getContinent()));
+ footerItems.forEach((index, footerItem) -> getMenu().getSlot(index).setClickHandler(footerItem.clickHandler()));
+
// Set click event for plots difficulty item
getMenu().getSlot(6).setClickHandler(((clickPlayer, clickInformation) -> {
selectedPlotDifficulty = CompanionMenu.clickEventPlotDifficulty(selectedPlotDifficulty, clickPlayer, getMenu());
@@ -134,14 +102,16 @@ public static boolean generateRandomPlot(Player player, @NotNull List getValidCityProjects(PlotDifficulty selectedPlotDifficulty, Player player, Country country) {
- return CityProject.getCityProjects(country, true).stream().filter(test -> {
- if (test instanceof CityProject project) {
- var pd = selectedPlotDifficulty;
- try {
- if (pd == null) pd = Plot.getPlotDifficultyForBuilder(project.getID(), Builder.byUUID(player.getUniqueId())).get();
- if (pd == null) pd = PlotDifficulty.EASY;
- return project.isVisible() && project.getOpenPlotsForPlayer(project.getID(), pd) > 0;
- } catch (SQLException | ExecutionException | InterruptedException e) {
- sqlError(player, e);
- }
- } else {
- return false;
+ public static @NotNull @Unmodifiable List getValidCityProjects(PlotDifficulty selectedPlotDifficulty, Player player, @NotNull Country country) {
+ return DataProvider.CITY_PROJECT.getByCountryCode(country.getCode(), true).stream().filter(test -> {
+ if (!(test instanceof CityProject project)) return false;
+ var pd = selectedPlotDifficulty;
+ try {
+ if (pd == null) pd = Plot.getPlotDifficultyForBuilder(project, Builder.byUUID(player.getUniqueId())).get();
+ if (pd == null) pd = PlotDifficulty.EASY;
+
+ return project.isVisible() && !DataProvider.PLOT.getPlots(project, pd, Status.unclaimed).isEmpty();
+ } catch (ExecutionException | InterruptedException e) {
+ sqlError(player, e);
}
return false;
}).toList();
@@ -170,7 +138,7 @@ public static List getValidCityProjects(PlotDifficulty selectedPlot
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
+ .item(Utils.DEFAULT_ITEM)
.pattern("001111001")
.pattern(Utils.EMPTY_MASK)
.pattern(Utils.EMPTY_MASK)
@@ -182,7 +150,7 @@ protected Mask getMask() {
@Override
protected List> getSource() {
- if (projects == null) projects = CityProject.getCityProjects(country, true);
+ if (projects == null) projects = DataProvider.CITY_PROJECT.getByCountryCode(country.getCode(), true);
return projects;
}
@@ -191,12 +159,7 @@ protected void setPaginatedMenuItemsAsync(@NotNull List> source) {
List cities = source.stream().map(l -> (CityProject) l).toList();
int slot = 9;
for (CityProject city : cities) {
- try {
- getMenu().getSlot(slot).setItem(city.getItem(getMenuPlayer(), selectedPlotDifficulty));
- } catch (SQLException e) {
- Utils.logSqlException(e);
- getMenu().getSlot(slot).setItem(MenuItems.errorItem(getMenuPlayer()));
- }
+ getMenu().getSlot(slot).setItem(city.getItem(getMenuPlayer(), selectedPlotDifficulty));
slot++;
}
}
@@ -215,24 +178,24 @@ protected void setPaginatedItemClickEventsAsync(@NotNull List> source) {
clickPlayer.closeInventory();
Builder builder = Builder.byUUID(clickPlayer.getUniqueId());
- int cityID = city.getID();
try {
- PlotDifficulty plotDifficultyForCity = selectedPlotDifficulty != null ? selectedPlotDifficulty : Plot.getPlotDifficultyForBuilder(cityID, builder).get();
- if (plotDifficultyForCity == null || Plot.getPlots(cityID, plotDifficultyForCity, Status.unclaimed).isEmpty()) {
+ PlotDifficulty plotDifficultyForCity = selectedPlotDifficulty != null ? selectedPlotDifficulty : Plot.getPlotDifficultyForBuilder(city, builder).get();
+ List unclaimedPlots = DataProvider.PLOT.getPlots(city, plotDifficultyForCity, Status.unclaimed);
+ if (unclaimedPlots.isEmpty()) {
clickPlayer.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(clickPlayer, LangPaths.Message.Error.NO_PLOTS_LEFT)));
clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.ERROR_SOUND, 1, 1);
return;
}
- if (selectedPlotDifficulty != null && PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.ENABLE_SCORE_REQUIREMENT) && !Plot.hasPlotDifficultyScoreRequirement(builder, selectedPlotDifficulty)) {
+ if (selectedPlotDifficulty != null && PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.ENABLE_SCORE_REQUIREMENT) && !DataProvider.DIFFICULTY.builderMeetsRequirements(builder, selectedPlotDifficulty)) {
clickPlayer.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(clickPlayer, LangPaths.Message.Error.PLAYER_NEEDS_HIGHER_SCORE)));
clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.ERROR_SOUND, 1, 1);
return;
}
- new DefaultPlotGenerator(cityID, plotDifficultyForCity, builder);
- } catch (SQLException | ExecutionException | InterruptedException ex) {
+ new DefaultPlotGenerator(city, plotDifficultyForCity, builder);
+ } catch (ExecutionException | InterruptedException ex) {
sqlError(clickPlayer, ex);
}
});
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CompanionMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CompanionMenu.java
index d950def03..72d40fa5b 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CompanionMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CompanionMenu.java
@@ -1,40 +1,16 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus.companion;
-import com.alpsbte.alpslib.utils.head.AlpsHeadUtils;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.BuilderUtilitiesMenu;
import com.alpsbte.plotsystem.core.menus.PlayerPlotsMenu;
import com.alpsbte.plotsystem.core.menus.PlotActionsMenu;
import com.alpsbte.plotsystem.core.menus.SettingsMenu;
import com.alpsbte.plotsystem.core.menus.tutorial.TutorialsMenu;
import com.alpsbte.plotsystem.core.system.Builder;
-import com.alpsbte.plotsystem.core.system.Country;
+import com.alpsbte.plotsystem.core.system.Difficulty;
import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Continent;
@@ -44,13 +20,14 @@
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import com.alpsbte.plotsystem.utils.items.BaseItems;
-import com.alpsbte.plotsystem.utils.items.CustomHeads;
import com.alpsbte.plotsystem.utils.items.MenuItems;
+import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.ipvp.canvas.Menu;
+import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -59,13 +36,18 @@
import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class CompanionMenu {
- private CompanionMenu() {}
+ private CompanionMenu() {throw new IllegalStateException("Utility class");}
+
public static boolean hasContinentView() {
- return Arrays.stream(Continent.values()).map(continent -> Country.getCountries(continent).size()).filter(count -> count > 0).count() > 1;
+ // TODO: make this run async
+ return Arrays.stream(Continent.values()).map(continent -> DataProvider.COUNTRY.getCountriesByContinent(continent).size()).filter(count -> count > 0).count() > 1;
}
/**
@@ -77,7 +59,8 @@ public static void open(Player player) {
if (hasContinentView()) {
new ContinentMenu(player);
} else {
- Optional continent = Arrays.stream(Continent.values()).filter(c -> !Country.getCountries(c).isEmpty()).findFirst();
+ // TODO: make this run async
+ Optional continent = Arrays.stream(Continent.values()).filter(c -> !DataProvider.COUNTRY.getCountriesByContinent(c).isEmpty()).findFirst();
if (continent.isEmpty()) {
player.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(player, LangPaths.Message.Error.ERROR_OCCURRED)));
@@ -96,7 +79,7 @@ public static void open(Player player) {
* @param returnToMenu a lambda to call when needing to return to current menu
* @return FooterItems indexed by slot number
*/
- public static Map getFooterItems(int startingSlot, Player player, Consumer returnToMenu) {
+ public static @NotNull Map getFooterItems(int startingSlot, Player player, Consumer returnToMenu) {
HashMap items = new HashMap<>();
// Set builder utilities menu item
items.put(startingSlot + 5, new FooterItem(BuilderUtilitiesMenu.getMenuItem(player), (clickPlayer, clickInformation) -> new BuilderUtilitiesMenu(clickPlayer)));
@@ -116,18 +99,13 @@ public static Map getFooterItems(int startingSlot, Player p
final int i_ = i;
- Plot plot = builder.getPlot(Slot.values()[i]);
- items.put(startingSlot + 1 + i, new FooterItem(builder.getPlotMenuItem(plot, Slot.values()[i].ordinal(), player), (clickPlayer, clickInformation) -> {
+ Plot plot = builder.getSlot(Slot.values()[i]);
+ ItemStack slotItem = getPlotMenuItem(plot, i, player);
+ items.put(startingSlot + 1 + i, new FooterItem(slotItem, (clickPlayer, clickInformation) -> {
if (plot == null) return;
- try {
- new PlotActionsMenu(clickPlayer, builder.getPlot(Slot.values()[i_]));
- } catch (SQLException ex) {
- clickPlayer.sendMessage(Utils.ChatUtils.getAlertFormat(LangUtil.getInstance().get(clickPlayer, LangPaths.Message.Error.ERROR_OCCURRED)));
- clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.ERROR_SOUND, 1, 1);
- PlotSystem.getPlugin().getComponentLogger().error(text("An error occurred while opening the plot actions menu!"), ex);
- }
+ new PlotActionsMenu(clickPlayer, builder.getSlot(Slot.values()[i_]));
}));
- } catch (NullPointerException | SQLException ex) {
+ } catch (NullPointerException ex) {
PlotSystem.getPlugin().getComponentLogger().error(text("An error occurred while placing player slot items!"), ex);
items.put(startingSlot + 1 + i, new FooterItem(MenuItems.errorItem(player)));
}
@@ -142,31 +120,32 @@ public static ItemStack getDifficultyItem(Player player, PlotDifficulty selected
if (selectedPlotDifficulty != null) {
switch (selectedPlotDifficulty) {
case EASY:
- item = AlpsHeadUtils.getCustomHead(CustomHeads.GREEN_CONCRETE.getId()); break;
+ item = BaseItems.DIFFICULTY_EASY.getItem(); break;
case MEDIUM:
- item = AlpsHeadUtils.getCustomHead(CustomHeads.YELLOW_CONCRETE.getId()); break;
+ item = BaseItems.DIFFICULTY_MEDIUM.getItem(); break;
case HARD:
- item = AlpsHeadUtils.getCustomHead(CustomHeads.RED_CONCRETE.getId()); break;
+ item = BaseItems.DIFFICULTY_HARD.getItem(); break;
default:
break;
}
- } else item = AlpsHeadUtils.getCustomHead(CustomHeads.WHITE_CONCRETE.getId());
-
- try {
- return new ItemBuilder(item)
- .setName(text(LangUtil.getInstance().get(player, LangPaths.MenuTitle.PLOT_DIFFICULTY), AQUA).decoration(BOLD, true))
- .setLore(new LoreBuilder()
- .emptyLine()
- .addLines(selectedPlotDifficulty != null ? Utils.ItemUtils.getFormattedDifficulty(selectedPlotDifficulty) : text(LangUtil.getInstance().get(player, LangPaths.Difficulty.AUTOMATIC), WHITE).decoration(BOLD, true),
- selectedPlotDifficulty != null ? text(LangUtil.getInstance().get(player, LangPaths.Difficulty.SCORE_MULTIPLIER) + ": ", GRAY).append(text("x" + Plot.getMultiplierByDifficulty(selectedPlotDifficulty), WHITE)) : empty())
- .emptyLine()
- .addLine(text(LangUtil.getInstance().get(player, LangPaths.MenuDescription.PLOT_DIFFICULTY), GRAY))
- .build())
- .build();
- } catch (SQLException ex) {
- PlotSystem.getPlugin().getComponentLogger().error(text("A SQL error occurred!"), ex);
- return MenuItems.errorItem(player);
+ } else item = BaseItems.DIFFICULTY_AUTOMATIC.getItem();
+
+ Optional difficulty = DataProvider.DIFFICULTY.getDifficultyByEnum(selectedPlotDifficulty);
+ if (difficulty.isEmpty() && selectedPlotDifficulty != null) {
+ PlotSystem.getPlugin().getComponentLogger().error(text("No database entry for difficulty " + selectedPlotDifficulty.name() + " was found!"));
}
+ double scoreMultiplier = difficulty.map(Difficulty::getMultiplier).orElse(0.0);
+
+ return new ItemBuilder(item)
+ .setName(text(LangUtil.getInstance().get(player, LangPaths.MenuTitle.PLOT_DIFFICULTY), AQUA).decoration(BOLD, true))
+ .setLore(new LoreBuilder()
+ .emptyLine()
+ .addLines(selectedPlotDifficulty != null ? Utils.ItemUtils.getFormattedDifficulty(selectedPlotDifficulty, player) : text(LangUtil.getInstance().get(player, LangPaths.Difficulty.AUTOMATIC), WHITE).decoration(BOLD, true),
+ selectedPlotDifficulty != null ? text(LangUtil.getInstance().get(player, LangPaths.Difficulty.SCORE_MULTIPLIER) + ": ", GRAY).append(text("x" + scoreMultiplier, WHITE)) : empty())
+ .emptyLine()
+ .addLine(text(LangUtil.getInstance().get(player, LangPaths.MenuDescription.PLOT_DIFFICULTY), GRAY))
+ .build())
+ .build();
}
/**
@@ -208,18 +187,38 @@ public static void clickEventTutorialItem(Menu menu) {
});
}
- public static class FooterItem {
- public final ItemStack item;
- public final org.ipvp.canvas.slot.Slot.ClickHandler clickHandler;
+ public static ItemStack getPlotMenuItem(Plot plot, int slotIndex, Player langPlayer) {
+ String nameText = LangUtil.getInstance().get(langPlayer, LangPaths.MenuTitle.SLOT).toUpperCase() + " " + (slotIndex + 1);
+ ItemStack baseItem = plot == null ? BaseItems.PLOT_SLOT_EMPTY.getItem().clone() : BaseItems.PLOT_SLOT_FILLED.getItem().clone();
+ baseItem.setAmount(1 + slotIndex);
+ ArrayList lore;
- FooterItem(ItemStack item, org.ipvp.canvas.slot.Slot.ClickHandler clickHandler) {
- this.item = item;
- this.clickHandler = clickHandler;
+ if (plot == null) {
+ TextComponent slotDescriptionComp = text(LangUtil.getInstance().get(langPlayer, LangPaths.MenuDescription.SLOT), GRAY);
+ lore = new LoreBuilder()
+ .addLine(slotDescriptionComp)
+ .build();
+ } else {
+ String plotIdText = LangUtil.getInstance().get(langPlayer, LangPaths.Plot.ID);
+ String plotCityText = LangUtil.getInstance().get(langPlayer, LangPaths.Plot.CITY);
+ String plotDifficultyText = LangUtil.getInstance().get(langPlayer, LangPaths.Plot.DIFFICULTY);
+ String statusText = LangUtil.getInstance().get(langPlayer, LangPaths.Database.STATUS + "." + plot.getStatus().name() + ".name");
+
+ TextComponent statusComp = text(LangUtil.getInstance().get(langPlayer, LangPaths.Plot.STATUS) + ": ", GOLD)
+ .decoration(BOLD, true)
+ .append(text(statusText, GRAY));
+ lore = new LoreBuilder()
+ .addLines(text(plotIdText + ": ", GRAY).append(text(plot.getId(), WHITE)),
+ text(plotCityText + ": ", GRAY).append(text(plot.getCityProject().getName(langPlayer), WHITE)),
+ text(plotDifficultyText + ": ", GRAY).append(text(plot.getDifficulty().name().charAt(0) + plot.getDifficulty().name().substring(1).toLowerCase(), WHITE)),
+ empty(),
+ statusComp)
+ .build();
}
- FooterItem(ItemStack item) {
- this.item = item;
- this.clickHandler = null;
- }
+ return new ItemBuilder(baseItem)
+ .setName(text(nameText, GOLD).decoration(BOLD, true))
+ .setLore(lore)
+ .build();
}
}
\ No newline at end of file
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/ContinentMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/ContinentMenu.java
index 9ab39aa10..381dbe734 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/ContinentMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/ContinentMenu.java
@@ -1,39 +1,12 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus.companion;
-import com.alpsbte.alpslib.utils.item.ItemBuilder;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.AbstractMenu;
-import com.alpsbte.plotsystem.core.system.Country;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Continent;
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import com.alpsbte.plotsystem.utils.items.MenuItems;
-import net.kyori.adventure.text.Component;
-import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
@@ -60,9 +33,8 @@ public class ContinentMenu extends AbstractMenu {
protected void setPreviewItems() {
getMenu().getSlot(0).setItem(MenuItems.getRandomItem(getMenuPlayer())); // Set random selection item
- for (Map.Entry entry : CompanionMenu.getFooterItems(9 * 4, getMenuPlayer(), ContinentMenu::new).entrySet()) {
- getMenu().getSlot(entry.getKey()).setItem(entry.getValue().item);
- }
+ Map footerItems = CompanionMenu.getFooterItems(9 * 4, getMenuPlayer(), ContinentMenu::new);
+ footerItems.forEach((index, footerItem) -> getMenu().getSlot(index).setItem(footerItem.item()));
super.setPreviewItems();
}
@@ -79,7 +51,7 @@ protected void setItemClickEventsAsync() {
List layout2 = new java.util.ArrayList<>(layout.values().stream().toList());
while (!layout2.isEmpty()) {
var rndContinent = layout2.get(Utils.getRandom().nextInt(layout2.size()));
- var successful = CountryMenu.generateRandomPlot(clickPlayer, Country.getCountries(rndContinent), null);
+ var successful = CountryMenu.generateRandomPlot(clickPlayer, DataProvider.COUNTRY.getCountriesByContinent(rndContinent), null);
if (successful) {
return;
} else {
@@ -92,19 +64,18 @@ protected void setItemClickEventsAsync() {
getMenu().getSlot(continent.getKey()).setClickHandler((clickPlayer, clickInfo) -> new CountryMenu(clickPlayer, continent.getValue()));
}
- for (Map.Entry entry : CompanionMenu.getFooterItems(9 * 4, getMenuPlayer(), ContinentMenu::new).entrySet()) {
- getMenu().getSlot(entry.getKey()).setClickHandler(entry.getValue().clickHandler);
- }
+ Map footerItems = CompanionMenu.getFooterItems(9 * 4, getMenuPlayer(), ContinentMenu::new);
+ footerItems.forEach((index, footerItem) -> getMenu().getSlot(index).setClickHandler(footerItem.clickHandler()));
}
@Override
protected Mask getMask() {
return BinaryMask.builder(getMenu())
- .item(new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(Component.empty()).build())
+ .item(Utils.DEFAULT_ITEM)
.pattern("011111111")
.pattern("010101010")
.pattern("111101111")
- .pattern("111111111")
+ .pattern(Utils.FULL_MASK)
.pattern("100010001")
.build();
}
diff --git a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CountryMenu.java b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CountryMenu.java
index 4dab2b33a..91e500a78 100644
--- a/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CountryMenu.java
+++ b/src/main/java/com/alpsbte/plotsystem/core/menus/companion/CountryMenu.java
@@ -1,37 +1,13 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright © 2025, Alps BTE
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
package com.alpsbte.plotsystem.core.menus.companion;
import com.alpsbte.alpslib.utils.item.ItemBuilder;
import com.alpsbte.alpslib.utils.item.LoreBuilder;
import com.alpsbte.plotsystem.PlotSystem;
+import com.alpsbte.plotsystem.core.database.DataProvider;
import com.alpsbte.plotsystem.core.menus.AbstractMenu;
import com.alpsbte.plotsystem.core.menus.tutorial.TutorialsMenu;
import com.alpsbte.plotsystem.core.system.CityProject;
import com.alpsbte.plotsystem.core.system.Country;
-import com.alpsbte.plotsystem.core.system.plot.Plot;
import com.alpsbte.plotsystem.utils.Utils;
import com.alpsbte.plotsystem.utils.enums.Continent;
import com.alpsbte.plotsystem.utils.enums.PlotDifficulty;
@@ -40,27 +16,29 @@
import com.alpsbte.plotsystem.utils.io.LangPaths;
import com.alpsbte.plotsystem.utils.io.LangUtil;
import com.alpsbte.plotsystem.utils.items.MenuItems;
-import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.ipvp.canvas.mask.BinaryMask;
import org.ipvp.canvas.mask.Mask;
import org.jetbrains.annotations.NotNull;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import static net.kyori.adventure.text.Component.empty;
import static net.kyori.adventure.text.Component.text;
-import static net.kyori.adventure.text.format.NamedTextColor.*;
+import static net.kyori.adventure.text.format.NamedTextColor.AQUA;
+import static net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GOLD;
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
import static net.kyori.adventure.text.format.TextDecoration.BOLD;
public class CountryMenu extends AbstractMenu {
private List countryProjects;
private final Continent selectedContinent;
- private PlotDifficulty selectedPlotDifficulty = null;
+ private PlotDifficulty selectedPlotDifficulty = PlotDifficulty.EASY;
CountryMenu(Player player, @NotNull Continent continent) {
super(6, LangUtil.getInstance().get(player, continent.langPath) + " → " + LangUtil.getInstance().get(player, LangPaths.MenuTitle.COMPANION_SELECT_COUNTRY), player);
@@ -81,11 +59,10 @@ protected void setPreviewItems() {
// Set tutorial item
getMenu().getSlot(7).setItem(PlotSystem.getPlugin().getConfig().getBoolean(ConfigPaths.TUTORIAL_ENABLE) ?
- TutorialsMenu.getTutorialItem(getMenuPlayer()) : new ItemBuilder(Material.GRAY_STAINED_GLASS_PANE, 1).setName(empty()).build());
+ TutorialsMenu.getTutorialItem(getMenuPlayer()) : Utils.DEFAULT_ITEM);
- for (Map.Entry entry : CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, selectedContinent)).entrySet()) {
- getMenu().getSlot(entry.getKey()).setItem(entry.getValue().item);
- }
+ Map footerItems = CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, selectedContinent));
+ footerItems.forEach((index, footerItem) -> getMenu().getSlot(index).setItem(footerItem.item()));
super.setPreviewItems();
}
@@ -93,10 +70,8 @@ protected void setPreviewItems() {
@Override
protected void setMenuItemsAsync() {
// Set city project items
- try {
- countryProjects = Country.getCountries(selectedContinent);
- setCountryItems();
- } catch (SQLException ex) {Utils.logSqlException(ex);}
+ countryProjects = DataProvider.COUNTRY.getCountriesByContinent(selectedContinent);
+ setCountryItems();
}
@Override
@@ -106,10 +81,14 @@ protected void setItemClickEventsAsync() {
// Set click event for plots difficulty item
getMenu().getSlot(6).setClickHandler((clickPlayer, clickInformation) -> {
- selectedPlotDifficulty = CompanionMenu.clickEventPlotDifficulty(selectedPlotDifficulty, clickPlayer, getMenu());
- try {
- setCountryItems();
- } catch (SQLException ex) {Utils.logSqlException(ex);}
+ selectedPlotDifficulty = (selectedPlotDifficulty == null ?
+ PlotDifficulty.values()[0] : selectedPlotDifficulty.ordinal() != PlotDifficulty.values().length - 1 ?
+ PlotDifficulty.values()[selectedPlotDifficulty.ordinal() + 1] : null);
+
+ getMenu().getSlot(6).setItem(CompanionMenu.getDifficultyItem(getMenuPlayer(), selectedPlotDifficulty));
+ clickPlayer.playSound(clickPlayer.getLocation(), Utils.SoundUtils.DONE_SOUND, 1, 1);
+
+ setCountryItems();
});
CompanionMenu.clickEventTutorialItem(getMenu());
@@ -124,9 +103,8 @@ protected void setItemClickEventsAsync() {
getMenu().getSlot(startingSlot + i).setClickHandler((clickPlayer, clickInformation) -> new CityProjectMenu(clickPlayer, country, selectedPlotDifficulty));
}
- for (Map.Entry entry : CompanionMenu.getFooterItems(45, getMenuPlayer(), player -> new CountryMenu(player, selectedContinent)).entrySet()) {
- getMenu().getSlot(entry.getKey()).setClickHandler(entry.getValue().clickHandler);
- }
+ Map