diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml new file mode 100644 index 00000000..ea967bbf --- /dev/null +++ b/.github/workflows/gradle-publish.yml @@ -0,0 +1,55 @@ +name: Java CI with Gradle +on: [push, pull_request] + +jobs: + compile: + if: "!contains(github.event.head_commit.message, 'ci-skip') || !contains(github.event.head_commit.message, 'CI-SKIP') || !contains(github.event.head_commit.message, 'CI SKIP') || !contains(github.event.head_commit.message, 'ci skip') " + runs-on: ubuntu-24.04 + strategy: + matrix: + java: ['21', '23'] + steps: + # 1. Check out the current working tree + - name: Checkout ArmorStandEditor Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + # 2. Setup Java JDK + - name: Set up JDK Environments + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: 'zulu' + + # 3. Setup local Gradle cache to speed up building + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Grant execute permission for Gradle Wrapper + run: chmod +x ./gradlew + + # 4. Build and analyze + - name: Build and analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: ./gradlew build sonar -Dsonar.projectKey=wolfieheart_ArmorStandEditor || echo "Skipping SonarQube analysis" + + # 5. Create a Clean Package - and Verify it + - name: Clean and build + run: ./gradlew clean build + + # 6. Upload Artifacts (Debug Purposes) + - name: Upload Artifact for Debugging + uses: actions/upload-artifact@v4.0.0 + if: success() && matrix.java == '21' + with: + name: artifact + path: /home/runner/work/ArmorStandEditor/ArmorStandEditor/build/libs/armorstandeditor-*.jar + if-no-files-found: error + diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml deleted file mode 100644 index 4db83226..00000000 --- a/.github/workflows/maven-publish.yml +++ /dev/null @@ -1,63 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Java CI with Maven -on: [push, pull_request] - -jobs: - compile: - if: "!contains(github.event.head_commit.message, 'ci-skip') || !contains(github.event.head_commit.message, 'CI-SKIP') || !contains(github.event.head_commit.message, 'CI SKIP') || !contains(github.event.head_commit.message, 'ci skip') " - runs-on: ubuntu-latest - strategy: - matrix: - java: ['17', '18'] - steps: - # 1. Check out the current working tree - - name: Checkout ArmorStandEditor Repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - # 2. Setup Java JDK - - name: Set up JDK Environments - uses: actions/setup-java@v4 - with: - java-version: ${{ matrix.java }} - distribution: 'zulu' - - # 3. Setup local Maven package cache to speed up building - - name: Cache SonarCloud packages - uses: actions/cache@v3 - with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar - - - name: Cache Maven packages - uses: actions/cache@v3 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - # 4. Build via Maven - - name: Build and analyze - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=wolfieheart_ArmorStandEditor - - #5: Create a Clean Package - and Verify it - - name: Clean package - run: mvn -B clean package - - - name: Clean Verify - run: mvn -B clean verify - - #6 Upload Artifacts (Debug Purposes) - - name: Upload Artifact for Debugging - uses: actions/upload-artifact@v4.0.0 - with: - name: artifact - path: /home/runner/work/ArmorStandEditor/ArmorStandEditor/target/armorstandeditor-*-*.jar - if-no-files-found: error diff --git a/.gitignore b/.gitignore index 9d631327..74b090a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,28 @@ +# IntelliJ IDEA .idea/ -target/ *.iml + +# Build directories /bin/ -/.project -/.classpath -/.settings/ +**/build +dist/ + + +# Eclipse IDE +.project +.classpath +.settings/ + +# Java specific metadata /src/main/java/META-INF/*.MF /src/main/java/META-INF/ + +# Project-specific files /TODO-LIST.MD -/dependency-reduced-pom.xml + +# Gradle +.gradle/ +!gradle/wrapper/gradle-wrapper.jar + +# Gradle Wrapper +.gradle-wrapper/ diff --git a/API-Example-Plugin/pom.xml b/API-Example-Plugin/pom.xml deleted file mode 100644 index 4e90681c..00000000 --- a/API-Example-Plugin/pom.xml +++ /dev/null @@ -1,115 +0,0 @@ - - 4.0.0 - io.github.rypofalem.apiexample - armorstandeditor-apitest - jar - 1.20.1-43.2 - armorstandeditor-apitest - s://maven.apache.org - - - 17 - UTF-8 - 3.0.1 - wolfieheart - https://sonarcloud.io - - - - - Wolfieheart - Wolfieheart - https://github.com/Wolfieheart - - - RypoFalem - RypoFalem - https://github.com/RypoFalem - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - paper-repo - https://repo.papermc.io/repository/maven-public/ - - - jitpack.io - https://jitpack.io - - - - - - - org.spigotmc - spigot-api - 1.20.1-R0.1-SNAPSHOT - provided - - - dev.folia - folia-api - 1.19.4-R0.1-SNAPSHOT - provided - - - com.github.wolfieheart - armorstandeditor - 1.20.2-44.1 - provided - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - compile - package - - attach-artifact - - - - - ${project.build.directory}/${project.artifactId}.jar - jar - optional - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.12.0 - - 17 - 17 - - - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - [ci skip] || [CI SKIP] || [CI-SKIP] - @{project.version} - - - - - diff --git a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java b/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java deleted file mode 100644 index 06e6d50b..00000000 --- a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.apiexample; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.player.PlayerInteractAtEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; - -public class ASEventTester implements Listener { - - Player player; - - //ArmorStandRenameEvent - @EventHandler - public void renameArmorStand(PlayerInteractAtEntityEvent ASRenameEvent) { - player = ASRenameEvent.getPlayer(); - ASRenameEvent.setCancelled(true); - if (ASRenameEvent.isCancelled()) { - player.sendMessage("ArmorStandRenameEvent has been cancelled"); - } else { - player.sendMessage("ArmorStandRenameEvent has not been cancelled. Continuing...."); - } - } - - //ArmorStandManipEvent - @EventHandler - public void manipulateArmorStand(PlayerInteractAtEntityEvent ASManipEvent) { - player = ASManipEvent.getPlayer(); - ASManipEvent.setCancelled(true); - if (ASManipEvent.isCancelled()) { - player.sendMessage("ArmorStandManipulationEvent has been cancelled"); - } else { - player.sendMessage("ArmorStandManipulationEvent has not been cancelled. Continuing...."); - } - } - - //ArmorStandTargetedEvent - @EventHandler - public void targetEvent(PlayerSwapHandItemsEvent targetASEvent) { - player = targetASEvent.getPlayer(); - targetASEvent.setCancelled(true); - if (targetASEvent.isCancelled()) { - player.sendMessage("ArmorStandTargetedEvent has been cancelled"); - } else { - player.sendMessage("ArmorStandTargetedEvent has not been cancelled. Continuing...."); - } - } - - //PlayerOpenMenuEvent - //onArmorStandDamage EntityDamageByEntityEvent event - @EventHandler - public void playerOpeningMenuEvent(EntityDamageByEntityEvent ASEDamageMenuOpenEvent) { - player = (Player) ASEDamageMenuOpenEvent.getDamager(); - ASEDamageMenuOpenEvent.setCancelled(true); - if (ASEDamageMenuOpenEvent.isCancelled()) { - player.sendMessage("PlayerOpenMenuEvent has been cancelled"); - } else { - player.sendMessage("PlayerOpenMenuEvent has not been cancelled. Continuing...."); - } - } - - //Also PlayerOpenMenuEvent when RightClicking/Interacting - @EventHandler - public void playerOpeningMenuRightClickEvent(PlayerInteractEvent ASERightClickMenuOpenEvent) { - player = ASERightClickMenuOpenEvent.getPlayer(); - ASERightClickMenuOpenEvent.setCancelled(true); - if (ASERightClickMenuOpenEvent.isCancelled()) { - player.sendMessage("PlayerOpenMenuEvent has been cancelled"); - } else { - player.sendMessage("PlayerOpenMenuEvent has not been cancelled. Continuing...."); - } - } -} diff --git a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java b/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java deleted file mode 100644 index 7d366781..00000000 --- a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.apiexample; - -import org.bukkit.plugin.java.JavaPlugin; - -public class ArmorStandEditorAPITest extends JavaPlugin { - - @Override - public void onEnable() { - this.getLogger().info("[ArmorStandEditor] API Testing Plugin v1.20.0-43 - Enable"); - this.getServer().getPluginManager().registerEvents(new ASEventTester(), this); - this.getServer().getPluginManager().registerEvents(new IFEventTester(), this); - } - -} diff --git a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java b/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java deleted file mode 100644 index d80bf182..00000000 --- a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.apiexample; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.player.PlayerInteractAtEntityEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; - -public class IFEventTester implements Listener { - Player player; - - //ItemFrameGlowEvent - @EventHandler - public void manipulateArmorStand(PlayerInteractAtEntityEvent IFGlowEvent) { - player = IFGlowEvent.getPlayer(); - IFGlowEvent.setCancelled(true); - if (IFGlowEvent.isCancelled()) { - player.sendMessage("ItemFrameGlowEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameGlowEvent has not been cancelled. Continuing...."); - } - } - - @EventHandler - public void manipulateItemFrame(EntityDamageByEntityEvent IFManipulationLeftClickEvent) { - player = (Player) IFManipulationLeftClickEvent.getDamager(); - IFManipulationLeftClickEvent.setCancelled(true); - if (IFManipulationLeftClickEvent.isCancelled()) { - player.sendMessage("ItemFrameManipulatedEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameManipulatedEvent has not been cancelled. Continuing...."); - } - } - - @EventHandler - public void manipulateItemFrameRightClick(PlayerInteractAtEntityEvent IFManipulationRightClickEvent) { - player = IFManipulationRightClickEvent.getPlayer(); - IFManipulationRightClickEvent.setCancelled(true); - if (IFManipulationRightClickEvent.isCancelled()) { - player.sendMessage("ItemFrameManipulatedEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameManipulatedEvent has not been cancelled. Continuing...."); - } - } - - @EventHandler - public void targetEvent(PlayerSwapHandItemsEvent targetIFEvent) { - player = targetIFEvent.getPlayer(); - targetIFEvent.setCancelled(true); - if (targetIFEvent.isCancelled()) { - player.sendMessage("ItemFrameTargetedEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameTargetedEvent has not been cancelled. Continuing...."); - } - } - -} diff --git a/API-Example-Plugin/src/main/resources/plugin.yml b/API-Example-Plugin/src/main/resources/plugin.yml deleted file mode 100644 index 407101c7..00000000 --- a/API-Example-Plugin/src/main/resources/plugin.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: ArmorStandEditor-APITester -main: io.github.rypofalem.apiexample.ArmorStandEditorAPITest -version: 1.20.1-43.2 -api-version: "1.13" -website: https://www.spigotmc.org/resources/94503/ -authors: [Wolfstorm, Pinnkk] -description: Allows players to edit data of armorstands without any commands. diff --git a/TODO_Rewrite.md b/TODO_Rewrite.md new file mode 100644 index 00000000..299251a6 --- /dev/null +++ b/TODO_Rewrite.md @@ -0,0 +1,35 @@ +# What Still has to be rewritten +
+ +## In Progress +- API + - Add New APIs for Menu Opening. +- Player Editor Reimplementation + +## TODO: +- Menus from 1.21.4-48 + - Sizing Rework + - Preset poses + - Standard ASE Menu + - Equipment +- Player Editor Reimplementation + - Start with Menu Critical things +- Commands +- Permissions +- Protections +- Testing for Config Options in the Code + + +## Done +- Configuration Options and Loading them in +- Scoreboards +- SpigotMC check / PaperMc and Fork Checks +- Metrics and Handling them +- Debug Output +- Langauges +- Utils +- Folia Support +- Modes +- API + - Readd everything there currently. +- Gradle Migration \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..f34ee4e8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,80 @@ +plugins { + id 'java' + id 'maven-publish' + id 'org.sonarqube' version '6.0.1.5171' +} + +group = 'io.github.rypofalem.armorstandeditor' +version = '0.x-Rewrite' + +def javaVersion = 21 + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(javaVersion)) + } +} + +sonar { + properties { + property "sonar.projectKey", "wolfieheart_ArmorStandEditor" + property "sonar.organization", "wolfieheart" + property "sonar.host.url", "https://sonarcloud.io" + property "sonar.token", System.getenv("SONAR_TOKEN") + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +repositories { + mavenCentral() + maven { + url = 'https://repo.papermc.io/repository/maven-public/' + } + maven { + url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + } +} + +dependencies { + compileOnly 'io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT' + compileOnly 'org.projectlombok:lombok:1.18.34' + + testImplementation 'org.mockito:mockito-core:5.5.0' + testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0' +} + +tasks.jar { + manifest { + attributes( + 'Implementation-Title': 'armorstandeditor', + 'Implementation-Version': version + ) + } +} + +tasks.register('attachArtifact') { + doLast { + println "Attach optional artifact if needed." + // Gradle doesn't natively support attaching optional artifacts like Maven. Additional logic might be added here. + } +} + +testing { + suites { + test(JvmTestSuite) { + useJUnitJupiter() + } + } +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..1e250ab8 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,16 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format + +[versions] +io-papermc-paper-paper-api = "1.21.4-R0.1-SNAPSHOT" +org-junit-jupiter-junit-jupiter-api = "5.10.0" +org-junit-jupiter-junit-jupiter-engine = "5.10.0" +org-mockito-mockito-core = "5.5.0" +org-projectlombok-lombok = "1.18.34" + +[libraries] +io-papermc-paper-paper-api = { module = "io.papermc.paper:paper-api", version.ref = "io-papermc-paper-paper-api" } +org-junit-jupiter-junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "org-junit-jupiter-junit-jupiter-api" } +org-junit-jupiter-junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "org-junit-jupiter-junit-jupiter-engine" } +org-mockito-mockito-core = { module = "org.mockito:mockito-core", version.ref = "org-mockito-mockito-core" } +org-projectlombok-lombok = { module = "org.projectlombok:lombok", version.ref = "org-projectlombok-lombok" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e6441136 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..cea7a793 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..1aa94a42 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..25da30db --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index ff7d1246..00000000 --- a/pom.xml +++ /dev/null @@ -1,297 +0,0 @@ - - 4.0.0 - io.github.rypofalem.armorstandeditor - armorstandeditor - jar - 1.20.4-45 - armorstandeditor - https://maven.apache.org - - - 17 - UTF-8 - 3.0.1 - wolfieheart - https://sonarcloud.io - - - - - Wolfieheart - Wolfieheart - https://github.com/Wolfieheart - - - RypoFalem - RypoFalem - https://github.com/RypoFalem - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - paper-repo - https://repo.papermc.io/repository/maven-public/ - - - - sk89q-repo - https://maven.enginehub.org/repo/ - - - - sonatype - https://oss.sonatype.org/content/groups/public/ - - - sonatype snapshots - https://s01.oss.sonatype.org/content/groups/public/ - - - - glaremasters repo - https://repo.glaremasters.me/repository/towny/ - - - glaremasters - https://repo.glaremasters.me/repository/bloodshot/ - - - - jeff-media-public - https://hub.jeff-media.com/nexus/repository/jeff-media-public/ - - - - jitpack.io - https://jitpack.io - - - - bg-repo - https://repo.bg-software.com/repository/api/ - - - - codemc-repo - https://repo.codemc.org/repository/maven-public/ - - - - minecraft-repo - https://libraries.minecraft.net/ - - - - - - - com.intellectualsites.bom - bom-1.18.x - 1.31 - import - pom - - - - - - - - org.spigotmc - spigot-api - 1.20.4-R0.1-SNAPSHOT - provided - - - dev.folia - folia-api - 1.19.4-R0.1-SNAPSHOT - provided - - - - com.sk89q.worldguard - worldguard-bukkit - 7.1.0-SNAPSHOT - provided - - - - com.intellectualsites.plotsquared - plotsquared-core - 7.3.0 - provided - - - com.intellectualsites.plotsquared - plotsquared-bukkit - 7.3.0 - provided - - - plotsquared-core - * - - - - - - com.github.TechFortress - GriefPrevention - 16.18.1 - provided - - - - com.palmergames.bukkit.towny - towny - 0.100.0.14 - provided - - - - com.jeff_media - SpigotUpdateChecker - 3.0.3 - compile - - - - com.bgsoftware - SuperiorSkyblockAPI - 2023.3 - provided - - - - com.griefdefender - api - 2.1.0-SNAPSHOT - provided - - - - com.github.angeschossen - LandsAPI - 6.42.8 - provided - - - - world.bentobox - bentobox - 1.23.2 - provided - - - - com.mojang - authlib - 4.0.43 - provided - - - - - org.projectlombok - lombok - 1.18.30 - provided - - - - - - - org.openrewrite.maven - rewrite-maven-plugin - 5.16.0 - - - org.openrewrite.java.migrate.UpgradeToJava17 - org.openrewrite.java.format.AutoFormat - org.openrewrite.java.recipes.FindRecipes - org.openrewrite.java.OrderImports - org.openrewrite.java.ShortenFullyQualifiedTypeReferences - org.openrewrite.java.RemoveUnusedImports - - - - - org.openrewrite.recipe - rewrite-migrate-java - 2.4.2 - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - compile - package - - attach-artifact - - - - - ${project.build.directory}/${project.artifactId}.jar - jar - optional - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.12.0 - - ${java.version} - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.1 - - - package - - shade - - - - - com.jeff_media.updatechecker - io.github.rypofalem.armorstandeditor.updatechecker - - - - - - - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - [ci skip] || [CI SKIP] || [CI-SKIP] - @{project.version} - - - - - diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..7c16d16d --- /dev/null +++ b/settings.gradle @@ -0,0 +1,5 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +rootProject.name = 'armorstandeditor' diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java index b6a8d3bd..943aa8e9 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java @@ -1,703 +1,304 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - package io.github.rypofalem.armorstandeditor; -import com.jeff_media.updatechecker.UpdateCheckSource; -import com.jeff_media.updatechecker.UpdateChecker; -import com.jeff_media.updatechecker.UserAgentBuilder; +import io.github.rypofalem.armorstandeditor.devtools.Debug; -import io.github.rypofalem.armorstandeditor.Metrics.*; -import io.github.rypofalem.armorstandeditor.language.Language; +import io.github.rypofalem.armorstandeditor.language.Lang; +import io.github.rypofalem.armorstandeditor.metricshandler.MetricsHandler; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.bukkit.*; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.World; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; -import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; -public class ArmorStandEditorPlugin extends JavaPlugin { +import org.bukkit.plugin.java.JavaPlugin; - //!!! DO NOT REMOVE THESE UNDER ANY CIRCUMSTANCES - Required for BStats and UpdateChecker !!! - public static final int SPIGOT_RESOURCE_ID = 94503; //Used for Update Checker - private static final int PLUGIN_ID = 12668; //Used for BStats Metrics +public final class ArmorStandEditorPlugin extends JavaPlugin { - private NamespacedKey iconKey; - private static ArmorStandEditorPlugin instance; - private Language lang; - - //Server Version Detection: Paper or Spigot and Invalid NMS Version - String nmsVersion; - String languageFolderLocation = "lang/"; - String warningMCVer = "Minecraft Version: "; - public boolean hasSpigot = false; - public boolean hasPaper = false; - public boolean hasFolia = false; - String nmsVersionNotLatest = null; - PluginDescriptionFile pdfFile = this.getDescription(); public static final String SEPARATOR_FIELD = "================================"; - public PlayerEditorManager editorManager; + // Classes + private static ArmorStandEditorPlugin instance; + private NamespacedKey iconKey; + private Debug debug = new Debug(this); + MetricsHandler metricsHandler; + protected PlayerEditorManager editorManager; + private Lang language; + + // Server Software Check True/False + boolean isFolia; + boolean isPaper; + + //Config Items (in Order) + boolean debugFlag; // Debug Flag - Not for Production + boolean requireToolName; + boolean requireToolData; + boolean requireToolLore; + boolean perWorldSupport; + boolean requireSneaking; + boolean sendToActionBar; + boolean invisibleItemFrames; + boolean invisibleArmorStands; + + String aseVersion; + String nmsVersion; + String editToolType; + String editToolName; + String editToolLore; - //Output for Updates - boolean opUpdateNotification = false; - boolean runTheUpdateChecker = false; - double updateCheckerInterval; + double coarseRotation; + double fineRotation; + double minScaleValue; + double maxScaleValue; - //Edit Tool Information Material editTool; - String toolType; - int editToolData = Integer.MIN_VALUE; - boolean requireToolData = false; - boolean requireToolName = false; - String editToolName = null; - boolean requireToolLore = false; - List editToolLore = null; - boolean enablePerWorld = false; + Integer editToolData; List allowedWorldList = null; - boolean allowCustomModelData = false; - Integer customModelDataInt = Integer.MIN_VALUE; - - //GUI Settings - boolean requireSneaking = false; - boolean sendToActionBar = true; - - //Armor Stand Specific Settings - double coarseRot; - double fineRot; - boolean glowItemFrames = false; - boolean invisibleItemFrames = true; - boolean armorStandVisibility = true; - - //Misc Options - boolean allowedToRetrievePlayerHead = false; - boolean adminOnlyNotifications = false; - - //Glow Entity Colors - public Scoreboard scoreboard; - public Team team; - String lockedTeam = "ASLocked"; - - //Debugging Options.... Not Exposed - boolean debugFlag; - private static ArmorStandEditorPlugin plugin; + // Format Strings + String warningMCVer; + String aseVersionToLog; + String warningTeamAlreadyRegistered; + String warningTeamAlreadyRemoved; + String errorToolNameRequiredButNoName; + + // Teams + Scoreboard scoreboard; + Team team; + List asTeams = new ArrayList<>(); + String lockedTeam = "ASLocked"; + String inUseTeam = "AS-InUse"; public ArmorStandEditorPlugin() { instance = this; } + @Override public void onEnable() { + // Plugin startup logic + debugFlag = isDebug(); - if (!Scheduler.isFolia()) - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - - //Get NMS Version - nmsVersion = getNmsVersion(); - - //Load Messages in Console - getLogger().info("======= ArmorStandEditor ======="); - getLogger().info("Plugin Version: " + pdfFile.getVersion()); - - // Check if the Minecraft version is supported - if (nmsVersion.compareTo("v1_17") < 0) { - getLogger().log(Level.WARNING, warningMCVer + "{0}", nmsVersion); - getLogger().warning("ArmorStandEditor is not compatible with this version of Minecraft. Please update to at least version 1.17. Loading failed."); - getServer().getPluginManager().disablePlugin(this); - getLogger().info(SEPARATOR_FIELD); - return; - } - - //Also Warn People to Update if using nmsVersion lower than latest - if (nmsVersion.compareTo("v1_20") < 0) { - getLogger().log(Level.WARNING, warningMCVer + "{0}", nmsVersion); - getLogger().warning("ArmorStandEditor is compatible with this version of Minecraft, but it is not the latest supported version."); - getLogger().warning("Loading continuing, but please consider updating to the latest version."); - } else { - getLogger().log(Level.INFO, warningMCVer + "{0}", nmsVersion); - getLogger().info("ArmorStandEditor is compatible with this version of Minecraft. Loading continuing."); - } - //Spigot Check - hasSpigot = getHasSpigot(); - hasPaper = getHasPaper(); - hasFolia = Scheduler.isFolia(); - - //If Paper and Spigot are both FALSE - Disable the plugin - if (!hasPaper && !hasSpigot) { - getLogger().severe("This plugin requires either Paper, Spigot or one of its forks to run. This is not an error, please do not report this!"); - getServer().getPluginManager().disablePlugin(this); - getLogger().info(SEPARATOR_FIELD); - return; - } else { - if (hasSpigot) { - getLogger().log(Level.INFO, "SpigotMC: {0}", hasSpigot); - } else { - getLogger().log(Level.INFO, "PaperMC: {0}", hasPaper); - } + if(debugFlag) { + debug.log("Debug Mode = ON. SET FOR REWRITE"); } - getServer().getPluginManager().enablePlugin(this); + debug.log("Enabling ASE, Getting ASE Version and logging Server Checks"); - if (!hasFolia) { - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - registerScoreboards(scoreboard); - } else { - getServer().getLogger().warning("Scoreboards currently do not work on Folia. Scoreboard Coloring will not work"); - } + aseVersion = getASEVersion(); + aseVersionToLog = String.format("Plugin Version: v%s", aseVersion); + getLogger().log(Level.INFO,"======= ArmorStandEditor ======="); + getLogger().log(Level.INFO, aseVersionToLog ); + isFolia = isFolia(); + debug.log("Using Folia: " + isFolia); + isPaper = isPaper(); + debug.log("Using Paper or a Fork: " + isPaper); - getLogger().info(SEPARATOR_FIELD); - - //saveResource doesn't accept File.separator on Windows, need to hardcode unix separator "/" instead - updateConfig("", "config.yml"); - updateConfig(languageFolderLocation, "de_DE.yml"); - updateConfig(languageFolderLocation, "es_ES.yml"); - updateConfig(languageFolderLocation, "fr_FR.yml"); - updateConfig(languageFolderLocation, "ja_JP.yml"); - updateConfig(languageFolderLocation, "nl_NL.yml"); - updateConfig(languageFolderLocation, "pl_PL.yml"); - updateConfig(languageFolderLocation, "pt_BR.yml"); - updateConfig(languageFolderLocation, "ro_RO.yml"); - updateConfig(languageFolderLocation, "ru_RU.yml"); - updateConfig(languageFolderLocation, "test_NA.yml"); - updateConfig(languageFolderLocation, "uk_UA.yml"); - updateConfig(languageFolderLocation, "zh_CN.yml"); - - //English is the default language and needs to be unaltered to so that there is always a backup message string - saveResource("lang/en_US.yml", true); - lang = new Language(getConfig().getString("lang"), this); - - //Rotation - coarseRot = getConfig().getDouble("coarse"); - fineRot = getConfig().getDouble("fine"); - - //Set Tool to be used in game - toolType = getConfig().getString("tool"); - if (toolType != null) { - editTool = Material.getMaterial(toolType); //Ignore Warning + if(isFolia || isPaper){ + getLogger().log(Level.INFO, "Server Type: Paper/Folia/Purpur or a Fork"); + getServer().getPluginManager().enablePlugin(this); } else { - getLogger().severe("Unable to get Tool for Use with Plugin. Unable to continue!"); - getLogger().info(SEPARATOR_FIELD); + debug.log("Using SpigotMc: True, which no longer is supported"); + getLogger().log(Level.INFO, "Server Type: SpigotMC"); + getLogger().log(Level.SEVERE, "This Plugin No Longer works on Spigot. Disabling ArmorStandEditor"); getServer().getPluginManager().disablePlugin(this); - return; } - //Do we require a custom tool name? - requireToolName = getConfig().getBoolean("requireToolName", false); - if (requireToolName) { - editToolName = getConfig().getString("toolName", null); - if (editToolName != null) editToolName = ChatColor.translateAlternateColorCodes('&', editToolName); - } + // NMS Version Checks - Paper Versions + nmsVersion = getServer().getMinecraftVersion(); + debug.log("Minecraft Server Version: " + nmsVersion); + doNMSChecks(nmsVersion); - //Custom Model Data - allowCustomModelData = getConfig().getBoolean("allowCustomModelData", false); + // Setup the Teams and Scoreboards that ASE uses + doScoreboardSetup(); - if (allowCustomModelData) { - customModelDataInt = getConfig().getInt("customModelDataInt", Integer.MIN_VALUE); - } - - //ArmorStandVisibility Node - armorStandVisibility = getConfig().getBoolean("armorStandVisibility", true); - - //Is there NBT Required for the tool - requireToolData = getConfig().getBoolean("requireToolData", false); - - if (requireToolData) { - editToolData = getConfig().getInt("toolData", Integer.MIN_VALUE); - } - - requireToolLore = getConfig().getBoolean("requireToolLore", false); + //TODO: Readd Languages here! + language = new Lang(getLanguageConfig(), this); - if (requireToolLore) { - editToolLore = getConfig().getList("toolLore", null); - } - - enablePerWorld = getConfig().getBoolean("enablePerWorldSupport", false); - if(enablePerWorld) { - allowedWorldList = getConfig().getList("allowed-worlds", null); - if (allowedWorldList != null && allowedWorldList.get(0).equals("*")) { - allowedWorldList = getServer().getWorlds().stream().map(World::getName).toList(); - } - } + // Get all the Configuration Options + coarseRotation = getCoarseConfig(); + fineRotation = getFineConfig(); + minScaleValue = getMinScaleConfig(); + maxScaleValue = getMaxScaleConfig(); + requireSneaking = getRequireSneakingConfig(); + sendToActionBar = getSendToActionBarConfig(); + invisibleArmorStands = getInvisibleArmorStandsConfig(); + invisibleItemFrames = getInvisibleItemFramesConfig(); - //Require Sneaking - Wolfst0rm/ArmorStandEditor#17 - requireSneaking = getConfig().getBoolean("requireSneaking", false); + // Everything requiring setup and (possible) Component Interactions + editToolType = getToolTypeConfig(); + doEditToolSetup(editToolType); - //Send Messages to Action Bar - sendToActionBar = getConfig().getBoolean("sendMessagesToActionBar", true); + requireToolName = getRequireToolNameConfig(); + doRequireToolNameSetup(requireToolName); // First Case of Conversion of &C to LegacyComponent - //All ItemFrame Stuff - glowItemFrames = getConfig().getBoolean("glowingItemFrame", true); - invisibleItemFrames = getConfig().getBoolean("invisibleItemFrames", true); + requireToolData = getRequireToolDataConfig(); + doRequireToolDataSetup(requireToolData); - //Add ability to enable ot Disable the running of the Updater - runTheUpdateChecker = getConfig().getBoolean("runTheUpdateChecker", true); + requireToolLore = getRequireToolLoreConfig(); + doToolLoreSetup(requireToolLore); - //Add Ability to check for UpdatePerms that Notify Ops - https://github.com/Wolfieheart/ArmorStandEditor/issues/86 - opUpdateNotification = getConfig().getBoolean("opUpdateNotification", true); - updateCheckerInterval = getConfig().getDouble("updateCheckerInterval", 24); + perWorldSupport = getPerWorldSupportConfig(); + doPerWorldSupportSetup(perWorldSupport); - //Ability to get Player Heads via a command - allowedToRetrievePlayerHead = getConfig().getBoolean("allowedToRetrievePlayerHead", true); + getLogger().log(Level.INFO, SEPARATOR_FIELD); - adminOnlyNotifications = getConfig().getBoolean("adminOnlyNotifications", true); - - debugFlag = getConfig().getBoolean("debugFlag", false); - if(debugFlag){ - getServer().getLogger().warning(ArmorStandEditorPlugin.SEPARATOR_FIELD); - getServer().getLogger().warning(" ArmorStandEditor - Debug Mode "); - getServer().getLogger().warning(" Debug Mode: ENABLED! "); - getServer().getLogger().warning(" USE THIS FOR DEVELOPMENT PURPOSES ONLY! "); - getServer().getLogger().warning(ArmorStandEditorPlugin.SEPARATOR_FIELD); - } - - //Run UpdateChecker - Reports out to Console on Startup ONLY! - if (!hasFolia && runTheUpdateChecker) { - - if (opUpdateNotification) { - runUpdateCheckerWithOPNotifyOnJoinEnabled(); - } else { - runUpdateCheckerConsoleUpdateCheck(); - } - - } - - //Get Metrics from bStats - getMetrics(); - - editorManager = new PlayerEditorManager(this); - CommandEx execute = new CommandEx(this); - - //CommandExecution and TabCompletion - Objects.requireNonNull(getCommand("ase")).setExecutor(execute); - Objects.requireNonNull(getCommand("ase")).setTabCompleter(execute); - - getServer().getPluginManager().registerEvents(editorManager, this); + // Do all the Metrics for BStats + metricsHandler = new MetricsHandler(this); + editorManager = new PlayerEditorManager(this); } - private void runUpdateCheckerConsoleUpdateCheck() { - if (getArmorStandEditorVersion().contains(".x")) { - getLogger().warning("Note from the development team: "); - getLogger().warning("It appears that you are using the development version of ArmorStandEditor"); - getLogger().warning("This version can be unstable and is not recommended for Production Environments."); - getLogger().warning("Please, report bugs to: https://github.com/Wolfieheart/ArmorStandEditor. "); - getLogger().warning("This warning is intended to be displayed when using a Dev build and is NOT A BUG!"); - getLogger().info("Update Checker does not work on Development Builds."); - } else { - new UpdateChecker(this, UpdateCheckSource.SPIGET, "" + SPIGOT_RESOURCE_ID + "") - .setDownloadLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/") - .setChangelogLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/history") - .setColoredConsoleOutput(true) - .setUserAgent(new UserAgentBuilder().addPluginNameAndVersion().addServerVersion()) - .checkEveryXHours(updateCheckerInterval) - .checkNow(); - } - } - - private void runUpdateCheckerWithOPNotifyOnJoinEnabled() { - if (getArmorStandEditorVersion().contains(".x")) { - getLogger().warning("Note from the development team: "); - getLogger().warning("It appears that you are using the development version of ArmorStandEditor"); - getLogger().warning("This version can be unstable and is not recommended for Production Environments."); - getLogger().warning("Please, report bugs to: https://github.com/Wolfieheart/ArmorStandEditor . "); - getLogger().warning("This warning is intended to be displayed when using a Dev build and is NOT A BUG!"); - getLogger().info("Update Checker does not work on Development Builds."); - } else { - new UpdateChecker(this, UpdateCheckSource.SPIGET, "" + SPIGOT_RESOURCE_ID + "") - .setDownloadLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/") - .setChangelogLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/history") - .setColoredConsoleOutput(true) - .setNotifyOpsOnJoin(true) - .setUserAgent(new UserAgentBuilder().addPluginNameAndVersion().addServerVersion()) - .checkEveryXHours(updateCheckerInterval) - .checkNow(); - } - } - - //Implement Glow Effects for Wolfstorm/ArmorStandEditor-Issues#5 - Add Disable Slots with Different Glow than Default - private void registerScoreboards(Scoreboard scoreboard) { - getServer().getLogger().info("Registering Scoreboards required for Glowing Effects"); - - //Fix for Scoreboard Issue reported by Starnos - Wolfst0rm/ArmorStandEditor-Issues/issues/18 - if (scoreboard.getTeam(lockedTeam) == null) { - scoreboard.registerNewTeam(lockedTeam); - scoreboard.getTeam(lockedTeam).setColor(ChatColor.RED); - } else { - getServer().getLogger().info("Scoreboard for ASLocked Already exists. Continuing to load"); - } - } - - private void unregisterScoreboards(Scoreboard scoreboard) { - getLogger().info("Removing Scoreboards required for Glowing Effects"); - - team = scoreboard.getTeam(lockedTeam); - if (team != null) { //Basic Sanity Check to ensure that the team is there - team.unregister(); - } else { - getLogger().severe("Team Already Appears to be removed. Please do not do this manually!"); - } - } - - private void updateConfig(String folder, String config) { - if (!new File(getDataFolder() + File.separator + folder + config).exists()) { - saveResource(folder + config, false); - } - } - @Override public void onDisable() { - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - if (player.getOpenInventory().getTopInventory().getHolder() == editorManager.getMenuHolder()) player.closeInventory(); - } - - if (!hasFolia) { - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - unregisterScoreboards(scoreboard); - } - } - - public String getNmsVersion() { - return this.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; + // Plugin shutdown logic + doScoreboardDestruction(); } - public boolean getHasSpigot() { - try { - Class.forName("org.spigotmc.SpigotConfig"); - nmsVersionNotLatest = "SpigotMC ASAP."; + // Static Methods - Only Ran ON ENABLE / On Disable + public static boolean isFolia(){ + try{ + Class.forName("io.papermc.paper.threadedregions.RegionziedServer"); return true; - } catch (ClassNotFoundException e) { - nmsVersionNotLatest = ""; + } catch (ClassNotFoundException e){ return false; } } - - public boolean getHasPaper() { - try { - Class.forName("com.destroystokyo.paper.PaperConfig"); - nmsVersionNotLatest = "PaperMC ASAP."; + public static boolean isPaper() { + try{ + Class.forName("io.papermc.paper.text.PaperComponents"); return true; - } catch (ClassNotFoundException e) { - nmsVersionNotLatest = ""; + } catch (ClassNotFoundException e){ return false; } } + private void doNMSChecks(String nmsVersion) { + // Check if the Minecraft version is supported + warningMCVer = String.format("Mineacraft Version: %s", nmsVersion); - public boolean getHasFolia() { - return Scheduler.isFolia(); - } - - public String getArmorStandEditorVersion() { - return getConfig().getString("version"); - } - - public boolean getArmorStandVisibility() { - return getConfig().getBoolean("armorStandVisibility"); - } - - public boolean getItemFrameVisibility() { - return getConfig().getBoolean("invisibleItemFrames"); - } - - public Language getLang() { - return lang; - } - - public boolean getAllowCustomModelData() { - return this.getConfig().getBoolean("allowCustomModelData"); - } - - public Material getEditTool() { - return this.editTool; - } - - public boolean getRunTheUpdateChecker() { - return this.getConfig().getBoolean("runTheUpdateChecker"); - } - - public Integer getCustomModelDataInt() { - return this.getConfig().getInt("customModelDataInt"); - } - - //New in 1.20-43: Allow the ability to get a player head from a command - ENABLED VIA CONFIG ONLY! - public boolean getAllowedToRetrievePlayerHead() { - return this.getConfig().getBoolean("allowedToRetrievePlayerHead"); - } - - public boolean getAdminOnlyNotifications() { - return this.getConfig().getBoolean("adminOnlyNotifications"); - } - - public boolean isEditTool(ItemStack itemStk) { - if (itemStk == null) { - return false; - } - if (editTool != itemStk.getType()) { - return false; + if (nmsVersion.contains("1.21")) { + getLogger().log(Level.INFO, warningMCVer); + getLogger().info("ArmorStandEditor is compatible with this version of Minecraft. Loading continuing."); + } else if (nmsVersion.contains("1.17") || nmsVersion.contains("1.18") || nmsVersion.contains("1.19") || nmsVersion.contains("1.20")) { + getLogger().log(Level.WARNING, warningMCVer); + getLogger().warning("ArmorStandEditor is compatible with this version of Minecraft, but it is not the latest supported version."); + getLogger().warning("Loading continuing, but please consider updating to the latest version."); + } else { + getLogger().log(Level.WARNING, warningMCVer); + getLogger().warning("ArmorStandEditor is not compatible with this version of Minecraft. Please update to at least version 1.17. Loading failed."); + getServer().getPluginManager().disablePlugin(this); + getLogger().info(SEPARATOR_FIELD); } + } - ItemMeta itemMeta = itemStk.getItemMeta(); - if (itemMeta == null) return false; - - //FIX: Depreciated Stack for getDurability - if (requireToolData) { - Damageable d1 = (Damageable) itemMeta; //Get the Damageable Options for itemStk - if (d1 != null) { //We do this to prevent NullPointers - if (d1.getDamage() != (short) editToolData) { - return false; + // Setup and Destruction Methods + private void doScoreboardSetup() { + if(!isFolia){ + scoreboard = getServer().getScoreboardManager().getMainScoreboard(); + asTeams.add(lockedTeam); + asTeams.add(inUseTeam); + for (String teamToBeRegistered : asTeams) { + scoreboard.registerNewTeam(teamToBeRegistered); + team = scoreboard.getTeam(teamToBeRegistered); + if (team != null) { + if (teamToBeRegistered.equals(lockedTeam)) { + getServer().getLogger().info("Registering Scoreboards required for Glowing Effects when Disabling Slots..."); + scoreboard.getTeam(teamToBeRegistered).color(NamedTextColor.RED); + } + } else { + warningTeamAlreadyRegistered = String.format("Scoreboard for Team '%s' already exists. Continuing to load", teamToBeRegistered); + getServer().getLogger().info(warningTeamAlreadyRegistered); } } } - - if (requireToolName && editToolName != null) { - if (!itemStk.hasItemMeta()) { - return false; - } - - //Get the name of the Edit Tool - If Null, return false - String itemName = itemMeta.getDisplayName(); - - //If the name of the Edit Tool is not the Name specified in Config then Return false - if (!itemName.equals(editToolName)) { - return false; + } + private void doScoreboardDestruction() { + if(!isFolia){ + getLogger().info("Removing Scoreboards required for Glowing Effects when Disabling Slots..."); + for (String teamToBeRegistered : asTeams) { + team = scoreboard.getTeam(teamToBeRegistered); + if (team != null) { + team.unregister(); + } else { + warningTeamAlreadyRemoved = String.format("Team '%s' already appears to be removed. Avoid manual removal to prevent errors!", teamToBeRegistered); + getServer().getLogger().severe(warningTeamAlreadyRemoved); + } } - } - - if (requireToolLore && editToolLore != null) { - - //If the ItemStack does not have Metadata then we return false - if (!itemStk.hasItemMeta()) { - return false; - } - - //Get the lore of the Item and if it is null - Return False - List itemLore = itemMeta.getLore(); - - //If the Item does not have Lore - Return False - boolean hasTheItemLore = itemMeta.hasLore(); - if (!hasTheItemLore) { - return false; - } - - //Get the localised ListString of editToolLore - List listStringOfEditToolLore = (List) editToolLore; - - //Return False if itemLore on the item does not match what we expect in the config. - if (!itemLore.equals(listStringOfEditToolLore)) { - return false; - } - + } + private void doEditToolSetup(String editToolType){ + if(editToolType != null){ + editTool = Material.getMaterial(editToolType); + } else{ + getLogger().severe("Unable to get Tool for Use with Plugin. Unable to continue!"); + getLogger().info(SEPARATOR_FIELD); + getServer().getPluginManager().disablePlugin(this); } - - if (allowCustomModelData && customModelDataInt != null) { - //If the ItemStack does not have Metadata then we return false - if (!itemStk.hasItemMeta()) { - return false; + } + private void doRequireToolNameSetup(boolean requireToolName){ + if(requireToolName){ + editToolName = getToolNameConfig(); + if(editToolName != null){ + editToolName = String.valueOf(LegacyComponentSerializer.legacyAmpersand().deserialize(editToolName)); + } else { + errorToolNameRequiredButNoName = String.format("RequireToolName is set %b, but editToolName is empty. Please give your tool a name. Unable to Continue", requireToolName); + getLogger().severe(errorToolNameRequiredButNoName); + getLogger().info(SEPARATOR_FIELD); + getServer().getPluginManager().disablePlugin(this); } - Integer itemCustomModel = itemMeta.getCustomModelData(); - return itemCustomModel.equals(customModelDataInt); } - return true; } - public void performReload() { - - //Unregister Scoreboard before before performing the reload - if (!hasFolia) { - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - unregisterScoreboards(scoreboard); + private void doRequireToolDataSetup(boolean requireToolData){ + if(requireToolData){ + editToolData = getEditToolDataConfig(); } - - //Perform Reload - reloadConfig(); - - //Re-Register Scoreboards - if (!hasFolia) registerScoreboards(scoreboard); - - //Reload Config File - reloadConfig(); - - //Set Language - lang = new Language(getConfig().getString("lang"), this); - - - //Rotation - coarseRot = getConfig().getDouble("coarse"); - fineRot = getConfig().getDouble("fine"); - - //Set Tool to be used in game - toolType = getConfig().getString("tool"); - if (toolType != null) { - editTool = Material.getMaterial(toolType); //Ignore Warning - } - - //Do we require a custom tool name? - requireToolName = getConfig().getBoolean("requireToolName", false); - if (requireToolName) { - editToolName = getConfig().getString("toolName", null); - if (editToolName != null) editToolName = ChatColor.translateAlternateColorCodes('&', editToolName); - } - - //Custom Model Data - allowCustomModelData = getConfig().getBoolean("allowCustomModelData", false); - - if (allowCustomModelData) { - customModelDataInt = getConfig().getInt("customModelDataInt", Integer.MIN_VALUE); - } - - //ArmorStandVisibility Node - armorStandVisibility = getConfig().getBoolean("armorStandVisibility", true); - - //Is there NBT Required for the tool - requireToolData = getConfig().getBoolean("requireToolData", false); - - if (requireToolData) { - editToolData = getConfig().getInt("toolData", Integer.MIN_VALUE); - } - - requireToolLore = getConfig().getBoolean("requireToolLore", false); - - if (requireToolLore) { - editToolLore = getConfig().getList("toolLore", null); + } + private void doToolLoreSetup(boolean requireToolLore){ + if(requireToolLore){ + editToolLore = getToolLoreConfig(); } - - - enablePerWorld = getConfig().getBoolean("enablePerWorldSupport", false); - if(enablePerWorld) { - allowedWorldList = getConfig().getList("allowed-worlds", null); - if (allowedWorldList != null && allowedWorldList.get(0).equals("*")) { + } + private void doPerWorldSupportSetup(boolean perWorldSupport){ + if(perWorldSupport){ + allowedWorldList = getAllowedWorldListConfig(); + if(allowedWorldList != null && allowedWorldList.get(0).equals("*")){ allowedWorldList = getServer().getWorlds().stream().map(World::getName).toList(); } } - - //Require Sneaking - Wolfst0rm/ArmorStandEditor#17 - requireSneaking = getConfig().getBoolean("requireSneaking", false); - - //Send Messages to Action Bar - sendToActionBar = getConfig().getBoolean("sendMessagesToActionBar", true); - - //All ItemFrame Stuff - glowItemFrames = getConfig().getBoolean("glowingItemFrame", true); - invisibleItemFrames = getConfig().getBoolean("invisibleItemFrames", true); - - //Add ability to enable ot Disable the running of the Updater - runTheUpdateChecker = getConfig().getBoolean("runTheUpdateChecker", true); - - //Ability to get Player Heads via a command - allowedToRetrievePlayerHead = getConfig().getBoolean("allowedToRetrievePlayerHead", true); - adminOnlyNotifications = getConfig().getBoolean("adminOnlyNotifications", true); - - //Add Ability to check for UpdatePerms that Notify Ops - https://github.com/Wolfieheart/ArmorStandEditor/issues/86 - opUpdateNotification = getConfig().getBoolean("opUpdateNotification", true); - updateCheckerInterval = getConfig().getDouble("updateCheckerInterval", 24); - - //Run UpdateChecker - Reports out to Console on Startup ONLY! - if (!hasFolia && runTheUpdateChecker) { - - if (opUpdateNotification) { - runUpdateCheckerWithOPNotifyOnJoinEnabled(); - } else { - runUpdateCheckerConsoleUpdateCheck(); - } - - } } - public static ArmorStandEditorPlugin instance() { - return instance; + // Config Methods as Getters - Useful for Config Reload etc. + public boolean isDebug() { return getConfig().getBoolean("debugFlag"); } + public String getASEVersion() { + return getConfig().getString("version"); } - - //Metrics/bStats Support - private void getMetrics() { - - Metrics metrics = new Metrics(this, PLUGIN_ID); - - //RequireToolLore Metric - metrics.addCustomChart(new SimplePie("tool_lore_enabled", () -> getConfig().getString("requireToolLore"))); - - //RequireToolData - metrics.addCustomChart(new SimplePie("tool_data_enabled", () -> getConfig().getString("requireToolData"))); - - //Send Messages to ActionBar - metrics.addCustomChart(new SimplePie("action_bar_messages", () -> getConfig().getString("sendMessagesToActionBar"))); - - //Check for Sneaking - metrics.addCustomChart(new SimplePie("require_sneaking", () -> getConfig().getString("requireSneaking"))); - - //Language is used - metrics.addCustomChart(new DrilldownPie("language_used", () -> { - Map> map = new HashMap<>(); - Map entry = new HashMap<>(); - - String languageUsed = getConfig().getString("lang"); - assert languageUsed != null; - - if (languageUsed.startsWith("nl")) { - map.put("Dutch", entry); - } else if (languageUsed.startsWith("de")) { - map.put("German", entry); - } else if (languageUsed.startsWith("es")) { - map.put("Spanish", entry); - } else if (languageUsed.startsWith("fr")) { - map.put("French", entry); - } else if (languageUsed.startsWith("ja")) { - map.put("Japanese", entry); - } else if (languageUsed.startsWith("pl")) { - map.put("Polish", entry); - } else if (languageUsed.startsWith("ru")) { //See PR# 41 by KPidS - map.put("Russian", entry); - } else if (languageUsed.startsWith("ro")) { - map.put("Romanian", entry); - } else if (languageUsed.startsWith("uk")) { - map.put("Ukrainian", entry); - } else if (languageUsed.startsWith("zh")) { - map.put("Chinese", entry); - } else if (languageUsed.startsWith("pt")) { - map.put("Brazilian", entry); - } else { - map.put("English", entry); - } - return map; - })); - - //ArmorStandInvis Config - metrics.addCustomChart(new SimplePie("armor_stand_invisibility_usage", () -> getConfig().getString("armorStandVisibility"))); - - //ArmorStandInvis Config - metrics.addCustomChart(new SimplePie("itemframe_invisibility_used", () -> getConfig().getString("invisibleItemFrames"))); - - //Add tracking to see who is using Custom Naming in BStats - metrics.addCustomChart(new SimplePie("custom_toolname_enabled", () -> getConfig().getString("requireToolName"))); - - metrics.addCustomChart(new SimplePie("using_the_update_checker", () -> getConfig().getString("runTheUpdateChecker"))); - metrics.addCustomChart(new SimplePie("op_updates", () -> getConfig().getString("opUpdateNotification"))); - - + public boolean getRequireToolNameConfig() { return getConfig().getBoolean("requireToolName", false); } + public boolean getRequireToolDataConfig() { return getConfig().getBoolean("requireToolData", false); } + public boolean getRequireToolLoreConfig() { return getConfig().getBoolean("requireToolLore", false); } + public boolean getPerWorldSupportConfig() { return getConfig().getBoolean("enablePerWorldSupport", false); } + public boolean getRequireSneakingConfig() { return getConfig().getBoolean("requireSneaking", false); } + public boolean getInvisibleArmorStandsConfig() { return getConfig().getBoolean("armorStandVisibility", false); } + public boolean getInvisibleItemFramesConfig() { return getConfig().getBoolean("invisibleItemFrames", false); } + public boolean getSendToActionBarConfig() { return getConfig().getBoolean("sendMessagesToActionBar", false); } + public double getCoarseConfig() { return getConfig().getDouble("coarse"); } + public double getFineConfig() { return getConfig().getDouble("fine"); } + public double getMinScaleConfig() { return getConfig().getDouble("minScaleValue"); } + public double getMaxScaleConfig() { return getConfig().getDouble("maxScaleValue"); } + public String getToolTypeConfig() { return getConfig().getString("tool");} + public String getToolNameConfig() { return getConfig().getString("editToolName");} + public String getToolLoreConfig(){ return getConfig().getString("toolLore", null); } + public String getLanguageConfig(){ return getConfig().getString("lang"); } + public Integer getEditToolDataConfig() { return getConfig().getInt("toolData", Integer.MIN_VALUE); } + public List getAllowedWorldListConfig(){ return getConfig().getList("allowed-worlds", null); } + public Lang getLanguage(){ + return language; } public NamespacedKey getIconKey() { @@ -705,14 +306,6 @@ public NamespacedKey getIconKey() { return iconKey; } - /** - * For debugging ASE - Do not use this outside of Development or stuff - */ - public boolean isDebug() { - return debugFlag; - } - public void debugMsgHandler(String msg){ - if(isDebug()) getServer().getLogger().log(Level.WARNING, "[ASE-DEBUG]: {0}", msg); - } } + diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java b/src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java deleted file mode 100644 index ee1f3fb9..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java +++ /dev/null @@ -1,628 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import com.jeff_media.updatechecker.UpdateCheckSource; -import com.jeff_media.updatechecker.UpdateChecker; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; - -import io.github.rypofalem.armorstandeditor.modes.AdjustmentMode; -import io.github.rypofalem.armorstandeditor.modes.Axis; -import io.github.rypofalem.armorstandeditor.modes.EditMode; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.command.*; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.net.URL; -import java.util.*; - -public class CommandEx implements CommandExecutor, TabCompleter { - ArmorStandEditorPlugin plugin; - final String LISTMODE = ChatColor.YELLOW + "/ase mode <" + Util.getEnumList(EditMode.class) + ">"; - final String LISTAXIS = ChatColor.YELLOW + "/ase axis <" + Util.getEnumList(Axis.class) + ">"; - final String LISTADJUSTMENT = ChatColor.YELLOW + "/ase adj <" + Util.getEnumList(AdjustmentMode.class) + ">"; - final String LISTSLOT = ChatColor.YELLOW + "/ase slot <1-9>"; - final String HELP = ChatColor.YELLOW + "/ase help or /ase ?"; - final String VERSION = ChatColor.YELLOW + "/ase version"; - final String UPDATE = ChatColor.YELLOW + "/ase update"; - final String RELOAD = ChatColor.YELLOW + "/ase reload"; - final String GIVECUSTOMMODEL = ChatColor.YELLOW + "/ase give"; - final String GIVEPLAYERHEAD = ChatColor.YELLOW + "/ase playerhead "; - final String GETARMORSTATS = ChatColor.YELLOW + "/ase stats"; - Gson gson = new Gson(); - - public CommandEx(ArmorStandEditorPlugin armorStandEditorPlugin) { - this.plugin = armorStandEditorPlugin; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - - if (sender instanceof ConsoleCommandSender) { //Fix to Support #267 - if(plugin.isDebug()) plugin.debugMsgHandler("Sender is CONSOLE!"); - if (args.length == 0) { - sender.sendMessage(VERSION); - sender.sendMessage(HELP); - sender.sendMessage(RELOAD); - } else { - switch (args[0].toLowerCase()) { - case "reload" -> commandReloadConsole(sender); - case "help", "?" -> commandHelpConsole(sender); - case "version" -> commandVersionConsole(sender); - default -> { - sender.sendMessage(plugin.getLang().getMessage("noconsolecom", "warn")); - } - } - return true; - } - - } - - if (sender instanceof Player player && !getPermissionBasic(player)) { - if(plugin.isDebug()) plugin.debugMsgHandler("Sender is Player but asedit.basic is" + getPermissionBasic(player)); - sender.sendMessage(plugin.getLang().getMessage("nopermoption", "warn", "basic")); - return true; - } else { - Player player = (Player) sender; - - if(plugin.isDebug()) plugin.debugMsgHandler("Sender is Player and asedit.basic is" + getPermissionBasic(player)); - if (args.length == 0) { - player.sendMessage(LISTMODE); - player.sendMessage(LISTAXIS); - player.sendMessage(LISTSLOT); - player.sendMessage(LISTADJUSTMENT); - player.sendMessage(VERSION); - player.sendMessage(UPDATE); - player.sendMessage(HELP); - player.sendMessage(RELOAD); - player.sendMessage(GIVECUSTOMMODEL); - player.sendMessage(GIVEPLAYERHEAD); - player.sendMessage(GETARMORSTATS); - return true; - } - switch (args[0].toLowerCase()) { - case "mode" -> commandMode(player, args); - case "axis" -> commandAxis(player, args); - case "adj" -> commandAdj(player, args); - case "slot" -> commandSlot(player, args); - case "help", "?" -> commandHelp(player); - case "version" -> commandVersion(player); - case "update" -> commandUpdate(player); - case "give" -> commandGive(player); - case "playerhead" -> commandGivePlayerHead(player, args); - case "reload" -> commandReload(player); - case "stats" -> commandStats(player); - default -> { - sender.sendMessage(LISTMODE); - sender.sendMessage(LISTAXIS); - sender.sendMessage(LISTSLOT); - sender.sendMessage(LISTADJUSTMENT); - sender.sendMessage(VERSION); - sender.sendMessage(UPDATE); - sender.sendMessage(HELP); - sender.sendMessage(RELOAD); - sender.sendMessage(GIVECUSTOMMODEL); - sender.sendMessage(GIVEPLAYERHEAD); - sender.sendMessage(GETARMORSTATS); - } - } - return true; - } - } - - // Implemented to fix: - // https://github.com/Wolfieheart/ArmorStandEditor-Issues/issues/35 & - // https://github.com/Wolfieheart/ArmorStandEditor-Issues/issues/30 - See Remarks OTHER - private void commandGive(Player player) { - if (plugin.getAllowCustomModelData() && checkPermission(player, "give", true)) { - ItemStack stack = new ItemStack(plugin.getEditTool()); //Only Support EditTool at the MOMENT - ItemMeta meta = stack.getItemMeta(); - Objects.requireNonNull(meta).setCustomModelData(plugin.getCustomModelDataInt()); - meta.setUnbreakable(true); - meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - stack.setItemMeta(meta); - player.getInventory().addItem(stack); - player.sendMessage(plugin.getLang().getMessage("give", "info")); - } else { - player.sendMessage(plugin.getLang().getMessage("nogive", "warn")); - } - } - - private void commandGivePlayerHead(Player player, String[] args) { - - if (plugin.getAllowedToRetrievePlayerHead() && checkPermission(player, "head", true)) { - - if (args.length == 2) { - - //Get the Player head Texture - String skinTexture = getPlayerHeadTexture(args[1]); - - if (skinTexture == null) { - player.sendMessage(plugin.getLang().getMessage("playerheaderror", "warn")); - } - - //Create the ItemStack for the PlayerHead - ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD, 1); - - // Get the meta therefore - SkullMeta playerHeadMeta = (SkullMeta) playerHead.getItemMeta(); - assert playerHeadMeta != null; - - //Generate a Random UUID - GameProfile gameProfile = new GameProfile(UUID.randomUUID(), null); - gameProfile.getProperties().put("textures", new Property("textures", skinTexture)); - Field profileField = null; - - try { - profileField = playerHeadMeta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(playerHeadMeta, gameProfile); - } catch (NoSuchFieldException | IllegalAccessException e) { - player.sendMessage(plugin.getLang().getMessage("playerheaderror", "warn")); - } finally { - if (profileField != null) { - profileField.setAccessible(false); - } - } - - //Set the Display Name to be that of the Player Given - playerHeadMeta.setDisplayName(args[1]); - - //Set the Item Meta - playerHead.setItemMeta(playerHeadMeta); - - //Add the head to the Players Inventory + display PlayerHead Success Message - player.getInventory().addItem(playerHead); - player.sendMessage(plugin.getLang().getMessage("playerhead", "info")); - - //Let Admins know this command has been ran - for (Player onlineList : Bukkit.getOnlinePlayers()) { - if (onlineList.hasPermission("asedit.permpack.admin") && plugin.getAdminOnlyNotifications()) { - onlineList.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] " + player.getName() + "has just used the /ase playerhead command to get the head for " + args[1]); - } - } - } - } else { - player.sendMessage(plugin.getLang().getMessage("noplayerhead", "warn")); - } - } - - private String getPlayerHeadTexture(String playerName) { - try { - // Get the UUID of the Player in Question - URL uuidURL = new URL("https://api.mojang.com/users/profiles/minecraft/" + playerName); - try (InputStreamReader uuidURLReader = new InputStreamReader(uuidURL.openStream())) { - JsonObject uuidObject = gson.fromJson(uuidURLReader, JsonObject.class); - String uuid = uuidObject.get("id").getAsString(); - - - // Get the Skin from that UUID - URL skinURL = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false"); - try (InputStreamReader skinURLReader = new InputStreamReader(skinURL.openStream())) { - JsonObject skinObject = gson.fromJson(skinURLReader, JsonObject.class); - JsonObject skinTextureProperty = skinObject.get("properties").getAsJsonArray().get(0).getAsJsonObject(); - return skinTextureProperty.get("value").getAsString(); - } - } - } catch (IOException | IllegalStateException e) { - return null; - } - } - - - private void commandSlot(Player player, String[] args) { - - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("noslotnumcom", "warn")); - player.sendMessage(LISTSLOT); - } - - if (args.length > 1) { - try { - byte slot = (byte) (Byte.parseByte(args[1]) - 0b1); - if (slot >= 0 && slot < 9) { - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setCopySlot(slot); - } else { - player.sendMessage(LISTSLOT); - } - - } catch (NumberFormatException nfe) { - player.sendMessage(LISTSLOT); - } - } - } - - private void commandAdj(Player player, String[] args) { - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("noadjcom", "warn")); - player.sendMessage(LISTADJUSTMENT); - } - - if (args.length > 1) { - for (AdjustmentMode adj : AdjustmentMode.values()) { - if (adj.toString().toLowerCase().contentEquals(args[1].toLowerCase())) { - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setAdjMode(adj); - return; - } - } - player.sendMessage(LISTADJUSTMENT); - } - } - - private void commandAxis(Player player, String[] args) { - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("noaxiscom", "warn")); - player.sendMessage(LISTAXIS); - } - - if (args.length > 1) { - for (Axis axis : Axis.values()) { - if (axis.toString().toLowerCase().contentEquals(args[1].toLowerCase())) { - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setAxis(axis); - return; - } - } - player.sendMessage(LISTAXIS); - } - } - - private void commandMode(Player player, String[] args) { - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("nomodecom", "warn")); - player.sendMessage(LISTMODE); - } - - if (args.length > 1) { - for (EditMode mode : EditMode.values()) { - if (mode.toString().toLowerCase().contentEquals(args[1].toLowerCase())) { - if (args[1].equals("invisible") && !(checkPermission(player, "togglearmorstandvisibility", true) || plugin.getArmorStandVisibility())) return; - if (args[1].equals("itemframe") && !(checkPermission(player, "toggleitemframevisibility", true) || plugin.getItemFrameVisibility())) return; - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setMode(mode); - if(plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " chose the mode: " + mode); - return; - } - } - } - } - - private void commandHelp(Player player) { - player.closeInventory(); - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1f); - player.sendMessage(plugin.getLang().getMessage("help", "info", plugin.editTool.name())); - player.sendMessage(""); - player.sendMessage(plugin.getLang().getMessage("helptips", "info")); - player.sendMessage(""); - player.sendRawMessage(plugin.getLang().getMessage("helpurl", "")); - player.sendRawMessage(plugin.getLang().getMessage("helpdiscord", "")); - } - - private void commandHelpConsole(CommandSender sender) { - sender.sendMessage(plugin.getLang().getMessage("help", "info", plugin.editTool.name())); - sender.sendMessage(""); - sender.sendMessage(plugin.getLang().getMessage("helptips", "info")); - sender.sendMessage(""); - sender.sendMessage(plugin.getLang().getMessage("helpurl", "info")); - sender.sendMessage(plugin.getLang().getMessage("helpdiscord", "info")); - } - - private void commandUpdate(Player player) { - if (!(checkPermission(player, "update", true))) return; - - //Only Run if the Update Command Works - if (plugin.isDebug()) plugin.debugMsgHandler("Current ArmorStandEditor Version is: " + plugin.getArmorStandEditorVersion()); - if (plugin.getArmorStandEditorVersion().contains(".x")) { - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Update Checker will not work on Development Versions."); - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Report all bugs to: https://github.com/Wolfieheart/ArmorStandEditor/issues"); - } else { - if (!plugin.getHasFolia() && plugin.getRunTheUpdateChecker()) { - new UpdateChecker(plugin, UpdateCheckSource.SPIGOT, "" + ArmorStandEditorPlugin.SPIGOT_RESOURCE_ID + "").checkNow(player); //Runs Update Check - } else if (plugin.getHasFolia()) { - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Update Checker does not currently work on Folia."); - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Report all bugs to: https://github.com/Wolfieheart/ArmorStandEditor/issues"); - } else { - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Update Checker is not enabled on this server"); - } - } - } - - private void commandVersion(Player player) { - if (plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " permission check for asedit.update: " + getPermissionUpdate(player)); - - if (!(getPermissionUpdate(player))) return; - String verString = plugin.getArmorStandEditorVersion(); - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Version: " + verString); - } - - private void commandVersionConsole(CommandSender sender) { - String verString = plugin.getArmorStandEditorVersion(); - sender.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Version: " + verString); - } - - private void commandReload(Player player) { - if (plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " permission check for asedit.reload: " + getPermissionReload(player)); - - if (!(getPermissionReload(player))) return; - plugin.performReload(); - player.sendMessage(plugin.getLang().getMessage("reloaded", "")); - } - - private void commandReloadConsole(CommandSender sender) { - plugin.performReload(); - sender.sendMessage(plugin.getLang().getMessage("reloaded", "info")); - } - - private void commandStats(Player player) { - if (plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " permission check for asedit.stats: " + getPermissionStats(player)); - - if(getPermissionStats(player)) { - for (Entity e : player.getNearbyEntities(1, 1, 1)) { - if (e instanceof ArmorStand as) { - - //Calculation TIME - Might move this out later, but is OK here for now - double headX = as.getHeadPose().getX(); - headX = Math.toDegrees(headX); - headX = Math.rint(headX); - - double headY = as.getHeadPose().getY(); - headY = Math.toDegrees(headY); - headY = Math.rint(headY); - - double headZ = as.getHeadPose().getZ(); - headZ = Math.toDegrees(headZ); - headZ = Math.rint(headZ); - - //Body - double bodyX = as.getBodyPose().getX(); - bodyX = Math.toDegrees(bodyX); - bodyX = Math.rint(bodyX); - - double bodyY = as.getBodyPose().getY(); - bodyY = Math.toDegrees(bodyY); - bodyY = Math.rint(bodyY); - - double bodyZ = as.getBodyPose().getZ(); - bodyZ = Math.toDegrees(bodyZ); - bodyZ = Math.rint(bodyZ); - - - //Arms - double rightArmX = as.getRightArmPose().getX(); - rightArmX = Math.toDegrees(rightArmX); - rightArmX = Math.rint(rightArmX); - - double rightArmY = as.getRightArmPose().getY(); - rightArmY = Math.toDegrees(rightArmY); - rightArmY = Math.rint(rightArmY); - - double rightArmZ = as.getRightArmPose().getZ(); - rightArmZ = Math.toDegrees(rightArmZ); - rightArmZ = Math.rint(rightArmZ); - - - double leftArmX = as.getLeftArmPose().getX(); - leftArmX = Math.toDegrees(leftArmX); - leftArmX = Math.rint(leftArmX); - - double leftArmY = as.getLeftArmPose().getY(); - leftArmY = Math.toDegrees(leftArmY); - leftArmY = Math.rint(leftArmY); - - double leftArmZ = as.getLeftArmPose().getZ(); - leftArmZ = Math.toDegrees(leftArmZ); - leftArmZ = Math.rint(leftArmZ); - - //Legs - double rightLegX = as.getRightLegPose().getX(); - rightLegX = Math.toDegrees(rightLegX); - rightLegX = Math.rint(rightLegX); - - double rightLegY = as.getRightLegPose().getY(); - rightLegY = Math.toDegrees(rightLegY); - rightLegY = Math.rint(rightLegY); - - double rightLegZ = as.getRightLegPose().getZ(); - rightLegZ = Math.toDegrees(rightLegZ); - rightArmX = Math.rint(rightLegZ); - - double leftLegX = as.getLeftLegPose().getX(); - leftLegX = Math.toDegrees(leftLegX); - leftLegX = Math.rint(leftLegX); - - double leftLegY = as.getLeftLegPose().getY(); - leftLegY = Math.toDegrees(leftLegY); - leftLegY = Math.rint(leftLegY); - - double leftLegZ = as.getLeftLegPose().getZ(); - leftLegZ = Math.toDegrees(leftLegZ); - leftLegZ = Math.rint(leftLegZ); - - //Coordinates - float locationX = (float) as.getLocation().getX(); - float locationY = (float) as.getLocation().getY(); - float locationZ = (float) as.getLocation().getZ(); - - //Toggles - boolean isVisible = as.isVisible(); - boolean armsVisible = as.hasArms(); - boolean basePlateVisible = as.hasBasePlate(); - boolean isVulnerable = as.isInvulnerable(); - boolean hasGravity = as.hasGravity(); - boolean isSmall = as.isSmall(); - boolean isGlowing = as.isGlowing(); - boolean isLocked = plugin.scoreboard.getTeam(plugin.lockedTeam).hasEntry(as.getUniqueId().toString()); - - player.sendMessage(ChatColor.YELLOW + "----------- Armor Stand Statistics -----------"); - player.sendMessage(ChatColor.YELLOW + plugin.getLang().getMessage("stats")); - player.sendMessage(ChatColor.YELLOW + "Head: " + ChatColor.AQUA + headX + " / " + headY + " / " + headZ); - player.sendMessage(ChatColor.YELLOW + "Body: " + ChatColor.AQUA + bodyX + " / " + bodyY + " / " + bodyZ); - player.sendMessage(ChatColor.YELLOW + "Right Arm: " + ChatColor.AQUA + rightArmX + " / " + rightArmY + " / " + rightArmZ); - player.sendMessage(ChatColor.YELLOW + "Left Arm: " + ChatColor.AQUA + leftArmX + " / " + leftArmY + " / " + leftArmZ); - player.sendMessage(ChatColor.YELLOW + "Right Leg: " + ChatColor.AQUA + rightLegX + " / " + rightLegY + " / " + rightLegZ); - player.sendMessage(ChatColor.YELLOW + "Left Leg: " + ChatColor.AQUA + leftLegX + " / " + leftLegY + " / " + leftLegZ); - player.sendMessage(ChatColor.YELLOW + "Coordinates: " + ChatColor.AQUA + " X: " + locationX + " / Y: " + locationY + " / Z: " + locationZ); - player.sendMessage(ChatColor.YELLOW + "Is Visible: " + ChatColor.AQUA + isVisible + ". " + ChatColor.YELLOW + "Arms Visible: " + ChatColor.AQUA + armsVisible + ". " + ChatColor.YELLOW + "Base Plate Visible: " + ChatColor.AQUA + basePlateVisible); - player.sendMessage(ChatColor.YELLOW + "Is Vulnerable: " + ChatColor.AQUA + isVulnerable + ". " + ChatColor.YELLOW + "Affected by Gravity: " + ChatColor.AQUA + hasGravity); - player.sendMessage(ChatColor.YELLOW + "Is Small: " + ChatColor.AQUA + isSmall + ". " + ChatColor.YELLOW + "Is Glowing: " + ChatColor.AQUA + isGlowing + ". " + ChatColor.YELLOW + "Is Locked: " + ChatColor.AQUA + isLocked); - player.sendMessage(ChatColor.YELLOW + "----------------------------------------------"); - } - } - }else{ - player.sendMessage(plugin.getLang().getMessage("norangeforstats", "warn")); - } - } - - - private boolean checkPermission(Player player, String permName, boolean sendMessageOnInvalidation) { - if (permName.equalsIgnoreCase("paste")) { - permName = "copy"; - } - if (player.hasPermission("asedit." + permName.toLowerCase())) { - return true; - } else { - if (sendMessageOnInvalidation) { - player.sendMessage(plugin.getLang().getMessage("noperm", "warn")); - } - return false; - } - } - - private boolean getPermissionBasic(Player player) { - return checkPermission(player, "basic", false); - } - private boolean getPermissionGive(Player player) { - return checkPermission(player, "give", false); - } - private boolean getPermissionUpdate(Player player) { - return checkPermission(player, "update", false); - } - private boolean getPermissionReload(Player player) { - return checkPermission(player, "reload", false); - } - private boolean getPermissionPlayerHead(Player player) { - return checkPermission(player, "head", false); - } - private boolean getPermissionStats(Player player) { - return checkPermission(player, "stats", false); - } - - //REFACTOR COMPLETION - @Override - public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { - List argList = new ArrayList<>(); - Player player = (Player) sender; - - if (isCommandValid(command.getName())) { - - if (args.length == 1) { - argList.add("mode"); - argList.add("axis"); - argList.add("adj"); - argList.add("slot"); - argList.add("help"); - argList.add("?"); - - //Will Only work with permissions - if (getPermissionGive(player)) { - argList.add("give"); - } - if (getPermissionUpdate(player)) { - argList.add("update"); - } - if (getPermissionReload(player)) { - argList.add("reload"); - } - if (getPermissionPlayerHead(player) && plugin.getAllowedToRetrievePlayerHead()) { - argList.add("playerhead"); - } - - if (getPermissionStats(player)){ - argList.add("stats"); - } - } - - if (args.length == 2 && args[0].equalsIgnoreCase("mode")) { - argList.addAll(getModeOptions()); - } - - if (args.length == 2 && args[0].equalsIgnoreCase("axis")) { - argList.addAll(getAxisOptions()); - } - - if (args.length == 2 && args[0].equalsIgnoreCase("slot")) { - argList.addAll(getSlotOptions()); - } - - if (args.length == 2 && args[0].equalsIgnoreCase("adj")) { - argList.addAll(getAdjOptions()); - } - - return argList.stream().filter(a -> a.startsWith(args[0])).toList(); - } - - return Collections.emptyList(); - } - - private boolean isCommandValid(String commandName) { - return commandName.equalsIgnoreCase("ase") || - commandName.equalsIgnoreCase("armorstandeditor") || - commandName.equalsIgnoreCase("asedit"); - } - - private List getModeOptions() { - return List.of( - "None", "Invisible", "ShowArms", "Gravity", "BasePlate", - "Size", "Copy", "Paste", "Head", "Body", "LeftArm", - "RightArm", "LeftLeg", "RightLeg", "Placement", - "DisableSlots", "Rotate", "Equipment", "Reset", - "ItemFrame", "ItemFrameGlow", "Vulnerability", "ArmorStandGlow" - ); - } - - private List getAxisOptions() { - return List.of("X", "Y", "Z"); - } - - private List getSlotOptions() { - return List.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); - } - - private List getAdjOptions() { - return List.of("Coarse", "Fine"); - } - -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java b/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java index a842cfab..a1c26557 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java @@ -45,7 +45,6 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; public class Metrics { @@ -60,7 +59,7 @@ public class Metrics { * @param serviceId The id of the service. It can be found at What is my plugin id? */ - public Metrics(JavaPlugin plugin, int serviceId) { + public Metrics(Plugin plugin, int serviceId) { this.plugin = plugin; // Get the config file File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); @@ -93,21 +92,36 @@ public Metrics(JavaPlugin plugin, int serviceId) { boolean logErrors = config.getBoolean("logFailedRequests", false); boolean logSentData = config.getBoolean("logSentData", false); boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false); + boolean isFolia = false; + try { + isFolia = Class.forName("io.papermc.paper.threadedregions.RegionizedServer") != null; + } catch (Exception e) { + } metricsBase = - new MetricsBase( + new // See https://github.com/Bastian/bstats-metrics/pull/126 + // See https://github.com/Bastian/bstats-metrics/pull/126 + // See https://github.com/Bastian/bstats-metrics/pull/126 + // See https://github.com/Bastian/bstats-metrics/pull/126 + // See https://github.com/Bastian/bstats-metrics/pull/126 + // See https://github.com/Bastian/bstats-metrics/pull/126 + // See https://github.com/Bastian/bstats-metrics/pull/126 + MetricsBase( "bukkit", serverUUID, serviceId, enabled, this::appendPlatformData, this::appendServiceData, - submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask), + isFolia + ? null + : submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask), plugin::isEnabled, (message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error), (message) -> this.plugin.getLogger().log(Level.INFO, message), logErrors, logSentData, - logResponseStatusText); + logResponseStatusText, + false); } /** Shuts down the underlying scheduler service. */ @@ -158,7 +172,7 @@ private int getPlayerAmount() { public static class MetricsBase { /** The version of the Metrics class. */ - public static final String METRICS_VERSION = "3.0.2"; + public static final String METRICS_VERSION = "3.1.0"; private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s"; @@ -212,6 +226,7 @@ public static class MetricsBase { * @param logErrors Whether or not errors should be logged. * @param logSentData Whether or not the sent data should be logged. * @param logResponseStatusText Whether or not the response status text should be logged. + * @param skipRelocateCheck Whether or not the relocate check should be skipped. */ public MetricsBase( String platform, @@ -226,9 +241,16 @@ public MetricsBase( Consumer infoLogger, boolean logErrors, boolean logSentData, - boolean logResponseStatusText) { + boolean logResponseStatusText, + boolean skipRelocateCheck) { ScheduledThreadPoolExecutor scheduler = - new ScheduledThreadPoolExecutor(1, task -> new Thread(task, "bStats-Metrics")); + new ScheduledThreadPoolExecutor( + 1, + task -> { + Thread thread = new Thread(task, "bStats-Metrics"); + thread.setDaemon(true); + return thread; + }); // We want delayed tasks (non-periodic) that will execute in the future to be // cancelled when the scheduler is shutdown. // Otherwise, we risk preventing the server from shutting down even when @@ -248,7 +270,9 @@ public MetricsBase( this.logErrors = logErrors; this.logSentData = logSentData; this.logResponseStatusText = logResponseStatusText; - checkRelocation(); + if (!skipRelocateCheck) { + checkRelocation(); + } if (enabled) { // WARNING: Removing the option to opt-out will get your plugin banned from // bStats @@ -393,9 +417,9 @@ private static byte[] compress(final String str) throws IOException { } } - public static class SimplePie extends CustomChart { + public static class AdvancedBarChart extends CustomChart { - private final Callable callable; + private final Callable> callable; /** * Class constructor. @@ -403,25 +427,39 @@ public static class SimplePie extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public SimplePie(String chartId, Callable callable) { + public AdvancedBarChart(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - String value = callable.call(); - if (value == null || value.isEmpty()) { + JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { // Null = skip the chart return null; } - return new JsonObjectBuilder().appendField("value", value).build(); + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().length == 0) { + // Skip this invalid + continue; + } + allSkipped = false; + valuesBuilder.appendField(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); } } - public static class MultiLineChart extends CustomChart { + public static class SimplePie extends CustomChart { - private final Callable> callable; + private final Callable callable; /** * Class constructor. @@ -429,39 +467,25 @@ public static class MultiLineChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public MultiLineChart(String chartId, Callable> callable) { + public SimplePie(String chartId, Callable callable) { super(chartId); this.callable = callable; } @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { + String value = callable.call(); + if (value == null || value.isEmpty()) { // Null = skip the chart return null; } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); + return new JsonObjectBuilder().appendField("value", value).build(); } } - public static class AdvancedPie extends CustomChart { + public static class DrilldownPie extends CustomChart { - private final Callable> callable; + private final Callable>> callable; /** * Class constructor. @@ -469,29 +493,33 @@ public static class AdvancedPie extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public AdvancedPie(String chartId, Callable> callable) { + public DrilldownPie(String chartId, Callable>> callable) { super(chartId); this.callable = callable; } @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { + public JsonObjectBuilder.JsonObject getChartData() throws Exception { JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); + Map> map = callable.call(); if (map == null || map.isEmpty()) { // Null = skip the chart return null; } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; + boolean reallyAllSkipped = true; + for (Map.Entry> entryValues : map.entrySet()) { + JsonObjectBuilder valueBuilder = new JsonObjectBuilder(); + boolean allSkipped = true; + for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { + valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build()); } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); } - if (allSkipped) { + if (reallyAllSkipped) { // Null = skip the chart return null; } @@ -499,9 +527,9 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { } } - public static class SimpleBarChart extends CustomChart { + public static class SingleLineChart extends CustomChart { - private final Callable> callable; + private final Callable callable; /** * Class constructor. @@ -509,29 +537,25 @@ public static class SimpleBarChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public SimpleBarChart(String chartId, Callable> callable) { + public SingleLineChart(String chartId, Callable callable) { super(chartId); this.callable = callable; } @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { + int value = callable.call(); + if (value == 0) { // Null = skip the chart return null; } - for (Map.Entry entry : map.entrySet()) { - valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()}); - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); + return new JsonObjectBuilder().appendField("value", value).build(); } } - public static class AdvancedBarChart extends CustomChart { + public static class MultiLineChart extends CustomChart { - private final Callable> callable; + private final Callable> callable; /** * Class constructor. @@ -539,7 +563,7 @@ public static class AdvancedBarChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public AdvancedBarChart(String chartId, Callable> callable) { + public MultiLineChart(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @@ -547,14 +571,14 @@ public AdvancedBarChart(String chartId, Callable> callable) { @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); + Map map = callable.call(); if (map == null || map.isEmpty()) { // Null = skip the chart return null; } boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { // Skip this invalid continue; } @@ -569,9 +593,9 @@ protected JsonObjectBuilder.JsonObject getChartData() throws Exception { } } - public static class DrilldownPie extends CustomChart { + public static class AdvancedPie extends CustomChart { - private final Callable>> callable; + private final Callable> callable; /** * Class constructor. @@ -579,33 +603,29 @@ public static class DrilldownPie extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public DrilldownPie(String chartId, Callable>> callable) { + public AdvancedPie(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @Override - public JsonObjectBuilder.JsonObject getChartData() throws Exception { + protected JsonObjectBuilder.JsonObject getChartData() throws Exception { JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map> map = callable.call(); + Map map = callable.call(); if (map == null || map.isEmpty()) { // Null = skip the chart return null; } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JsonObjectBuilder valueBuilder = new JsonObjectBuilder(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build()); + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + // Skip this invalid + continue; } + allSkipped = false; + valuesBuilder.appendField(entry.getKey(), entry.getValue()); } - if (reallyAllSkipped) { + if (allSkipped) { // Null = skip the chart return null; } @@ -647,9 +667,9 @@ public JsonObjectBuilder.JsonObject getRequestJsonObject( protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception; } - public static class SingleLineChart extends CustomChart { + public static class SimpleBarChart extends CustomChart { - private final Callable callable; + private final Callable> callable; /** * Class constructor. @@ -657,19 +677,23 @@ public static class SingleLineChart extends CustomChart { * @param chartId The id of the chart. * @param callable The callable which is used to request the chart data. */ - public SingleLineChart(String chartId, Callable callable) { + public SimpleBarChart(String chartId, Callable> callable) { super(chartId); this.callable = callable; } @Override protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - int value = callable.call(); - if (value == 0) { + JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { // Null = skip the chart return null; } - return new JsonObjectBuilder().appendField("value", value).build(); + for (Map.Entry entry : map.entrySet()) { + valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()}); + } + return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); } } @@ -878,4 +902,5 @@ public String toString() { } } } -} \ No newline at end of file +} + diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java index 9d26c0e7..c22f9032 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java @@ -1,75 +1,37 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ package io.github.rypofalem.armorstandeditor; -import io.github.rypofalem.armorstandeditor.menu.PresetArmorPosesMenu; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.TextComponent; - -import io.github.rypofalem.armorstandeditor.api.*; -import io.github.rypofalem.armorstandeditor.menu.EquipmentMenu; -import io.github.rypofalem.armorstandeditor.menu.Menu; +import io.github.rypofalem.armorstandeditor.devtools.Debug; import io.github.rypofalem.armorstandeditor.modes.AdjustmentMode; -import io.github.rypofalem.armorstandeditor.modes.ArmorStandData; import io.github.rypofalem.armorstandeditor.modes.Axis; import io.github.rypofalem.armorstandeditor.modes.CopySlots; import io.github.rypofalem.armorstandeditor.modes.EditMode; - -import org.bukkit.*; +import lombok.Getter; import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scoreboard.Team; -import org.bukkit.util.EulerAngle; import java.util.ArrayList; import java.util.UUID; public class PlayerEditor { public ArmorStandEditorPlugin plugin; - Team team; + private Debug debug; private UUID uuid; - UUID armorStandID; - EditMode eMode; - AdjustmentMode adjMode; + private long lastOpened = Integer.MIN_VALUE; + + @Getter EditMode eMode; + @Getter AdjustmentMode adjMode; CopySlots copySlots; - Axis axis; + @Getter Axis axis; double eulerAngleChange; double degreeAngleChange; double movChange; - Menu chestMenu; - ArmorStand target; + //TODO: Add Menu Here once that is reimplemented + ArmorStand targeted; ArrayList targetList = null; - - //NEW: ItemFrame Stuff - ItemFrame frameTarget; - ArrayList frameTargetList = null; int targetIndex = 0; - int frameTargetIndex = 0; - EquipmentMenu equipMenu; - PresetArmorPosesMenu presetPoseMenu; long lastCancelled = 0; - public PlayerEditor(UUID uuid, ArmorStandEditorPlugin plugin) { + public PlayerEditor(UUID uuid, ArmorStandEditorPlugin plugin){ this.uuid = uuid; this.plugin = plugin; eMode = EditMode.NONE; @@ -79,566 +41,6 @@ public PlayerEditor(UUID uuid, ArmorStandEditorPlugin plugin) { eulerAngleChange = getManager().coarseAdj; degreeAngleChange = eulerAngleChange / Math.PI * 180; movChange = getManager().coarseMov; - chestMenu = new Menu(this); - } - - public void setMode(EditMode editMode) { - this.eMode = editMode; - sendMessage("setmode", editMode.toString().toLowerCase()); - } - - public void setAxis(Axis axis) { - this.axis = axis; - sendMessage("setaxis", axis.toString().toLowerCase()); - } - - public void setAdjMode(AdjustmentMode adjMode) { - this.adjMode = adjMode; - if (adjMode == AdjustmentMode.COARSE) { - eulerAngleChange = getManager().coarseAdj; - movChange = getManager().coarseMov; - } else { - eulerAngleChange = getManager().fineAdj; - movChange = getManager().fineMov; - } - degreeAngleChange = eulerAngleChange / Math.PI * 180; - sendMessage("setadj", adjMode.toString().toLowerCase()); - } - - public void setCopySlot(byte slot) { - copySlots.changeSlots(slot); - sendMessage("setslot", String.valueOf((slot + 1))); - } - - public void editArmorStand(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.basic")) { - - armorStand = attemptTarget(armorStand); - switch (eMode) { - case LEFTARM: - armorStand.setLeftArmPose(subEulerAngle(armorStand.getLeftArmPose())); - break; - case RIGHTARM: - armorStand.setRightArmPose(subEulerAngle(armorStand.getRightArmPose())); - break; - case BODY: - armorStand.setBodyPose(subEulerAngle(armorStand.getBodyPose())); - break; - case HEAD: - armorStand.setHeadPose(subEulerAngle(armorStand.getHeadPose())); - break; - case LEFTLEG: - armorStand.setLeftLegPose(subEulerAngle(armorStand.getLeftLegPose())); - break; - case RIGHTLEG: - armorStand.setRightLegPose(subEulerAngle(armorStand.getRightLegPose())); - break; - case SHOWARMS: - toggleArms(armorStand); - break; - case SIZE: - toggleSize(armorStand); - break; - case INVISIBLE: - toggleVisible(armorStand); - break; - case BASEPLATE: - togglePlate(armorStand); - break; - case GRAVITY: - toggleGravity(armorStand); - break; - case COPY: - copy(armorStand); - break; - case PASTE: - paste(armorStand); - break; - case PLACEMENT: - move(armorStand); - break; - case ROTATE: - rotate(armorStand); - break; - case DISABLESLOTS: - toggleDisableSlots(armorStand); - break; - case VULNERABILITY: - toggleInvulnerability(armorStand); - break; - case EQUIPMENT: - openEquipment(armorStand); - break; - case RESET: - resetPosition(armorStand); - break; - case GLOWING: - toggleGlowing(armorStand); - break; - case PRESET: - choosePreset(armorStand); - break; - case NONE: - default: - sendMessage("nomode", null); - break; - - } - }else return; - } - - public void editItemFrame(ItemFrame itemFrame) { - if (getPlayer().hasPermission("asedit.toggleitemframevisibility") || plugin.invisibleItemFrames) { - - //Generate a new ArmorStandManipulationEvent and call it out. - ItemFrameManipulatedEvent event = new ItemFrameManipulatedEvent(itemFrame, getPlayer()); - Bukkit.getPluginManager().callEvent(event); // Bukkit handles the call out - if (event.isCancelled()) return; //do nothing if cancelled - - switch (eMode) { - case ITEMFRAME: - toggleItemFrameVisible(itemFrame); - break; - case RESET: - itemFrame.setVisible(true); - break; - case NONE: - default: - sendMessage("nomodeif", null); - break; - } - }else return; - } - - private void openEquipment(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.equipment")) return; - //if (team != null && team.hasEntry(armorStand.getName())) return; //Do not allow editing if the ArmorStand is Disabled - equipMenu = new EquipmentMenu(this, armorStand); - equipMenu.open(); - } - - private void choosePreset(ArmorStand armorStand){ - if (!getPlayer().hasPermission("asedit.basic")) return; - presetPoseMenu = new PresetArmorPosesMenu(this, armorStand); - presetPoseMenu.openMenu(); - } - - public void reverseEditArmorStand(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.basic")) return; - - //Generate a new ArmorStandManipulationEvent and call it out. - ArmorStandManipulatedEvent event = new ArmorStandManipulatedEvent(armorStand, getPlayer()); - Bukkit.getPluginManager().callEvent(event); // Bukkit handles the call out //TODO: Folia Refactor - if (event.isCancelled()) return; //do nothing if cancelled - - armorStand = attemptTarget(armorStand); - switch (eMode) { - case LEFTARM: - armorStand.setLeftArmPose(addEulerAngle(armorStand.getLeftArmPose())); - break; - case RIGHTARM: - armorStand.setRightArmPose(addEulerAngle(armorStand.getRightArmPose())); - break; - case BODY: - armorStand.setBodyPose(addEulerAngle(armorStand.getBodyPose())); - break; - case HEAD: - armorStand.setHeadPose(addEulerAngle(armorStand.getHeadPose())); - break; - case LEFTLEG: - armorStand.setLeftLegPose(addEulerAngle(armorStand.getLeftLegPose())); - break; - case RIGHTLEG: - armorStand.setRightLegPose(addEulerAngle(armorStand.getRightLegPose())); - break; - case PLACEMENT: - reverseMove(armorStand); - break; - case ROTATE: - reverseRotate(armorStand); - break; - default: - editArmorStand(armorStand); - } - } - - private void move(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.movement")) return; - - //Generate a new ArmorStandManipulationEvent and call it out. - ArmorStandManipulatedEvent event = new ArmorStandManipulatedEvent(armorStand, getPlayer()); - Bukkit.getPluginManager().callEvent(event); // Bukkit handles the call out //TODO: Folia Refactor - if (event.isCancelled()) return; //do nothing if cancelled - - Location loc = armorStand.getLocation(); - switch (axis) { - case X: - loc.add(movChange, 0, 0); - break; - case Y: - loc.add(0, movChange, 0); - break; - case Z: - loc.add(0, 0, movChange); - break; - } - Scheduler.teleport(armorStand, loc); - } - - private void reverseMove(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.movement")) return; - Location loc = armorStand.getLocation(); - switch (axis) { - case X: - loc.subtract(movChange, 0, 0); - break; - case Y: - loc.subtract(0, movChange, 0); - break; - case Z: - loc.subtract(0, 0, movChange); - break; - } - Scheduler.teleport(armorStand, loc); - } - - private void rotate(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.rotation")) return; - Location loc = armorStand.getLocation(); - float yaw = loc.getYaw(); - loc.setYaw((yaw + 180 + (float) degreeAngleChange) % 360 - 180); - Scheduler.teleport(armorStand, loc); - } - - private void reverseRotate(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.rotation")) return; - Location loc = armorStand.getLocation(); - float yaw = loc.getYaw(); - loc.setYaw((yaw + 180 - (float) degreeAngleChange) % 360 - 180); - Scheduler.teleport(armorStand, loc); - } - - private void copy(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.copy")) { - copySlots.copyDataToSlot(armorStand); - sendMessage("copied", "" + (copySlots.currentSlot + 1)); - setMode(EditMode.PASTE); - }else{ - sendMessage("nopermoption", "warn", "copy"); - } - - } - - private void paste(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.paste")) { - ArmorStandData data = copySlots.getDataToPaste(); - if (data == null) return; - armorStand.setHeadPose(data.headPos); - armorStand.setBodyPose(data.bodyPos); - armorStand.setLeftArmPose(data.leftArmPos); - armorStand.setRightArmPose(data.rightArmPos); - armorStand.setLeftLegPose(data.leftLegPos); - armorStand.setRightLegPose(data.rightLegPos); - armorStand.setSmall(data.size); - armorStand.setGravity(data.gravity); - armorStand.setBasePlate(data.basePlate); - armorStand.setArms(data.showArms); - armorStand.setVisible(data.visible); - - //Only Paste the Items on the stand if in Creative Mode - // - Do not run elsewhere for good fecking reason! - if (this.getPlayer().getGameMode() == GameMode.CREATIVE) { - armorStand.getEquipment().setHelmet(data.head); - armorStand.getEquipment().setChestplate(data.body); - armorStand.getEquipment().setLeggings(data.legs); - armorStand.getEquipment().setBoots(data.feetsies); - armorStand.getEquipment().setItemInMainHand(data.rightHand); - armorStand.getEquipment().setItemInOffHand(data.leftHand); - } - sendMessage("pasted", "" + (copySlots.currentSlot + 1)); - }else{ - sendMessage("nopermoption", "warn", "paste"); - } - } - - private void resetPosition(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.reset")) { - armorStand.setHeadPose(new EulerAngle(0, 0, 0)); - armorStand.setBodyPose(new EulerAngle(0, 0, 0)); - armorStand.setLeftArmPose(new EulerAngle(0, 0, 0)); - armorStand.setRightArmPose(new EulerAngle(0, 0, 0)); - armorStand.setLeftLegPose(new EulerAngle(0, 0, 0)); - armorStand.setRightLegPose(new EulerAngle(0, 0, 0)); - } else{ - sendMessage("nopermoption", "warn", "reset"); - } - } - - private void toggleDisableSlots(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.disableSlots")){ - sendMessage("nopermoption", "warn", "disableslots"); - } else { - if (armorStand.hasEquipmentLock(EquipmentSlot.HAND, ArmorStand.LockType.REMOVING_OR_CHANGING)) { //Adds a lock to every slot or removes it - team = Scheduler.isFolia() ? null : plugin.scoreboard.getTeam(plugin.lockedTeam); - armorStandID = armorStand.getUniqueId(); - - for (final EquipmentSlot slot : EquipmentSlot.values()) { // UNLOCKED - armorStand.removeEquipmentLock(slot, ArmorStand.LockType.REMOVING_OR_CHANGING); - armorStand.removeEquipmentLock(slot, ArmorStand.LockType.ADDING); - } - getPlayer().playSound(getPlayer().getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.PLAYERS, 1.0f, 1.0f); - - if (team != null) { - team.removeEntry(armorStandID.toString()); - armorStand.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 50, 1, false, false)); //300 Ticks = 15 seconds - } - - - } else { - for (final EquipmentSlot slot : EquipmentSlot.values()) { //LOCKED - armorStand.addEquipmentLock(slot, ArmorStand.LockType.REMOVING_OR_CHANGING); - armorStand.addEquipmentLock(slot, ArmorStand.LockType.ADDING); - } - getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_ARMOR_EQUIP_IRON, SoundCategory.PLAYERS, 1.0f, 1.0f); - if (team != null) { - team.addEntry(armorStandID.toString()); - armorStand.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 50, 1, false, false)); //300 Ticks = 15 seconds - } - } - - sendMessage("disabledslots", null); - } - - } - - private void toggleInvulnerability(ArmorStand armorStand) { //See NewFeature-Request #256 for more info - if (getPlayer().hasPermission("asedit.toggleInvulnerability")) { - armorStand.setInvulnerable(!armorStand.isInvulnerable()); - sendMessage("toggleinvulnerability", String.valueOf(armorStand.isInvulnerable())); - } else { - sendMessage("nopermoption","warn", "vulnerability"); - } - } - - - private void toggleGravity(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.togglegravity")){ - armorStand.setGravity(!armorStand.hasGravity()); - sendMessage("setgravity", String.valueOf(armorStand.hasGravity()));//Fix for Wolfst0rm/ArmorStandEditor-Issues#6: Translation of On/Off Keys are broken - } else{ - sendMessage("nopermoption","warn", "gravity"); - } - - - - } - - void togglePlate(ArmorStand armorStand) { - if(getPlayer().hasPermission("asedit.togglebaseplate")){ - armorStand.setBasePlate(!armorStand.hasBasePlate()); - } else{ - sendMessage("nopermoption", "warn", "baseplate"); - } - - } - - void toggleGlowing(ArmorStand armorStand){ - if(getPlayer().hasPermission("asedit.togglearmorstandglow")){ - //Will only make it glow white - Not something we can do like with Locking. Do not request this! - //Otherwise, this simple function becomes a mess to maintain. As you would need a Team generated with each - //Color and I ain't going to impose that on servers. - armorStand.setGlowing(!armorStand.isGlowing()); - } else{ - sendMessage("nopermoption", "warn", "armorstandglow"); - } - } - - void toggleArms(ArmorStand armorStand) { - if(getPlayer().hasPermission("asedit.togglearms")){ - armorStand.setArms(!armorStand.hasArms()); - }else{ - sendMessage("nopermoption", "warn", "showarms"); - } - } - - void toggleVisible(ArmorStand armorStand) { - if(getPlayer().hasPermission("asedit.togglearmorstandvisibility") || plugin.getArmorStandVisibility()){ - armorStand.setVisible(!armorStand.isVisible()); - } else{ //Throw No Permission Message - sendMessage("nopermoption", "warn", "armorstandvisibility"); - } - } - - void toggleItemFrameVisible(ItemFrame itemFrame) { - if (getPlayer().hasPermission("asedit.toggleitemframevisibility") || plugin.invisibleItemFrames) { //Option to use perms or Config - itemFrame.setVisible(!itemFrame.isVisible()); - }else { - sendMessage("nopermoption", "warn", "itemframevisibility"); - } - } - - void toggleSize(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.togglesize")) { - armorStand.setSmall(!armorStand.isSmall()); - } else { - sendMessage("nopermoption", "warn", "size"); - } - } - - void cycleAxis(int i) { - int index = axis.ordinal(); - index += i; - index = index % Axis.values().length; - while (index < 0) { - index += Axis.values().length; - } - setAxis(Axis.values()[index]); - } - - private EulerAngle addEulerAngle(EulerAngle angle) { - switch (axis) { - case X: - angle = angle.setX(Util.addAngle(angle.getX(), eulerAngleChange)); - break; - case Y: - angle = angle.setY(Util.addAngle(angle.getY(), eulerAngleChange)); - break; - case Z: - angle = angle.setZ(Util.addAngle(angle.getZ(), eulerAngleChange)); - break; - default: - break; - } - return angle; - } - - private EulerAngle subEulerAngle(EulerAngle angle) { - switch (axis) { - case X: - angle = angle.setX(Util.subAngle(angle.getX(), eulerAngleChange)); - break; - case Y: - angle = angle.setY(Util.subAngle(angle.getY(), eulerAngleChange)); - break; - case Z: - angle = angle.setZ(Util.subAngle(angle.getZ(), eulerAngleChange)); - break; - default: - break; - } - return angle; - } - - - public void setTarget(ArrayList armorStands) { - if (armorStands == null || armorStands.isEmpty()) { - target = null; - targetList = null; - sendMessage("notarget", "armorstand"); - } else { - if (targetList == null) { - targetList = armorStands; - targetIndex = 0; - sendMessage("target", null); - } else { - boolean same = targetList.size() == armorStands.size(); - if (same) for (ArmorStand as : armorStands) { - same = targetList.contains(as); - if (!same) break; - } - - if (same) { - targetIndex = ++targetIndex % targetList.size(); - } else { - targetList = armorStands; - targetIndex = 0; - sendMessage("target", null); - } - } - - //API: ArmorStandTargetedEvent - ArmorStandTargetedEvent e = new ArmorStandTargetedEvent(targetList.get(targetIndex), getPlayer()); - Bukkit.getPluginManager().callEvent(e); //TODO: Folia Refactor - if (e.isCancelled()) return; - - target = targetList.get(targetIndex); - highlight(target); //NOTE: If Targeted and Locked, it displays the TEAM Color Glow: RED - // Otherwise, its unlocked and will display WHITE as its not in a team by default - - } - } - - - public void setFrameTarget(ArrayList itemFrames) { - if (itemFrames == null || itemFrames.isEmpty()) { - frameTarget = null; - frameTargetList = null; - sendMessage("notarget", "itemframe"); - } else { - - if (frameTargetList == null) { - frameTargetList = itemFrames; - frameTargetIndex = 0; - sendMessage("frametarget", null); - } else { - boolean same = frameTargetList.size() == itemFrames.size(); - if (same) for (final ItemFrame itemf : itemFrames) { - same = frameTargetList.contains(itemf); - if (!same) break; - } - - if (same) { - frameTargetIndex = ++frameTargetIndex % frameTargetList.size(); - } else { - frameTargetList = itemFrames; - frameTargetIndex = 0; - sendMessage("frametarget", null); - } - - //API: ItemFrameTargetedEvent - ItemFrameTargetedEvent e = new ItemFrameTargetedEvent(frameTargetList.get(frameTargetIndex), getPlayer()); - Bukkit.getPluginManager().callEvent(e); //TODO: Folia Refactor - if (e.isCancelled()) return; - - frameTarget = frameTargetList.get(frameTargetIndex); - } - } - } - - - - ArmorStand attemptTarget(ArmorStand armorStand) { - if (target == null - || !target.isValid() - || target.getWorld() != getPlayer().getWorld() - || target.getLocation().distanceSquared(getPlayer().getLocation()) > 100) - return armorStand; - armorStand = target; - return armorStand; - } - - void sendMessage(String path, String format, String option) { - String message = plugin.getLang().getMessage(path, format, option); - if (plugin.sendToActionBar) { - if (ArmorStandEditorPlugin.instance().getHasPaper() || ArmorStandEditorPlugin.instance().getHasSpigot()) { //Paper and Spigot having the same Interaction for sendToActionBar - plugin.getServer().getPlayer(getUUID()).spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(message)); - } else { - String rawText = plugin.getLang().getRawMessage(path, format, option); - String command = "title %s actionbar %s".formatted(plugin.getServer().getPlayer(getUUID()).getName(), rawText); - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - } - } else { - plugin.getServer().getPlayer(getUUID()).sendMessage(message); - } - } - - void sendMessage(String path, String option) { - sendMessage(path, "info", option); - } - - private void highlight(ArmorStand armorStand) { - armorStand.removePotionEffect(PotionEffectType.GLOWING); - armorStand.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 50, 1, false, false)); //300 Ticks = 15 seconds } public PlayerEditorManager getManager() { @@ -653,32 +55,4 @@ public UUID getUUID() { return uuid; } - public void openMenu() { - if (!isMenuCancelled()) { - Scheduler.runTaskLater(plugin, new OpenMenuTask(), 1); - } - } - - public void cancelOpenMenu() { - lastCancelled = getManager().getTime(); - } - - boolean isMenuCancelled() { - return getManager().getTime() - lastCancelled < 2; - } - - private class OpenMenuTask implements Runnable { - - @Override - public void run() { - if (isMenuCancelled()) return; - - //API: PlayerOpenMenuEvent - PlayerOpenMenuEvent event = new PlayerOpenMenuEvent(getPlayer()); - Bukkit.getPluginManager().callEvent(event); //TODO: Folia Refactor - if (event.isCancelled()) return; - - chestMenu.openMenu(); - } - } } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java index aa341a88..e1c9aee9 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java @@ -1,483 +1,33 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - package io.github.rypofalem.armorstandeditor; -import com.google.common.collect.ImmutableList; - -import io.github.rypofalem.armorstandeditor.api.ArmorStandRenameEvent; -import io.github.rypofalem.armorstandeditor.api.ItemFrameGlowEvent; -import io.github.rypofalem.armorstandeditor.menu.ASEHolder; -import io.github.rypofalem.armorstandeditor.protections.*; +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; +import io.github.rypofalem.armorstandeditor.util.Util; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.*; -import org.bukkit.event.*; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.player.*; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.persistence.PersistentDataType; -import org.bukkit.util.Vector; - -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.UUID; -//Manages PlayerEditors and Player Events related to editing armorstands public class PlayerEditorManager implements Listener { private ArmorStandEditorPlugin plugin; private HashMap players; - private ASEHolder menuHolder = new ASEHolder(); //Inventory holder that owns the main ase menu inventories for the plugin - private ASEHolder equipmentHolder = new ASEHolder(); //Inventory holder that owns the equipment menu - private ASEHolder presetHolder = new ASEHolder(); //Inventory Holder that owns the PresetArmorStand Post Menu double coarseAdj; double fineAdj; double coarseMov; double fineMov; private boolean ignoreNextInteract = false; private TickCounter counter; - private ArrayList as = null; - private ArrayList itemF = null; - private Integer noSize = 0; - - // Instantiate protections used to determine whether a player may edit an armor stand or item frame - //NOTE: GriefPreventionProtection is Depreciated as of v1.19.3-40 - private final List protections = ImmutableList.of( - new GriefDefenderProtection(), - new GriefPreventionProtection(), - new LandsProtection(), - new PlotSquaredProtection(), - new SkyblockProtection(), - new TownyProtection(), - new WorldGuardProtection(), - new BentoBoxProtection()); - PlayerEditorManager(ArmorStandEditorPlugin plugin) { + PlayerEditorManager(final ArmorStandEditorPlugin plugin) { this.plugin = plugin; players = new HashMap<>(); - coarseAdj = Util.FULL_CIRCLE / plugin.coarseRot; - fineAdj = Util.FULL_CIRCLE / plugin.fineRot; + coarseAdj = Util.FULL_CIRCLE / plugin.getCoarseConfig(); + fineAdj = Util.FULL_CIRCLE / plugin.getFineConfig(); coarseMov = 1; fineMov = .03125; // 1/32 counter = new TickCounter(); - Scheduler.runTaskTimer(plugin, counter, 1, 1); - } - - @EventHandler(priority = EventPriority.LOWEST) - void onArmorStandDamage(EntityDamageByEntityEvent event) { - if (!(event.getDamager() instanceof Player)) return; - Player player = (Player) event.getDamager(); - if (!plugin.isEditTool(player.getInventory().getItemInMainHand())) return; - if (!((event.getEntity() instanceof ArmorStand) || event.getEntity() instanceof ItemFrame)) { - event.setCancelled(true); - getPlayerEditor(player.getUniqueId()).openMenu(); - return; - } - if (event.getEntity() instanceof ArmorStand) { - ArmorStand as = (ArmorStand) event.getEntity(); - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - event.setCancelled(true); - if (canEdit(player, as)) - applyLeftTool(player, as); - } else if (event.getEntity() instanceof ItemFrame) { - ItemFrame itemf = (ItemFrame) event.getEntity(); - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - event.setCancelled(true); - if (canEdit(player, itemf)) applyLeftTool(player, itemf); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - void onArmorStandInteract(PlayerInteractAtEntityEvent event) { - if (ignoreNextInteract) return; - if (event.getHand() != EquipmentSlot.HAND) return; - Player player = event.getPlayer(); - if (!((event.getRightClicked() instanceof ArmorStand) || event.getRightClicked() instanceof ItemFrame)) return; - - if (event.getRightClicked() instanceof ArmorStand) { - ArmorStand as = (ArmorStand) event.getRightClicked(); - - if (!canEdit(player, as)) return; - if (plugin.isEditTool(player.getInventory().getItemInMainHand())) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - event.setCancelled(true); - applyRightTool(player, as); - return; - } - - - //Attempt rename - if (player.getInventory().getItemInMainHand().getType() == Material.NAME_TAG && player.hasPermission("asedit.rename")) { - ItemStack nameTag = player.getInventory().getItemInMainHand(); - String name; - if (nameTag.getItemMeta() != null && nameTag.getItemMeta().hasDisplayName()) { - name = nameTag.getItemMeta().getDisplayName().replace('&', ChatColor.COLOR_CHAR); - } else { - name = null; - } - - //API: ArmorStandRenameEvent - ArmorStandRenameEvent e = new ArmorStandRenameEvent(as, player, name); - Bukkit.getPluginManager().callEvent(e); - if (e.isCancelled()) return; - - if (name == null) { - as.setCustomName(null); - as.setCustomNameVisible(false); - event.setCancelled(true); - } else if (!name.equals("")) { // nametag is not blank - event.setCancelled(true); - - if ((player.getGameMode() != GameMode.CREATIVE)) { - if (nameTag.getAmount() > 1) { - nameTag.setAmount(nameTag.getAmount() - 1); - } else { - nameTag = new ItemStack(Material.AIR); - } - player.getInventory().setItemInMainHand(nameTag); - } - - //minecraft will set the name after this event even if the event is cancelled. - //change it 1 tick later to apply formatting without it being overwritten - Scheduler.runTaskLater(plugin, () -> { - as.setCustomName(name); - as.setCustomNameVisible(true); - }, 1); - } - } - } else if (event.getRightClicked() instanceof ItemFrame) { - ItemFrame itemFrame = (ItemFrame) event.getRightClicked(); - - if (!canEdit(player, itemFrame)) return; - if (plugin.isEditTool(player.getInventory().getItemInMainHand())) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - if (!itemFrame.getItem().getType().equals(Material.AIR)) { - event.setCancelled(true); - } - applyRightTool(player, itemFrame); - return; - } - - if (player.getInventory().getItemInMainHand().getType().equals(Material.GLOW_INK_SAC) //attempt glowing - && player.hasPermission("asedit.basic") - && plugin.glowItemFrames && player.isSneaking()) { - - ItemFrameGlowEvent e = new ItemFrameGlowEvent(itemFrame, player); - Bukkit.getPluginManager().callEvent(e); - if (e.isCancelled()) return; - - ItemStack glowSacs = player.getInventory().getItemInMainHand(); - ItemStack contents = null; - Rotation rotation = null; - if (itemFrame.getItem().getType() != Material.AIR) { - contents = itemFrame.getItem(); //save item - rotation = itemFrame.getRotation(); // save item rotation - } - Location itemFrameLocation = itemFrame.getLocation(); - BlockFace facing = itemFrame.getFacing(); - - if (player.getGameMode() != GameMode.CREATIVE) { - if (glowSacs.getAmount() > 1) { - glowSacs.setAmount(glowSacs.getAmount() - 1); - } else glowSacs = new ItemStack(Material.AIR); - } - - itemFrame.remove(); - GlowItemFrame glowFrame = (GlowItemFrame) player.getWorld().spawnEntity(itemFrameLocation, EntityType.GLOW_ITEM_FRAME); - glowFrame.setFacingDirection(facing); - if (contents != null) { - glowFrame.setItem(contents); - glowFrame.setRotation(rotation); - } - - } - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - void onArmorStandBreak(EntityDamageByEntityEvent event) { // Fixes issue #309 - if (!(event.getDamager() instanceof Player)) return; // If the damager is not a player, ignore. - if (!(event.getEntity() instanceof ArmorStand)) return; // If the damaged entity is not an ArmorStand, ignore. - - if (event.getEntity() instanceof ArmorStand entityAS) { - // Check if the ArmorStand is invulnerable and if the damager is a player. - if (entityAS.isInvulnerable() && event.getDamager() instanceof Player p) { - // Check if the player is in Creative mode. - if (p.getGameMode() == GameMode.CREATIVE) { - // If the player is in Creative mode and the ArmorStand is invulnerable, - // cancel the event to prevent breaking the ArmorStand. - p.sendMessage(plugin.getLang().getMessage("unabledestroycreative")); - event.setCancelled(true); // Cancel the event to prevent ArmorStand destruction. - } - } - } - - if(event.getEntity() instanceof ArmorStand entityAS && entityAS.isDead()){ - //TODO: Find a more permanent fix for "Once you destroy that armor stand, the armor stand will keep it's name and colour given by the name tag." THIS IS A TEMP SOLUTION FOR NOW. - event.getEntity().setCustomName(null); - event.getEntity().setCustomNameVisible(false); - event.setCancelled(false); - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onSwitchHands(PlayerSwapHandItemsEvent event) { - if (!plugin.isEditTool(event.getOffHandItem())) return; //event assumes they are already switched - event.setCancelled(true); - Player player = event.getPlayer(); - - as = getTargets(player); //Get All ArmorStand closest to player - itemF = getFrameTargets(player); //Get ItemFrame Closest to Player - - - // Check for null and empty lists - if (as != null && itemF != null && !as.isEmpty() && !itemF.isEmpty()) { - getPlayerEditor(player.getUniqueId()).sendMessage("doubletarget", "warn"); - } else if (as != null && !as.isEmpty()) { - getPlayerEditor(player.getUniqueId()).setTarget(as); - } else if (itemF != null && !itemF.isEmpty()) { - getPlayerEditor(player.getUniqueId()).setFrameTarget(itemF); - } else { - getPlayerEditor(player.getUniqueId()).sendMessage("nodoubletarget","warn"); - } + Bukkit.getServer().getScheduler().runTaskTimer(plugin, counter, 0, 1); } - private ArrayList getTargets(Player player) { - Location eyeLaser = player.getEyeLocation(); - Vector direction = player.getLocation().getDirection(); - ArrayList armorStands = new ArrayList<>(); - - double STEPSIZE = .5; - Vector STEP = direction.multiply(STEPSIZE); - double RANGE = 10; - double LASERRADIUS = .3; - List nearbyEntities = player.getNearbyEntities(RANGE, RANGE, RANGE); - if (nearbyEntities.isEmpty()) return null; - - for (double i = 0; i < RANGE; i += STEPSIZE) { - List nearby = (List) player.getWorld().getNearbyEntities(eyeLaser, LASERRADIUS, LASERRADIUS, LASERRADIUS); - if (!nearby.isEmpty()) { - boolean endLaser = false; - for (Entity e : nearby) { - if (e instanceof ArmorStand stand) { - armorStands.add(stand); - endLaser = true; - } - } - - if (endLaser) break; - } - if (eyeLaser.getBlock().getType().isSolid()) break; - eyeLaser.add(STEP); - } - return armorStands; - } - - private ArrayList getFrameTargets(Player player) { - Location eyeLaser = player.getEyeLocation(); - Vector direction = player.getLocation().getDirection(); - ArrayList itemFrames = new ArrayList<>(); - - double STEPSIZE = .5; - Vector STEP = direction.multiply(STEPSIZE); - double RANGE = 10; - double LASERRADIUS = .3; - List nearbyEntities = player.getNearbyEntities(RANGE, RANGE, RANGE); - if (nearbyEntities.isEmpty()) return null; - - for (double i = 0; i < RANGE; i += STEPSIZE) { - List nearby = (List) player.getWorld().getNearbyEntities(eyeLaser, LASERRADIUS, LASERRADIUS, LASERRADIUS); - if (!nearby.isEmpty()) { - boolean endLaser = false; - for (Entity e : nearby) { - if (e instanceof ItemFrame frame) { - itemFrames.add(frame); - endLaser = true; - } - } - - if (endLaser) break; - } - if (eyeLaser.getBlock().getType().isSolid()) break; - eyeLaser.add(STEP); - } - - return itemFrames; - } - - - boolean canEdit(Player player, Entity entity) { - //Get the Entity being checked for editing - Block block = entity.getLocation().getBlock(); - - // Check if all protections allow this edit, if one fails, don't allow edit - return protections.stream().allMatch(protection -> protection.checkPermission(block, player)); - } - - void applyLeftTool(Player player, ArmorStand as) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).editArmorStand(as); - } - - void applyLeftTool(Player player, ItemFrame itemf) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).editItemFrame(itemf); - } - - void applyRightTool(Player player, ItemFrame itemf) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).editItemFrame(itemf); - } - - void applyRightTool(Player player, ArmorStand as) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).reverseEditArmorStand(as); - } - - //Unused? - @EventHandler(priority = EventPriority.LOWEST) - void onRightClickTool(PlayerInteractEvent e) { - if (!(e.getAction() == Action.LEFT_CLICK_AIR - || e.getAction() == Action.RIGHT_CLICK_AIR - || e.getAction() == Action.LEFT_CLICK_BLOCK - || e.getAction() == Action.RIGHT_CLICK_BLOCK)) return; - Player player = e.getPlayer(); - if (!plugin.isEditTool(player.getInventory().getItemInMainHand())) return; - if (plugin.requireSneaking && !player.isSneaking()) return; - if (!player.hasPermission("asedit.basic")) return; - if (plugin.enablePerWorld && (!plugin.allowedWorldList.contains(player.getWorld().getName()))) { - //Implementation for Per World ASE - getPlayerEditor(player.getUniqueId()).sendMessage("notincorrectworld", "warn"); - e.setCancelled(true); - return; - } - e.setCancelled(true); - getPlayerEditor(player.getUniqueId()).openMenu(); - } - - @EventHandler(priority = EventPriority.NORMAL) - void onScrollNCrouch(PlayerItemHeldEvent e) { - Player player = e.getPlayer(); - if (!player.isSneaking()) return; - if (!plugin.isEditTool(player.getInventory().getItem(e.getPreviousSlot()))) return; - - e.setCancelled(true); - if (e.getNewSlot() == e.getPreviousSlot() + 1 || (e.getNewSlot() == 0 && e.getPreviousSlot() == 8)) { - getPlayerEditor(player.getUniqueId()).cycleAxis(1); - } else if (e.getNewSlot() == e.getPreviousSlot() - 1 || (e.getNewSlot() == 8 && e.getPreviousSlot() == 0)) { - getPlayerEditor(player.getUniqueId()).cycleAxis(-1); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - void onPlayerMenuSelect(InventoryClickEvent e) { - if (e.getInventory().getHolder() == null) return; - if (!(e.getInventory().getHolder() instanceof ASEHolder)) return; - if (e.getInventory().getHolder() == menuHolder) { - e.setCancelled(true); - ItemStack item = e.getCurrentItem(); - if (item != null && item.hasItemMeta()) { - Player player = (Player) e.getWhoClicked(); - String command = item.getItemMeta().getPersistentDataContainer().get(plugin.getIconKey(), PersistentDataType.STRING); - if (command != null) { - player.performCommand(command); - return; - } - } - } - if (e.getInventory().getHolder() == equipmentHolder) { - ItemStack item = e.getCurrentItem(); - if (item == null) return; - if (item.getItemMeta() == null) return; - if (item.getItemMeta().getPersistentDataContainer().has(plugin.getIconKey(), PersistentDataType.STRING)) { - e.setCancelled(true); - } - } - - if (e.getInventory().getHolder() == presetHolder){ - e.setCancelled(true); - ItemStack item = e.getCurrentItem(); - if(item != null && item.hasItemMeta()){ - Player player = (Player) e.getWhoClicked(); - String itemName = item.getItemMeta().getDisplayName(); - PlayerEditor pe = players.get(player.getUniqueId()); - pe.presetPoseMenu.handlePresetPose(itemName, player); - } - } - } - - - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - void onPlayerMenuClose(InventoryCloseEvent e) { - if (e.getInventory().getHolder() == null) return; - if (!(e.getInventory().getHolder() instanceof ASEHolder)) return; - if (e.getInventory().getHolder() == equipmentHolder) { - PlayerEditor pe = players.get(e.getPlayer().getUniqueId()); - pe.equipMenu.equipArmorstand(); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - void onPlayerLogOut(PlayerQuitEvent e) { - removePlayerEditor(e.getPlayer().getUniqueId()); - } - - public PlayerEditor getPlayerEditor(UUID uuid) { - return players.containsKey(uuid) ? players.get(uuid) : addPlayerEditor(uuid); - } - - PlayerEditor addPlayerEditor(UUID uuid) { - PlayerEditor pe = new PlayerEditor(uuid, plugin); - players.put(uuid, pe); - return pe; - } - - private void removePlayerEditor(UUID uuid) { - players.remove(uuid); - } - - public ASEHolder getMenuHolder() { - return menuHolder; - } - - public ASEHolder getEquipmentHolder() { - return equipmentHolder; - } - - public ASEHolder getPresetHolder() { - return presetHolder; - } - - long getTime() { - return counter.ticks; - } - - - class TickCounter implements Runnable { long ticks = 0; //I am optimistic diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java deleted file mode 100644 index 9df80d7a..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandManipulatedEvent extends ArmorStandEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ArmorStandManipulatedEvent(ArmorStand armorStand, Player player) { - super(armorStand); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java new file mode 100644 index 00000000..bc35b053 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java @@ -0,0 +1,48 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ArmorStandEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class ArmorStandManipulationEvent extends ArmorStandEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + + public ArmorStandManipulationEvent(ArmorStand armorStand, Player player) { + super(armorStand); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java index 5b243872..1607e82b 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java @@ -1,36 +1,20 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ package io.github.rypofalem.armorstandeditor.api; +import io.github.rypofalem.armorstandeditor.api.interfaces.ArmorStandEvent; import lombok.Getter; import lombok.Setter; - import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; public class ArmorStandRenameEvent extends ArmorStandEvent implements Cancellable { + @Getter @Setter - private boolean cancelled = false; + private boolean isCancelled = false; @Getter @Setter protected String name; @@ -56,4 +40,13 @@ public HandlerList getHandlers() { return (handlers); } + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java deleted file mode 100644 index 196a039e..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandTargetedEvent extends ArmorStandEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ArmorStandTargetedEvent(ArmorStand armorStand, Player player) { - super(armorStand); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java new file mode 100644 index 00000000..4b0bec19 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java @@ -0,0 +1,48 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ArmorStandEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class ArmorStandTargettedEvent extends ArmorStandEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + + public ArmorStandTargettedEvent(ArmorStand armorStand, Player player) { + super(armorStand); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java new file mode 100644 index 00000000..b79c13cc --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java @@ -0,0 +1,50 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.OpenMenuEvent; +import io.github.rypofalem.armorstandeditor.menu.EditorMenu; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class EquipmentMenuOpenedEvent extends OpenMenuEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + @Getter + protected final EditorMenu edtMenu; + + private static final HandlerList HANDLERS = new HandlerList(); + + public EquipmentMenuOpenedEvent(Player player, EditorMenu edtMenu){ + super(player, edtMenu); + this.player = player; + this.edtMenu = edtMenu; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java index 7f5cdc97..c1ad84c2 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java @@ -1,5 +1,6 @@ package io.github.rypofalem.armorstandeditor.api; +import io.github.rypofalem.armorstandeditor.api.interfaces.ItemFrameEvent; import lombok.Getter; import lombok.Setter; @@ -11,7 +12,7 @@ public class ItemFrameGlowEvent extends ItemFrameEvent implements Cancellable { @Getter @Setter - private boolean cancelled = false; + private boolean isCancelled = false; @Getter protected final Player player; @@ -32,4 +33,14 @@ public static HandlerList getHandlerList() { public HandlerList getHandlers() { return (handlers); } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } } \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java deleted file mode 100644 index 9c80c077..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ItemFrameEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameManipulatedEvent extends ItemFrameEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameManipulatedEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} - diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java new file mode 100644 index 00000000..eabee5da --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java @@ -0,0 +1,46 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ItemFrameEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameManipulationEvent extends ItemFrameEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + public ItemFrameManipulationEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java deleted file mode 100644 index 1c9c162c..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameTargetedEvent extends ItemFrameEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameTargetedEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java new file mode 100644 index 00000000..aaa4bad8 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java @@ -0,0 +1,46 @@ +package io.github.rypofalem.armorstandeditor.api; +import io.github.rypofalem.armorstandeditor.api.interfaces.ItemFrameEvent; +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameTargettedEvent extends ItemFrameEvent implements Cancellable { + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + public ItemFrameTargettedEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} + diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/MainMenuOpenedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/MainMenuOpenedEvent.java new file mode 100644 index 00000000..7ae4330d --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/MainMenuOpenedEvent.java @@ -0,0 +1,49 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.OpenMenuEvent; +import io.github.rypofalem.armorstandeditor.menu.EditorMenu; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class MainMenuOpenedEvent extends OpenMenuEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + @Getter + protected final EditorMenu edtMenu; + + private static final HandlerList HANDLERS = new HandlerList(); + + public MainMenuOpenedEvent(Player player, EditorMenu edtMenu) { + super(player, edtMenu); + this.player = player; + this.edtMenu = edtMenu; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + public static HandlerList getHandlerList() { + return HANDLERS; + } + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java deleted file mode 100644 index 908b6693..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class PlayerOpenMenuEvent extends Event implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public PlayerOpenMenuEvent(Player player) { - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ArmorStandEvent.java similarity index 94% rename from src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java rename to src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ArmorStandEvent.java index e82445c1..28a128da 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ArmorStandEvent.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.github.rypofalem.armorstandeditor.api; +package io.github.rypofalem.armorstandeditor.api.interfaces; import lombok.Getter; diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ItemFrameEvent.java similarity index 94% rename from src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java rename to src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ItemFrameEvent.java index d6358613..61a5502f 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ItemFrameEvent.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.github.rypofalem.armorstandeditor.api; +package io.github.rypofalem.armorstandeditor.api.interfaces; import lombok.Getter; diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java new file mode 100644 index 00000000..2d287e7d --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java @@ -0,0 +1,21 @@ +package io.github.rypofalem.armorstandeditor.api.interfaces; + +import io.github.rypofalem.armorstandeditor.menu.EditorMenu; +import lombok.Getter; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; + +public abstract class OpenMenuEvent extends Event { + + @Getter + protected final Player player; + + @Getter + protected final EditorMenu edtMenu; + + public OpenMenuEvent(Player player, EditorMenu edtMenu){ + this.player = player; + this.edtMenu = edtMenu; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/devtools/Debug.java b/src/main/java/io/github/rypofalem/armorstandeditor/devtools/Debug.java new file mode 100644 index 00000000..eff31da5 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/devtools/Debug.java @@ -0,0 +1,24 @@ +package io.github.rypofalem.armorstandeditor.devtools; + +import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; + +import java.util.logging.Level; + +public class Debug { + + boolean debugTurnedOn; + private final ArmorStandEditorPlugin plugin; + String debugOutputToConsole; + + public Debug(ArmorStandEditorPlugin plugin) { + this.plugin = plugin; + } + + public void log(String msg) { + debugTurnedOn = plugin.isDebug(); + if (!debugTurnedOn) return; + + debugOutputToConsole = String.format("[ArmorStandEditor-Debug] %s", msg); + plugin.getServer().getLogger().log(Level.INFO, debugOutputToConsole); + } +} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java b/src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java new file mode 100644 index 00000000..57b9a69e --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java @@ -0,0 +1,84 @@ +package io.github.rypofalem.armorstandeditor.language; + +import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class Lang { + + protected static final String DEFAULT_LANG = "en_us.yml"; + protected final ArmorStandEditorPlugin plugin; + private YamlConfiguration langConfig = null; + private YamlConfiguration defConfig = null; + private File langFile = null; + + + public Lang(final String langFilename, ArmorStandEditorPlugin plugin) { + this.plugin = plugin; + reloadLang(langFilename); + } + + public void reloadLang(String langFileName){ + if(langFileName == null) langFileName = DEFAULT_LANG; + File langFolder = new File(plugin.getDataFolder().getPath() + File.separator + "lang"); + langFile = new File(langFolder, langFileName); + InputStream inputStream = plugin.getResource("lang" + "/" + DEFAULT_LANG); + Reader defaultLangStream = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + defConfig = YamlConfiguration.loadConfiguration(defaultLangStream); + inputStream = null; + try{ + inputStream = new FileInputStream(langFile); + } catch (FileNotFoundException e){ + e.printStackTrace(); + return; + } + Reader langStream = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + langConfig = YamlConfiguration.loadConfiguration(langStream); + } + + //path: yml path to message in language file + //format: yml path to format in language file + //option: path-specific variable that may be used + public String getMessage(String path, String format, String option) { + if (langConfig == null) reloadLang(langFile.getName()); + if (path == null) return ""; + if (option == null) option = ""; + + format = getFormat(format); + for (int i = 0; i < format.length(); i += 2) { //place formatting symbol before each character + format = format.substring(0, i) + '\u00A7' + format.substring(i); + } + + if (getString(path + "." + option) != null) option = getString(path + "." + option); + String message = format + getString(path + ".msg"); + message = message.replace("", option); + return message; + } + + + public String getMessage(String path, String format) { + return getMessage(path, format, null); + } + + public String getMessage(String path) { + return getMessage(path, "info"); + } + + private String getFormat(String format) { + format = getString(format); + return format == null ? "" : format; + } + + private String getString(String path) { + String message = null; + if (langConfig.contains(path)) { + message = langConfig.getString(path); + } else if (defConfig.contains(path)) { + message = defConfig.getString(path); + } + return message; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java b/src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java deleted file mode 100644 index 16b6e783..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -package io.github.rypofalem.armorstandeditor.language; - -import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; - -import org.bukkit.ChatColor; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.*; -import java.nio.charset.StandardCharsets; - -public class Language { - final String DEFAULT_LANG = "en_US.yml"; - private YamlConfiguration langConfig = null; - private YamlConfiguration defConfig = null; - private File langFile = null; - ArmorStandEditorPlugin plugin; - - public Language(String langFileName, ArmorStandEditorPlugin plugin) { - this.plugin = plugin; - reloadLang(langFileName); - } - - public void reloadLang(String langFileName) { - if (langFileName == null) langFileName = DEFAULT_LANG; - File langFolder = new File(plugin.getDataFolder().getPath() + File.separator + "lang"); - langFile = new File(langFolder, langFileName); - - InputStream input = plugin.getResource("lang" + "/" + DEFAULT_LANG); //getResource doesn't accept File.seperator on windows, need to hardcode unix seperator "/" instead - assert input != null; - Reader defaultLangStream = new InputStreamReader(input, StandardCharsets.UTF_8); - defConfig = YamlConfiguration.loadConfiguration(defaultLangStream); - - input = null; - try { - input = new FileInputStream(langFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - return; - } - - Reader langStream = new InputStreamReader(input, StandardCharsets.UTF_8); - langConfig = YamlConfiguration.loadConfiguration(langStream); - } - - //path: yml path to message in language file - //format: yml path to format in language file - //option: path-specific variable that may be used - public String getMessage(String path, String format, String option) { - if (langConfig == null) reloadLang(langFile.getName()); - if (path == null) return ""; - if (option == null) option = ""; - - format = getFormat(format); - for (int i = 0; i < format.length(); i += 2) { //place formatting symbol before each character - format = format.substring(0, i) + ChatColor.COLOR_CHAR + format.substring(i); - } - - if (getString(path + "." + option) != null) option = getString(path + "." + option); - String message = format + getString(path + ".msg"); - message = message.replace("", option); - return message; - } - - public String getMessage(String path, String format) { - return getMessage(path, format, null); - } - - public String getMessage(String path) { - return getMessage(path, "info"); - } - - public String getRawMessage(String path, String format, String option) { - String message = ChatColor.stripColor(getMessage(path, format, option)); - format = getFormat(format); - ChatColor color = ChatColor.WHITE; - String bold = "" , italic = "" , underlined = "" , obfuscated = "" , strikethrough = ""; - for (int i = 0; i < format.length(); i++) { - ChatColor code = ChatColor.getByChar(format.charAt(i)); - switch (code) { - case MAGIC: - obfuscated = ", \"obfuscated\": true"; - break; - case BOLD: - bold = ", \"bold\": true"; - break; - case STRIKETHROUGH: - strikethrough = ", \"strikethrough\": true"; - break; - case UNDERLINE: - underlined = ", \"underlined\": true"; - break; - case ITALIC: - italic = ", \"italic\": true"; - break; - default: color = !code.isColor() ? color : code; - } - } - return "{\"text\":\"%s\", \"color\":\"%s\"%s%s%s%s%s}".formatted(message, color.name().toLowerCase(), - obfuscated, bold, strikethrough, underlined, italic); - } - - private String getFormat(String format) { - format = getString(format); - return format == null ? "" : format; - } - - private String getString(String path) { - String message = null; - if (langConfig.contains(path)) { - message = langConfig.getString(path); - } else if (defConfig.contains(path)) { - message = defConfig.getString(path); - } - return message; - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java index c5d341cd..61761d52 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java @@ -1,33 +1,8 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - package io.github.rypofalem.armorstandeditor.menu; -import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; - -public class ASEHolder implements InventoryHolder { - - @Override - public Inventory getInventory() { - return null; - } - +public interface ASEHolder extends InventoryHolder { } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java new file mode 100644 index 00000000..ce05e0fd --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java @@ -0,0 +1,9 @@ +package io.github.rypofalem.armorstandeditor.menu; + +import org.bukkit.entity.ArmorStand; + +public interface EditorMenu extends ASEHolder{ + void open(); + void fillInventory(); + ArmorStand getArmorStand(); +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java index 81aa44e7..98535d8c 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java @@ -1,25 +1,9 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - package io.github.rypofalem.armorstandeditor.menu; import io.github.rypofalem.armorstandeditor.PlayerEditor; +import io.github.rypofalem.armorstandeditor.api.EquipmentMenuOpenedEvent; +import io.github.rypofalem.armorstandeditor.devtools.Debug; +import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -30,27 +14,46 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -public class EquipmentMenu { - Inventory menuInv; +import static net.kyori.adventure.text.Component.text; + +public class EquipmentMenu implements EditorMenu { + + Inventory equipMenu; private PlayerEditor pe; - private ArmorStand armorstand; - static String name = "ArmorStand Equipment"; - ItemStack helmet, chest, pants, feetsies, rightHand, leftHand; + private ArmorStand armorStand; + String menuName; + public Debug debug; - public EquipmentMenu(PlayerEditor pe, ArmorStand as) { + public EquipmentMenu(PlayerEditor pe, ArmorStand as){ this.pe = pe; - this.armorstand = as; - name = pe.plugin.getLang().getMessage("equiptitle", "menutitle"); - menuInv = Bukkit.createInventory(pe.getManager().getEquipmentHolder(), 18, name); + this.armorStand = as; + menuName = pe.plugin.getLanguage().getMessage("equiptitle", "menutitle"); + this.debug = new Debug(pe.plugin); + equipMenu = Bukkit.createInventory(this, 18, text(menuName)); + } + + @Override + public void open() { + + EquipmentMenuOpenedEvent event = new EquipmentMenuOpenedEvent(pe.getPlayer(), this); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return; + + if(pe.getPlayer().hasPermission("asedit.equipment")) { + fillInventory(); + debug.log("Player '" + pe.getPlayer().getName() + "' has opened the Equipment Menu."); + pe.getPlayer().openInventory(this.equipMenu); + } } - private void fillInventory() { - menuInv.clear(); - EntityEquipment equipment = armorstand.getEquipment(); - assert equipment != null; + @Override + public void fillInventory() { + equipMenu.clear(); + EntityEquipment equipment = armorStand.getEquipment(); ItemStack helmet = equipment.getHelmet(); ItemStack chest = equipment.getChestplate(); ItemStack pants = equipment.getLeggings(); @@ -61,7 +64,7 @@ private void fillInventory() { ItemStack disabledIcon = new ItemStack(Material.BARRIER); ItemMeta meta = disabledIcon.getItemMeta(); - meta.setDisplayName(pe.plugin.getLang().getMessage("disabled", "warn")); //equipslot.msg