Compare commits
No commits in common. "46dec9a933cdd78b0d52345745f4f439ef8a6762" and "6190c43eb11f7e7a7632a00da5f31210e95c2d59" have entirely different histories.
46dec9a933
...
6190c43eb1
26
Jenkinsfile
vendored
26
Jenkinsfile
vendored
|
|
@ -3,13 +3,7 @@ pipeline {
|
||||||
stages {
|
stages {
|
||||||
stage('Gradle') {
|
stage('Gradle') {
|
||||||
steps {
|
steps {
|
||||||
withCredentials([usernamePassword(credentialsId: 'alttd-snapshot-user', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
|
sh './gradlew build'
|
||||||
sh '''
|
|
||||||
set +x
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew build -PalttdSnapshotUsername=$USERNAME -PalttdSnapshotPassword=$PASSWORD
|
|
||||||
'''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Archive') {
|
stage('Archive') {
|
||||||
|
|
@ -22,14 +16,14 @@ pipeline {
|
||||||
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
|
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// stage('Copy to /mnt/updates/plugins') {
|
stage('Copy to /mnt/updates/plugins') {
|
||||||
// when {
|
when {
|
||||||
// branch 'main'
|
branch 'main'
|
||||||
// branch 'master'
|
branch 'master'
|
||||||
// }
|
}
|
||||||
// steps {
|
steps {
|
||||||
// sh 'cp build/libs/*.jar /mnt/updates/plugins/'
|
sh 'cp build/libs/*.jar /mnt/updates/plugins/'
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,23 +2,28 @@ import java.io.ByteArrayOutputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||||
import net.minecrell.pluginyml.paper.PaperPluginDescription
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("java-library")
|
id("java-library")
|
||||||
id("de.eldoria.plugin-yml.paper") version "0.9.0"
|
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
|
||||||
id("xyz.jpenilla.run-paper") version "1.0.6"
|
id("xyz.jpenilla.run-paper") version "1.0.6"
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.alttd.playershops"
|
group = "com.alttd.playershops"
|
||||||
version = System.getenv("BUILD_NUMBER") ?: "1.4-SNAPSHOT"
|
version = System.getenv("BUILD_NUMBER") ?: "1.3-SNAPSHOT"
|
||||||
description = "Player Shop plugin for Altitude."
|
description = "Player Shop plugin for Altitude."
|
||||||
|
|
||||||
apply<JavaLibraryPlugin>()
|
apply<JavaLibraryPlugin>()
|
||||||
apply(plugin = "maven-publish")
|
apply(plugin = "maven-publish")
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion.set(JavaLanguageVersion.of(21))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
withType<JavaCompile> {
|
withType<JavaCompile> {
|
||||||
options.encoding = Charsets.UTF_8.name()
|
options.encoding = Charsets.UTF_8.name()
|
||||||
|
|
@ -29,17 +34,16 @@ tasks {
|
||||||
}
|
}
|
||||||
|
|
||||||
runServer {
|
runServer {
|
||||||
val dir = File(System.getProperty("user.home") + "/share/devserver/")
|
val fileName = "./run/cosmos.jar"
|
||||||
if (!dir.parentFile.exists()) {
|
val file = File(fileName)
|
||||||
dir.parentFile.mkdirs()
|
if (!file.parentFile.exists()) {
|
||||||
|
file.parentFile.mkdirs()
|
||||||
|
}
|
||||||
|
if (!file.exists()) {
|
||||||
|
download("https://jenkins.destro.xyz/job/Cosmos/lastSuccessfulBuild/artifact/cosmos-server/build/libs/cosmos-bundler-1.21.6-R0.1-SNAPSHOT-mojmap.jar", fileName)
|
||||||
}
|
}
|
||||||
runDirectory.set(dir)
|
|
||||||
|
|
||||||
val fileName = "/cosmos.jar"
|
|
||||||
val file = File(dir.path + fileName)
|
|
||||||
|
|
||||||
serverJar(file)
|
serverJar(file)
|
||||||
minecraftVersion("26.2")
|
minecraftVersion("1.21")
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
|
@ -57,10 +61,8 @@ publishing {
|
||||||
configure<PublishingExtension> {
|
configure<PublishingExtension> {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
name = "AlttdNexus"
|
name = "maven"
|
||||||
url = uri(
|
url = uri("https://repo.destro.xyz/snapshots/")
|
||||||
"https://repo.alttd.com/repository/alttd-snapshot/"
|
|
||||||
)
|
|
||||||
credentials(PasswordCredentials::class)
|
credentials(PasswordCredentials::class)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -68,14 +70,23 @@ publishing {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("com.alttd.cosmos:cosmos-api:26.2.build.17-stable")
|
compileOnly("com.alttd.cosmos:cosmos-api:1.21.6-R0.1-SNAPSHOT")
|
||||||
compileOnly("com.github.milkbowl:VaultAPI:1.7") {
|
compileOnly("com.github.milkbowl:VaultAPI:1.7") {
|
||||||
exclude("org.bukkit","bukkit")
|
exclude("org.bukkit","bukkit")
|
||||||
}
|
}
|
||||||
compileOnly("com.github.TechFortress:GriefPrevention:16.17.1")
|
compileOnly("com.github.TechFortress:GriefPrevention:16.17.1")
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.46")
|
compileOnly("org.projectlombok:lombok:1.18.30")
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.46")
|
annotationProcessor("org.projectlombok:lombok:1.18.30")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun gitCommit(): String {
|
||||||
|
val os = ByteArrayOutputStream()
|
||||||
|
project.exec {
|
||||||
|
commandLine = "git rev-parse --short HEAD".split(" ")
|
||||||
|
standardOutput = os
|
||||||
|
}
|
||||||
|
return String(os.toByteArray()).trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun download(link: String, path: String) {
|
fun download(link: String, path: String) {
|
||||||
|
|
@ -86,23 +97,14 @@ fun download(link: String, path: String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paper {
|
bukkit {
|
||||||
name = rootProject.name
|
name = rootProject.name
|
||||||
main = "$group.${rootProject.name}"
|
main = "$group.${rootProject.name}"
|
||||||
bootstrapper = "$group.${rootProject.name}Bootstrap"
|
version = "${rootProject.version}-${gitCommit()}"
|
||||||
version = "${rootProject.version}"
|
apiVersion = "1.20"
|
||||||
apiVersion = "1.21"
|
|
||||||
authors = listOf("destro174")
|
authors = listOf("destro174")
|
||||||
serverDependencies {
|
depend = listOf("Vault")
|
||||||
register("Vault") {
|
softDepend = listOf("GriefPrevention")
|
||||||
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
|
|
||||||
}
|
|
||||||
|
|
||||||
register("GriefPrevention") {
|
|
||||||
required = false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
permissions {
|
permissions {
|
||||||
register("playershops.admin") {
|
register("playershops.admin") {
|
||||||
|
|
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
|
||||||
15
gradlew
vendored
15
gradlew
vendored
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
|
@ -15,8 +15,6 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
|
|
@ -57,7 +55,7 @@
|
||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
|
@ -86,7 +84,7 @@ done
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|
@ -114,6 +112,7 @@ case "$( uname )" in #(
|
||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
|
|
@ -171,6 +170,7 @@ fi
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if "$cygwin" || "$msys" ; then
|
if "$cygwin" || "$msys" ; then
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
|
@ -203,14 +203,15 @@ fi
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# Collect all arguments for the java command:
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# and any embedded shellness will be escaped.
|
# 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
|
# * 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.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
|
|
|
||||||
25
gradlew.bat
vendored
25
gradlew.bat
vendored
|
|
@ -13,8 +13,6 @@
|
||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
@rem SPDX-License-Identifier: Apache-2.0
|
|
||||||
@rem
|
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|
@ -45,11 +43,11 @@ set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
|
|
@ -59,21 +57,22 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,9 @@
|
||||||
rootProject.name = "PlayerShops"
|
rootProject.name = "PlayerShops"
|
||||||
|
|
||||||
val nexusUser = providers.gradleProperty("alttdSnapshotUsername").orNull ?: System.getenv("NEXUS_USERNAME")
|
|
||||||
val nexusPass = providers.gradleProperty("alttdSnapshotPassword").orNull ?: System.getenv("NEXUS_PASSWORD")
|
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
|
||||||
url = uri("https://repo.alttd.com/repository/alttd-snapshot/")
|
|
||||||
credentials {
|
|
||||||
username = nexusUser
|
|
||||||
password = nexusPass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url = uri("https://repo.alttd.com/repository/alttd/")
|
|
||||||
credentials {
|
|
||||||
username = nexusUser
|
|
||||||
password = nexusPass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maven("https://repo.destro.xyz/snapshots")
|
|
||||||
maven("https://jitpack.io") { // Vault
|
maven("https://jitpack.io") { // Vault
|
||||||
content {
|
content {
|
||||||
includeGroup("com.github.milkbowl")
|
includeGroup("com.github.milkbowl")
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,21 @@
|
||||||
package com.alttd.playershops;
|
package com.alttd.playershops;
|
||||||
|
|
||||||
import com.alttd.playershops.commands.PlayerShopCommand;
|
import com.alttd.playershops.commands.PlayerShopCommands;
|
||||||
import com.alttd.playershops.config.Config;
|
import com.alttd.playershops.config.Config;
|
||||||
import com.alttd.playershops.config.DatabaseConfig;
|
import com.alttd.playershops.config.DatabaseConfig;
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.gui.GuiIcon;
|
||||||
import com.alttd.playershops.handler.ShopHandler;
|
import com.alttd.playershops.handler.ShopHandler;
|
||||||
import com.alttd.playershops.listener.*;
|
import com.alttd.playershops.listener.*;
|
||||||
import com.alttd.playershops.shop.ShopType;
|
import com.alttd.playershops.shop.ShopType;
|
||||||
import com.alttd.playershops.storage.database.DatabaseManager;
|
import com.alttd.playershops.storage.database.DatabaseManager;
|
||||||
import com.alttd.playershops.storage.database.DatabaseHelper;
|
import com.alttd.playershops.storage.database.DatabaseHelper;
|
||||||
import io.papermc.paper.command.brigadier.Commands;
|
|
||||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
|
||||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.milkbowl.vault.economy.Economy;
|
import net.milkbowl.vault.economy.Economy;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PlayerShops extends JavaPlugin {
|
public class PlayerShops extends JavaPlugin {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -36,6 +31,7 @@ public class PlayerShops extends JavaPlugin {
|
||||||
private ShopListener shopListener;
|
private ShopListener shopListener;
|
||||||
private PlayerListener playerListener;
|
private PlayerListener playerListener;
|
||||||
private TransactionListener transactionListener;
|
private TransactionListener transactionListener;
|
||||||
|
private InventoryListener inventoryListener;
|
||||||
private GriefPreventionListener griefPreventionListener;
|
private GriefPreventionListener griefPreventionListener;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -44,14 +40,14 @@ public class PlayerShops extends JavaPlugin {
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
if(!setupEconomy()) {
|
if(!setupEconomy()) {
|
||||||
getLogger().warning("Error loading Vault and economy.\n Disabling plugin");
|
Bukkit.getLogger().warning("Error loading Vault and economy.\n Disabling plugin");
|
||||||
this.setEnabled(false);
|
this.setEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getLogger().info("Hooked into Vault economy provided by " + econ.getName());
|
Bukkit.getLogger().info("Hooked into Vault economy provided by " + econ.getName());
|
||||||
reloadConfigs();
|
reloadConfigs();
|
||||||
if(!setupDatabase()) {
|
if(!setupDatabase()) {
|
||||||
getLogger().warning("Error setting up database connection.\n Disabling plugin");
|
Bukkit.getLogger().warning("Error setting up database connection.\n Disabling plugin");
|
||||||
this.setEnabled(false);
|
this.setEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +95,7 @@ public class PlayerShops extends JavaPlugin {
|
||||||
shopListener = new ShopListener(this);
|
shopListener = new ShopListener(this);
|
||||||
playerListener = new PlayerListener(this);
|
playerListener = new PlayerListener(this);
|
||||||
transactionListener = new TransactionListener(this);
|
transactionListener = new TransactionListener(this);
|
||||||
|
inventoryListener = new InventoryListener(this);
|
||||||
griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP
|
griefPreventionListener = new GriefPreventionListener(this); // TODO hook into GP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,14 +103,11 @@ public class PlayerShops extends JavaPlugin {
|
||||||
shopListener.unregister();
|
shopListener.unregister();
|
||||||
playerListener.unregister();
|
playerListener.unregister();
|
||||||
transactionListener.unregister();
|
transactionListener.unregister();
|
||||||
|
inventoryListener.unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerCommands() {
|
private void registerCommands() {
|
||||||
LifecycleEventManager<Plugin> manager = this.getLifecycleManager();
|
PlayerShopCommands.registerCommands();
|
||||||
manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> {
|
|
||||||
final Commands commands = event.registrar();
|
|
||||||
commands.register(new PlayerShopCommand().command(), null, List.of("shop", "shops"));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadConfigs() {
|
public void reloadConfigs() {
|
||||||
|
|
@ -125,6 +119,9 @@ public class PlayerShops extends JavaPlugin {
|
||||||
for (ShopType shopType : ShopType.values()) {
|
for (ShopType shopType : ShopType.values()) {
|
||||||
// preload ShopType to get the configs active
|
// preload ShopType to get the configs active
|
||||||
}
|
}
|
||||||
|
for (GuiIcon guiIcon : GuiIcon.values()) {
|
||||||
|
// preload to get config values generated
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package com.alttd.playershops;
|
|
||||||
|
|
||||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
|
||||||
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
|
|
||||||
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
public class PlayerShopsBootstrap implements PluginBootstrap {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bootstrap(BootstrapContext context) {}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +1,147 @@
|
||||||
package com.alttd.playershops.commands;
|
package com.alttd.playershops.commands;
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
|
||||||
import com.alttd.playershops.commands.arguments.OfflinePlayerArgument;
|
|
||||||
import com.alttd.playershops.commands.subcommands.CheckStockCommand;
|
import com.alttd.playershops.commands.subcommands.CheckStockCommand;
|
||||||
import com.alttd.playershops.dialog.ShopDialog;
|
import com.alttd.playershops.commands.subcommands.ReloadCommand;
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
import com.alttd.playershops.commands.subcommands.TransferShopsCommand;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.alttd.playershops.gui.HomeGui;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.alttd.playershops.utils.Util;
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import io.papermc.paper.command.brigadier.Commands;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.permissions.Permission;
|
||||||
|
import org.bukkit.permissions.PermissionDefault;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class PlayerShopCommand {
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public static final String BASE_PERM = "playershops.command";
|
import static net.kyori.adventure.text.Component.text;
|
||||||
|
import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||||
|
|
||||||
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
|
public class PlayerShopCommand extends Command {
|
||||||
final LiteralArgumentBuilder<CommandSourceStack> builder =
|
|
||||||
Commands.literal("playershop")
|
|
||||||
.requires(
|
|
||||||
commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM)
|
|
||||||
&& commandSourceStack.getSender() instanceof Player
|
|
||||||
)
|
|
||||||
.executes((source) -> {
|
|
||||||
if (!(source.getSource().getSender() instanceof Player player))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
ShopDialog shopDialog = new ShopDialog(player.getUniqueId());
|
public static final String BASE_PERM = "playershops.command"; // TODO load from config
|
||||||
shopDialog.open();
|
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
Commands.literal("reload")
|
|
||||||
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".reload"))
|
|
||||||
.executes(source -> {
|
|
||||||
PlayerShops.getInstance().reloadConfigs();
|
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.then(
|
|
||||||
Commands.literal("checkstock")
|
|
||||||
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".checkstock")
|
|
||||||
&& commandSourceStack.getSender() instanceof Player)
|
|
||||||
.then(
|
|
||||||
Commands.argument("range", IntegerArgumentType.integer(1, 100))
|
|
||||||
.executes(source -> {
|
|
||||||
if (!(source.getSource().getSender() instanceof Player player))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
int range = source.getArgument("range", Integer.class);
|
// subcommand label -> subcommand
|
||||||
int stock = -1;
|
private static final Map<String, Subcommand> SUBCOMMANDS = PlayerShopCommands.make(() -> {
|
||||||
CheckStockCommand.doStockCheck(player, range, stock);
|
final Map<Set<String>, Subcommand> commands = new HashMap<>();
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
Commands.argument("stock", IntegerArgumentType.integer())
|
|
||||||
.executes(source -> {
|
|
||||||
if (!(source.getSource().getSender() instanceof Player player))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
int range = source.getArgument("range", Integer.class);
|
commands.put(Set.of("reload"), new ReloadCommand());
|
||||||
int stock = source.getArgument("stock", Integer.class);
|
commands.put(Set.of("checkstock"), new CheckStockCommand());
|
||||||
CheckStockCommand.doStockCheck(player, range, stock);
|
commands.put(Set.of("transfershops"), new TransferShopsCommand());
|
||||||
return 1;
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(
|
|
||||||
Commands.literal("transfershops")
|
|
||||||
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(BASE_PERM + ".transfershops"))
|
|
||||||
.then(
|
|
||||||
Commands.argument("old", new OfflinePlayerArgument())
|
|
||||||
.then(
|
|
||||||
Commands.argument("new", new OfflinePlayerArgument())
|
|
||||||
)
|
|
||||||
.executes(
|
|
||||||
source -> {
|
|
||||||
OfflinePlayer oldOwner = source.getArgument("old", OfflinePlayer.class);
|
|
||||||
OfflinePlayer newOwner = source.getArgument("new", OfflinePlayer.class);
|
|
||||||
PlayerShops.getInstance().getShopHandler().transferShops(source.getSource().getSender(), oldOwner, newOwner);
|
|
||||||
|
|
||||||
return 1;
|
return commands.entrySet().stream()
|
||||||
}
|
.flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue())))
|
||||||
)
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
)
|
});
|
||||||
)
|
// alias -> subcommand label
|
||||||
;
|
private static final Map<String, String> ALIASES = PlayerShopCommands.make(() -> {
|
||||||
return builder.build();
|
final Map<String, Set<String>> aliases = new HashMap<>();
|
||||||
|
|
||||||
|
aliases.put("reload", Set.of("reloadconfig"));
|
||||||
|
|
||||||
|
return aliases.entrySet().stream()
|
||||||
|
.flatMap(entry -> entry.getValue().stream().map(s -> Map.entry(s, entry.getKey())))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
});
|
||||||
|
|
||||||
|
public PlayerShopCommand() {
|
||||||
|
super("playershop");
|
||||||
|
this.description = "PlayerShop related commands";
|
||||||
|
this.usageMessage = "/playershop [" + String.join(" | ", SUBCOMMANDS.keySet()) + "]";
|
||||||
|
this.setAliases(List.of("shop", "shops"));
|
||||||
|
final List<String> permissions = new ArrayList<>();
|
||||||
|
permissions.add(BASE_PERM);
|
||||||
|
permissions.addAll(SUBCOMMANDS.keySet().stream().map(s -> BASE_PERM + "." + s).toList());
|
||||||
|
this.setPermission(String.join(";", permissions));
|
||||||
|
final PluginManager pluginManager = Bukkit.getServer().getPluginManager();
|
||||||
|
for (final String perm : permissions) {
|
||||||
|
pluginManager.addPermission(new Permission(perm, PermissionDefault.OP));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean testPermission(final CommandSender sender, final String permission) {
|
||||||
|
if (sender.hasPermission(BASE_PERM + "." + permission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sender.sendMessage(Bukkit.permissionMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<String> tabComplete(
|
||||||
|
final @NotNull CommandSender sender,
|
||||||
|
final @NotNull String alias,
|
||||||
|
final String[] args,
|
||||||
|
final @Nullable Location location
|
||||||
|
) throws IllegalArgumentException {
|
||||||
|
if (args.length <= 1) {
|
||||||
|
return PlayerShopCommands.getListMatchingLast(sender, args, SUBCOMMANDS.keySet(), BASE_PERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
final @Nullable Pair<String, Subcommand> subCommand = resolveCommand(args[0]);
|
||||||
|
if (subCommand != null) {
|
||||||
|
return subCommand.second().tabComplete(sender, subCommand.first(), Arrays.copyOfRange(args, 1, args.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(
|
||||||
|
final @NotNull CommandSender sender,
|
||||||
|
final @NotNull String commandLabel,
|
||||||
|
final String[] args
|
||||||
|
) {
|
||||||
|
if (!testPermission(sender)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length == 0) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
sender.sendMessage(Util.parseMiniMessage("<red>Only players can use this command."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HomeGui gui = new HomeGui(player.getUniqueId());
|
||||||
|
gui.open();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final @Nullable Pair<String, Subcommand> subCommand = resolveCommand(args[0]);
|
||||||
|
|
||||||
|
if (subCommand == null) {
|
||||||
|
sender.sendMessage(text("Usage: " + this.usageMessage, RED));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!testPermission(sender, subCommand.first())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final String[] choppedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
return subCommand.second().execute(sender, subCommand.first(), choppedArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @Nullable Pair<String, Subcommand> resolveCommand(String label) {
|
||||||
|
label = label.toLowerCase(Locale.ENGLISH);
|
||||||
|
@Nullable Subcommand subCommand = SUBCOMMANDS.get(label);
|
||||||
|
if (subCommand == null) {
|
||||||
|
final @Nullable String command = ALIASES.get(label);
|
||||||
|
if (command != null) {
|
||||||
|
label = command;
|
||||||
|
subCommand = SUBCOMMANDS.get(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subCommand != null) {
|
||||||
|
return Pair.of(label, subCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.alttd.playershops.commands;
|
||||||
|
|
||||||
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class PlayerShopCommands {
|
||||||
|
|
||||||
|
private PlayerShopCommands() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<String, Command> COMMANDS = new HashMap<>();
|
||||||
|
static {
|
||||||
|
COMMANDS.put("playershop", new PlayerShopCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerCommands() {
|
||||||
|
COMMANDS.forEach((s, command) -> {
|
||||||
|
Bukkit.getCommandMap().register(s, command.getName(), command);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code from Mojang - copyright them | Altered to fit our needs
|
||||||
|
public static List<String> getListMatchingLast(final CommandSender sender, final String[] args, final String basePermission, final String... matches) {
|
||||||
|
return getListMatchingLast(sender, args, Arrays.asList(matches), basePermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean matches(final String s, final String s1) {
|
||||||
|
return s1.regionMatches(true, 0, s, 0, s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getListMatchingLast(final CommandSender sender, final String[] strings, final Collection<?> collection, final String basePermission) {
|
||||||
|
String last = strings[strings.length - 1];
|
||||||
|
ArrayList<String> results = Lists.newArrayList();
|
||||||
|
|
||||||
|
if (!collection.isEmpty()) {
|
||||||
|
|
||||||
|
for (String s1 : collection.stream().map(Functions.toStringFunction()).toList()) {
|
||||||
|
if (matches(last, s1) && (sender.hasPermission(basePermission + "." + s1))) {
|
||||||
|
results.add(s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T make(Supplier<T> factory) {
|
||||||
|
return factory.get();
|
||||||
|
}
|
||||||
|
// end copy stuff
|
||||||
|
}
|
||||||
19
src/main/java/com/alttd/playershops/commands/Subcommand.java
Normal file
19
src/main/java/com/alttd/playershops/commands/Subcommand.java
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.alttd.playershops.commands;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@DefaultQualifier(NonNull.class)
|
||||||
|
public interface Subcommand {
|
||||||
|
|
||||||
|
boolean execute(CommandSender sender, String subCommand, String[] args);
|
||||||
|
|
||||||
|
default List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
package com.alttd.playershops.commands.arguments;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.Message;
|
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
|
||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
|
||||||
import io.papermc.paper.command.brigadier.MessageComponentSerializer;
|
|
||||||
import io.papermc.paper.command.brigadier.argument.CustomArgumentType;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class OfflinePlayerArgument implements CustomArgumentType.Converted<OfflinePlayer, String> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull OfflinePlayer convert(String nativeType) throws CommandSyntaxException {
|
|
||||||
try {
|
|
||||||
return Bukkit.getOfflinePlayer(nativeType);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Message message = MessageComponentSerializer.message().serialize(Component.text("Invalid PlayerName %s!".formatted(nativeType), NamedTextColor.RED));
|
|
||||||
|
|
||||||
throw new CommandSyntaxException(new SimpleCommandExceptionType(message), message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ArgumentType<String> getNativeType() {
|
|
||||||
return StringArgumentType.word();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <S> @NotNull CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
|
|
||||||
Bukkit.getOnlinePlayers().stream()
|
|
||||||
.map(Player::getName)
|
|
||||||
.filter(name -> name.toLowerCase(Locale.ROOT).startsWith(builder.getRemainingLowerCase()))
|
|
||||||
.forEach(builder::suggest);
|
|
||||||
return builder.buildFuture();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,8 @@ package com.alttd.playershops.commands.subcommands;
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
import com.alttd.playershops.PlayerShops;
|
||||||
import com.alttd.playershops.commands.PlayerShopCommand;
|
import com.alttd.playershops.commands.PlayerShopCommand;
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
import com.alttd.playershops.commands.PlayerShopCommands;
|
||||||
|
import com.alttd.playershops.commands.Subcommand;
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
import com.alttd.playershops.utils.ShopUtil;
|
import com.alttd.playershops.utils.ShopUtil;
|
||||||
import com.alttd.playershops.utils.Util;
|
import com.alttd.playershops.utils.Util;
|
||||||
|
|
@ -12,26 +13,78 @@ import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@DefaultQualifier(NonNull.class)
|
@DefaultQualifier(NonNull.class)
|
||||||
public class CheckStockCommand {
|
public class CheckStockCommand implements Subcommand {
|
||||||
|
|
||||||
public static void doStockCheck(final Player player, int radius, int minimumStock) {
|
@Override
|
||||||
List<Stock> stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player, minimumStock);
|
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||||
sendStockMessage(player, stockList, minimumStock);
|
return this.doStockCheck(sender, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||||
|
// TODO give some default tab completions
|
||||||
|
if (args.length == 1) {
|
||||||
|
return PlayerShopCommands.getListMatchingLast(sender, args, PlayerShopCommand.BASE_PERM + ".checkstock", "help");
|
||||||
|
} else if (args.length == 2) {
|
||||||
|
// return PlayerShopCommands.getListMatchingLast(sender, args, "radius");
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int minimumStock = -1;
|
||||||
|
|
||||||
|
public boolean doStockCheck(final CommandSender sender, final String[] args) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
sender.sendRichMessage("<red>Only players can use this command.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (args.length != 1 && args.length != 2) {
|
||||||
|
player.sendRichMessage("<red>Invalid command syntax, use /checkstock <radius> [minimum stock]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int radius;
|
||||||
|
try {
|
||||||
|
radius = Integer.parseInt(args[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
player.sendRichMessage("<red>radius has to be a valid number, use /checkstock <radius> [minimum stock]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radius > 100 || radius <= 0) {
|
||||||
|
player.sendRichMessage("<red>Please keep the radius between 1 and 100");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length == 2) {
|
||||||
|
try {
|
||||||
|
minimumStock = Integer.parseInt(args[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
player.sendRichMessage("<red>minimum stock has to be a valid number, use /checkstock <radius> [minimum stock]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Stock> stockList = checkStock(player.getLocation().getBlockX(), player.getLocation().getBlockZ(), radius, player);
|
||||||
|
sendStockMessage(player, stockList);
|
||||||
highlightLowStock(player, stockList);
|
highlightLowStock(player, stockList);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Stole this code from AlttdUtility by ___Kappa___ and reworked it slightly
|
//Stole this code from AlttdUtility by ___Kappa___ and reworked it slightly
|
||||||
private static void highlightLowStock(Player player, List<Stock> stockList) {
|
private void highlightLowStock(Player player, List<Stock> stockList) {
|
||||||
ParticleBuilder particleBuilder = new ParticleBuilder(Particle.DUST);
|
ParticleBuilder particleBuilder = new ParticleBuilder(Particle.DUST);
|
||||||
particleBuilder.color(255, 255, 255);
|
particleBuilder.color(255, 255, 255);
|
||||||
particleBuilder.receivers(player);
|
particleBuilder.receivers(player);
|
||||||
|
|
@ -86,7 +139,7 @@ public class CheckStockCommand {
|
||||||
* @param caller Player who is checking for stock, can only see the stock from their shops unless they have base_perm.checkstock.bypass
|
* @param caller Player who is checking for stock, can only see the stock from their shops unless they have base_perm.checkstock.bypass
|
||||||
* @return A list of Stock that the player is allowed to see
|
* @return A list of Stock that the player is allowed to see
|
||||||
*/
|
*/
|
||||||
private static List<Stock> checkStock(int x, int z, int radius, Player caller, int minimumStock) {
|
private List<Stock> checkStock(int x, int z, int radius, Player caller) {
|
||||||
List<PlayerShop> shops = PlayerShops.getInstance().getShopHandler().getShopsInRadius(x, z, radius);
|
List<PlayerShop> shops = PlayerShops.getInstance().getShopHandler().getShopsInRadius(x, z, radius);
|
||||||
Stream<PlayerShop> playerShopStream = shops.stream();
|
Stream<PlayerShop> playerShopStream = shops.stream();
|
||||||
if (minimumStock != -1)
|
if (minimumStock != -1)
|
||||||
|
|
@ -104,7 +157,8 @@ public class CheckStockCommand {
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sendStockMessage(Player player, List<Stock> stockList, int minimumStock) {
|
private static final String putInConfig = "<yellow><click:run_command:'/cmi tppos <x> <y> <z>'>[<aqua><item_component></aqua>] <amount> left in stock</click></yellow>";
|
||||||
|
private void sendStockMessage(Player player, List<Stock> stockList) {
|
||||||
Component component = null;
|
Component component = null;
|
||||||
for (Stock stock : stockList) {
|
for (Stock stock : stockList) {
|
||||||
TagResolver resolver = TagResolver.resolver(
|
TagResolver resolver = TagResolver.resolver(
|
||||||
|
|
@ -115,9 +169,9 @@ public class CheckStockCommand {
|
||||||
Placeholder.parsed("amount", stock.stock + "")
|
Placeholder.parsed("amount", stock.stock + "")
|
||||||
);
|
);
|
||||||
if (component == null)
|
if (component == null)
|
||||||
component = Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver);
|
component = Util.parseMiniMessage(putInConfig, resolver);
|
||||||
else
|
else
|
||||||
component = component.append(Component.newline()).append(Util.parseMiniMessage(MessageConfig.SHOP_STOCK_CHECK, resolver));
|
component = component.append(Component.newline()).append(Util.parseMiniMessage(putInConfig, resolver));
|
||||||
}
|
}
|
||||||
if (component == null)
|
if (component == null)
|
||||||
if (minimumStock == -1)
|
if (minimumStock == -1)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.alttd.playershops.commands.subcommands;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.commands.Subcommand;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
|
@DefaultQualifier(NonNull.class)
|
||||||
|
public class ReloadCommand implements Subcommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||||
|
PlayerShops.getInstance().reloadConfigs();
|
||||||
|
// Todo message when config is reloaded
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.alttd.playershops.commands.subcommands;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.commands.Subcommand;
|
||||||
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@DefaultQualifier(NonNull.class)
|
||||||
|
public class TransferShopsCommand implements Subcommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(CommandSender sender, String subCommand, String[] args) {
|
||||||
|
if (!(sender instanceof Player player)) {
|
||||||
|
sender.sendRichMessage("<red>Only players can use this command.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (args.length != 1 && args.length != 2) {
|
||||||
|
player.sendRichMessage("<red>Invalid command syntax, use /transfershops <uuid> <newplayer>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
OfflinePlayer oldOfflinePlayer = Bukkit.getOfflinePlayer(args[0]);
|
||||||
|
if (!oldOfflinePlayer.hasPlayedBefore()) {
|
||||||
|
player.sendRichMessage("<red>" + args[0] + " has not joined this server before.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Player newShopOwner = Bukkit.getPlayer(args[1]);
|
||||||
|
if (newShopOwner == null) {
|
||||||
|
player.sendRichMessage("<red>" + args[1] + " is not online and has to be online for this process.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UUID oldUUID = oldOfflinePlayer.getUniqueId();
|
||||||
|
List<PlayerShop> playerShops = PlayerShops.getInstance().getShopHandler().getShops(oldUUID);
|
||||||
|
sender.sendRichMessage("<red>Starting the transfer process now, this might lag the server.");
|
||||||
|
for (PlayerShop playerShop : playerShops) {
|
||||||
|
playerShop.setOwner(newShopOwner);
|
||||||
|
}
|
||||||
|
newShopOwner.sendRichMessage(playerShops.size() + " have been transferred to you.");
|
||||||
|
sender.sendRichMessage(playerShops.size() + " have been transferred to " + args[1] + ".");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -143,11 +143,9 @@ public class MessageConfig {
|
||||||
|
|
||||||
public static String SHOP_INFO = "<yellow>This shop <action> <gold><amount></gold> <item> for <gold><price></gold>.</yellow>";
|
public static String SHOP_INFO = "<yellow>This shop <action> <gold><amount></gold> <item> for <gold><price></gold>.</yellow>";
|
||||||
public static String SHOP_STOCK_INFO = "<yellow>This <type> shop has <gold><stock></gold> stock.</yellow>";
|
public static String SHOP_STOCK_INFO = "<yellow>This <type> shop has <gold><stock></gold> stock.</yellow>";
|
||||||
public static String SHOP_STOCK_CHECK = "<yellow><click:run_command:'/cmi tppos <x> <y> <z>'>[<aqua><item_component></aqua>] <amount> left in stock</click></yellow>";
|
|
||||||
private static void otherMessages() {
|
private static void otherMessages() {
|
||||||
SHOP_INFO = getString("messages.shop-info", SHOP_INFO);
|
SHOP_INFO = getString("messages.shop-info", SHOP_INFO);
|
||||||
SHOP_STOCK_INFO = getString("messages.shop-stock-info", SHOP_STOCK_INFO);
|
SHOP_STOCK_INFO = getString("messages.shop-stock-info", SHOP_STOCK_INFO);
|
||||||
SHOP_STOCK_CHECK = getString("messages.shop-stock-check", SHOP_STOCK_CHECK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String CHANGE_PRICE_PROMPT = "What should the price be? Type cancel to cancel this action.";
|
public static String CHANGE_PRICE_PROMPT = "What should the price be? Type cancel to cancel this action.";
|
||||||
|
|
@ -174,14 +172,12 @@ public class MessageConfig {
|
||||||
public static String GUI_HOME_TITLE = "<green>PlayerShops";
|
public static String GUI_HOME_TITLE = "<green>PlayerShops";
|
||||||
public static String GUI_LIST_PLAYERS_TITLE = "<green>Player shops";
|
public static String GUI_LIST_PLAYERS_TITLE = "<green>Player shops";
|
||||||
public static String GUI_LIST_SHOPS_TITLE = "<green>Players shops by <playername>";
|
public static String GUI_LIST_SHOPS_TITLE = "<green>Players shops by <playername>";
|
||||||
public static String GUI_LIST_SHOPS_ITEM_TITLE = "<green>Players shops by item";
|
|
||||||
public static String GUI_LIST_TRANSACTIONS_TITLE = "<green>Shop Transactions";
|
public static String GUI_LIST_TRANSACTIONS_TITLE = "<green>Shop Transactions";
|
||||||
public static String GUI_MANAGE_TITLE = "<green>Shop Manager";
|
public static String GUI_MANAGE_TITLE = "<green>Shop Manager";
|
||||||
public static String GUI_PLAYER_SETTINGS_TITLE = "<green>Shop Settings Manager";
|
public static String GUI_PLAYER_SETTINGS_TITLE = "<green>Shop Settings Manager";
|
||||||
private static void guiTitles() {
|
private static void guiTitles() {
|
||||||
GUI_HOME_TITLE = getString("gui.home-title", GUI_HOME_TITLE);
|
GUI_HOME_TITLE = getString("gui.home-title", GUI_HOME_TITLE);
|
||||||
GUI_LIST_PLAYERS_TITLE = getString("gui.list-players-title", GUI_LIST_PLAYERS_TITLE);
|
GUI_LIST_PLAYERS_TITLE = getString("gui.list-players-title", GUI_LIST_PLAYERS_TITLE);
|
||||||
GUI_LIST_SHOPS_ITEM_TITLE = getString("gui.list-items-title", GUI_LIST_SHOPS_ITEM_TITLE);
|
|
||||||
GUI_LIST_SHOPS_TITLE = getString("gui.list-shops-title", GUI_LIST_SHOPS_TITLE);
|
GUI_LIST_SHOPS_TITLE = getString("gui.list-shops-title", GUI_LIST_SHOPS_TITLE);
|
||||||
GUI_LIST_TRANSACTIONS_TITLE = getString("gui.list-transactions-title", GUI_LIST_TRANSACTIONS_TITLE);
|
GUI_LIST_TRANSACTIONS_TITLE = getString("gui.list-transactions-title", GUI_LIST_TRANSACTIONS_TITLE);
|
||||||
GUI_MANAGE_TITLE = getString("gui.manage-title", GUI_MANAGE_TITLE);
|
GUI_MANAGE_TITLE = getString("gui.manage-title", GUI_MANAGE_TITLE);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
package com.alttd.playershops.conversation;
|
||||||
|
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.gui.ShopManagementGui;
|
||||||
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
import com.alttd.playershops.shop.ShopType;
|
||||||
|
import com.alttd.playershops.utils.EconomyUtils;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.conversations.*;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ConversationManager implements ConversationAbandonedListener {
|
||||||
|
|
||||||
|
PlayerShop playerShop;
|
||||||
|
Player player;
|
||||||
|
Conversation conversation;
|
||||||
|
|
||||||
|
public ConversationManager(JavaPlugin plugin, Player player, ConversationType conversationType, PlayerShop playerShop) {
|
||||||
|
if (player.isConversing()) return;
|
||||||
|
this.player = player;
|
||||||
|
this.playerShop = playerShop;
|
||||||
|
ConversationFactory conversationFactory = new ConversationFactory(plugin)
|
||||||
|
.withModality(true)
|
||||||
|
.withFirstPrompt(getPrompt(conversationType))
|
||||||
|
.addConversationAbandonedListener(this)
|
||||||
|
.withEscapeSequence("cancel");
|
||||||
|
conversation = conversationFactory.buildConversation(player);
|
||||||
|
conversation.setLocalEchoEnabled(false); // why is this not in the builder
|
||||||
|
conversation.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Prompt getPrompt(ConversationType conversationType) {
|
||||||
|
switch (conversationType) {
|
||||||
|
case CHANGE_ITEM -> {
|
||||||
|
return new ChangeItemPrompt();
|
||||||
|
}
|
||||||
|
case CHANGE_AMOUNT -> {
|
||||||
|
return new ChangeAmountPrompt();
|
||||||
|
}
|
||||||
|
case CHANGE_TYPE -> {
|
||||||
|
return new ChangeTypePrompt();
|
||||||
|
}
|
||||||
|
case WITHDRAW_BALANCE -> {
|
||||||
|
return new WithdrawBalancePrompt();
|
||||||
|
}
|
||||||
|
case ADD_BALANCE -> {
|
||||||
|
return new AddBalancePrompt();
|
||||||
|
}
|
||||||
|
case CHANGE_PRICE -> {
|
||||||
|
return new ChangePricePrompt();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openGui() {
|
||||||
|
player.abandonConversation(conversation);
|
||||||
|
ShopManagementGui shopManagementGui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||||
|
shopManagementGui.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void conversationAbandoned(@NotNull ConversationAbandonedEvent abandonedEvent) {
|
||||||
|
// abandonedEvent.getContext().getForWhom().sendRawMessage("Conversation ended.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChangeTypePrompt extends FixedSetPrompt {
|
||||||
|
|
||||||
|
public ChangeTypePrompt() {
|
||||||
|
super("buy", "sell", "none", "random");
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||||
|
return Util.parseMiniMessage("What shoptype would you like to use: " + Joiner.on(", ").join(fixedSet) + " Type cancel to cancel this action.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Prompt acceptValidatedInput(ConversationContext context, String input) {
|
||||||
|
ShopType newType = ShopType.fromString(input);
|
||||||
|
playerShop.setShopType(newType);
|
||||||
|
openGui();
|
||||||
|
return END_OF_CONVERSATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChangePricePrompt extends NumericPrompt {
|
||||||
|
|
||||||
|
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||||
|
return Util.parseMiniMessage(MessageConfig.CHANGE_PRICE_PROMPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||||
|
return input.doubleValue() >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||||
|
return MessageConfig.CHANGE_PRICE_FAILED_PROMPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||||
|
playerShop.setPrice(number.doubleValue());
|
||||||
|
openGui();
|
||||||
|
return END_OF_CONVERSATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChangeAmountPrompt extends NumericPrompt {
|
||||||
|
|
||||||
|
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||||
|
return Util.parseMiniMessage(MessageConfig.CHANGE_AMOUNT_PROMPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||||
|
return input.intValue() > 0 && input.intValue() <= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||||
|
return MessageConfig.CHANGE_AMOUNT_FAILED_PROMPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||||
|
playerShop.setAmount(number.intValue());
|
||||||
|
openGui();
|
||||||
|
return END_OF_CONVERSATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AddBalancePrompt extends NumericPrompt {
|
||||||
|
|
||||||
|
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||||
|
return Util.parseMiniMessage(MessageConfig.ADD_BALANCE_PROMPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||||
|
if (input.doubleValue() < 0)
|
||||||
|
return false;
|
||||||
|
return EconomyUtils.hasSufficientFunds(player, input.doubleValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||||
|
return MessageConfig.ADD_BALANCE_FAILED_PROMPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||||
|
playerShop.addBalance(number.doubleValue());
|
||||||
|
EconomyUtils.removeFunds(player, number.doubleValue());
|
||||||
|
openGui();
|
||||||
|
return END_OF_CONVERSATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class WithdrawBalancePrompt extends NumericPrompt {
|
||||||
|
|
||||||
|
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||||
|
return Util.parseMiniMessage(MessageConfig.WITHDRAW_BALANCE_PROMPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isNumberValid(ConversationContext context, Number input) {
|
||||||
|
if (input.doubleValue() < 0)
|
||||||
|
return false;
|
||||||
|
return EconomyUtils.hasSufficientFunds(playerShop, input.doubleValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getFailedValidationText(ConversationContext context, Number invalidInput) {
|
||||||
|
return MessageConfig.WITHDRAW_BALANCE_FAILED_PROMPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Prompt acceptValidatedInput(ConversationContext context, Number number) {
|
||||||
|
playerShop.removeBalance(number.doubleValue());
|
||||||
|
EconomyUtils.addFunds(player, number.doubleValue());
|
||||||
|
openGui();
|
||||||
|
return END_OF_CONVERSATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChangeItemPrompt extends FixedSetPrompt {
|
||||||
|
|
||||||
|
ChangeItemPrompt() {
|
||||||
|
super("continue");
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull Component getPromptMessage(ConversationContext context) {
|
||||||
|
return Util.parseMiniMessage(MessageConfig.CHANGE_ITEM_PROMPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Prompt acceptValidatedInput(ConversationContext context, String input) {
|
||||||
|
playerShop.setItemStack(player.getInventory().getItemInMainHand().clone());
|
||||||
|
openGui();
|
||||||
|
return END_OF_CONVERSATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.alttd.playershops.conversation;
|
||||||
|
|
||||||
|
public enum ConversationType {
|
||||||
|
CHANGE_ITEM,
|
||||||
|
CHANGE_AMOUNT,
|
||||||
|
CHANGE_TYPE,
|
||||||
|
CHANGE_PRICE,
|
||||||
|
WITHDRAW_BALANCE,
|
||||||
|
ADD_BALANCE;
|
||||||
|
}
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.body.DialogBody;
|
|
||||||
import io.papermc.paper.registry.data.dialog.input.DialogInput;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public abstract class AbstractDialog {
|
|
||||||
|
|
||||||
Dialog dialog;
|
|
||||||
protected final int INV_SIZE = 54;
|
|
||||||
UUID uuid;
|
|
||||||
AbstractDialog lastDialog;
|
|
||||||
List<ActionButton> actions = new ArrayList<>();
|
|
||||||
List<DialogInput> inputs = new ArrayList<>();
|
|
||||||
List<DialogBody> texts = new ArrayList<>();
|
|
||||||
ActionButton closeButton;
|
|
||||||
|
|
||||||
AbstractDialog(UUID uuid) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.lastDialog = null;
|
|
||||||
closeButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Go back</gold>")).action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasLastGui()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract Dialog initDialog();
|
|
||||||
|
|
||||||
public void open() {
|
|
||||||
if (dialog == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Player player = getPlayer();
|
|
||||||
if (player != null) {
|
|
||||||
// player.closeDialog();
|
|
||||||
player.showDialog(dialog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void close() {
|
|
||||||
Player player = getPlayer();
|
|
||||||
if (player != null) {
|
|
||||||
player.closeInventory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initContents() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Player getPlayer() {
|
|
||||||
return Bukkit.getPlayer(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastGui(AbstractDialog lastDialog) {
|
|
||||||
this.lastDialog = lastDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasLastGui() {
|
|
||||||
return this.lastDialog != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.kyori.adventure.text.object.ObjectContents;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ListPlayersDialog extends AbstractDialog {
|
|
||||||
|
|
||||||
private final List<UUID> owners;
|
|
||||||
|
|
||||||
public ListPlayersDialog(UUID uuid) {
|
|
||||||
super(uuid);
|
|
||||||
this.owners = PlayerShops.getInstance().getShopHandler().getShopOwnersForThisServer();
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Dialog initDialog() {
|
|
||||||
if (getPlayer() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
initContents();
|
|
||||||
|
|
||||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
|
||||||
dialogRegistryBuilderFactory.empty()
|
|
||||||
.type(DialogType.multiAction(
|
|
||||||
actions,
|
|
||||||
closeButton,
|
|
||||||
3)
|
|
||||||
)
|
|
||||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_PLAYERS_TITLE))
|
|
||||||
.body(texts)
|
|
||||||
.inputs(inputs)
|
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initContents() {
|
|
||||||
super.initContents();
|
|
||||||
|
|
||||||
for (UUID shopOwnerUUID : owners) {
|
|
||||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(shopOwnerUUID);
|
|
||||||
String playerName;
|
|
||||||
if (!offlinePlayer.hasPlayedBefore()) {
|
|
||||||
playerName = "Unknown";
|
|
||||||
} else {
|
|
||||||
playerName = offlinePlayer.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
Component.object(ObjectContents.playerHead(shopOwnerUUID)).append(Component.space().append(Component.text(playerName))))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListShopsDialog listShopsDialog = new ListShopsDialog(uuid, shopOwnerUUID);
|
|
||||||
listShopsDialog.setLastGui(this);
|
|
||||||
listShopsDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
|
||||||
import com.alttd.playershops.shop.ShopType;
|
|
||||||
import com.alttd.playershops.utils.EconomyUtils;
|
|
||||||
import com.alttd.playershops.utils.ShopUtil;
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.body.DialogBody;
|
|
||||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ListShopsDialog extends AbstractDialog {
|
|
||||||
|
|
||||||
List<PlayerShop> shops;
|
|
||||||
UUID playerToList;
|
|
||||||
Component title;
|
|
||||||
TagResolver placeholders;
|
|
||||||
|
|
||||||
public ListShopsDialog(UUID uuid, UUID playerToList) {
|
|
||||||
super(uuid);
|
|
||||||
this.playerToList = playerToList;
|
|
||||||
this.shops = PlayerShops.getInstance().getShopHandler().getShops(this.playerToList);
|
|
||||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(this.playerToList);
|
|
||||||
|
|
||||||
placeholders = TagResolver.resolver(
|
|
||||||
Placeholder.unparsed("playername", offlinePlayer.hasPlayedBefore() ? offlinePlayer.getName() : "Unknown")
|
|
||||||
);
|
|
||||||
title = MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_SHOPS_TITLE, placeholders);
|
|
||||||
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ListShopsDialog(UUID uuid, List<PlayerShop> playerShops) {
|
|
||||||
super(uuid);
|
|
||||||
this.shops = playerShops;
|
|
||||||
|
|
||||||
placeholders = TagResolver.resolver(
|
|
||||||
Placeholder.unparsed("material", "Unknown")
|
|
||||||
);
|
|
||||||
title = MiniMessage.miniMessage().deserialize("Shops per item");
|
|
||||||
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Dialog initDialog() {
|
|
||||||
if (getPlayer() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
initContents();
|
|
||||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
|
||||||
dialogRegistryBuilderFactory.empty()
|
|
||||||
.type(DialogType.multiAction(
|
|
||||||
actions,
|
|
||||||
closeButton,
|
|
||||||
3)
|
|
||||||
)
|
|
||||||
.base(DialogBase.builder(title)
|
|
||||||
.body(texts)
|
|
||||||
.inputs(inputs)
|
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initContents() {
|
|
||||||
super.initContents();
|
|
||||||
|
|
||||||
texts.add(DialogBody.plainMessage(MiniMessage.miniMessage().deserialize("<gold>This menu will <red>not</red> display shops that are not initialized")));
|
|
||||||
|
|
||||||
for (PlayerShop shop : shops) {
|
|
||||||
if (!shop.isInitialized()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
ShopUtil.spriteComponent(shop.getItemStack()))
|
|
||||||
.tooltip(shop.getHoverComponent(getPlayer()))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ShopUtil.canManageShop(player, shop)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), shop);
|
|
||||||
manageShopDialog.setLastGui(this);
|
|
||||||
manageShopDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (uuid != null && uuid.equals(playerToList) && getPlayer().hasPermission("playershops.shop.collectall")) {
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
MiniMessage.miniMessage().deserialize("<gold>Collect sales</gold>"))
|
|
||||||
.tooltip(MiniMessage.miniMessage().deserialize("<gold>Click to collect all balance from your shops.</gold>"))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double d = 0;
|
|
||||||
int count = 0;
|
|
||||||
for (PlayerShop playerShop : shops) {
|
|
||||||
if (!ShopUtil.canManageShop(player, playerShop))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (playerShop.getType().equals(ShopType.BUY))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
double balance = playerShop.getBalance();
|
|
||||||
if (balance == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
playerShop.removeBalance(balance);
|
|
||||||
EconomyUtils.addFunds(player, balance);
|
|
||||||
d += balance;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
TagResolver placeholders = TagResolver.resolver(
|
|
||||||
Placeholder.parsed("balance", String.valueOf(d)),
|
|
||||||
Placeholder.parsed("count", String.valueOf(count))
|
|
||||||
);
|
|
||||||
player.sendRichMessage(count > 0 ? "<green>You have collected <balance> from <count> shops." : "<red>No shops to be collected from.", placeholders);
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
|
||||||
import com.alttd.playershops.shop.ShopType;
|
|
||||||
import com.alttd.playershops.utils.EconomyUtils;
|
|
||||||
import com.alttd.playershops.utils.ShopUtil;
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.input.DialogInput;
|
|
||||||
import io.papermc.paper.registry.data.dialog.input.SingleOptionDialogInput;
|
|
||||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ManageShopDialog extends AbstractDialog {
|
|
||||||
|
|
||||||
PlayerShop shop;
|
|
||||||
|
|
||||||
public ManageShopDialog(UUID uuid, PlayerShop shop) {
|
|
||||||
super(uuid);
|
|
||||||
this.shop = shop;
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Dialog initDialog() {
|
|
||||||
if (getPlayer() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
initContents();
|
|
||||||
|
|
||||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
|
||||||
dialogRegistryBuilderFactory.empty()
|
|
||||||
.type(DialogType.multiAction(
|
|
||||||
actions,
|
|
||||||
closeButton,
|
|
||||||
3)
|
|
||||||
)
|
|
||||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize("<gold>PlayerShop - <playername>", Placeholder.component("playername", getPlayer().displayName())))
|
|
||||||
.body(texts)
|
|
||||||
.inputs(inputs)
|
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initContents() {
|
|
||||||
super.initContents();
|
|
||||||
|
|
||||||
inputs.add(
|
|
||||||
DialogInput.singleOption("shoptype", MiniMessage.miniMessage().deserialize("<gold>ShopType</gold>"),
|
|
||||||
Arrays.stream(ShopType.values()).map(
|
|
||||||
shopType -> SingleOptionDialogInput.OptionEntry.create(shopType.name(), MiniMessage.miniMessage().deserialize("<green>" + shopType.name()), shop.getType() == shopType)
|
|
||||||
).toList())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
inputs.add(
|
|
||||||
DialogInput.text("balance", MiniMessage.miniMessage().deserialize("<gold>Balance</gold>"))
|
|
||||||
.initial(String.valueOf(shop.getBalance()))
|
|
||||||
.width(300)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
inputs.add(
|
|
||||||
DialogInput.bool("changeitem", MiniMessage.miniMessage().deserialize("<gold>Change item?</gold>"))
|
|
||||||
.initial(false)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
int maxQty = (shop.isInitialized() && shop.getItemStack() != null ? shop.getItemStack().getMaxStackSize() : 64);
|
|
||||||
int initialQty = (shop.isInitialized() ? Math.min(shop.getAmount(), maxQty) : 1);
|
|
||||||
inputs.add(
|
|
||||||
DialogInput.numberRange("amount", MiniMessage.miniMessage().deserialize("<gold>Change amount</gold>"), 1f, (float) maxQty)
|
|
||||||
.step(1f)
|
|
||||||
.initial((float) initialQty)
|
|
||||||
.width(300)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
inputs.add(
|
|
||||||
DialogInput.text("price", MiniMessage.miniMessage().deserialize("<gold>Change price</gold>"))
|
|
||||||
.initial(String.valueOf(shop.getPrice()))
|
|
||||||
.width(300)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
ActionButton saveButton = ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Confirm</gold>")).action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ShopUtil.canManageShop(player, shop)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change type
|
|
||||||
String shopTypeString = view.getText("shoptype");
|
|
||||||
ShopType shopType = ShopType.fromString(shopTypeString);
|
|
||||||
if (shop.getType() != shopType) {
|
|
||||||
shop.setShopType(shopType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change Balance
|
|
||||||
String balanceString = view.getText("balance");
|
|
||||||
if (balanceString != null && !balanceString.isBlank()) {
|
|
||||||
Double balance;
|
|
||||||
try {
|
|
||||||
balance = EconomyUtils.parseValue(balanceString);
|
|
||||||
if (balance != null && balance >= 0) {
|
|
||||||
if (balance != shop.getBalance()) {
|
|
||||||
double difference = balance - shop.getBalance();
|
|
||||||
if (difference >= 0) {
|
|
||||||
if (EconomyUtils.hasSufficientFunds(player, difference)) {
|
|
||||||
shop.addBalance(difference);
|
|
||||||
EconomyUtils.removeFunds(player, difference);
|
|
||||||
}
|
|
||||||
} else if (difference <= 0) {
|
|
||||||
double diff = -1 * difference;
|
|
||||||
if (EconomyUtils.hasSufficientFunds(shop, diff)) {
|
|
||||||
shop.removeBalance(diff);
|
|
||||||
EconomyUtils.addFunds(player, diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change Item
|
|
||||||
if (Boolean.TRUE.equals(view.getBoolean("changeitem"))) {
|
|
||||||
ItemStack itemStack = player.getInventory().getItemInMainHand().clone();
|
|
||||||
shop.setItemStack(itemStack);
|
|
||||||
// String selection = view.getText("item");
|
|
||||||
// if (selection != null) {
|
|
||||||
// if (selection.equalsIgnoreCase("reset")) {
|
|
||||||
// shop.setItemStack(null);
|
|
||||||
// } else {
|
|
||||||
// int slot;
|
|
||||||
// try {
|
|
||||||
// slot = Integer.parseInt(selection);
|
|
||||||
// shop.setItemStack(player.getInventory().getItem(slot));
|
|
||||||
// } catch (NumberFormatException ignored) {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change Amount
|
|
||||||
int amount = view.getFloat("amount").intValue();
|
|
||||||
if (amount != shop.getAmount()) {
|
|
||||||
shop.setAmount(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change Price
|
|
||||||
String priceString = view.getText("price");
|
|
||||||
if (priceString != null && !priceString.isBlank()) {
|
|
||||||
Double price = EconomyUtils.parseValue(priceString);
|
|
||||||
if (price != null && price >= 0) {
|
|
||||||
if (price != shop.getPrice()) {
|
|
||||||
shop.setPrice(price);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
).build();
|
|
||||||
actions.add(saveButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List<SingleOptionDialogInput.OptionEntry> itemEntries() {
|
|
||||||
// List<SingleOptionDialogInput.OptionEntry> optionEntries = new ArrayList<>();
|
|
||||||
//
|
|
||||||
// if (getPlayer() == null) {
|
|
||||||
// return optionEntries;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// optionEntries.add(
|
|
||||||
// SingleOptionDialogInput.OptionEntry.create("reset", MiniMessage.miniMessage().deserialize("<gold>Reset"), false)
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < getPlayer().getInventory().getSize() ; i++) {
|
|
||||||
// ItemStack item = getPlayer().getInventory().getItem(i);
|
|
||||||
// if (item == null || item.getType() == Material.AIR) continue;
|
|
||||||
// ItemStack itemStack = item.clone();
|
|
||||||
// optionEntries.add(
|
|
||||||
// SingleOptionDialogInput.OptionEntry.create(String.valueOf(i), ShopUtil.spriteComponent(itemStack), shop.getItemStack() == itemStack)
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return optionEntries;
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
|
||||||
import com.alttd.playershops.utils.ShopUtil;
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class SearchShopsDialog extends AbstractDialog {
|
|
||||||
|
|
||||||
List<PlayerShop> shops;
|
|
||||||
|
|
||||||
public SearchShopsDialog(UUID uuid) {
|
|
||||||
super(uuid);
|
|
||||||
// this.shops = PlayerShops.getInstance().getShopHandler().getShops(playerToList);
|
|
||||||
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Dialog initDialog() {
|
|
||||||
if (getPlayer() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
initContents();
|
|
||||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
|
||||||
dialogRegistryBuilderFactory.empty()
|
|
||||||
.type(DialogType.multiAction(
|
|
||||||
actions,
|
|
||||||
closeButton,
|
|
||||||
5)
|
|
||||||
)
|
|
||||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_LIST_SHOPS_ITEM_TITLE))
|
|
||||||
.body(texts)
|
|
||||||
.inputs(inputs)
|
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initContents() {
|
|
||||||
super.initContents();
|
|
||||||
|
|
||||||
for (Map.Entry<Material, List<PlayerShop>> entry : PlayerShops.getInstance().getShopHandler().shopByMaterial().entrySet()) {
|
|
||||||
actions.add(ActionButton.builder(ShopUtil.spriteComponent(entry.getKey()))
|
|
||||||
.tooltip(
|
|
||||||
MiniMessage.miniMessage().deserialize(
|
|
||||||
entry.getValue().size() + "<green> Shops"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListShopsDialog listShopsDialog = new ListShopsDialog(uuid, entry.getValue());
|
|
||||||
listShopsDialog.setLastGui(this);
|
|
||||||
listShopsDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ShopDialog extends AbstractDialog {
|
|
||||||
|
|
||||||
public ShopDialog(UUID uuid) {
|
|
||||||
super(uuid);
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Dialog initDialog() {
|
|
||||||
if (getPlayer() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
initContents();
|
|
||||||
|
|
||||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
|
||||||
dialogRegistryBuilderFactory.empty()
|
|
||||||
.type(DialogType.multiAction(
|
|
||||||
actions,
|
|
||||||
closeButton,
|
|
||||||
3)
|
|
||||||
)
|
|
||||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_HOME_TITLE))
|
|
||||||
.body(texts)
|
|
||||||
.inputs(inputs)
|
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initContents() {
|
|
||||||
super.initContents();
|
|
||||||
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
MiniMessage.miniMessage().deserialize("Your shops"))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListShopsDialog abstractDialog = new ListShopsDialog(uuid, uuid);
|
|
||||||
abstractDialog.setLastGui(this);
|
|
||||||
abstractDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
MiniMessage.miniMessage().deserialize("All shops"))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListPlayersDialog abstractDialog = new ListPlayersDialog(uuid);
|
|
||||||
abstractDialog.setLastGui(this);
|
|
||||||
abstractDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
MiniMessage.miniMessage().deserialize("Shops per item"))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchShopsDialog abstractDialog = new SearchShopsDialog(uuid);
|
|
||||||
abstractDialog.setLastGui(this);
|
|
||||||
abstractDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
/* actions.add(
|
|
||||||
ActionButton.builder(
|
|
||||||
MiniMessage.miniMessage().deserialize("Settings"))
|
|
||||||
.action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShopSettingsDialog abstractDialog = new ShopSettingsDialog(uuid);
|
|
||||||
abstractDialog.setLastGui(this);
|
|
||||||
abstractDialog.open();
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
package com.alttd.playershops.dialog;
|
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
|
||||||
import com.alttd.playershops.shop.PlayerSettings;
|
|
||||||
import io.papermc.paper.dialog.Dialog;
|
|
||||||
import io.papermc.paper.registry.data.dialog.ActionButton;
|
|
||||||
import io.papermc.paper.registry.data.dialog.DialogBase;
|
|
||||||
import io.papermc.paper.registry.data.dialog.action.DialogAction;
|
|
||||||
import io.papermc.paper.registry.data.dialog.input.DialogInput;
|
|
||||||
import io.papermc.paper.registry.data.dialog.type.DialogType;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
|
||||||
import net.kyori.adventure.text.event.ClickCallback;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ShopSettingsDialog extends AbstractDialog {
|
|
||||||
|
|
||||||
PlayerSettings playerSettings;
|
|
||||||
public ShopSettingsDialog(UUID uuid) {
|
|
||||||
super(uuid);
|
|
||||||
playerSettings = PlayerShops.getInstance().getShopHandler().getPlayerSettings(uuid);
|
|
||||||
dialog = initDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Dialog initDialog() {
|
|
||||||
if (getPlayer() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
initContents();
|
|
||||||
|
|
||||||
return Dialog.create(dialogRegistryBuilderFactory ->
|
|
||||||
dialogRegistryBuilderFactory.empty()
|
|
||||||
.type(DialogType.multiAction(
|
|
||||||
actions,
|
|
||||||
closeButton,
|
|
||||||
1)
|
|
||||||
)
|
|
||||||
.base(DialogBase.builder(MiniMessage.miniMessage().deserialize(MessageConfig.GUI_PLAYER_SETTINGS_TITLE))
|
|
||||||
.body(texts)
|
|
||||||
.inputs(inputs)
|
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initContents() {
|
|
||||||
super.initContents();
|
|
||||||
|
|
||||||
for(Object2BooleanMap.Entry<PlayerSettings.Option> entry : playerSettings.optionsMap.object2BooleanEntrySet()) {
|
|
||||||
String setting = entry.getKey().name();
|
|
||||||
System.out.println(setting);
|
|
||||||
inputs.add(
|
|
||||||
DialogInput.bool(setting, MiniMessage.miniMessage().deserialize("<gold>" + entry.getKey().toString() + "</gold>"))
|
|
||||||
.initial(playerSettings.getOption(entry.getKey()))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Confirm</gold>")).action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (Boolean.TRUE.equals(view.getBoolean("changeitem"))) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
).build()
|
|
||||||
);
|
|
||||||
actions.add(
|
|
||||||
ActionButton.builder(MiniMessage.miniMessage().deserialize("<gold>Set shop default values</gold>")).action(
|
|
||||||
DialogAction.customClick((view, audience) -> {
|
|
||||||
if (!(audience instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, ClickCallback.Options.builder()
|
|
||||||
.lifetime(Duration.ofMinutes(5))
|
|
||||||
.uses(-1)
|
|
||||||
.build())
|
|
||||||
).build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
158
src/main/java/com/alttd/playershops/gui/AbstractGui.java
Normal file
158
src/main/java/com/alttd/playershops/gui/AbstractGui.java
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class AbstractGui implements InventoryHolder {
|
||||||
|
|
||||||
|
Inventory inventory;
|
||||||
|
protected final int INV_SIZE = 54;
|
||||||
|
int currentSlot;
|
||||||
|
UUID uuid;
|
||||||
|
int pageIndex;
|
||||||
|
AbstractGui lastGui;
|
||||||
|
|
||||||
|
|
||||||
|
AbstractGui(UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.currentSlot = 0;
|
||||||
|
this.lastGui = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
Player player = getPlayer();
|
||||||
|
if (player != null) {
|
||||||
|
player.openInventory(inventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean close() {
|
||||||
|
Player player = getPlayer();
|
||||||
|
if (player != null) {
|
||||||
|
player.closeInventory();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrollPageNext() {
|
||||||
|
ItemStack nextPageIcon = inventory.getItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot());
|
||||||
|
if (nextPageIcon != null && nextPageIcon.equals(getNextPageIcon())) {
|
||||||
|
inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), getPrevPageIcon());
|
||||||
|
++pageIndex;
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrollPagePrev() {
|
||||||
|
ItemStack prevPageIcon = inventory.getItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot());
|
||||||
|
if (prevPageIcon != null && prevPageIcon.equals(getPrevPageIcon())) {
|
||||||
|
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), getNextPageIcon());
|
||||||
|
--pageIndex;
|
||||||
|
if (pageIndex == 0) {
|
||||||
|
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), null);
|
||||||
|
}
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean addItem(int slot, ItemStack icon) {
|
||||||
|
currentSlot = slot;
|
||||||
|
return addItem(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean addItem(ItemStack icon) {
|
||||||
|
if (currentSlot == inventory.getSize() - 9)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
inventory.setItem(currentSlot, icon);
|
||||||
|
currentSlot++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initInvContents() {
|
||||||
|
clearInvBody();
|
||||||
|
currentSlot = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void clearInvBody() {
|
||||||
|
for (int i = 0; i < inventory.getSize() - 9; ++i) {
|
||||||
|
// inventory.setItem(i, null);
|
||||||
|
inventory.setItem(i, getDivider());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeMenuBar() {
|
||||||
|
for (int i = inventory.getSize() - 9; i < inventory.getSize(); ++i) {
|
||||||
|
inventory.setItem(i, getDivider());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Player getPlayer() {
|
||||||
|
return Bukkit.getPlayer(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Inventory getInventory() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack getPrevPageIcon() {
|
||||||
|
return GuiIcon.MENUBAR_PREV_PAGE.getItemStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack getNextPageIcon() {
|
||||||
|
return GuiIcon.MENUBAR_NEXT_PAGE.getItemStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack getExitIcon() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack getDivider() {
|
||||||
|
return GuiIcon.DIVIDER.getItemStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClick(int slot, ItemStack item) {
|
||||||
|
// TODO a better way to do this.
|
||||||
|
// check all menu actions here
|
||||||
|
if (slot == GuiIcon.MENUBAR_BACK.getSlot() && GuiIcon.MENUBAR_BACK.getItemStack().equals(item)) {
|
||||||
|
if (hasLastGui())
|
||||||
|
lastGui.open();
|
||||||
|
} else if (slot == GuiIcon.MENUBAR_EXIT.getSlot() && GuiIcon.MENUBAR_EXIT.getItemStack().equals(item)) {
|
||||||
|
getPlayer().closeInventory();
|
||||||
|
} else if (slot == GuiIcon.MENUBAR_SEARCH.getSlot() && GuiIcon.MENUBAR_SEARCH.getItemStack().equals(item)) {
|
||||||
|
// TODO
|
||||||
|
} else if (slot == GuiIcon.MENUBAR_PREV_PAGE.getSlot() && GuiIcon.MENUBAR_PREV_PAGE.getItemStack().equals(item)) {
|
||||||
|
scrollPagePrev();
|
||||||
|
} else if (slot == GuiIcon.MENUBAR_NEXT_PAGE.getSlot() && GuiIcon.MENUBAR_NEXT_PAGE.getItemStack().equals(item)) {
|
||||||
|
scrollPageNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastGui(AbstractGui lastGui) {
|
||||||
|
this.lastGui = lastGui;
|
||||||
|
inventory.setItem(GuiIcon.MENUBAR_BACK.getSlot(), GuiIcon.MENUBAR_BACK.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLastGui() {
|
||||||
|
return lastGui != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPrevPageItem() {
|
||||||
|
inventory.setItem(GuiIcon.MENUBAR_PREV_PAGE.getSlot(), GuiIcon.MENUBAR_PREV_PAGE.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
void addNextPageItem() {
|
||||||
|
inventory.setItem(GuiIcon.MENUBAR_NEXT_PAGE.getSlot(), GuiIcon.MENUBAR_NEXT_PAGE.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
83
src/main/java/com/alttd/playershops/gui/GuiIcon.java
Normal file
83
src/main/java/com/alttd/playershops/gui/GuiIcon.java
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.config.GuiIconConfig;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemFlag;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum GuiIcon {
|
||||||
|
DIVIDER,
|
||||||
|
MENUBAR_BACK,
|
||||||
|
MENUBAR_EXIT,
|
||||||
|
MENUBAR_SEARCH,
|
||||||
|
MENUBAR_PREV_PAGE,
|
||||||
|
MENUBAR_NEXT_PAGE,
|
||||||
|
|
||||||
|
MANAGE_SHOP,
|
||||||
|
MANAGE_SHOP_BALANCE_ADD,
|
||||||
|
MANAGE_SHOP_BALANCE_REMOVE,
|
||||||
|
MANAGE_SHOP_SALES,
|
||||||
|
MANAGE_SHOP_ITEM,
|
||||||
|
MANAGE_SHOP_TYPE,
|
||||||
|
MANAGE_SHOP_AMOUNT,
|
||||||
|
MANAGE_SHOP_PRICE,
|
||||||
|
MANAGE_SHOP_COLLECT_SALES,
|
||||||
|
MANAGE_SHOP_COLLECT_SALE,
|
||||||
|
|
||||||
|
HOME_LIST_OWN_SHOPS,
|
||||||
|
HOME_LIST_PLAYERS,
|
||||||
|
HOME_SETTINGS,
|
||||||
|
LIST_SHOP,
|
||||||
|
LIST_PLAYER,
|
||||||
|
LIST_PLAYER_ADMIN,
|
||||||
|
EMPTY_SHOP,
|
||||||
|
|
||||||
|
SETTING_ON,
|
||||||
|
SETTING_OFF;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int slot;
|
||||||
|
@Getter
|
||||||
|
private final ItemStack itemStack;
|
||||||
|
|
||||||
|
GuiIcon() {
|
||||||
|
GuiIconConfig config = new GuiIconConfig(this.toString());
|
||||||
|
this.slot = config.slot;
|
||||||
|
this.itemStack = createItem(config.material, config.displayName, config.lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack createItem(String materialString, String displayName, List<String> itemlore) {
|
||||||
|
Material material = Material.getMaterial(materialString);
|
||||||
|
if (material == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ItemStack item = new ItemStack(material);
|
||||||
|
ItemMeta itemMeta = item.getItemMeta();
|
||||||
|
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
|
||||||
|
itemMeta.displayName(format(displayName));
|
||||||
|
List<Component> lore = new ArrayList<>();
|
||||||
|
for (String line : itemlore) {
|
||||||
|
lore.add(format(line));
|
||||||
|
}
|
||||||
|
itemMeta.lore(lore);
|
||||||
|
item.setItemMeta(itemMeta);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component format(String s) {
|
||||||
|
return Util.parseMiniMessage(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/main/java/com/alttd/playershops/gui/HomeGui.java
Normal file
48
src/main/java/com/alttd/playershops/gui/HomeGui.java
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class HomeGui extends AbstractGui {
|
||||||
|
|
||||||
|
public HomeGui(UUID uuid) {
|
||||||
|
super(uuid);
|
||||||
|
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_HOME_TITLE));
|
||||||
|
makeMenuBar();
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initInvContents() {
|
||||||
|
super.initInvContents();
|
||||||
|
inventory.setItem(GuiIcon.HOME_LIST_OWN_SHOPS.getSlot(), GuiIcon.HOME_LIST_OWN_SHOPS.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.HOME_LIST_PLAYERS.getSlot(), GuiIcon.HOME_LIST_PLAYERS.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.HOME_SETTINGS.getSlot(), GuiIcon.HOME_SETTINGS.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(int slot, ItemStack item) {
|
||||||
|
super.onClick(slot, item);
|
||||||
|
|
||||||
|
if (slot >= 45)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (slot == GuiIcon.HOME_LIST_OWN_SHOPS.getSlot() && GuiIcon.HOME_LIST_OWN_SHOPS.getItemStack().equals(item)) {
|
||||||
|
ListShopsGui listShopsGui = new ListShopsGui(uuid, uuid);
|
||||||
|
listShopsGui.setLastGui(this);
|
||||||
|
listShopsGui.open();
|
||||||
|
} else if (slot == GuiIcon.HOME_LIST_PLAYERS.getSlot() && GuiIcon.HOME_LIST_PLAYERS.getItemStack().equals(item)) {
|
||||||
|
ListPlayersGui listPlayersGui = new ListPlayersGui(uuid);
|
||||||
|
listPlayersGui.setLastGui(this);
|
||||||
|
listPlayersGui.open();
|
||||||
|
}/* else if (slot == GuiIcon.HOME_SETTINGS.getSlot() && GuiIcon.HOME_SETTINGS.getItemStack().equals(item)) {
|
||||||
|
PlayerSettingsGui playerSettingsGui = new PlayerSettingsGui(uuid);
|
||||||
|
playerSettingsGui.setLastGui(this);
|
||||||
|
playerSettingsGui.open();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/main/java/com/alttd/playershops/gui/ListPlayersGui.java
Normal file
63
src/main/java/com/alttd/playershops/gui/ListPlayersGui.java
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.utils.ShopUtil;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ListPlayersGui extends AbstractGui {
|
||||||
|
|
||||||
|
private final List<UUID> owners;
|
||||||
|
public ListPlayersGui(UUID uuid) {
|
||||||
|
super(uuid);
|
||||||
|
this.owners = PlayerShops.getInstance().getShopHandler().getShopOwnersForThisServer();
|
||||||
|
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_PLAYERS_TITLE));
|
||||||
|
makeMenuBar();
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initInvContents() {
|
||||||
|
super.initInvContents();
|
||||||
|
|
||||||
|
int startIndex = pageIndex * 45;
|
||||||
|
ItemStack item;
|
||||||
|
for (int i = startIndex; i < owners.size(); i++) {
|
||||||
|
item = ShopUtil.getPlayerHead(owners.get(i));
|
||||||
|
|
||||||
|
if (!addItem(item)) {
|
||||||
|
addNextPageItem();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
addPrevPageItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(int slot, ItemStack item) {
|
||||||
|
super.onClick(slot, item);
|
||||||
|
|
||||||
|
if (slot >= 45)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (item.getType() != Material.PLAYER_HEAD)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int index = pageIndex * 45 + slot;
|
||||||
|
if (index >= owners.size())
|
||||||
|
return;
|
||||||
|
UUID playerToList = owners.get(index);
|
||||||
|
|
||||||
|
ListShopsGui listShopGUI = new ListShopsGui(uuid, playerToList);
|
||||||
|
listShopGUI.setLastGui(this);
|
||||||
|
listShopGUI.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
123
src/main/java/com/alttd/playershops/gui/ListShopsGui.java
Normal file
123
src/main/java/com/alttd/playershops/gui/ListShopsGui.java
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
import com.alttd.playershops.shop.ShopType;
|
||||||
|
import com.alttd.playershops.utils.EconomyUtils;
|
||||||
|
import com.alttd.playershops.utils.ShopUtil;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ListShopsGui extends AbstractGui {
|
||||||
|
|
||||||
|
List<PlayerShop> shops;
|
||||||
|
UUID playerToList;
|
||||||
|
|
||||||
|
public ListShopsGui(UUID uuid, UUID playerToList) {
|
||||||
|
super(uuid);
|
||||||
|
this.playerToList = playerToList;
|
||||||
|
this.shops = PlayerShops.getInstance().getShopHandler().getShops(playerToList);
|
||||||
|
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerToList);
|
||||||
|
|
||||||
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
|
Placeholder.unparsed("playername", offlinePlayer.hasPlayedBefore() ? offlinePlayer.getName() : "error")
|
||||||
|
);
|
||||||
|
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_SHOPS_TITLE, placeholders));
|
||||||
|
makeMenuBar();
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void makeMenuBar() {
|
||||||
|
super.makeMenuBar();
|
||||||
|
if (!uuid.equals(playerToList) && getPlayer().hasPermission("playershops.shop.collectall"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_COLLECT_SALES.getSlot(), GuiIcon.MANAGE_SHOP_COLLECT_SALES.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initInvContents() {
|
||||||
|
super.initInvContents();
|
||||||
|
|
||||||
|
// Todo add option to sort shops?
|
||||||
|
|
||||||
|
int startIndex = pageIndex * 45;
|
||||||
|
for (int i = startIndex; i < shops.size(); i++) {
|
||||||
|
PlayerShop shop = shops.get(i);
|
||||||
|
ItemStack item = shop.getItemStack();
|
||||||
|
if (!shop.isInitialized() || item == null)
|
||||||
|
item = GuiIcon.EMPTY_SHOP.getItemStack();
|
||||||
|
|
||||||
|
if (!addItem(item)) {
|
||||||
|
addNextPageItem();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
addPrevPageItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(int slot, ItemStack item) {
|
||||||
|
super.onClick(slot, item);
|
||||||
|
|
||||||
|
if (slot == GuiIcon.MANAGE_SHOP_COLLECT_SALES.getSlot() && GuiIcon.MANAGE_SHOP_COLLECT_SALES.getItemStack().equals(item)) {
|
||||||
|
Player player = getPlayer();
|
||||||
|
double d = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (PlayerShop playerShop : shops) {
|
||||||
|
if (!ShopUtil.canManageShop(player, playerShop))
|
||||||
|
continue;
|
||||||
|
if (playerShop.getType().equals(ShopType.BUY))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double balance = playerShop.getBalance();
|
||||||
|
if (balance == 0)
|
||||||
|
continue;
|
||||||
|
playerShop.removeBalance(balance);
|
||||||
|
EconomyUtils.addFunds(player, balance);
|
||||||
|
d += balance;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
|
Placeholder.parsed("balance", String.valueOf(d)),
|
||||||
|
Placeholder.parsed("count", String.valueOf(count))
|
||||||
|
);
|
||||||
|
player.sendRichMessage(count > 0 ? "<green>You have collected <balance> from <count> shops." : "<red>No shops to be collected from.", placeholders);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot >= 45)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player player = getPlayer();
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int index = pageIndex * 45 + slot;
|
||||||
|
if (index >= shops.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayerShop playerShop = shops.get(index);
|
||||||
|
if (playerShop == null) return;
|
||||||
|
|
||||||
|
if (!ShopUtil.canManageShop(player, playerShop))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ShopManagementGui shopManagementGui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||||
|
shopManagementGui.setLastGui(this);
|
||||||
|
shopManagementGui.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
import com.alttd.playershops.shop.ShopTransaction;
|
||||||
|
import com.alttd.playershops.utils.ShopUtil;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ListTransactionsGui extends AbstractGui {
|
||||||
|
|
||||||
|
private final List<ShopTransaction> transactions;
|
||||||
|
public ListTransactionsGui(UUID uuid, PlayerShop shop) {
|
||||||
|
super(uuid);
|
||||||
|
this.transactions = shop.getTransactions();
|
||||||
|
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_LIST_TRANSACTIONS_TITLE));
|
||||||
|
makeMenuBar();
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initInvContents() {
|
||||||
|
super.initInvContents();
|
||||||
|
|
||||||
|
int startIndex = pageIndex * 45;
|
||||||
|
ItemStack item;
|
||||||
|
for (int i = startIndex; i < transactions.size(); i++) {
|
||||||
|
item = ShopUtil.getShopTransactionItem(transactions.get(i));
|
||||||
|
|
||||||
|
if (!addItem(item)) {
|
||||||
|
addNextPageItem();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
addPrevPageItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.shop.PlayerSettings;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||||
|
import net.kyori.adventure.text.TextReplacementConfig;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerSettingsGui extends AbstractGui {
|
||||||
|
|
||||||
|
public PlayerSettingsGui(UUID uuid) {
|
||||||
|
super(uuid);
|
||||||
|
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_PLAYER_SETTINGS_TITLE));
|
||||||
|
makeMenuBar();
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initInvContents() {
|
||||||
|
super.initInvContents();
|
||||||
|
int startIndex = pageIndex * 45;
|
||||||
|
ItemStack item;
|
||||||
|
|
||||||
|
for(Object2BooleanMap.Entry<PlayerSettings.Option> entry : PlayerShops.getInstance().getShopHandler().getPlayerSettings(uuid).optionsMap.object2BooleanEntrySet()) {
|
||||||
|
item = entry.getBooleanValue() ? GuiIcon.SETTING_ON.getItemStack() : GuiIcon.SETTING_OFF.getItemStack();
|
||||||
|
ItemMeta itemMeta = item.getItemMeta();
|
||||||
|
if (itemMeta.hasDisplayName()) {
|
||||||
|
itemMeta.displayName(
|
||||||
|
itemMeta.displayName().replaceText(
|
||||||
|
TextReplacementConfig.builder()
|
||||||
|
.match("<setting>")
|
||||||
|
.replacement(entry.getKey().toString().toLowerCase().replace("_", " ")).build()));
|
||||||
|
}
|
||||||
|
item.setItemMeta(itemMeta);
|
||||||
|
|
||||||
|
if (!addItem(item)) {
|
||||||
|
addNextPageItem();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
addPrevPageItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(int slot, ItemStack item) {
|
||||||
|
super.onClick(slot, item);
|
||||||
|
|
||||||
|
if (slot >= 45)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
142
src/main/java/com/alttd/playershops/gui/ShopManagementGui.java
Normal file
142
src/main/java/com/alttd/playershops/gui/ShopManagementGui.java
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
package com.alttd.playershops.gui;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
|
import com.alttd.playershops.conversation.ConversationManager;
|
||||||
|
import com.alttd.playershops.conversation.ConversationType;
|
||||||
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
import com.alttd.playershops.shop.ShopType;
|
||||||
|
import com.alttd.playershops.utils.EconomyUtils;
|
||||||
|
import com.alttd.playershops.utils.ShopUtil;
|
||||||
|
import com.alttd.playershops.utils.Util;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ShopManagementGui extends AbstractGui {
|
||||||
|
|
||||||
|
PlayerShop shop;
|
||||||
|
|
||||||
|
public ShopManagementGui(UUID uuid, PlayerShop shop) {
|
||||||
|
super(uuid);
|
||||||
|
this.inventory = Bukkit.createInventory(this, INV_SIZE, Util.parseMiniMessage(MessageConfig.GUI_MANAGE_TITLE));
|
||||||
|
this.shop = shop;
|
||||||
|
makeMenuBar();
|
||||||
|
initInvContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initInvContents() {
|
||||||
|
super.initInvContents();
|
||||||
|
|
||||||
|
ItemStack shopIcon = GuiIcon.MANAGE_SHOP.getItemStack();
|
||||||
|
ItemMeta meta = shopIcon.getItemMeta();
|
||||||
|
List<Component> lore = new ArrayList<>();
|
||||||
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
|
Placeholder.unparsed("balance", shop.getBalance() + ""),
|
||||||
|
Placeholder.unparsed("price", shop.getPrice() + ""),
|
||||||
|
Placeholder.unparsed("amount", shop.getAmount() + ""),
|
||||||
|
Placeholder.unparsed("shoptype", shop.getType().toString()),
|
||||||
|
Placeholder.component("itemname", ShopUtil.itemNameComponent(shop.getItemStack()))
|
||||||
|
);
|
||||||
|
lore.add(Util.parseMiniMessage("Balance: <balance>", placeholders));
|
||||||
|
lore.add(Util.parseMiniMessage("item: <itemname>", placeholders));
|
||||||
|
lore.add(Util.parseMiniMessage("amount: <amount>", placeholders));
|
||||||
|
lore.add(Util.parseMiniMessage("Type: <shoptype>", placeholders));
|
||||||
|
lore.add(Util.parseMiniMessage("Price: <price>", placeholders));
|
||||||
|
|
||||||
|
meta.lore(lore);
|
||||||
|
shopIcon.setItemMeta(meta);
|
||||||
|
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP.getSlot(), shopIcon);
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot(), GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_COLLECT_SALE.getSlot(), GuiIcon.MANAGE_SHOP_COLLECT_SALE.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_SALES.getSlot(), GuiIcon.MANAGE_SHOP_SALES.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_ITEM.getSlot(), GuiIcon.MANAGE_SHOP_ITEM.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_TYPE.getSlot(), GuiIcon.MANAGE_SHOP_TYPE.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_AMOUNT.getSlot(), GuiIcon.MANAGE_SHOP_AMOUNT.getItemStack());
|
||||||
|
inventory.setItem(GuiIcon.MANAGE_SHOP_PRICE.getSlot(), GuiIcon.MANAGE_SHOP_PRICE.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void makeMenuBar() {
|
||||||
|
super.makeMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(int slot, ItemStack item) {
|
||||||
|
super.onClick(slot, item);
|
||||||
|
|
||||||
|
if (slot == GuiIcon.MANAGE_SHOP_COLLECT_SALE.getSlot() && GuiIcon.MANAGE_SHOP_COLLECT_SALE.getItemStack().equals(item)) {
|
||||||
|
Player player = getPlayer();
|
||||||
|
double d = 0;
|
||||||
|
int count = 0;
|
||||||
|
if (!ShopUtil.canManageShop(player, this.shop))
|
||||||
|
return;
|
||||||
|
if (this.shop.getType().equals(ShopType.BUY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
double balance = this.shop.getBalance();
|
||||||
|
if (balance == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.shop.removeBalance(balance);
|
||||||
|
EconomyUtils.addFunds(player, balance);
|
||||||
|
d += balance;
|
||||||
|
count++;
|
||||||
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
|
Placeholder.parsed("balance", String.valueOf(d)),
|
||||||
|
Placeholder.parsed("count", String.valueOf(count))
|
||||||
|
);
|
||||||
|
player.sendRichMessage("<green>You have collected <balance> from <count> shops.", placeholders);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot >= 45)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (slot == GuiIcon.MANAGE_SHOP.getSlot() && GuiIcon.MANAGE_SHOP.getItemStack().equals(item)) {
|
||||||
|
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_BALANCE_ADD.getSlot() && GuiIcon.MANAGE_SHOP_BALANCE_ADD.getItemStack().equals(item)) {
|
||||||
|
if (EconomyUtils.getFunds(getPlayer()) > 0) {
|
||||||
|
openChangePrompt(ConversationType.ADD_BALANCE);
|
||||||
|
} else {
|
||||||
|
getPlayer().sendRichMessage("<red>You do not have money to add to this shop");
|
||||||
|
}
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getSlot() && GuiIcon.MANAGE_SHOP_BALANCE_REMOVE.getItemStack().equals(item)) {
|
||||||
|
if (shop.getBalance() > 0) {
|
||||||
|
openChangePrompt(ConversationType.WITHDRAW_BALANCE);
|
||||||
|
} else {
|
||||||
|
getPlayer().sendRichMessage("<red>You can't withdraw money from this shop");
|
||||||
|
}
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_SALES.getSlot() && GuiIcon.MANAGE_SHOP_SALES.getItemStack().equals(item)) {
|
||||||
|
ListTransactionsGui listTransactionsGui = new ListTransactionsGui(uuid, shop);
|
||||||
|
listTransactionsGui.setLastGui(this);
|
||||||
|
listTransactionsGui.open();
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_ITEM.getSlot() && GuiIcon.MANAGE_SHOP_ITEM.getItemStack().equals(item)) {
|
||||||
|
openChangePrompt(ConversationType.CHANGE_ITEM);
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_TYPE.getSlot() && GuiIcon.MANAGE_SHOP_TYPE.getItemStack().equals(item)) {
|
||||||
|
openChangePrompt(ConversationType.CHANGE_TYPE);
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_AMOUNT.getSlot() && GuiIcon.MANAGE_SHOP_AMOUNT.getItemStack().equals(item)) {
|
||||||
|
openChangePrompt(ConversationType.CHANGE_AMOUNT);
|
||||||
|
} else if (slot == GuiIcon.MANAGE_SHOP_PRICE.getSlot() && GuiIcon.MANAGE_SHOP_PRICE.getItemStack().equals(item)) {
|
||||||
|
openChangePrompt(ConversationType.CHANGE_PRICE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openChangePrompt(ConversationType conversationType) {
|
||||||
|
Player player = getPlayer();
|
||||||
|
player.closeInventory();
|
||||||
|
new ConversationManager(PlayerShops.getInstance(), player, conversationType, shop);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,18 +6,14 @@ import com.alttd.playershops.shop.PlayerSettings;
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
import com.alttd.playershops.storage.database.DatabaseHelper;
|
import com.alttd.playershops.storage.database.DatabaseHelper;
|
||||||
import com.alttd.playershops.utils.Logger;
|
import com.alttd.playershops.utils.Logger;
|
||||||
import com.alttd.playershops.utils.Pair;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.DoubleChest;
|
import org.bukkit.block.DoubleChest;
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
|
||||||
|
|
@ -182,47 +178,4 @@ public class ShopHandler {
|
||||||
return playerSettings.computeIfAbsent(uuid, PlayerSettings::loadFromFile);
|
return playerSettings.computeIfAbsent(uuid, PlayerSettings::loadFromFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void transferShops(CommandSender sender, OfflinePlayer oldOwner, OfflinePlayer newOwner) {
|
|
||||||
if (!oldOwner.hasPlayedBefore()) {
|
|
||||||
sender.sendRichMessage("<red>" + oldOwner.getName() + " has not joined this server before.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!newOwner.hasPlayedBefore()) {
|
|
||||||
sender.sendRichMessage("<red>" + newOwner.getName() + " has not joined this server before.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PlayerShop> playerShops = PlayerShops.getInstance().getShopHandler().getShops(oldOwner.getUniqueId());
|
|
||||||
sender.sendRichMessage("<red>Starting the transfer process now, this might lag the server.");
|
|
||||||
for (PlayerShop playerShop : playerShops) {
|
|
||||||
playerShop.setOwner(newOwner);
|
|
||||||
}
|
|
||||||
if (newOwner.isOnline() && newOwner.getPlayer() != null) {
|
|
||||||
newOwner.getPlayer().sendRichMessage(playerShops.size() + " have been transferred to you.");
|
|
||||||
}
|
|
||||||
sender.sendRichMessage(playerShops.size() + " from " + oldOwner.getName() + " have been transferred to " + newOwner.getName() + ".");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On demand calculation of shops per material
|
|
||||||
*
|
|
||||||
* @return TreeMap containing a list of PlayerShops per material.
|
|
||||||
*/
|
|
||||||
public TreeMap<Material, List<PlayerShop>> shopByMaterial() {
|
|
||||||
// TODO -- make this a cache. update cache on change, do not calc dynamically
|
|
||||||
TreeMap<Material, List<PlayerShop>> shopByMaterialTreeSet = new TreeMap<>();
|
|
||||||
|
|
||||||
for (PlayerShop shop : getShops()) {
|
|
||||||
if (!shop.isInitialized()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Material material = shop.getShopItemType();
|
|
||||||
List<PlayerShop> shopList = shopByMaterialTreeSet.computeIfAbsent(material, v -> new ArrayList<>());
|
|
||||||
shopList.add(shop);
|
|
||||||
}
|
|
||||||
|
|
||||||
return shopByMaterialTreeSet;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.alttd.playershops.listener;
|
||||||
|
|
||||||
|
import com.alttd.playershops.PlayerShops;
|
||||||
|
import com.alttd.playershops.gui.AbstractGui;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class InventoryListener extends EventListener {
|
||||||
|
|
||||||
|
private final PlayerShops plugin;
|
||||||
|
public InventoryListener(PlayerShops plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.register(this.plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClickEvent(InventoryClickEvent event) {
|
||||||
|
if (!(event.getWhoClicked() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(event.getView().getTopInventory().getHolder() instanceof AbstractGui gui))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((event.getView().getBottomInventory().equals(event.getClickedInventory())))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event.getClick() == ClickType.NUMBER_KEY) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack clicked = event.getCurrentItem();
|
||||||
|
if (!(clicked != null && clicked.getType() != Material.AIR))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
gui.onClick(event.getRawSlot(), clicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ package com.alttd.playershops.listener;
|
||||||
|
|
||||||
import com.alttd.playershops.PlayerShops;
|
import com.alttd.playershops.PlayerShops;
|
||||||
import com.alttd.playershops.config.MessageConfig;
|
import com.alttd.playershops.config.MessageConfig;
|
||||||
import com.alttd.playershops.dialog.ManageShopDialog;
|
import com.alttd.playershops.gui.ShopManagementGui;
|
||||||
import com.alttd.playershops.handler.ShopHandler;
|
import com.alttd.playershops.handler.ShopHandler;
|
||||||
import com.alttd.playershops.hook.WorldGuardHook;
|
import com.alttd.playershops.hook.WorldGuardHook;
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
|
|
@ -92,10 +92,8 @@ public class TransactionListener extends EventListener {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
ShopManagementGui gui = new ShopManagementGui(player.getUniqueId(), playerShop);
|
||||||
// gui.open();
|
gui.open();
|
||||||
ManageShopDialog manageShopDialog = new ManageShopDialog(player.getUniqueId(), playerShop);
|
|
||||||
manageShopDialog.open();
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,7 @@ import java.util.UUID;
|
||||||
public class PlayerSettings {
|
public class PlayerSettings {
|
||||||
public enum Option {
|
public enum Option {
|
||||||
SALE_OWNER_NOTIFICATIONS, SALE_USER_NOTIFICATIONS,
|
SALE_OWNER_NOTIFICATIONS, SALE_USER_NOTIFICATIONS,
|
||||||
STOCK_NOTIFICATIONS, DISCORD_STOCK_NOTIFICATIONS;
|
STOCK_NOTIFICATIONS, DISCORD_STOCK_NOTIFICATIONS
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.name().toLowerCase().replace("_", " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
|
|
|
||||||
|
|
@ -3,25 +3,18 @@ package com.alttd.playershops.shop;
|
||||||
import com.alttd.playershops.PlayerShops;
|
import com.alttd.playershops.PlayerShops;
|
||||||
import com.alttd.playershops.events.*;
|
import com.alttd.playershops.events.*;
|
||||||
import com.alttd.playershops.utils.*;
|
import com.alttd.playershops.utils.*;
|
||||||
import com.alttd.playershops.utils.sprite.MaterialSprites;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.block.Sign;
|
import org.bukkit.block.Sign;
|
||||||
import org.bukkit.block.sign.Side;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -37,8 +30,8 @@ public class PlayerShop {
|
||||||
private final Location signLocation;
|
private final Location signLocation;
|
||||||
private final Location shopLocation;
|
private final Location shopLocation;
|
||||||
private String server;
|
private String server;
|
||||||
private double price = 0;
|
private double price;
|
||||||
private int amount = 1;
|
private int amount;
|
||||||
private double balance;
|
private double balance;
|
||||||
private ItemStack itemStack;
|
private ItemStack itemStack;
|
||||||
@Setter
|
@Setter
|
||||||
|
|
@ -116,7 +109,7 @@ public class PlayerShop {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches(ItemStack item) {
|
public boolean matches(ItemStack item) {
|
||||||
return ItemMatcher.matches(getItemStack(), item);
|
return ShopUtil.matches(getItemStack(), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(ItemStack item, int amount) {
|
public void remove(ItemStack item, int amount) {
|
||||||
|
|
@ -141,17 +134,16 @@ public class PlayerShop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOwner(OfflinePlayer player) {
|
public void setOwner(Player player) {
|
||||||
ownerUUID = player.getUniqueId();
|
ownerUUID = player.getUniqueId();
|
||||||
ownerName = player.getName();
|
ownerName = player.getName();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Inventory getInventory() {
|
public Inventory getInventory() {
|
||||||
if (shopLocation.getBlock().getState() instanceof InventoryHolder inventoryHolder) {
|
// Could use a check if the block is still an InventoryHolder.
|
||||||
return inventoryHolder.getInventory();
|
InventoryHolder container = (InventoryHolder) shopLocation.getBlock().getState();
|
||||||
}
|
return container.getInventory();
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
public boolean isInitialized() {
|
||||||
|
|
@ -179,15 +171,14 @@ public class PlayerShop {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return;
|
if (!(signLocation.getBlock().getState() instanceof Sign signBlock)) return;
|
||||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
Component itemComponent = getItemStack() == null ? ShopUtil.trimmedItemNameComponent(getItemStack()): MaterialSprites.get(getItemStack().getType()).append(Component.space()).append(ShopUtil.trimmedItemNameComponent(getItemStack()));
|
|
||||||
TagResolver tagResolver = TagResolver.resolver(
|
TagResolver tagResolver = TagResolver.resolver(
|
||||||
Placeholder.unparsed("ownername", getOwnerName()),
|
Placeholder.unparsed("ownername", getOwnerName()),
|
||||||
Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))),
|
Placeholder.unparsed("price", trimPrice(String.valueOf(ShopUtil.round(getPrice())))),
|
||||||
Placeholder.unparsed("amount", String.valueOf(getAmount())),
|
Placeholder.unparsed("amount", String.valueOf(getAmount())),
|
||||||
Placeholder.component("itemname", itemComponent)
|
Placeholder.component("itemname", ShopUtil.trimmedItemNameComponent(getItemStack()))
|
||||||
);
|
);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
signBlock.getSide(Side.FRONT).line(i, miniMessage.deserialize(signLines.get(i), tagResolver));
|
signBlock.line(i, miniMessage.deserialize(signLines.get(i), tagResolver));
|
||||||
}
|
}
|
||||||
signBlock.update(true);
|
signBlock.update(true);
|
||||||
}
|
}
|
||||||
|
|
@ -369,12 +360,8 @@ public class PlayerShop {
|
||||||
if (Util.callCancellableEvent(shopItemChangeEvent))
|
if (Util.callCancellableEvent(shopItemChangeEvent))
|
||||||
return; // cancelled by another plugin, does this need logging?
|
return; // cancelled by another plugin, does this need logging?
|
||||||
|
|
||||||
if (itemStack == null) {
|
this.itemStack = itemStack;
|
||||||
this.itemStack = null;
|
this.itemStack.setAmount(this.amount != 0 ? this.amount : 1);
|
||||||
} else {
|
|
||||||
this.itemStack = itemStack.clone();
|
|
||||||
this.itemStack.setAmount(this.amount != 0 ? this.amount : 1);
|
|
||||||
}
|
|
||||||
setDirty(true);
|
setDirty(true);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
@ -433,15 +420,12 @@ public class PlayerShop {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getItemStack() {
|
public ItemStack getItemStack() {
|
||||||
if (!isInitialized()) {
|
if (!isInitialized())
|
||||||
return null;
|
return null;
|
||||||
}
|
if (this.getType() != ShopType.RANDOM)
|
||||||
if (this.getType() != ShopType.RANDOM) {
|
|
||||||
return itemStack;
|
return itemStack;
|
||||||
}
|
if (this.getInventory().isEmpty())
|
||||||
if (this.getInventory() == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
ArrayList<ItemStack> contents = new ArrayList<>();
|
ArrayList<ItemStack> contents = new ArrayList<>();
|
||||||
for (ItemStack it : this.getInventory().getContents()) {
|
for (ItemStack it : this.getInventory().getContents()) {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
|
|
@ -467,34 +451,4 @@ public class PlayerShop {
|
||||||
+ " balance :" + this.balance
|
+ " balance :" + this.balance
|
||||||
+ " lastTransaction :" + this.lastTransaction;
|
+ " lastTransaction :" + this.lastTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getHoverComponent(Player player) {
|
|
||||||
Component component = ShopUtil.itemNameComponent(getItemStack())
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.text("ShopOwner: " + getOwnerName()))
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.text("ShopType: " + type))
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.text("Price: " + price))
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.text("Amount: " + amount))
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.text("World: " + shopLocation.getWorld().getName()))
|
|
||||||
.append(Component.newline())
|
|
||||||
.append(Component.text("Coordinates: " + shopLocation.getBlockX() + ", " + shopLocation.getBlockY() + ", " + shopLocation.getBlockZ()))
|
|
||||||
;
|
|
||||||
if (getOwnerUUID().equals(player.getUniqueId())) {
|
|
||||||
component = component.append(Component.newline()).append(Component.text("Balance: " + balance));
|
|
||||||
}
|
|
||||||
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Material getShopItemType() {
|
|
||||||
if (this.type == ShopType.RANDOM) {
|
|
||||||
return Material.STRUCTURE_VOID; // TODO -- Load from config
|
|
||||||
}
|
|
||||||
return itemStack.getType();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,37 +65,4 @@ public class EconomyUtils {
|
||||||
return bd.doubleValue();
|
return bd.doubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double parseValue(String input) {
|
|
||||||
Double value = null;
|
|
||||||
if (input == null || input.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
value = Double.parseDouble(input);
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
Double multiplier = multiplierValue(input.substring(input.length() - 1));
|
|
||||||
if (multiplier == null) {
|
|
||||||
multiplier = 1.0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
value = Double.parseDouble(input.substring(0, input.length() - 1));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
if (value != null) {
|
|
||||||
value = value * multiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Double multiplierValue(String input) {
|
|
||||||
Double value = null;
|
|
||||||
switch(input.toLowerCase()) {
|
|
||||||
case "k" -> value = 1000.0;
|
|
||||||
case "m" -> value = 1000000.0;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ public class InventoryUtils {
|
||||||
for (ItemStack iStack : inv.getContents()) {
|
for (ItemStack iStack : inv.getContents()) {
|
||||||
if (iStack == null)
|
if (iStack == null)
|
||||||
continue;
|
continue;
|
||||||
if (ItemMatcher.matches(item, iStack)) {
|
if (ShopUtil.matches(item, iStack)) {
|
||||||
items += iStack.getAmount();
|
items += iStack.getAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ public class InventoryUtils {
|
||||||
int amount = itemStack.getAmount();
|
int amount = itemStack.getAmount();
|
||||||
for (ItemStack stack : contents) {
|
for (ItemStack stack : contents) {
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
if (ItemMatcher.matches(stack, itemStack)) {
|
if (ShopUtil.matches(stack, itemStack)) {
|
||||||
if (stack.getAmount() > amount) {
|
if (stack.getAmount() > amount) {
|
||||||
stack.setAmount(stack.getAmount() - amount);
|
stack.setAmount(stack.getAmount() - amount);
|
||||||
inventory.setContents(contents);
|
inventory.setContents(contents);
|
||||||
|
|
|
||||||
|
|
@ -1,340 +0,0 @@
|
||||||
package com.alttd.playershops.utils;
|
|
||||||
|
|
||||||
import org.bukkit.attribute.Attribute;
|
|
||||||
import org.bukkit.block.BlockState;
|
|
||||||
import org.bukkit.block.ShulkerBox;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.*;
|
|
||||||
import org.bukkit.map.MapView;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class ItemMatcher {
|
|
||||||
|
|
||||||
private final static List<Matcher> matcherList = new ArrayList<>();
|
|
||||||
|
|
||||||
static {
|
|
||||||
// DisplayName
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) ->
|
|
||||||
Objects.equals(meta1.displayName(), meta2.displayName())
|
|
||||||
);
|
|
||||||
// Damage
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof Damageable damageable1 && meta2 instanceof Damageable damageable2) {
|
|
||||||
return damageable1.getDamage() == damageable2.getDamage();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Enchants
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1.hasEnchants() != meta2.hasEnchants()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta1.hasEnchants()) {
|
|
||||||
final Map<Enchantment, Integer> enchants1 = meta1.getEnchants();
|
|
||||||
final Map<Enchantment, Integer> enchants2 = meta2.getEnchants();
|
|
||||||
return listMatches(enchants1.entrySet(), enchants2.entrySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Potions
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof PotionMeta potion1 && meta2 instanceof PotionMeta potion2) {
|
|
||||||
if (potion1.hasColor() != potion2.hasColor()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (potion1.hasColor() && !Objects.equals(potion1.getColor(), potion2.getColor())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (potion1.hasCustomEffects() != potion2.hasCustomEffects()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (potion1.hasCustomEffects() && !Arrays.deepEquals(potion1.getCustomEffects().toArray(), potion2.getCustomEffects().toArray())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (potion1.getBasePotionType() != null && potion2.getBasePotionType() != null) {
|
|
||||||
List<PotionEffect> effects1 = new ArrayList<>();
|
|
||||||
List<PotionEffect> effects2 = new ArrayList<>();
|
|
||||||
|
|
||||||
if (potion1.getBasePotionType() != null) {
|
|
||||||
effects1.addAll(potion1.getBasePotionType().getPotionEffects());
|
|
||||||
}
|
|
||||||
if (potion1.hasCustomEffects()) {
|
|
||||||
effects1.addAll(potion1.getCustomEffects());
|
|
||||||
}
|
|
||||||
if (potion2.getBasePotionType() != null) {
|
|
||||||
effects2.addAll(potion2.getBasePotionType().getPotionEffects());
|
|
||||||
}
|
|
||||||
if (potion2.hasCustomEffects()) {
|
|
||||||
effects2.addAll(potion2.getCustomEffects());
|
|
||||||
}
|
|
||||||
return listMatches(effects1, effects2);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Attributes
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1.hasAttributeModifiers() != meta2.hasAttributeModifiers()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (meta1.hasAttributeModifiers() && meta2.hasAttributeModifiers()) {
|
|
||||||
final Set<Attribute> set1 = Objects.requireNonNull(meta1.getAttributeModifiers()).keySet();
|
|
||||||
final Set<Attribute> set2 = Objects.requireNonNull(meta2.getAttributeModifiers()).keySet();
|
|
||||||
for(final Attribute att : set1) {
|
|
||||||
if(!set2.contains(att)) {
|
|
||||||
return false;
|
|
||||||
} else if(!meta1.getAttributeModifiers().get(att).equals(meta2.getAttributeModifiers().get(att))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Itemflags
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
return Arrays.deepEquals(meta1.getItemFlags().toArray(), meta2.getItemFlags().toArray());
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Books
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof BookMeta bookMeta1 && meta2 instanceof BookMeta bookMeta2) {
|
|
||||||
if (bookMeta1.hasTitle() != bookMeta2.hasTitle()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bookMeta1.hasTitle() && !Objects.equals(bookMeta1.getTitle(), bookMeta2.getTitle())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bookMeta1.hasPages() != bookMeta2.hasPages()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bookMeta1.hasPages() && !bookMeta1.getPages().equals(bookMeta2.getPages())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bookMeta1.hasAuthor() != bookMeta2.hasAuthor()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bookMeta1.hasAuthor() && !Objects.equals(bookMeta1.getAuthor(), bookMeta2.getAuthor())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bookMeta1.hasGeneration() != bookMeta2.hasGeneration()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return !bookMeta1.hasGeneration() || Objects.equals(bookMeta1.getGeneration(), bookMeta2.getGeneration());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Fireworks
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof FireworkMeta fireworkMeta1 && meta2 instanceof FireworkMeta fireworkMeta2) {
|
|
||||||
if (fireworkMeta1.hasEffects() != fireworkMeta2.hasEffects()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!fireworkMeta1.getEffects().equals(fireworkMeta2.getEffects())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return fireworkMeta1.getPower() == fireworkMeta2.getPower();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Banners
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof BannerMeta bannerMeta1 && meta2 instanceof BannerMeta bannerMeta2) {
|
|
||||||
if (bannerMeta1.numberOfPatterns() != bannerMeta2.numberOfPatterns()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return new HashSet<>(bannerMeta1.getPatterns()).containsAll(bannerMeta2.getPatterns());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Skulls/heads
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof SkullMeta skullMeta1 && meta2 instanceof SkullMeta skullMeta2) {
|
|
||||||
return Objects.equals(skullMeta1.getOwningPlayer(), skullMeta2.getOwningPlayer());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Bundles
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof BundleMeta bundleMeta1 && meta2 instanceof BundleMeta bundleMeta2) {
|
|
||||||
if (bundleMeta1.hasItems() != bundleMeta2.hasItems()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bundleMeta1.hasItems()) {
|
|
||||||
return listMatches(bundleMeta1.getItems(), bundleMeta2.getItems());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Maps
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof MapMeta mapMeta1 && meta2 instanceof MapMeta mapMeta2) {
|
|
||||||
if (mapMeta1.hasMapView() != mapMeta2.hasMapView()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// TODO -- do we need checks on color?
|
|
||||||
// mapMeta1.getColor()
|
|
||||||
MapView mapView1 = mapMeta1.getMapView();
|
|
||||||
MapView mapView2 = mapMeta2.getMapView();
|
|
||||||
if (mapView1 == null || mapView2 == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return mapView1.getId() == mapView2.getId();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Leather
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof LeatherArmorMeta leatherArmorMeta1 && meta2 instanceof LeatherArmorMeta leatherArmorMeta2) {
|
|
||||||
return leatherArmorMeta1.getColor().equals(leatherArmorMeta2.getColor());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Tropical fishes
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof TropicalFishBucketMeta tropicalFishBucketMeta1 && meta2 instanceof TropicalFishBucketMeta tropicalFishBucketMeta2) {
|
|
||||||
if (tropicalFishBucketMeta1.hasVariant() && tropicalFishBucketMeta2.hasVariant()) {
|
|
||||||
if (tropicalFishBucketMeta1.getPattern() != tropicalFishBucketMeta2.getPattern()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (tropicalFishBucketMeta1.getBodyColor() != tropicalFishBucketMeta2.getBodyColor()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return tropicalFishBucketMeta1.getPatternColor() == tropicalFishBucketMeta2.getPatternColor();
|
|
||||||
}
|
|
||||||
// return !tropicalFishBucketMeta1.hasVariant()
|
|
||||||
// || (tropicalFishBucketMeta1.getPattern() == tropicalFishBucketMeta2.getPattern()
|
|
||||||
// && tropicalFishBucketMeta1.getBodyColor().equals(tropicalFishBucketMeta2.getBodyColor())
|
|
||||||
// && tropicalFishBucketMeta1.getPatternColor().equals(tropicalFishBucketMeta2.getPatternColor()));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Axolotls
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof AxolotlBucketMeta axolotlBucketMeta1 && meta2 instanceof AxolotlBucketMeta axolotlBucketMeta2) {
|
|
||||||
return axolotlBucketMeta1.getVariant() == axolotlBucketMeta2.getVariant();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Shulkerboxes
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof BlockStateMeta blockStateMeta1 && meta2 instanceof BlockStateMeta blockStateMeta2) {
|
|
||||||
// extra heavy - Banners, Shulkerboxes, beehive and more?
|
|
||||||
BlockState blockState1 = blockStateMeta1.getBlockState();
|
|
||||||
BlockState blockState2 = blockStateMeta2.getBlockState();
|
|
||||||
|
|
||||||
if (blockState1 instanceof ShulkerBox shulkerBox1 && blockState2 instanceof ShulkerBox shulkerBox2) {
|
|
||||||
if (shulkerBox1.getColor() != shulkerBox2.getColor())
|
|
||||||
return false; // not the same color
|
|
||||||
|
|
||||||
// Do we need all of the above checks inside the shulker?
|
|
||||||
if (Arrays.equals(shulkerBox1.getInventory().getContents(), shulkerBox2.getInventory().getContents()))
|
|
||||||
return true; // same content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// Suspicious stews
|
|
||||||
matcherList.add(
|
|
||||||
(meta1, meta2) -> {
|
|
||||||
if (meta1 instanceof SuspiciousStewMeta suspiciousStewMeta1 && meta2 instanceof SuspiciousStewMeta suspiciousStewMeta2) {
|
|
||||||
if (suspiciousStewMeta1.hasCustomEffects() != suspiciousStewMeta2.hasCustomEffects()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (suspiciousStewMeta1.hasCustomEffects()) {
|
|
||||||
return listMatches(suspiciousStewMeta1.getCustomEffects(), suspiciousStewMeta2.getCustomEffects());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean matches(ItemStack item1, ItemStack item2) {
|
|
||||||
if (item1 == null && item2 == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item1 == null || item2 == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!item1.getType().equals(item2.getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item1.isSimilar(item2)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item1.hasItemMeta() && item2.hasItemMeta()) {
|
|
||||||
return metaMatches(item1, item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !item1.hasItemMeta() && !item1.hasItemMeta();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static boolean metaMatches(ItemStack item1, ItemStack item2) {
|
|
||||||
ItemMeta meta1 = item1.getItemMeta();
|
|
||||||
ItemMeta meta2 = item2.getItemMeta();
|
|
||||||
|
|
||||||
if (meta1 != null && meta2 != null) {
|
|
||||||
for (Matcher matcher : matcherList) {
|
|
||||||
boolean result = matcher.match(meta1, meta2);
|
|
||||||
if (!result) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return meta1 == null && meta2 == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean listMatches(Collection<?> list1, Collection<?> list2) {
|
|
||||||
return list1.containsAll(list2) && list2.containsAll(list1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface Matcher {
|
|
||||||
|
|
||||||
boolean match(ItemMeta meta1, ItemMeta meta2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package com.alttd.playershops.utils;
|
|
||||||
|
|
||||||
public record Pair<X, Y>(X x, Y y) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -2,17 +2,20 @@ package com.alttd.playershops.utils;
|
||||||
|
|
||||||
import com.alttd.playershops.shop.PlayerShop;
|
import com.alttd.playershops.shop.PlayerShop;
|
||||||
import com.alttd.playershops.shop.ShopTransaction;
|
import com.alttd.playershops.shop.ShopTransaction;
|
||||||
import com.alttd.playershops.utils.sprite.MaterialSprites;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.BlockState;
|
||||||
|
import org.bukkit.block.ShulkerBox;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.*;
|
import org.bukkit.inventory.meta.*;
|
||||||
|
import org.bukkit.map.MapView;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
@ -34,6 +37,167 @@ public class ShopUtil {
|
||||||
return (loc.getWorld().isChunkLoaded(x, z));
|
return (loc.getWorld().isChunkLoaded(x, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two items to each other. Returns true if they match.
|
||||||
|
*
|
||||||
|
* @param stack1
|
||||||
|
* The first item stack
|
||||||
|
* @param stack2
|
||||||
|
* The second item stack
|
||||||
|
* @return true if the itemstacks match. (Material, durability, enchants, name)
|
||||||
|
*/
|
||||||
|
public static boolean matches(ItemStack stack1, ItemStack stack2) {
|
||||||
|
if (stack1 == stack2)
|
||||||
|
return true; // Referring to the same thing, or both are null.
|
||||||
|
if (stack1 == null || stack2 == null)
|
||||||
|
return false; // One of them is null (Can't be both, see above)
|
||||||
|
if (stack1.getType() != stack2.getType())
|
||||||
|
return false; // Not the same material
|
||||||
|
if (stack1.getDurability() != stack2.getDurability())
|
||||||
|
return false; // Not the same durability
|
||||||
|
if (!stack1.getEnchantments().equals(stack2.getEnchantments()))
|
||||||
|
return false; // They have the same enchants
|
||||||
|
if (!stack1.getItemMeta().equals(stack2.getItemMeta()))
|
||||||
|
return false; // They have the same enchants
|
||||||
|
if (stack1.getItemMeta().hasDisplayName() || stack2.getItemMeta().hasDisplayName()) {
|
||||||
|
if (stack1.getItemMeta().hasDisplayName() && stack2.getItemMeta().hasDisplayName()) {
|
||||||
|
if (!stack1.getItemMeta().getDisplayName().equals(stack2.getItemMeta().getDisplayName())) {
|
||||||
|
return false; // items have different display name
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false; // one of the item stacks have a display name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Class.forName("org.bukkit.inventory.meta.EnchantmentStorageMeta");
|
||||||
|
boolean book1 = stack1.getItemMeta() instanceof EnchantmentStorageMeta;
|
||||||
|
boolean book2 = stack2.getItemMeta() instanceof EnchantmentStorageMeta;
|
||||||
|
if (book1 != book2)
|
||||||
|
return false;// One has enchantment meta, the other does not.
|
||||||
|
if (book1 == true) { // They are the same here (both true or both
|
||||||
|
// false). So if one is true, the other is
|
||||||
|
// true.
|
||||||
|
Map<Enchantment, Integer> ench1 = ((EnchantmentStorageMeta) stack1.getItemMeta()).getStoredEnchants();
|
||||||
|
Map<Enchantment, Integer> ench2 = ((EnchantmentStorageMeta) stack2.getItemMeta()).getStoredEnchants();
|
||||||
|
if (!ench1.equals(ench2))
|
||||||
|
return false; // Enchants aren't the same.
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
}
|
||||||
|
return matches2(stack1, stack2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean matches2(ItemStack stack1, ItemStack stack2) {
|
||||||
|
if (stack1 == stack2)
|
||||||
|
return true; // Referring to the same thing, or both are null.
|
||||||
|
|
||||||
|
if (stack1 == null || stack2 == null)
|
||||||
|
return false; // One of them is null (Can't be both, see above)
|
||||||
|
|
||||||
|
if (stack1.getType() != stack2.getType())
|
||||||
|
return false; // Not the same material
|
||||||
|
|
||||||
|
if ((!stack1.hasItemMeta() && !stack2.hasItemMeta()))
|
||||||
|
return true; // Only one of the items has item meta
|
||||||
|
|
||||||
|
if (stack1.hasItemMeta() && stack2.hasItemMeta()) {
|
||||||
|
ItemMeta itemMeta1 = stack1.getItemMeta();
|
||||||
|
ItemMeta itemMeta2 = stack2.getItemMeta();
|
||||||
|
|
||||||
|
if ((itemMeta1.hasDisplayName() != itemMeta2.hasDisplayName()))
|
||||||
|
return false; // Only one has a display name
|
||||||
|
|
||||||
|
if (!itemMeta1.getDisplayName().equals(itemMeta2.getDisplayName()))
|
||||||
|
return false; // items have different display name
|
||||||
|
|
||||||
|
// This is where the heavy checks are :/
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName("org.bukkit.inventory.meta.EnchantmentStorageMeta");
|
||||||
|
boolean book1 = itemMeta1 instanceof EnchantmentStorageMeta;
|
||||||
|
boolean book2 = itemMeta2 instanceof EnchantmentStorageMeta;
|
||||||
|
if (book1 != book2)
|
||||||
|
return false;// One has enchantment meta, the other does not.
|
||||||
|
if (book1 == true) { // They are the same here (both true or both false). So if one is true, the other is true.
|
||||||
|
Map<Enchantment, Integer> ench1 = ((EnchantmentStorageMeta) itemMeta1).getStoredEnchants();
|
||||||
|
Map<Enchantment, Integer> ench2 = ((EnchantmentStorageMeta) itemMeta2).getStoredEnchants();
|
||||||
|
if (!ench1.equals(ench2))
|
||||||
|
return false; // Enchants aren't the same.
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemMeta1 instanceof Damageable damageable1 && itemMeta2 instanceof Damageable damageable2)
|
||||||
|
if (damageable1.getDamage() != damageable2.getDamage())
|
||||||
|
return false; // Not the same durability
|
||||||
|
|
||||||
|
// We need this check now because mapart stores data in the map NBT
|
||||||
|
if (itemMeta1 instanceof MapMeta mapMeta1 && itemMeta2 instanceof MapMeta mapMeta2) {
|
||||||
|
MapView mapView1 = mapMeta1.getMapView();
|
||||||
|
MapView mapView2 = mapMeta2.getMapView();
|
||||||
|
if (mapView1 == null || mapView2 == null)
|
||||||
|
return false; // at least one is null
|
||||||
|
|
||||||
|
if (mapView1.getId() == mapView2.getId())
|
||||||
|
return true; // ID does not match
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemMeta1 instanceof TropicalFishBucketMeta tropicalFishBucketMeta1 && itemMeta2 instanceof TropicalFishBucketMeta tropicalFishBucketMeta2) {
|
||||||
|
if (tropicalFishBucketMeta1.getBodyColor() != tropicalFishBucketMeta2.getBodyColor())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (tropicalFishBucketMeta1.getPattern() != tropicalFishBucketMeta2.getPattern())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (tropicalFishBucketMeta1.getPatternColor() != tropicalFishBucketMeta2.getPatternColor())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemMeta1 instanceof AxolotlBucketMeta axolotlBucketMeta1 && itemMeta2 instanceof AxolotlBucketMeta axolotlBucketMeta2) {
|
||||||
|
if (axolotlBucketMeta1.getVariant() != axolotlBucketMeta2.getVariant())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemMeta1 instanceof BlockStateMeta blockStateMeta1 && itemMeta2 instanceof BlockStateMeta blockStateMeta2) {
|
||||||
|
// extra heavy - Banners, Shulkerboxes, beehive and more?
|
||||||
|
BlockState blockState1 = blockStateMeta1.getBlockState();
|
||||||
|
BlockState blockState2 = blockStateMeta2.getBlockState();
|
||||||
|
|
||||||
|
if (blockState1 instanceof ShulkerBox shulkerBox1 && blockState2 instanceof ShulkerBox shulkerBox2) {
|
||||||
|
if (shulkerBox1.getColor() != shulkerBox2.getColor())
|
||||||
|
return false; // not the same color
|
||||||
|
|
||||||
|
// Do we need all of the above checks inside the shulker?
|
||||||
|
if (Arrays.equals(shulkerBox1.getInventory().getContents(), shulkerBox2.getInventory().getContents()))
|
||||||
|
return true; // same content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
/* if (itemMeta1 instanceof BannerMeta bannerMeta1 && itemMeta2 instanceof BannerMeta bannerMeta2) {
|
||||||
|
if (bannerMeta1.numberOfPatterns() != bannerMeta2.numberOfPatterns())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!bannerMeta1.getPatterns().equals(bannerMeta2.getPatterns()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemMeta1 instanceof BookMeta bookMeta1 && itemMeta2 instanceof BookMeta bookMeta2) {
|
||||||
|
// Todo Books
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemMeta1 instanceof PotionMeta potionMeta1 && itemMeta2 instanceof PotionMeta potionMeta2) {
|
||||||
|
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
// if (!stack1.getEnchantments().equals(stack2.getEnchantments()))
|
||||||
|
// return false; // They have the same enchants
|
||||||
|
// if (!stack1.getItemMeta().equals(stack2.getItemMeta()))
|
||||||
|
// return false; // They have the same enchants
|
||||||
|
return Arrays.equals(stack1.serializeAsBytes(), stack2.serializeAsBytes());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of items that can be given to the inventory safely.
|
* Returns the number of items that can be given to the inventory safely.
|
||||||
*
|
*
|
||||||
|
|
@ -52,7 +216,7 @@ public class ShopUtil {
|
||||||
for (ItemStack iStack : contents) {
|
for (ItemStack iStack : contents) {
|
||||||
if (iStack == null || iStack.getType() == Material.AIR) {
|
if (iStack == null || iStack.getType() == Material.AIR) {
|
||||||
space += item.getMaxStackSize();
|
space += item.getMaxStackSize();
|
||||||
} else if (ItemMatcher.matches(item, iStack)) {
|
} else if (matches(item, iStack)) {
|
||||||
space += item.getMaxStackSize() - iStack.getAmount();
|
space += item.getMaxStackSize() - iStack.getAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +329,7 @@ public class ShopUtil {
|
||||||
Component component;
|
Component component;
|
||||||
MiniMessage miniMessage = MiniMessage.miniMessage();
|
MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||||
if (item == null || item.getType().equals(Material.AIR))
|
if (item == null || item.getType().equals(Material.AIR))
|
||||||
return miniMessage.deserialize("No item");
|
return miniMessage.deserialize("NONE");
|
||||||
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
|
boolean dname = item.hasItemMeta() && item.getItemMeta().hasDisplayName();
|
||||||
if (dname) {
|
if (dname) {
|
||||||
component = item.getItemMeta().displayName();
|
component = item.getItemMeta().displayName();
|
||||||
|
|
@ -202,18 +366,4 @@ public class ShopUtil {
|
||||||
public static double round(double price) {
|
public static double round(double price) {
|
||||||
return (double) Math.round(price * 100) / 100;
|
return (double) Math.round(price * 100) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Component spriteComponent(ItemStack itemStack) {
|
|
||||||
Component component = Component.empty();
|
|
||||||
if (itemStack == null || itemStack.getType() == Material.AIR) return component;
|
|
||||||
|
|
||||||
component = MaterialSprites.get(itemStack.getType()).append(Component.space()).append(
|
|
||||||
itemStack.displayName().hoverEvent(itemStack.asHoverEvent()));
|
|
||||||
|
|
||||||
return component;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Component spriteComponent(Material material) {
|
|
||||||
return MaterialSprites.get(material).append(Component.space()).append(Component.text(material.key().value()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user