diff --git a/.gitbook.yaml b/.gitbook.yaml deleted file mode 100644 index a08464c7..00000000 --- a/.gitbook.yaml +++ /dev/null @@ -1,5 +0,0 @@ -root: ./wiki - -structure: - readme: README.md - summary: SUMMARY.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index b1790654..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Run the command '...' -2. Click on a mob '....' -3. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Software (please complete the following information):** - - Server: [e.g. Spigot 1.12] - - Plugin version [e.g. 2.12.1] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 11fc491e..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: enhancement -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index fa87672e..00000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,37 +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: CI - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - strategy: - fail-fast: true - max-parallel: 4 - matrix: - java-version: [ 16, 21, 23] - runs-on: ubuntu-latest - name: Java ${{ matrix.java-version }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: "Set up JDK ${{ matrix.java-version }}" - uses: actions/setup-java@v4 - with: - java-version: "${{ matrix.java-version }}" - distribution: 'temurin' - cache: 'maven' - - name: Build with Maven - run: ./mvnw -B -U package --file pom.xml - - name: Upload Build Artifact - if: "${{ matrix.java-version == 16 }}" - uses: actions/upload-artifact@v4 - with: - name: SimpleClans - path: target/SimpleClans.jar diff --git a/.github/workflows/publish_curseforge.yml b/.github/workflows/publish_curseforge.yml deleted file mode 100644 index 0fd96da0..00000000 --- a/.github/workflows/publish_curseforge.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Publish to CurseForge -on: - release: - types: [created] - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 16 - uses: actions/setup-java@v4 - with: - java-version: 16 - cache: 'maven' - distribution: 'temurin' - - name: Build with Maven - run: ./mvnw -B package --file pom.xml - - name: Upload artifact - uses: itsmeow/curseforge-upload@v3 - with: - token: ${{ secrets.CURSEFORGE_TOKEN }} - project_id: 380814 - game_endpoint: minecraft - file_path: target/SimpleClans.jar - changelog: ${{ github.event.release.body }} - changelog_type: markdown - display_name: ${{ github.event.release.tag_name }} - game_versions: 11515,9974,9190,8849,8503,7915,7667,7330,7105,6588,630,591,585,531 - release_type: release - relations: vault:optionalDependency,worldguard:optionalDependency,grief-prevention:optionalDependency,plotsquared:optionalDependency diff --git a/.github/workflows/publish_modrinth.yml b/.github/workflows/publish_modrinth.yml deleted file mode 100644 index adab2174..00000000 --- a/.github/workflows/publish_modrinth.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Publish to Modrinth -on: - release: - types: [created] - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 16 - uses: actions/setup-java@v4 - with: - java-version: 16 - cache: 'maven' - distribution: 'temurin' - - name: Build with Maven - run: ./mvnw -B package --file pom.xml - - name: Upload artifact - uses: RubixDev/modrinth-upload@v1.0.0 - with: - token: ${{ secrets.MODRINTH_TOKEN }} - project_id: quLDfyDl - file_path: target/SimpleClans.jar - changelog: ${{ github.event.release.body }} - name: ${{ github.event.release.tag_name }} - version: ${{ github.event.release.tag_name }} - game_versions: 1.21,1.20,1.19,1.18,1.17,1.16,1.15,1.14,1.13,1.12,1.11,1.10,1.9,1.8 - release_type: release - loaders: spigot - featured: true diff --git a/.github/workflows/publish_reposilite.yml b/.github/workflows/publish_reposilite.yml deleted file mode 100644 index 46eb80d0..00000000 --- a/.github/workflows/publish_reposilite.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Publish to Reposilite -on: - push: - branches: - - master - workflow_dispatch: - -jobs: - publish: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 16 - uses: actions/setup-java@v4 - with: - java-version: 16 - server-id: reposilite # Value of the distributionManagement/repository/id field of the pom.xml - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - cache: 'maven' - distribution: 'temurin' - - name: Build with Maven - run: ./mvnw -B package --file pom.xml - - name: Publish to Reposilite - run: ./mvnw -B deploy - env: - MAVEN_USERNAME: simpleclans - MAVEN_PASSWORD: ${{ secrets.REPOSILITE_TOKEN }} diff --git a/.github/workflows/release_please.yml b/.github/workflows/release_please.yml deleted file mode 100644 index 50cf2d9b..00000000 --- a/.github/workflows/release_please.yml +++ /dev/null @@ -1,15 +0,0 @@ -on: - push: - branches: - - master -name: release-please -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - with: - release-type: maven - package-name: SimpleClans - token: ${{ secrets.PAT_TOKEN }} - fork: false diff --git a/.gitignore b/.gitignore index 68ae5eb9..2c313b52 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ -/target/ -/.idea/ -/bin/ -/.classpath -/.project +.idea/ +bin/ +.classpath +.project *.jar +build/ +.gradle/ .settings .factorypath SimpleClans.iml -dependency-reduced-pom.xml diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index f95f1ee8..00000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. -wrapperVersion=3.3.2 -distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ca90b601..00000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Use https://travis-ci.org/ for automatic testing - -# This is a java project -language: java - -script: mvn install - -jdk: [openjdk8] - -# if one build failed, exit testing -matrix: - fast_finish: true - -addons: - artifacts: true - -# Disable caching in order to get notified if there are some repo/dependency issues -## Cache maven dependencies -#sudo: false -#cache: -# directories: -# - '$HOME/.m2/repository' diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 00000000..46a1e94b --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash + +# Fetch all submodule content. +git submodule update --force --recursive --init diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..eb4b1659 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,176 @@ +/* This is free and unencumbered software released into the public domain */ + +import org.gradle.kotlin.dsl.provideDelegate + +/* ------------------------------ Plugins ------------------------------ */ +plugins { + id("java") // Import Java plugin. + id("java-library") // Import Java Library plugin. + id("com.diffplug.spotless") version "7.0.4" // Import Spotless plugin. + id("com.gradleup.shadow") version "8.3.6" // Import Shadow plugin. + id("checkstyle") // Import Checkstyle plugin. + eclipse // Import Eclipse plugin. + kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin. +} + +extra["kotlinAttribute"] = Attribute.of("kotlin-tag", Boolean::class.javaObjectType) + +val kotlinAttribute: Attribute by rootProject.extra + +/* --------------------------- JDK / Kotlin ---------------------------- */ +java { + sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility. + toolchain { // Select Java toolchain. + languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17. + vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE. + } +} + +kotlin { jvmToolchain(17) } + +/* ----------------------------- Metadata ------------------------------ */ +group = "net.sacredlabyrinth.phaed.simpleclans" // Declare bundle identifier. + +version = "2.19.3-SNAPSHOT" // Declare plugin version (will be in .jar). + +val apiVersion = "1.19" // Declare minecraft server target version. + +/* ----------------------------- Resources ----------------------------- */ +tasks.named("processResources") { + val props = mapOf("version" to version, "apiVersion" to apiVersion) + inputs.properties(props) // Indicates to rerun if version changes. + filesMatching("plugin.yml") { expand(props) } + from("LICENSE") { into("/") } // Bundle licenses into jarfiles. +} + +/* ---------------------------- Repos ---------------------------------- */ +repositories { + mavenCentral() // Import the Maven Central Maven Repository. + gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository. + maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository. + maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") } + maven { url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") } + maven { url = uri("https://repo.codemc.org/repository/maven-public") } + maven { url = uri("https://repo.papermc.io/repository/maven-public/") } + maven { url = uri("https://repo.aikar.co/content/groups/aikar/") } + maven { url = uri("https://maven.enginehub.org/repo/") } + maven { url = uri("https://nexus.scarsz.me/content/groups/public/") } + maven { url = uri("https://eldonexus.de/repository/maven-public") } + maven { url = uri("https://jitpack.io") } + maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") } + System.getProperty("SELF_MAVEN_LOCAL_REPO")?.let { + val dir = file(it) + if (dir.isDirectory) { + println("Using SELF_MAVEN_LOCAL_REPO at: $it") + maven { url = uri("file://${dir.absolutePath}") } + } else { + logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()") + mavenLocal() + } + } ?: logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()") +} + +/* ---------------------- Java project deps ---------------------------- */ +dependencies { + compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") + compileOnly("com.github.MilkBowl:VaultAPI:1.7") { + exclude(group = "com.googlecode.json-simple", module = "json-simple") + } + implementation("org.bstats:bstats-bukkit:3.0.2") + compileOnly("me.clip:placeholderapi:2.11.3") + compileOnly("org.jetbrains:annotations:24.0.1") + implementation("io.papermc:paperlib:1.0.8-SNAPSHOT") + implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT") + implementation("com.github.cryptomorin:XSeries:11.2.0.1") + compileOnly("com.sk89q:worldguard:6.1.1-SNAPSHOT") + compileOnly("com.github.TechFortress:GriefPrevention:17.0.0") + compileOnly("com.discordsrv:discordsrv:1.28.0") + compileOnly("biz.princeps:landlord-latest:4.363") + implementation("com.google.code.gson:gson:2.10.1") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.11.3") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.11.3") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.11.3") + testImplementation("org.mockito:mockito-core:5.14.2") + testImplementation("org.mockito:mockito-junit-jupiter:5.14.2") +} + +apply(from = "eclipse.gradle.kts") // Import eclipse classpath support script. + +/* ---------------------- Reproducible jars ---------------------------- */ +tasks.withType().configureEach { // Ensure reproducible .jars + isPreserveFileTimestamps = false + isReproducibleFileOrder = true +} + +/* ----------------------------- Shadow -------------------------------- */ +tasks.shadowJar { + relocate("org.bstats", "net.sacredlabyrinth.phaed.simpleclans.metrics") + relocate("io.papermc.lib", "net.sacredlabyrinth.phaed.simpleclans.paperlib") + relocate("co.aikar.commands", "net.sacredlabyrinth.phaed.simpleclans.acf") + relocate("co.aikar.locales", "net.sacredlabyrinth.phaed.simpleclans.locales") + relocate("com.cryptomorin.xseries", "net.sacredlabyrinth.phaed.simpleclans.xseries") + relocate("com.google.gson", "net.sacredlabyrinth.phaed.simpleclans.gson") + dependencies { exclude(dependency("org.jetbrains:annotations:.*")) } + archiveBaseName.set("SimpleClans") + archiveClassifier.set("") +} + +tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only. + +tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar, tasks.javadoc) } // Build depends on spotless and shadow. + +/* --------------------------- Javac opts ------------------------------- */ +tasks.withType().configureEach { + options.compilerArgs.add("-parameters") // Enable reflection for java code. + options.isFork = true // Run javac in its own process. + options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages. + options.encoding = "UTF-8" // Use UTF-8 file encoding. +} + +tasks.test { useJUnitPlatform() } + +/* ----------------------------- Auto Formatting ------------------------ */ +spotless { + java { + eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting. + leadingTabsToSpaces() // Convert leftover leading tabs to spaces. + removeUnusedImports() // Remove imports that aren't being called. + } + kotlinGradle { + ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting. + target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format. + } +} + +checkstyle { + toolVersion = "10.18.1" // Declare checkstyle version to use. + configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file. + isIgnoreFailures = true // Don't fail the build if checkstyle does not pass. + isShowViolations = true // Show the violations in any IDE with the checkstyle plugin. +} + +tasks.named("compileJava") { + dependsOn("spotlessApply") // Run spotless before compiling with the JDK. +} + +tasks.named("spotlessCheck") { + dependsOn("spotlessApply") // Run spotless before checking if spotless ran. +} + +/* ------------------------------ Eclipse SHIM ------------------------- */ + +// This can't be put in eclipse.gradle.kts because Gradle is weird. +subprojects { + apply(plugin = "java-library") + apply(plugin = "eclipse") + eclipse.project.name = "${project.name}-${rootProject.name}" + tasks.withType().configureEach { archiveBaseName.set("${project.name}-${rootProject.name}") } +} + +tasks.register("copyToTestServer") { + val out = System.getenv("TEST_SERVER")?.let { file("$it/plugins") } + onlyIf { out != null } + dependsOn(tasks.shadowJar) + from(tasks.shadowJar) + into(out ?: layout.buildDirectory.dir("noop").get().asFile) +} diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 00000000..4c3ab959 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/formatter/eclipse-java-formatter.xml b/config/formatter/eclipse-java-formatter.xml new file mode 100644 index 00000000..a3e01a0e --- /dev/null +++ b/config/formatter/eclipse-java-formatter.xml @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eclipse.gradle.kts b/eclipse.gradle.kts new file mode 100644 index 00000000..b0dffb3d --- /dev/null +++ b/eclipse.gradle.kts @@ -0,0 +1,151 @@ +/* This is free and unencumbered software released into the public domain */ + +import org.gradle.plugins.ide.eclipse.model.EclipseModel +import java.nio.file.Files +import javax.xml.parsers.DocumentBuilderFactory +import javax.xml.transform.OutputKeys +import javax.xml.transform.TransformerFactory +import javax.xml.transform.dom.DOMSource +import javax.xml.transform.stream.StreamResult + +val kotlinAttribute: Attribute by rootProject.extra + +val kotlinPluginProjects = configurations +.getByName("compileClasspath") +.allDependencies + .filterIsInstance() + .filter { it -> it.attributes.getAttribute(kotlinAttribute) != null } + .map { it.path } +kotlinPluginProjects.forEach { evaluationDependsOn(it) } + +val ideLibs: Configuration by +configurations.creating { + isCanBeResolved = true + isCanBeConsumed = false +} + +configure { + project { + name = "Template-OG-Plugin" + } + classpath { + plusConfigurations.add(ideLibs) + } +} + +val ideLibDir = layout.buildDirectory.dir("ide-libs") +val hashRegex = Regex("-[0-9a-fA-F]{10}(?=\\.jar$)") // Black magic. + +val copyTasks = mutableListOf>() + +kotlinPluginProjects.forEach { path -> + val sub = project(path) + val shadowJarProv = sub.tasks.named("shadowJar") + val copyTask = + tasks.register("ideCopy${sub.name.replaceFirstChar(Char::titlecase)}") { + dependsOn(shadowJarProv) + from(shadowJarProv) + into(ideLibDir) + rename { it.replace(hashRegex, "") } // Remove git commit hash from jarfile. + } + copyTasks += copyTask +} + +/* Ensure the jars exist before .classpath is generated */ +tasks.named("eclipseClasspath").configure { dependsOn(copyTasks) } + +/* Supply those jars to the ideLibs configuration (after evaluation) */ +afterEvaluate { dependencies { add("ideLibs", fileTree(ideLibDir) { include("*.jar") }) } } + +val injectIdeLibs = + tasks.register("injectIdeLibs") { + dependsOn("eclipse") // run after all eclipse files are generated + doLast { + val cpFile = file(".classpath") + if (!cpFile.exists()) return@doLast + + val jars = fileTree(ideLibDir.get()) { include("*.jar") }.files.sortedBy { it.name } + if (jars.isEmpty()) return@doLast + + // Parse DOM + val dbf = DocumentBuilderFactory.newInstance() + val doc = dbf.newDocumentBuilder().parse(cpFile) + val root = doc.documentElement + + // Helper to see if an entry already exists + fun exists(path: String): Boolean = + root.getElementsByTagName("classpathentry").let { list -> + (0 until list.length).any { i -> + val n = list.item(i) + val kind = n.attributes?.getNamedItem("kind")?.nodeValue + val p = n.attributes?.getNamedItem("path")?.nodeValue + kind == "lib" && p == path + } + } + + // Remove any entry that points to ide-libs dir (folder or jars) to avoid dupes + val toRemove = mutableListOf() + val list = root.getElementsByTagName("classpathentry") + val dirPath = ideLibDir.get().asFile.absolutePath + for (i in 0 until list.length) { + val n = list.item(i) + val kind = n.attributes?.getNamedItem("kind")?.nodeValue + val p = n.attributes?.getNamedItem("path")?.nodeValue ?: "" + if (kind == "lib" && (p == dirPath || p.startsWith("$dirPath/"))) { + toRemove += n + } + } + toRemove.forEach { root.removeChild(it) } + + // Append our jar entries LAST + jars.forEach { f -> + val abs = f.absolutePath + if (!exists(abs)) { + val entry = doc.createElement("classpathentry") + entry.setAttribute("kind", "lib") + entry.setAttribute("path", abs) + root.appendChild(entry) + } + } + + // Write back pretty + val tf = + TransformerFactory.newInstance().newTransformer().apply { + setOutputProperty(OutputKeys.INDENT, "yes") + setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "1") + setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no") + setOutputProperty(OutputKeys.ENCODING, "UTF-8") + } + Files.newBufferedWriter(cpFile.toPath()).use { w -> tf.transform(DOMSource(doc), StreamResult(w)) } + } + } + +tasks.named("eclipse").configure { finalizedBy(injectIdeLibs) } + +val eclipseModel = extensions.getByType() + +fun Project.addResolvableEclipseConfigs() { + val jarAttr = + objects.named(org.gradle.api.attributes.LibraryElements::class, org.gradle.api.attributes.LibraryElements.JAR) + val apiAttr = objects.named(org.gradle.api.attributes.Usage::class, org.gradle.api.attributes.Usage.JAVA_API) + + val compileOnlyRes = + configurations.create("eclipseCompileOnly") { + extendsFrom(configurations.getByName("compileOnly")) + isCanBeResolved = true + isCanBeConsumed = false + attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr) + attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr) + } + val compileOnlyApiRes = + configurations.create("eclipseCompileOnlyApi") { + extendsFrom(configurations.getByName("compileOnlyApi")) + isCanBeResolved = true + isCanBeConsumed = false + attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr) + attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr) + } + eclipseModel.classpath.plusConfigurations.addAll(listOf(compileOnlyRes, compileOnlyApiRes)) +} + +addResolvableEclipseConfigs() diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..1a3cecd2 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=1024m -Dfile.encoding=UTF-8 + diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..d4081da4 --- /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.14.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..23d15a93 --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/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. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..5eed7ee8 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/mvnw b/mvnw deleted file mode 100755 index 19529ddf..00000000 --- a/mvnw +++ /dev/null @@ -1,259 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.2 -# -# Optional ENV vars -# ----------------- -# JAVA_HOME - location of a JDK home dir, required when download maven via java source -# MVNW_REPOURL - repo url base for downloading maven distribution -# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output -# ---------------------------------------------------------------------------- - -set -euf -[ "${MVNW_VERBOSE-}" != debug ] || set -x - -# OS specific support. -native_path() { printf %s\\n "$1"; } -case "$(uname)" in -CYGWIN* | MINGW*) - [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" - native_path() { cygpath --path --windows "$1"; } - ;; -esac - -# set JAVACMD and JAVACCMD -set_java_home() { - # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched - 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" - JAVACCMD="$JAVA_HOME/jre/sh/javac" - else - JAVACMD="$JAVA_HOME/bin/java" - JAVACCMD="$JAVA_HOME/bin/javac" - - if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then - echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 - echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 - return 1 - fi - fi - else - JAVACMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v java - )" || : - JAVACCMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v javac - )" || : - - if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then - echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 - return 1 - fi - fi -} - -# hash string like Java String::hashCode -hash_string() { - str="${1:-}" h=0 - while [ -n "$str" ]; do - char="${str%"${str#?}"}" - h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) - str="${str#?}" - done - printf %x\\n $h -} - -verbose() { :; } -[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - -die() { - printf %s\\n "$1" >&2 - exit 1 -} - -trim() { - # MWRAPPER-139: - # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. - # Needed for removing poorly interpreted newline sequences when running in more - # exotic environments such as mingw bash on Windows. - printf "%s" "${1}" | tr -d '[:space:]' -} - -# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties -while IFS="=" read -r key value; do - case "${key-}" in - distributionUrl) distributionUrl=$(trim "${value-}") ;; - distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; - esac -done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" -[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" - -case "${distributionUrl##*/}" in -maven-mvnd-*bin.*) - MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ - case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in - *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; - :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; - :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; - :Linux*x86_64*) distributionPlatform=linux-amd64 ;; - *) - echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 - distributionPlatform=linux-amd64 - ;; - esac - distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" - ;; -maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; -*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; -esac - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" -distributionUrlName="${distributionUrl##*/}" -distributionUrlNameMain="${distributionUrlName%.*}" -distributionUrlNameMain="${distributionUrlNameMain%-bin}" -MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" -MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" - -exec_maven() { - unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : - exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" -} - -if [ -d "$MAVEN_HOME" ]; then - verbose "found existing MAVEN_HOME at $MAVEN_HOME" - exec_maven "$@" -fi - -case "${distributionUrl-}" in -*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; -*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; -esac - -# prepare tmp dir -if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then - clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } - trap clean HUP INT TERM EXIT -else - die "cannot create temp dir" -fi - -mkdir -p -- "${MAVEN_HOME%/*}" - -# Download and Install Apache Maven -verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -verbose "Downloading from: $distributionUrl" -verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -# select .zip or .tar.gz -if ! command -v unzip >/dev/null; then - distributionUrl="${distributionUrl%.zip}.tar.gz" - distributionUrlName="${distributionUrl##*/}" -fi - -# verbose opt -__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' -[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v - -# normalize http auth -case "${MVNW_PASSWORD:+has-password}" in -'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; -has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; -esac - -if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then - verbose "Found wget ... using wget" - wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" -elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then - verbose "Found curl ... using curl" - curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" -elif set_java_home; then - verbose "Falling back to use Java to download" - javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" - targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" - cat >"$javaSource" <<-END - public class Downloader extends java.net.Authenticator - { - protected java.net.PasswordAuthentication getPasswordAuthentication() - { - return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); - } - public static void main( String[] args ) throws Exception - { - setDefault( new Downloader() ); - java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); - } - } - END - # For Cygwin/MinGW, switch paths to Windows format before running javac and java - verbose " - Compiling Downloader.java ..." - "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" - verbose " - Running Downloader.java ..." - "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" -fi - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -if [ -n "${distributionSha256Sum-}" ]; then - distributionSha256Result=false - if [ "$MVN_CMD" = mvnd.sh ]; then - echo "Checksum validation is not supported for maven-mvnd." >&2 - echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - elif command -v sha256sum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - elif command -v shasum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 - echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - fi - if [ $distributionSha256Result = false ]; then - echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 - echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 - exit 1 - fi -fi - -# unzip and move -if command -v unzip >/dev/null; then - unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" -else - tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" -fi -printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" -mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" - -clean || : -exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index 249bdf38..00000000 --- a/mvnw.cmd +++ /dev/null @@ -1,149 +0,0 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.2 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' -$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" -if ($env:MAVEN_USER_HOME) { - $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" -} -$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml deleted file mode 100644 index d5a110ed..00000000 --- a/pom.xml +++ /dev/null @@ -1,336 +0,0 @@ - - 4.0.0 - net.sacredlabyrinth.phaed.simpleclans - SimpleClans - 2.19.3-SNAPSHOT - SimpleClans - https://www.spigotmc.org/resources/simpleclans.71242/ - - - ${project.name} - - - - - . - true - ${basedir}/src/main/resources - - plugin.yml - config.yml - *.properties - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.13.0 - - 8 - true - true - - -parameters - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.4.2 - - - - - org.apache.maven.plugins - maven-release-plugin - 3.1.1 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - - org.bstats - net.sacredlabyrinth.phaed.simpleclans.metrics - - - io.papermc.lib - net.sacredlabyrinth.phaed.simpleclans.paperlib - - - co.aikar.commands - net.sacredlabyrinth.phaed.simpleclans.acf - - - co.aikar.locales - net.sacredlabyrinth.phaed.simpleclans.locales - - - com.cryptomorin.xseries - net.sacredlabyrinth.phaed.simpleclans.xseries - - - com.google.gson - net.sacredlabyrinth.phaed.simpleclans.gson - - - - - org.jetbrains:annotations - - - - - - - MANIFEST.MF - - - - - - package - - shade - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.7.1 - - - copy-installed - package - - copy - - - - - ${project.groupId} - ${project.artifactId} - ${project.version} - ${project.packaging} - - - ${env.TEST_SERVER}\plugins - true - - - - - - - io.github.git-commit-id - git-commit-id-maven-plugin - 9.0.1 - - - - revision - - validate - - - - ${project.basedir}/.git - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.10.1 - - - - javadoc - - package - - - - 8 - all,-missing - - - - - maven-surefire-plugin - 3.3.1 - - - - - - - org.spigotmc - spigot-api - 1.16.4-R0.1-SNAPSHOT - provided - - - com.github.MilkBowl - VaultAPI - 1.7 - provided - - - - com.googlecode.json-simple - json-simple - - - - - org.bstats - bstats-bukkit - 3.0.2 - compile - - - me.clip - placeholderapi - 2.11.3 - provided - - - org.jetbrains - annotations - 24.0.1 - - - io.papermc - paperlib - 1.0.8-SNAPSHOT - compile - - - co.aikar - acf-paper - 0.5.1-SNAPSHOT - - - com.github.cryptomorin - XSeries - 11.2.0.1 - - - com.sk89q - worldguard - 6.1.1-SNAPSHOT - provided - - - com.github.TechFortress - GriefPrevention - 17.0.0 - provided - - - com.discordsrv - discordsrv - 1.28.0 - provided - - - biz.princeps - landlord-latest - 4.363 - provided - - - com.google.code.gson - gson - 2.10.1 - - - - - org.junit.jupiter - junit-jupiter-api - 5.11.3 - test - - - org.mockito - mockito-core - 5.14.2 - test - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - placeholderapi-repo - https://repo.extendedclip.com/content/repositories/placeholderapi/ - - - bstats-repo - https://repo.codemc.org/repository/maven-public - - - papermc - https://repo.papermc.io/repository/maven-public/ - - - aikar - https://repo.aikar.co/content/groups/aikar/ - - - sk89q-repo - https://maven.enginehub.org/repo/ - - - Scarsz-Nexus - https://nexus.scarsz.me/content/groups/public/ - - - eldonexus - https://eldonexus.de/repository/maven-public - - - jitpack.io - https://jitpack.io - - - - - UTF-8 - - - - - - - reposilite - https://repo.roinujnosde.me/releases/ - - - reposilite - https://repo.roinujnosde.me/snapshots/ - - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..3c50eb5e --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,13 @@ +rootProject.name = "SimpleClans" + +ProcessBuilder("sh", "bootstrap.sh").directory(rootDir).inheritIO().start().let { + if (it.waitFor() != 0) throw GradleException("bootstrap.sh failed") +} + +file("libs") + .listFiles() + ?.filter { it.isDirectory && !it.name.startsWith(".") } + ?.forEach { dir -> + include(":libs:${dir.name}") + project(":libs:${dir.name}").projectDir = dir + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ChatBlock.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ChatBlock.java index cfff39e9..d91a900d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ChatBlock.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ChatBlock.java @@ -17,6 +17,7 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; * @author phaed */ public class ChatBlock { + private static final int LINE_LENGTH = 319; private final ArrayList columnFlexes = new ArrayList<>(); private final ArrayList columnSizes = new ArrayList<>(); @@ -28,86 +29,124 @@ public class ChatBlock { @Deprecated public void setCropRight(boolean cropRight) { + this.cropRight = cropRight; + } @Deprecated public void setPadRight(boolean padRight) { + this.padRight = padRight; + } public void setAlignment(String... columnAlignment) { + columnAlignments.addAll(Arrays.asList(columnAlignment)); + } public void setFlexibility(boolean... columnFlex) { + for (boolean flex : columnFlex) { + columnFlexes.add(flex); + } + } @Deprecated public void setColumnSizes(String prefix, double... columnPercentages) { + int ll = LINE_LENGTH; if (prefix != null) { + ll = LINE_LENGTH - (int) msgLength(prefix); + } for (double percentage : columnPercentages) { + columnSizes.add((int) Math.floor((percentage / 100) * ll)); + } + } @Deprecated public boolean hasContent() { + return !rows.isEmpty(); + } public void addRow(String... contents) { + rows.add(contents); + } - public int size() { + return rows.size(); + } @Deprecated public boolean isEmpty() { + return rows.isEmpty(); + } @Deprecated public void clear() { + rows.clear(); + } @Deprecated public boolean sendBlock(CommandSender player) { + return sendBlock(player, null, 0); + } @Deprecated public boolean sendBlock(CommandSender player, String prefix) { + return sendBlock(player, prefix, 0); + } public boolean sendBlock(CommandSender player, int amount) { + return sendBlock(player, null, amount); + } boolean sendBlock(CommandSender player, String prefix, int amount) { + if (player == null) { + return false; + } if (rows.isEmpty()) { + return false; + } if (amount == 0) { + amount = rows.size(); + } boolean prefix_used = prefix == null; @@ -123,65 +162,106 @@ public class ChatBlock { int colCount = rows.get(0).length; if (colCount > 1) { - for (int i = 0; i < colCount; i++) { - columnSizes.add(getMaxWidth(i) + 4); - } - } else { - columnSizes.add(LINE_LENGTH); - } - } + for (int i = 0; i < colCount; i++) { + + columnSizes.add(getMaxWidth(i) + 4); + + } + + } else { + + columnSizes.add(LINE_LENGTH); + + } + + } List messages = new ArrayList<>(); // size up all sections for (int i = 0; i < amount; i++) { + if (rows.isEmpty()) { + continue; + } List measuredCols = new ArrayList<>(); String row[] = rows.pollFirst(); for (int sid = 0; sid < row.length; sid++) { + String col = ""; String section = row[sid]; double colsize = (columnSizes.size() >= (sid + 1)) ? columnSizes.get(sid) : 0; String align = (columnAlignments.size() >= (sid + 1)) ? columnAlignments.get(sid) : "l"; if (align.equalsIgnoreCase("r")) { + if (msgLength(section) > colsize) { + col = cropLeftToFit(section, colsize); + } else if (msgLength(section) < colsize) { + col = paddLeftToFit(section, colsize); + } + } else if (align.equalsIgnoreCase("l")) { + if (msgLength(section) > colsize) { + if (cropRight) { + col = cropRightToFit(section, colsize); + } else { + col = section; + } + } else if (msgLength(section) < colsize) { + if (padRight) { + col = paddRightToFit(section, colsize); + } else { + col = section; + } + } + } else if (align.equalsIgnoreCase("c")) { + if (msgLength(section) > colsize) { + if (cropRight) { + col = cropRightToFit(section, colsize); + } else { + col = section; + } + } else if (msgLength(section) < colsize) { + col = centerInLineOf(section, colsize); + } + } measuredCols.add(col); + } // add in spacings @@ -189,46 +269,65 @@ public class ChatBlock { int availableSpacing = 12; while (calculatedRowSize(measuredCols) < LINE_LENGTH && availableSpacing > 0) { + for (int j = 0; j < measuredCols.size(); j++) { + String col = measuredCols.get(j); measuredCols.set(j, col + " "); if (calculatedRowSize(measuredCols) >= LINE_LENGTH) { + break; + } } availableSpacing -= 4; + } // cut off from flexible columns if too big if (columnFlexes.size() == measuredCols.size()) { + while (calculatedRowSize(measuredCols) > LINE_LENGTH) { + boolean didFlex = false; for (int j = 0; j < measuredCols.size(); j++) { + boolean flex = columnFlexes.get(j); if (flex) { + String col = measuredCols.get(j); if (col.length() > 0) { + measuredCols.set(j, col.substring(0, col.length() - 1)); didFlex = true; + } + } if (calculatedRowSize(measuredCols) <= LINE_LENGTH) { + break; + } + } if (!didFlex) { + break; + } + } + } // concatenate final strings @@ -236,60 +335,82 @@ public class ChatBlock { String finalString = ""; for (String measured : measuredCols) { + finalString += measured; + } // crop and print out String msg = (prefix_used ? empty_prefix : prefix + " ") + finalString; if (cropRight) { + msg = cropRightToFit(msg, LINE_LENGTH); + } + if (color.length() > 0) { + msg = color + msg; + } messages.add(msg); prefix_used = true; + } player.sendMessage(messages.toArray(new String[0])); return !rows.isEmpty(); + } private int calculatedRowSize(List cols) { + int out = 0; for (String col : cols) { + out += msgLength(col); + } return out; + } int getMaxWidth(int col) { + double maxWidth = 0; for (String[] row : rows) { + maxWidth = Math.max(maxWidth, msgLength(row[col])); + } return (int) maxWidth; + } @Deprecated public static String centerInLine(String msg) { + return centerInLineOf(msg, LINE_LENGTH); + } private static String centerInLineOf(String msg, double lineLength) { + double length = msgLength(msg); double diff = lineLength - length; // if too big for line return it as is if (diff < 0) { + return msg; + } double sideSpace = diff / 2; @@ -302,40 +423,56 @@ public class ChatBlock { msg = paddRightToFit(msg, lineLength); - return msg; + } public static String makeEmpty(String str) { + if (str == null) { + return ""; + } return paddLeftToFit("", msgLength(str)); + } private static String cropRightToFit(String msg, double length) { + if (msg == null || msg.length() == 0 || length == 0) { + return ""; + } while (msgLength(msg) > length) { + msg = msg.substring(0, msg.length() - 2); + } return msg; + } private static String cropLeftToFit(String msg, double length) { + if (msg == null || msg.length() == 0 || length == 0) { + return ""; + } while (msgLength(msg) >= length) { + msg = msg.substring(1); + } return msg; + } /** @@ -346,15 +483,21 @@ public class ChatBlock { * @return the padded message */ private static String paddLeftToFit(String msg, double length) { + if (msgLength(msg) >= length) { + return msg; + } while (msgLength(msg) < length) { + msg = " " + msg; + } return msg; + } /** @@ -365,60 +508,94 @@ public class ChatBlock { * @return the padded message */ private static String paddRightToFit(String msg, double length) { + if (msgLength(msg) >= length) { + return msg; + } while (msgLength(msg) < length) { + msg += " "; + } return msg; + } /** * Finds the length on the screen of a string. Ignores colors. */ private static double msgLength(String str) { + double length = 0; str = ChatColor.stripColor(str); - // Loop through all the characters, skipping any color characters and their following color codes + // Loop through all the characters, skipping any color characters and their + // following color codes for (int x = 0; x < str.length(); x++) { + int len = charLength(str.charAt(x)); if (len > 0) { + length += len; + } else { + x++; + } + } + return length; + } /** * Finds the visual length of the character on the screen. */ private static int charLength(char x) { + String normalized = StringSimplifier.simplifiedString(x + ""); if ("i.:,;|!".contains(normalized)) { + return 2; + } else if ("l'".contains(normalized)) { + return 3; + } else if ("tI[]".contains(normalized)) { + return 4; + } else if ("fk{}<>\"*()".contains(normalized)) { + return 5; + } else if ("abcdeghjmnopqrsuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ1234567890\\/#?$%-=_+&^".contains(normalized)) { + return 6; + } else if ("@~".contains(normalized)) { + return 7; + } else if (normalized.equals(" ")) { + return 4; + } else { + return 7; + } + } /** @@ -436,24 +613,29 @@ public class ChatBlock { // While i is less than the length of the array of words while (!split.isEmpty()) { + int len = 0; // Create an array list to hold individual words ArrayList words = new ArrayList<>(); - // go through the split array containing all the words, and adding them to the words array + // go through the split array containing all the words, and adding them to the + // words array // until reaching the point where their width no longer fits on a chat line while (!split.isEmpty() && split.get(0) != null && len <= LINE_LENGTH) { + double wordLength = msgLength(split.get(0)) + 4; // If a word is too long for a line if (wordLength > LINE_LENGTH) { + String[] tempArray = wordCut(len, split.remove(0)); words.add(tempArray[0]); split.add(tempArray[1]); + } // If the word is not too long to fit @@ -461,53 +643,76 @@ public class ChatBlock { len += wordLength; if (len < LINE_LENGTH) { + words.add(split.remove(0)); + } + } - // Merge the words into a sentence (that now fits into a single chat line) and add them to the output array. + // Merge the words into a sentence (that now fits into a single chat line) and + // add them to the output array. String merged = combineSplit(words.toArray(new String[0])); out.add(merged); + } // Convert to an array and return return out.toArray(new String[0]); + } private static String combineSplit(String[] string) { + StringBuilder builder = new StringBuilder(); for (String aString : string) { + builder.append(aString); builder.append(" "); + } + builder.deleteCharAt(builder.length() - " ".length()); return builder.toString(); + } /** * Cuts apart a word that is too long to fit on one line */ private static String[] wordCut(int lengthBefore, String str) { + int length = lengthBefore; - // Loop through all the characters, skipping any color characters and their following color codes + // Loop through all the characters, skipping any color characters and their + // following color codes String[] output = new String[2]; int x = 0; while (length < LINE_LENGTH && x < str.length()) { + int len = charLength(str.charAt(x)); if (len > 0) { + length += len; + } else { + x++; + } + x++; + } + if (x > str.length()) { + x = str.length(); + } // Add the substring to the output after cutting it @@ -518,6 +723,7 @@ public class ChatBlock { output[1] = str.substring(x); return output; + } /** @@ -527,11 +733,15 @@ public class ChatBlock { * @param msg the message */ public static void saySingle(CommandSender receiver, String msg) { + if (receiver == null) { + return; + } - receiver.sendMessage(colorize(new String[]{cropRightToFit(msg, LINE_LENGTH)})[0]); + receiver.sendMessage(colorize(new String[] { cropRightToFit(msg, LINE_LENGTH) })[0]); + } /** @@ -541,33 +751,48 @@ public class ChatBlock { * @param msg the message */ public static void sendMessage(@Nullable CommandSender receiver, @NotNull String msg) { + if (receiver == null) { + return; + } receiver.sendMessage(ChatUtils.parseColors(msg)); + } public static void sendMessage(@Nullable ClanPlayer receiver, @NotNull String msg) { + if (receiver == null) { + return; + } SimpleClans.getInstance().getProxyManager().sendMessage(receiver.getName(), ChatUtils.parseColors(msg)); + } - // ClanCommands#setbanner, LandCommands#Allow/BlockCommand/verify, StaffCommands#kick, etc + // ClanCommands#setbanner, LandCommands#Allow/BlockCommand/verify, + // StaffCommands#kick, etc public static void sendMessageKey(@Nullable CommandSender receiver, @NotNull String key, @NotNull Object... args) { + sendMessage(receiver, lang(key, receiver, args)); + } public static void sendMessageKey(@NotNull ClanPlayer clanPlayer, @NotNull String key, @NotNull Object... args) { + sendMessageKey(clanPlayer.toPlayer(), key, args); + } @Deprecated public void startColor(String color) { + this.color = color; + } /** @@ -576,11 +801,15 @@ public class ChatBlock { * @param receiver the receiver */ public static void sendBlank(CommandSender receiver) { + if (receiver == null) { + return; + } receiver.sendMessage(" "); + } /** @@ -588,28 +817,41 @@ public class ChatBlock { */ @Deprecated public static String[] say(String message) { + return colorize(wordWrap(message)); + } @Deprecated public static String[] getColorizedMessage(String msg) { + return colorize(wordWrap(msg)); + } private static String[] colorize(String[] message) { + try { + return colorizeBase(message); + } catch (Exception ex) { + return message; + } + } @Deprecated public static @Nullable String colorize(String message) { - return colorizeBase(new String[]{message})[0]; + + return colorizeBase(new String[] { message })[0]; + } private static @Nullable String[] colorizeBase(String[] message) { + if (message != null && message[0] != null && !message[0].isEmpty()) { // Go through each line @@ -618,27 +860,38 @@ public class ChatBlock { int counter = 0; for (String msg : message) { + // Loop through looking for a color code for (int x = 0; x < msg.length(); x++) { + // If the char is color code if (msg.codePointAt(x) == 167) { + // advance x to the next character x += 1; if (x < msg.length()) { + lastColor = ChatColor.COLOR_CHAR + "" + msg.charAt(x); + } + } + } // Replace the message with the colorful message message[counter] = prevColor + msg; prevColor = lastColor; counter++; + } + } - //noinspection ConstantConditions + // noinspection ConstantConditions return message; + } + } \ No newline at end of file diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Clan.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Clan.java index 4ad79919..fa6a4496 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Clan.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Clan.java @@ -67,11 +67,14 @@ public class Clan implements Serializable, Comparable { * */ public Clan() { + this.capeUrl = ""; this.tag = ""; + } public Clan(String tag, String name, boolean verified) { + this.tag = Helper.cleanTag(tag); this.colorTag = ChatUtils.parseColors(tag); this.name = name; @@ -80,33 +83,46 @@ public class Clan implements Serializable, Comparable { this.verified = verified; this.capeUrl = ""; if (SimpleClans.getInstance().getSettingsManager().is(CLAN_FF_ON_BY_DEFAULT)) { + friendlyFire = true; + } + } @Override public int hashCode() { + return getTag().hashCode() >> 13; + } @Override public boolean equals(@Nullable Object obj) { + if (!(obj instanceof Clan)) { + return false; + } Clan other = (Clan) obj; return other.getTag().equals(this.getTag()); + } @Override public int compareTo(Clan other) { + return this.getTag().compareToIgnoreCase(other.getTag()); + } @Override public String toString() { + return tag; + } /** @@ -114,36 +130,52 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public void deposit(double amount, Player player) { + if (SimpleClans.getInstance().getPermissionsManager().playerHasMoney(player, amount)) { + if (SimpleClans.getInstance().getPermissionsManager().chargePlayer(player, amount)) { + player.sendMessage(AQUA + lang("player.clan.deposit", player, CurrencyFormat.format(amount))); addBb(player.getName(), lang("bb.clan.deposit", CurrencyFormat.format(amount))); setBalance(getBalance() + amount); SimpleClans.getInstance().getStorageManager().updateClan(this); + } else { + player.sendMessage(AQUA + lang("not.sufficient.money", player, CurrencyFormat.format(amount))); + } + } else { + player.sendMessage(AQUA + lang("not.sufficient.money", player, amount)); + } + } /** * Deposits money to the clan */ public EconomyResponse deposit(@NotNull BankOperator sender, @NotNull Cause cause, double amount) { + EconomyResponse response = null; if (amount < 0) { + response = NEGATIVE_VALUE; + } if (response == null) { + response = setBalance(sender, cause, DEPOSIT, getBalance() + amount); + } SimpleClans.getInstance().getBankLogger().log(new BankLog(sender, this, response, DEPOSIT, cause, amount)); return response; + } /** @@ -151,37 +183,53 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public void withdraw(double amount, Player player) { + if (getBalance() >= amount) { + if (SimpleClans.getInstance().getPermissionsManager().grantPlayer(player, amount)) { + player.sendMessage(AQUA + lang("player.clan.withdraw", player, CurrencyFormat.format(amount))); addBb(player.getName(), lang("bb.clan.withdraw", CurrencyFormat.format(amount))); setBalance(getBalance() - amount); + } + } else { + player.sendMessage(AQUA + lang("clan.bank.not.enough.money", player)); + } + } /** * Withdraws money from the clan */ public EconomyResponse withdraw(@NotNull BankOperator sender, @NotNull Cause cause, double amount) { + EconomyResponse response = null; if (amount < 0) { + response = NEGATIVE_VALUE; + } if (getBalance() < amount) { + response = NOT_ENOUGH_BALANCE; + } if (response == null) { + response = setBalance(sender, cause, WITHDRAW, getBalance() - amount); + } SimpleClans.getInstance().getBankLogger().log(new BankLog(sender, this, response, WITHDRAW, cause, amount)); return response; + } /** @@ -191,7 +239,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("name") public String getName() { + return name; + } /** @@ -200,7 +250,9 @@ public class Clan implements Serializable, Comparable { * @param name the name to set */ public void setName(String name) { + this.name = name; + } /** @@ -209,24 +261,33 @@ public class Clan implements Serializable, Comparable { * @return the description or null if it doesn't have one */ public String getDescription() { + return description; + } /** * (used internally) */ public void setDescription(String description) { + this.description = description; + } /** * Sets the clan's fee */ public void setMemberFee(double fee) { + if (fee < 0) { + fee = 0; + } + this.fee = fee; + } /** @@ -235,7 +296,9 @@ public class Clan implements Serializable, Comparable { * @return the fee */ public double getMemberFee() { + return fee; + } /** @@ -245,7 +308,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("balance") public double getBalance() { + return balance; + } /** @@ -255,7 +320,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("balance_formatted") public String getBalanceFormatted() { + return CurrencyFormat.format(balance); + } /** @@ -264,27 +331,41 @@ public class Clan implements Serializable, Comparable { * @param balance the balance to set */ private void setBalance(double balance) { + setBalance(BankOperator.INTERNAL, Cause.INTERNAL, SET, balance); + } public EconomyResponse setBalance(@NotNull BankOperator operator, @NotNull Cause cause, - @NotNull BankLogger.Operation operation, double balance) { + @NotNull BankLogger.Operation operation, double balance) + { + EconomyResponse response = SUCCESS; ClanBalanceUpdateEvent event = new ClanBalanceUpdateEvent(operator, this, getBalance(), balance, cause); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + response = CANCELLED; + } this.balance = event.getNewBalance(); if (cause != Cause.LOADING) { + if (operation == SET) { - SimpleClans.getInstance().getBankLogger().log(new BankLog(operator, this, response, SET, cause, balance)); + + SimpleClans.getInstance().getBankLogger() + .log(new BankLog(operator, this, response, SET, cause, balance)); + } + SimpleClans.getInstance().getStorageManager().updateClan(this); + } + return response; + } /** @@ -294,7 +375,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("tag") public String getTag() { + return tag; + } /** @@ -303,8 +386,11 @@ public class Clan implements Serializable, Comparable { * @param tag the tag to set */ public void setTag(String tag) { + this.tag = tag; + } + /** * Returns the first color in the clan's tag * @@ -312,13 +398,21 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("color") public String getColor() { + if (colorTag.startsWith("\u00a7x")) { // Hexadecimal Code + return colorTag.substring(0, 14); + } else if (colorTag.charAt(0) == '\u00a7') { // Regular Code + return colorTag.substring(0, 2); + } else { // No Code + return ""; + } + } /** @@ -327,14 +421,18 @@ public class Clan implements Serializable, Comparable { * @return the lastUsed */ public long getLastUsed() { + return lastUsed; + } /** * Updates last used date to today (does not update clan on db) */ public void updateLastUsed() { + setLastUsed((new Date()).getTime()); + } /** @@ -342,23 +440,30 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("inactivedays") public int getInactiveDays() { + Timestamp now = new Timestamp((new Date()).getTime()); return (int) Math.floor(Dates.differenceInDays(new Timestamp(getLastUsed()), now)); + } /** - * Returns the max number of days the clan can be inactive - * A {@literal <=} 0 means it won't be purged + * Returns the max number of days the clan can be inactive A {@literal <=} 0 + * means it won't be purged */ public int getMaxInactiveDays() { + if (isPermanent()) { + return -1; + } int verifiedClanInactiveDays = SimpleClans.getInstance().getSettingsManager().getInt(PURGE_INACTIVE_CLAN_DAYS); - int unverifiedClanInactiveDays = SimpleClans.getInstance().getSettingsManager().getInt(PURGE_UNVERIFIED_CLAN_DAYS); + int unverifiedClanInactiveDays = SimpleClans.getInstance().getSettingsManager() + .getInt(PURGE_UNVERIFIED_CLAN_DAYS); return isVerified() ? verifiedClanInactiveDays : unverifiedClanInactiveDays; + } /** @@ -367,7 +472,9 @@ public class Clan implements Serializable, Comparable { * @param lastUsed the lastUsed to set */ public void setLastUsed(long lastUsed) { + this.lastUsed = lastUsed; + } /** @@ -377,7 +484,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("friendly_fire") public boolean isFriendlyFire() { + return friendlyFire; + } /** @@ -386,7 +495,9 @@ public class Clan implements Serializable, Comparable { * @param friendlyFire the friendlyFire to set */ public void setFriendlyFire(boolean friendlyFire) { + this.friendlyFire = friendlyFire; + } /** @@ -396,7 +507,9 @@ public class Clan implements Serializable, Comparable { * @return confirmation */ public boolean isMember(Player player) { + return isMember(player.getUniqueId()); + } /** @@ -406,17 +519,26 @@ public class Clan implements Serializable, Comparable { * @return confirmation */ public boolean isMember(UUID uuid) { + for (ClanPlayer cp : members) { + if (cp.getUniqueId().equals(uuid)) { + return true; + } + } + return false; + } @SuppressWarnings("deprecation") public boolean isMember(String playerName) { + return isMember(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** @@ -425,7 +547,9 @@ public class Clan implements Serializable, Comparable { * @return the bb */ public List getBb() { + return Collections.unmodifiableList(bb); + } /** @@ -435,20 +559,28 @@ public class Clan implements Serializable, Comparable { */ @Placeholder(value = "allies_count", resolver = "list_size") public List getAllies() { + return Collections.unmodifiableList(allies); + } private void addAlly(String tag) { + allies.add(tag); + } private boolean removeAlly(String ally) { + if (!allies.contains(ally)) { + return false; + } allies.remove(ally); return true; + } /** @@ -457,7 +589,9 @@ public class Clan implements Serializable, Comparable { * @return the founded */ public long getFounded() { + return founded; + } /** @@ -465,7 +599,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("founded") public String getFoundedString() { + return DateFormat.formatDateTime(founded); + } /** @@ -474,7 +610,9 @@ public class Clan implements Serializable, Comparable { * @param founded the founded to set */ public void setFounded(long founded) { + this.founded = founded; + } /** @@ -484,7 +622,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("color_tag") public String getColorTag() { + return colorTag; + } /** @@ -493,30 +633,40 @@ public class Clan implements Serializable, Comparable { * @param colorTag the colorTag to set */ public void setColorTag(String colorTag) { + this.colorTag = ChatUtils.parseColors(colorTag); + } /** * Adds a bulletin board message without announcer */ public void addBb(String msg) { + addBbWithoutSaving(msg); SimpleClans.getInstance().getStorageManager().updateClan(this); + } public void setBb(List bb) { + this.bb = new ArrayList<>(bb); + } /** * Adds a bulletin board message without saving it to the database */ public void addBbWithoutSaving(String msg) { + while (bb.size() > SimpleClans.getInstance().getSettingsManager().getInt(BB_SIZE)) { + bb.remove(0); + } bb.add(System.currentTimeMillis() + "_" + msg); + } /** @@ -525,32 +675,42 @@ public class Clan implements Serializable, Comparable { * @param updateLastUsed should the clan's last used time be updated as well? */ public void addBb(String msg, boolean updateLastUsed) { + addBbWithoutSaving(msg); SimpleClans.getInstance().getStorageManager().updateClan(this, updateLastUsed); + } /** * Clears the bulletin board */ public void clearBb() { + bb.clear(); SimpleClans.getInstance().getStorageManager().updateClan(this); + } /** * (used internally) */ public void importMember(ClanPlayer cp) { + if (!members.contains(cp)) { + members.add(cp); + } + } /** * (used internally) */ public void removeMember(UUID uuid) { + members.removeIf(cp -> cp.getUniqueId().equals(uuid)); + } /** @@ -558,7 +718,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("size") public int getSize() { + return members.size(); + } /** @@ -568,37 +730,48 @@ public class Clan implements Serializable, Comparable { */ @Placeholder(value = "rivals_count", resolver = "list_size") public List getRivals() { + return Collections.unmodifiableList(rivals); + } private void addRival(String tag) { + rivals.add(tag); + } private boolean removeRival(String rival) { + return rivals.remove(rival); + } /** * Check if the tag is a rival */ public boolean isRival(String tag) { + return rivals.contains(tag); + } /** * Check if the tag is an ally */ public boolean isAlly(String tag) { + return allies.contains(tag); + } /** - * Tells you if the clan is verified, always returns true if no verification - * is required + * Tells you if the clan is verified, always returns true if no verification is + * required */ @Placeholder("is_verified") public boolean isVerified() { + return !SimpleClans.getInstance().getSettingsManager().is(REQUIRE_VERIFICATION) || verified; } @@ -609,16 +782,22 @@ public class Clan implements Serializable, Comparable { * @param verified the verified to set */ public void setVerified(boolean verified) { + this.verified = verified; + } @Placeholder("is_permanent") public boolean isPermanent() { + return flags.getBoolean("permanent", false); + } public void setPermanent(boolean permanent) { + flags.put("permanent", permanent); + } /** @@ -628,7 +807,9 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public String getCapeUrl() { + return capeUrl; + } /** @@ -638,7 +819,9 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public void setCapeUrl(String capeUrl) { + this.capeUrl = capeUrl; + } /** @@ -647,7 +830,9 @@ public class Clan implements Serializable, Comparable { * @return the packedBb */ public String getPackedBb() { + return String.join("|", bb); + } /** @@ -656,7 +841,9 @@ public class Clan implements Serializable, Comparable { * @param packedBb the packedBb to set */ public void setPackedBb(String packedBb) { + bb = Helper.fromArrayToList(packedBb.split("[|]")); + } /** @@ -665,7 +852,9 @@ public class Clan implements Serializable, Comparable { * @return the packedAllies */ public String getPackedAllies() { + return String.join("|", allies); + } /** @@ -674,7 +863,9 @@ public class Clan implements Serializable, Comparable { * @param packedAllies the packedAllies to set */ public void setPackedAllies(String packedAllies) { + allies = Helper.fromArrayToList(packedAllies.split("[|]")); + } /** @@ -683,7 +874,9 @@ public class Clan implements Serializable, Comparable { * @return the packedRivals */ public String getPackedRivals() { + return String.join("|", rivals); + } /** @@ -692,21 +885,22 @@ public class Clan implements Serializable, Comparable { * @param packedRivals the packedRivals to set */ public void setPackedRivals(String packedRivals) { + rivals = Helper.fromArrayToList(packedRivals.split("[|]")); + } /** - * Returns a separator delimited string with all the ally clan's colored - * tags + * Returns a separator delimited string with all the ally clan's colored tags */ public String getAllyString(String sep, @Nullable CommandSender viewer) { - String coloredAllies = getAllies().stream(). - map(allyTag -> SimpleClans.getInstance().getClanManager().getClan(allyTag)). - filter(Objects::nonNull). - map(Clan::getColorTag). - collect(Collectors.joining(sep)); + + String coloredAllies = getAllies().stream() + .map(allyTag -> SimpleClans.getInstance().getClanManager().getClan(allyTag)).filter(Objects::nonNull) + .map(Clan::getColorTag).collect(Collectors.joining(sep)); return coloredAllies.isEmpty() ? lang("none", viewer) : coloredAllies; + } /** @@ -714,22 +908,23 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public String getAllyString(String sep) { + return getAllyString(sep, null); + } /** - * Returns a separator delimited string with all the rival clan's colored - * tags + * Returns a separator delimited string with all the rival clan's colored tags */ public String getRivalString(String sep, @Nullable CommandSender viewer) { - String coloredRivals = getRivals().stream(). - map(rivalTag -> SimpleClans.getInstance().getClanManager().getClan(rivalTag)). - filter(Objects::nonNull). - map(rival -> isWarring(rival) ? DARK_RED + "[" + rival.getTag() + "]" : rival.getColorTag()). - map(ChatUtils::parseColors). - collect(Collectors.joining(sep)); + + String coloredRivals = getRivals().stream() + .map(rivalTag -> SimpleClans.getInstance().getClanManager().getClan(rivalTag)).filter(Objects::nonNull) + .map(rival -> isWarring(rival) ? DARK_RED + "[" + rival.getTag() + "]" : rival.getColorTag()) + .map(ChatUtils::parseColors).collect(Collectors.joining(sep)); return coloredRivals.isEmpty() ? lang("none", viewer) : coloredRivals; + } /** @@ -737,7 +932,9 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public String getRivalString(String sep) { + return getRivalString(sep, null); + } /** @@ -746,8 +943,10 @@ public class Clan implements Serializable, Comparable { * @return the formatted leaders string */ public String getLeadersString(String prefix, String sep) { - return members.stream().filter(ClanPlayer::isLeader).map(ClanPlayer::getName). - collect(Collectors.joining(sep, prefix, "")); + + return members.stream().filter(ClanPlayer::isLeader).map(ClanPlayer::getName) + .collect(Collectors.joining(sep, prefix, "")); + } /** @@ -756,9 +955,10 @@ public class Clan implements Serializable, Comparable { * @return the leaders */ public boolean isLeader(Player player) { - return isLeader(player.getUniqueId()); - } + return isLeader(player.getUniqueId()); + + } /** * Check if a player is a leader of a clan @@ -766,30 +966,41 @@ public class Clan implements Serializable, Comparable { * @return the leaders */ public boolean isLeader(UUID playerUniqueId) { + if (isMember(playerUniqueId)) { + ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(playerUniqueId); return cp != null && cp.isLeader(); + } return false; + } @SuppressWarnings("deprecation") public boolean isLeader(String playerName) { + return isLeader(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** - * Get all members that must pay the fee (that excludes leaders and players with the permission to bypass it) + * Get all members that must pay the fee (that excludes leaders and players with + * the permission to bypass it) * * @return the fee payers */ public Set getFeePayers() { + return getMembers().stream().filter(cp -> !cp.isLeader()).filter(cp -> { + Rank rank = getRank(cp.getRankId()); return rank == null || !rank.getPermissions().contains(RankPermission.FEE_BYPASS.toString()); + }).collect(Collectors.toSet()); + } /** @@ -798,7 +1009,9 @@ public class Clan implements Serializable, Comparable { * @return the members */ public List getMembers() { + return new ArrayList<>(members); + } /** @@ -808,7 +1021,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder(value = "onlinemembers_count", resolver = "list_size", config = "filter_vanished") public List getOnlineMembers() { + return members.stream().filter(cp -> cp.toPlayer() != null).collect(Collectors.toList()); + } /** @@ -818,7 +1033,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder(value = "leader_size", resolver = "list_size") public List getLeaders() { + return members.stream().filter(ClanPlayer::isLeader).collect(Collectors.toList()); + } /** @@ -827,7 +1044,9 @@ public class Clan implements Serializable, Comparable { * @return non leaders */ public List getNonLeaders() { + return members.stream().filter(cp -> !cp.isLeader()).collect(Collectors.toList()); + } /** @@ -837,24 +1056,32 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public List getAllMembers() { + return getMembers(); + } /** * Get all the ally clan's members */ public Set getAllAllyMembers() { + Set out = new HashSet<>(); for (String tag : allies) { + Clan ally = SimpleClans.getInstance().getClanManager().getClan(tag); if (ally != null) { + out.addAll(ally.getMembers()); + } + } return out; + } /** @@ -863,22 +1090,31 @@ public class Clan implements Serializable, Comparable { @Placeholder(value = "total_kdr", resolver = "kdr") @Placeholder(value = "topclans_position", resolver = "ranking_position") public float getTotalKDR() { + if (members.isEmpty()) { + return 0; + } + double totalWeightedKills = 0; int totalDeaths = 0; for (ClanPlayer cp : members) { + totalWeightedKills += cp.getWeightedKills(); totalDeaths += cp.getDeaths(); + } if (totalDeaths == 0) { + totalDeaths = 1; + } return ((float) totalWeightedKills) / ((float) totalDeaths); + } /** @@ -886,17 +1122,23 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("total_deaths") public int getTotalDeaths() { + int totalDeaths = 0; if (members.isEmpty()) { + return totalDeaths; + } for (ClanPlayer cp : members) { + totalDeaths += cp.getDeaths(); + } return totalDeaths; + } /** @@ -904,22 +1146,30 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("average_wk") public int getAverageWK() { + int total = 0; if (members.isEmpty()) { + return total; + } for (ClanPlayer cp : members) { + total += cp.getWeightedKills(); + } return total / getSize(); + } @Placeholder("total_kills") public int getTotalKills() { + return getTotalCivilian() + getTotalNeutral() + getTotalRival() + getTotalAlly(); + } /** @@ -927,13 +1177,17 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("total_rival") public int getTotalRival() { + int total = 0; for (ClanPlayer cp : getMembers()) { + total += cp.getRivalKills(); + } return total; + } /** @@ -941,13 +1195,17 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("total_neutral") public int getTotalNeutral() { + int total = 0; for (ClanPlayer cp : getMembers()) { + total += cp.getNeutralKills(); + } return total; + } /** @@ -955,30 +1213,39 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("total_civilian") public int getTotalCivilian() { + int total = 0; for (ClanPlayer cp : getMembers()) { + total += cp.getCivilianKills(); + } return total; + } @Placeholder("total_ally") public int getTotalAlly() { + int total = 0; for (ClanPlayer cp : getMembers()) { + total += cp.getAllyKills(); + } return total; + } /** * Check whether the clan has crossed the rival limit */ public boolean reachedRivalLimit() { + int rivalCount = rivals.size(); int clanCount = SimpleClans.getInstance().getClanManager().getRivableClanCount() - 1; double rivalPercent = SimpleClans.getInstance().getSettingsManager().getPercent(RIVAL_LIMIT_PERCENT); @@ -986,19 +1253,23 @@ public class Clan implements Serializable, Comparable { double limit = ((double) clanCount) * (rivalPercent / ((double) 100)); return rivalCount > limit; + } /** * Add a new player to the clan */ public void addPlayerToClan(ClanPlayer cp) { + cp.removePastClan(getColorTag()); cp.setClan(this); cp.setLeader(false); cp.setJoinDate(new Date().getTime()); cp.setTrusted(SimpleClans.getInstance().getSettingsManager().is(CLAN_TRUST_MEMBERS_BY_DEFAULT)); if (defaultRank != null) { + cp.setRank(defaultRank); + } importMember(cp); @@ -1013,23 +1284,32 @@ public class Clan implements Serializable, Comparable { Player player = SimpleClans.getInstance().getServer().getPlayer(cp.getUniqueId()); if (player != null) { + SimpleClans.getInstance().getClanManager().updateDisplayName(player); + } + Bukkit.getPluginManager().callEvent(new PlayerJoinedClanEvent(this, cp)); + } @SuppressWarnings("deprecation") public void removePlayerFromClan(String playerName) { + removePlayerFromClan(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** * Remove a player from a clan */ public void removePlayerFromClan(UUID playerUniqueId) { + ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(playerUniqueId); if (cp == null || !isMember(playerUniqueId)) { + return; + } // remove clan group-permission @@ -1052,20 +1332,27 @@ public class Clan implements Serializable, Comparable { Player matched = SimpleClans.getInstance().getServer().getPlayer(playerUniqueId); if (matched != null) { + SimpleClans.getInstance().getClanManager().updateDisplayName(matched); + } + Bukkit.getPluginManager().callEvent(new PlayerKickedClanEvent(this, cp)); + } @SuppressWarnings("deprecation") public void promote(String playerName) { + promote(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** * Promote a member to a leader of a clan */ public void promote(UUID playerUniqueId) { + ClanPlayer cp = SimpleClans.getInstance().getClanManager().getCreateClanPlayer(playerUniqueId); cp.setLeader(true); @@ -1077,17 +1364,21 @@ public class Clan implements Serializable, Comparable { // add clan permission SimpleClans.getInstance().getPermissionsManager().addClanPermissions(cp); Bukkit.getPluginManager().callEvent(new PlayerPromoteEvent(this, cp)); + } @SuppressWarnings("deprecation") public void demote(String playerName) { + demote(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** * Demote a leader back to a member of a clan */ public void demote(UUID playerUniqueId) { + ClanPlayer cp = SimpleClans.getInstance().getClanManager().getCreateClanPlayer(playerUniqueId); cp.setLeader(false); @@ -1098,12 +1389,14 @@ public class Clan implements Serializable, Comparable { // add clan permission SimpleClans.getInstance().getPermissionsManager().addClanPermissions(cp); Bukkit.getPluginManager().callEvent(new PlayerDemoteEvent(this, cp)); + } /** * Add an ally to a clan, and the clan to the ally */ public void addAlly(Clan ally) { + removeRival(ally.getTag()); addAlly(ally.getTag()); @@ -1113,24 +1406,28 @@ public class Clan implements Serializable, Comparable { SimpleClans.getInstance().getStorageManager().updateClan(this); SimpleClans.getInstance().getStorageManager().updateClan(ally); Bukkit.getPluginManager().callEvent(new AllyClanAddEvent(this, ally)); + } /** * Remove an ally from the clan, and the clan from the ally */ public void removeAlly(Clan ally) { + removeAlly(ally.getTag()); ally.removeAlly(getTag()); SimpleClans.getInstance().getStorageManager().updateClan(this); SimpleClans.getInstance().getStorageManager().updateClan(ally); Bukkit.getPluginManager().callEvent(new AllyClanRemoveEvent(this, ally)); + } /** * Add a rival to the clan, and the clan to the rival */ public void addRival(Clan rival) { + removeAlly(rival.getTag()); addRival(rival.getTag()); @@ -1140,26 +1437,31 @@ public class Clan implements Serializable, Comparable { SimpleClans.getInstance().getStorageManager().updateClan(this); SimpleClans.getInstance().getStorageManager().updateClan(rival); Bukkit.getPluginManager().callEvent(new RivalClanAddEvent(this, rival)); + } /** * Removes a rival from the clan, the clan from the rival */ public void removeRival(Clan rival) { + removeRival(rival.getTag()); rival.removeRival(getTag()); SimpleClans.getInstance().getStorageManager().updateClan(this); SimpleClans.getInstance().getStorageManager().updateClan(rival); Bukkit.getPluginManager().callEvent(new RivalClanRemoveEvent(this, rival)); + } /** * Verify a clan */ public void verifyClan() { + setVerified(true); SimpleClans.getInstance().getStorageManager().updateClan(this); + } /** @@ -1167,7 +1469,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("is_anyonline") public boolean isAnyOnline() { + return members.stream().anyMatch(cp -> cp.toPlayer() != null); + } /** @@ -1177,6 +1481,7 @@ public class Clan implements Serializable, Comparable { * @return true if there are */ public boolean enoughLeadersOnlineToDemote(ClanPlayer cp) { + List online = getOnlineLeaders(); online.remove(cp); @@ -1185,8 +1490,8 @@ public class Clan implements Serializable, Comparable { double totalLeaders = getLeaders().size() - 1; double onlineLeaders = online.size(); - return ((onlineLeaders / totalLeaders) * 100) >= minimum; + } /** @@ -1195,22 +1500,30 @@ public class Clan implements Serializable, Comparable { * @return the online leaders */ public List getOnlineLeaders() { + return getOnlineMembers().stream().filter(ClanPlayer::isLeader).collect(Collectors.toList()); + } /** * Check whether all leaders of a clan are online */ public boolean allLeadersOnline() { + List leaders = getLeaders(); for (ClanPlayer leader : leaders) { + if (leader.toPlayer() == null) { + return false; + } + } return true; + } /** @@ -1218,100 +1531,140 @@ public class Clan implements Serializable, Comparable { */ @Deprecated public boolean allOtherLeadersOnline(String playerName) { + List leaders = getLeaders(); for (ClanPlayer leader : leaders) { + if (leader.getName().equalsIgnoreCase(playerName)) { + continue; + } if (leader.toPlayer() == null) { + return false; + } + } return true; + } /** * Check whether all leaders, except for the one passed in, are online */ public boolean allOtherLeadersOnline(UUID playerUniqueId) { + List leaders = getLeaders(); for (ClanPlayer leader : leaders) { + if (leader.getUniqueId().equals(playerUniqueId)) { + continue; + } if (leader.toPlayer() == null) { + return false; + } + } return true; + } /** * Change a clan's tag */ public void changeClanTag(String tag) { + setColorTag(tag); SimpleClans.getInstance().getStorageManager().updateClan(this); + } /** * Announce message to a whole clan */ public void clanAnnounce(String playerName, String msg) { + String message = SimpleClans.getInstance().getSettingsManager().getColored(CLANCHAT_ANNOUNCEMENT_COLOR) + msg; for (ClanPlayer cp : getMembers()) { + ChatBlock.sendMessage(cp, message); + } - Bukkit.getConsoleSender().sendMessage(AQUA + "[" + lang("clan.announce") + AQUA + "] " + AQUA + "[" + Helper.getColorName(playerName) + WHITE + "] " + message); + Bukkit.getConsoleSender().sendMessage(AQUA + "[" + lang("clan.announce") + AQUA + "] " + AQUA + "[" + + Helper.getColorName(playerName) + WHITE + "] " + message); + } /** * Announce message to all the leaders of a clan */ public void leaderAnnounce(String msg) { + String message = SimpleClans.getInstance().getSettingsManager().getColored(CLANCHAT_ANNOUNCEMENT_COLOR) + msg; List leaders = getLeaders(); for (ClanPlayer cp : leaders) { + ChatBlock.sendMessage(cp, message); + } + Bukkit.getConsoleSender().sendMessage(AQUA + "[" + lang("leader.announce") + AQUA + "] " + WHITE + message); + } /** * Add a new bb message and announce it to all online members of a clan */ public void addBb(String announcerName, String msg) { + if (isVerified()) { + addBb(msg); - clanAnnounce(announcerName, SimpleClans.getInstance().getSettingsManager().getColored(BB_PREFIX) + ChatUtils.parseColors(msg)); + clanAnnounce(announcerName, + SimpleClans.getInstance().getSettingsManager().getColored(BB_PREFIX) + ChatUtils.parseColors(msg)); + } + } /** * Add a new bb message and announce it to all online members of a clan */ public void addBb(String announcerName, String msg, boolean updateLastUsed) { + if (isVerified()) { + addBb(msg, updateLastUsed); - clanAnnounce(announcerName, SimpleClans.getInstance().getSettingsManager().getColored(BB_PREFIX) + ChatUtils.parseColors(msg)); + clanAnnounce(announcerName, + SimpleClans.getInstance().getSettingsManager().getColored(BB_PREFIX) + ChatUtils.parseColors(msg)); + } + } /** * Displays bb to a player */ public void displayBb(Player player) { + displayBb(player, -1); + } /** @@ -1320,8 +1673,11 @@ public class Clan implements Serializable, Comparable { * @param maxSize amount of lines to display */ public void displayBb(Player player, int maxSize) { + if (!isVerified()) { + return; + } SettingsManager settings = SimpleClans.getInstance().getSettingsManager(); @@ -1331,38 +1687,54 @@ public class Clan implements Serializable, Comparable { List localBb; if (maxSize == -1) { + localBb = bb; maxSize = settings.getInt(BB_SIZE); + } else { + localBb = new ArrayList<>(bb); + } while (localBb.size() > maxSize) { + localBb.remove(0); + } for (String msg : localBb) { + if (!sendBbTime(player, msg)) { + String bbPrefix = settings.getColored(BB_PREFIX); ChatBlock.sendMessage(player, bbPrefix + ChatUtils.parseColors(msg)); + } + } ChatBlock.sendBlank(player); + } /** - * Sends a bb message with the timestamp in a hover message, if the bb message is timestamped + * Sends a bb message with the timestamp in a hover message, if the bb message + * is timestamped * * @param msg the bb message * @return true if sent */ @SuppressWarnings("deprecation") private boolean sendBbTime(Player player, String msg) { + try { + int index = msg.indexOf("_"); if (index < 1) { + return false; + } String bbPrefix = SimpleClans.getInstance().getSettingsManager().getColored(BB_PREFIX); @@ -1372,13 +1744,17 @@ public class Clan implements Serializable, Comparable { BaseComponent[] baseComponent = TextComponent.fromLegacyText(msg); TextComponent textMessage = new TextComponent(baseComponent); - textMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText( - Dates.formatTime(time, 1) + lang("bb.ago")))); + textMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + TextComponent.fromLegacyText(Dates.formatTime(time, 1) + lang("bb.ago")))); player.spigot().sendMessage(textMessage); return true; + } catch (Exception rock) { + return false; + } + } /** @@ -1389,65 +1765,94 @@ public class Clan implements Serializable, Comparable { * @param force should it be force disbanded? */ public void disband(@Nullable CommandSender sender, boolean announce, boolean force) { + Collection clanPlayers = SimpleClans.getInstance().getClanManager().getAllClanPlayers(); List clans = SimpleClans.getInstance().getClanManager().getClans(); if (isPermanent() && !force) { + ChatBlock.sendMessage(sender, RED + lang("cannot.disband.permanent", sender)); return; + } if (announce) { + if (SimpleClans.getInstance().getSettingsManager().is(DISABLE_MESSAGES) && sender != null) { + clanAnnounce(sender.getName(), AQUA + lang("clan.has.been.disbanded", getName())); + } else { - SimpleClans.getInstance().getClanManager().serverAnnounce(AQUA + lang("clan.has.been.disbanded", getName())); + + SimpleClans.getInstance().getClanManager() + .serverAnnounce(AQUA + lang("clan.has.been.disbanded", getName())); + } + } SimpleClans.getInstance().getPermissionsManager().removeClanPermissions(this); for (ClanPlayer cp : clanPlayers) { + if (cp.getTag().equals(getTag())) { + cp.setClan(null); cp.setJoinDate(0); cp.setRank(null); if (isVerified()) { + cp.addPastClan(getColorTag() + (cp.isLeader() ? DARK_RED + "*" : "")); + } cp.setLeader(false); + } + } Bukkit.getPluginManager().callEvent(new DisbandClanEvent(sender, this)); clans.remove(this); for (Clan c : clans) { + String disbanded = lang("clan.disbanded"); if (c.removeWarringClan(this)) { + c.addBb(disbanded, lang("you.are.no.longer.at.war", c.getName(), getColorTag())); + } if (c.removeRival(getTag())) { + c.addBb(disbanded, lang("has.been.disbanded.rivalry.ended", getName())); + } if (c.removeAlly(getTag())) { + c.addBb(disbanded, lang("has.been.disbanded.alliance.ended", getName())); + } + } SimpleClans.getInstance().getRequestManager().removeRequest(getTag()); SimpleClans.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(SimpleClans.getInstance(), () -> { + SimpleClans.getInstance().getClanManager().removeClan(getTag()); SimpleClans.getInstance().getStorageManager().deleteClan(this); + }, 1); + } public void disband() { + disband(null, true, false); + } /** @@ -1455,7 +1860,9 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("is_unrivable") public boolean isUnrivable() { + return SimpleClans.getInstance().getSettingsManager().isUnrivable(getTag()); + } /** @@ -1464,7 +1871,9 @@ public class Clan implements Serializable, Comparable { * @param tag the tag of the clan we are at war with */ public boolean isWarring(String tag) { + return flags.getStringList(WARRING_KEY).contains(tag); + } /** @@ -1473,41 +1882,55 @@ public class Clan implements Serializable, Comparable { * @param clan the clan we are testing against */ public boolean isWarring(Clan clan) { + return isWarring(clan.getTag()); + } /** * Add a clan to be at war with */ public void addWarringClan(@Nullable ClanPlayer requestPlayer, Clan targetClan) { + List warring = flags.getStringList(WARRING_KEY); if (!warring.contains(targetClan.getTag())) { + warring.add(targetClan.getTag()); flags.put(WARRING_KEY, warring); if (requestPlayer != null) { - addBb(requestPlayer.getName(), lang("you.are.at.war", - getName(), targetClan.getColorTag())); + + addBb(requestPlayer.getName(), lang("you.are.at.war", getName(), targetClan.getColorTag())); + } + SimpleClans.getInstance().getStorageManager().updateClan(this); + } + } public void addWarringClan(Clan targetClan) { + addWarringClan(null, targetClan); + } /** * Remove a warring clan */ public boolean removeWarringClan(Clan clan) { + List warring = flags.getStringList(WARRING_KEY); if (warring.remove(clan.getTag())) { + flags.put(WARRING_KEY, warring); SimpleClans.getInstance().getStorageManager().updateClan(this); return true; + } return false; + } /** @@ -1516,8 +1939,10 @@ public class Clan implements Serializable, Comparable { * @return the clan list */ public List getWarringClans() { - return flags.getStringList(WARRING_KEY).stream().map(tag -> SimpleClans.getInstance().getClanManager() - .getClan(tag)).collect(Collectors.toList()); + + return flags.getStringList(WARRING_KEY).stream() + .map(tag -> SimpleClans.getInstance().getClanManager().getClan(tag)).collect(Collectors.toList()); + } /** @@ -1526,7 +1951,9 @@ public class Clan implements Serializable, Comparable { * @return the flags */ public String getFlags() { + return flags.toJSONString(); + } /** @@ -1535,23 +1962,33 @@ public class Clan implements Serializable, Comparable { * @param flagString the flags to set */ public void setFlags(String flagString) { + flags = new Flags(flagString); + } public void validateWarring() { + List warring = flags.getStringList(WARRING_KEY); Iterator iterator = warring.iterator(); while (iterator.hasNext()) { + String clanTag = iterator.next(); Clan clan = SimpleClans.getInstance().getClanManager().getClan(clanTag); if (clan == null) { + iterator.remove(); + } + } + flags.put(WARRING_KEY, warring); + } public void setHomeLocation(@Nullable Location home) { + flags.put("homeX", home != null ? home.getX() : 0); flags.put("homeY", home != null ? home.getY() : 0); flags.put("homeZ", home != null ? home.getZ() : 0); @@ -1563,17 +2000,25 @@ public class Clan implements Serializable, Comparable { flags.put("homeServer", name); SimpleClans.getInstance().getStorageManager().updateClan(this); + } public @Nullable Location getHomeLocation() { + String homeWorld = flags.getString("homeWorld"); if (homeWorld == null) { + return null; + } + World world = Bukkit.getWorld(homeWorld); if (world == null) { + return null; + } + double x = flags.getNumber("homeX").doubleValue(); double y = flags.getNumber("homeY").doubleValue(); double z = flags.getNumber("homeZ").doubleValue(); @@ -1581,18 +2026,23 @@ public class Clan implements Serializable, Comparable { float pitch = flags.getNumber("homePitch").floatValue(); return new Location(world, x, y, z, yaw, pitch); + } public String getTagLabel(boolean isLeader) { + SettingsManager sm = SimpleClans.getInstance().getSettingsManager(); String bracketColor = isLeader ? sm.getColored(TAG_BRACKET_LEADER_COLOR) : sm.getColored(TAG_BRACKET_COLOR); String bracketDefaultColor = sm.getColored(TAG_DEFAULT_COLOR); String bracketLeft = sm.getColored(TAG_BRACKET_LEFT); String bracketRight = sm.getColored(TAG_BRACKET_RIGHT); - String tagSeparatorColor = isLeader ? sm.getColored(TAG_SEPARATOR_LEADER_COLOR) : sm.getColored(TAG_SEPARATOR_COLOR); + String tagSeparatorColor = isLeader ? sm.getColored(TAG_SEPARATOR_LEADER_COLOR) + : sm.getColored(TAG_SEPARATOR_COLOR); String tagSeparator = sm.getString(TAG_SEPARATOR_CHAR); - return bracketColor + bracketLeft + bracketDefaultColor + getColorTag() + bracketColor + bracketRight + tagSeparatorColor + tagSeparator; + return bracketColor + bracketLeft + bracketDefaultColor + getColorTag() + bracketColor + bracketRight + + tagSeparatorColor + tagSeparator; + } /** @@ -1601,14 +2051,18 @@ public class Clan implements Serializable, Comparable { * @return true if enabled */ public boolean isMemberFeeEnabled() { + return feeEnabled; + } /** * Enables or disables the fee */ public void setMemberFeeEnabled(boolean enable) { + feeEnabled = enable; + } /** @@ -1616,14 +2070,18 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("allow_withdraw") public boolean isAllowWithdraw() { + return flags.getBoolean("allowWithdraw", false); + } /** * @param allowWithdraw the allowWithdraw to set */ public void setAllowWithdraw(boolean allowWithdraw) { + flags.put("allowWithdraw", allowWithdraw); + } /** @@ -1631,14 +2089,18 @@ public class Clan implements Serializable, Comparable { */ @Placeholder("allow_deposit") public boolean isAllowDeposit() { + return flags.getBoolean("allowDeposit", true); + } /** * @param allowDeposit the allowDeposit to set */ public void setAllowDeposit(boolean allowDeposit) { + flags.put("allowDeposit", allowDeposit); + } /** @@ -1647,15 +2109,19 @@ public class Clan implements Serializable, Comparable { * @param name the rank */ public boolean hasRank(@Nullable String name) { + return getRank(name) != null; + } /** * Creates a rank */ public void createRank(String name) { + Rank rank = new Rank(name); ranks.add(rank); + } /** @@ -1664,34 +2130,49 @@ public class Clan implements Serializable, Comparable { * @return the ranks */ public List getRanks() { + return ranks; + } /** * Sets the clan's ranks */ public void setRanks(@Nullable List ranks) { + if (ranks == null) { + ranks = new ArrayList<>(); + } + this.ranks = ranks; + } /** * Deletes a rank with the specified name */ public void deleteRank(String name) { + Rank r = getRank(name); if (r != null) { + ranks.remove(r); getMembers().forEach(cp -> { + if (Objects.equals(cp.getRankId(), r.getName())) { + cp.setRank(""); SimpleClans.getInstance().getStorageManager().updateClanPlayer(cp); + } + }); + } + } /** @@ -1701,14 +2182,23 @@ public class Clan implements Serializable, Comparable { * @return a rank or null */ public @Nullable Rank getRank(@Nullable String name) { + if (name != null) { + for (Rank r : ranks) { + if (r.getName().equals(name)) { + return r; + } + } + } + return null; + } /** @@ -1717,12 +2207,19 @@ public class Clan implements Serializable, Comparable { * @param name The name of the rank to be set as default */ public void setDefaultRank(@Nullable String name) { - // I don't know how this could happen, but if it somehow does, here's a check for it + + // I don't know how this could happen, but if it somehow does, here's a check + // for it if (!hasRank(name)) { + defaultRank = null; + } else { + defaultRank = name; + } + } /** @@ -1731,31 +2228,48 @@ public class Clan implements Serializable, Comparable { * @return The default rank or null if there is no default */ public @Nullable String getDefaultRank() { + return defaultRank; + } public void setBanner(@Nullable ItemStack banner) { + if (banner == null) { + this.banner = null; return; + } + banner = banner.clone(); banner.setAmount(1); ItemMeta itemMeta = banner.getItemMeta(); if (itemMeta != null) { - // hides the banner patterns from the lore (I don't know why it's called POTION_EFFECTS) + + // hides the banner patterns from the lore (I don't know why it's called + // POTION_EFFECTS) itemMeta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); itemMeta.setLore(null); itemMeta.setDisplayName(null); banner.setItemMeta(itemMeta); + } + this.banner = banner; + } public @Nullable ItemStack getBanner() { + if (banner != null) { + return banner.clone(); + } + return null; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanPlayer.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanPlayer.java index f7c67614..d3db9b21 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanPlayer.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanPlayer.java @@ -27,6 +27,7 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con * @author phaed */ public class ClanPlayer implements Serializable, Comparable { + private static final long serialVersionUID = 1L; private UUID uniqueId; private String displayName; @@ -49,12 +50,13 @@ public class ClanPlayer implements Serializable, Comparable { private @Nullable Locale locale; - /** * */ public ClanPlayer() { + this.tag = ""; + } /** @@ -62,49 +64,68 @@ public class ClanPlayer implements Serializable, Comparable { */ @Deprecated public ClanPlayer(String playerName) { + this(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** * @param uuid the Player's UUID */ public ClanPlayer(UUID uuid) { + uniqueId = uuid; Player onlinePlayer = SimpleClans.getInstance().getServer().getPlayer(uuid); if (onlinePlayer != null) { + displayName = onlinePlayer.getName(); + } else { + OfflinePlayer offlinePlayer = SimpleClans.getInstance().getServer().getOfflinePlayer(uuid); displayName = offlinePlayer.getName() != null ? offlinePlayer.getName() : "null"; + } + lastSeen = (new Date()).getTime(); joinDate = (new Date()).getTime(); tag = ""; + } @Override public int hashCode() { + return getName().hashCode() >> 13; + } @Override public boolean equals(Object obj) { + if (!(obj instanceof ClanPlayer)) { + return false; + } ClanPlayer other = (ClanPlayer) obj; return other.getName().equals(getName()); + } @Override public int compareTo(ClanPlayer other) { + return getUniqueId().compareTo(other.getUniqueId()); + } @Override public String toString() { + return displayName; + } /** @@ -114,7 +135,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("name") public String getName() { + return displayName; + } /** @@ -123,7 +146,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the uniqueId */ public UUID getUniqueId() { + return uniqueId; + } /** @@ -133,7 +158,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("clean_name") public String getCleanName() { + return displayName.toLowerCase(); + } /** @@ -142,7 +169,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param name the name to set */ public void setName(String name) { + displayName = name; + } /** @@ -151,7 +180,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param uniqueId the name to set */ public void setUniqueId(UUID uniqueId) { + this.uniqueId = uniqueId; + } /** @@ -161,7 +192,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("is_leader") public boolean isLeader() { + return leader; + } /** @@ -170,41 +203,52 @@ public class ClanPlayer implements Serializable, Comparable { * @param leader the leader to set */ public void setLeader(boolean leader) { + if (leader) { + trusted = true; + } this.leader = leader; + } /** * Check whether the player is an ally with another player */ public boolean isAlly(Player player) { + ClanPlayer allycp = SimpleClans.getInstance().getClanManager().getClanPlayer(player); if (allycp != null) { - //noinspection ConstantConditions + + // noinspection ConstantConditions return allycp.getClan().isAlly(tag); + } return false; + } /** * Check whether the player is an rival with another player */ public boolean isRival(Player player) { + ClanPlayer allycp = SimpleClans.getInstance().getClanManager().getClanPlayer(player); if (allycp != null) { - //noinspection ConstantConditions + + // noinspection ConstantConditions return allycp.getClan().isRival(tag); + } return false; - } + } /** * Returns the last seen date for this player in milliseconds @@ -212,7 +256,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the lastSeen */ public long getLastSeen() { + return lastSeen; + } /** @@ -221,14 +267,18 @@ public class ClanPlayer implements Serializable, Comparable { * @param lastSeen the lastSeen to set */ public void setLastSeen(long lastSeen) { + this.lastSeen = lastSeen; + } /** * Updates last seen date to today */ public void updateLastSeen() { + lastSeen = (new Date()).getTime(); + } /** @@ -236,7 +286,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("lastseendays") public String getLastSeenDaysString() { + return getLastSeenDaysString(null); + } /** @@ -244,31 +296,45 @@ public class ClanPlayer implements Serializable, Comparable { * @return a verbal representation of how many days ago a player was last seen */ public String getLastSeenDaysString(@Nullable CommandSender sender) { + double days = Dates.differenceInDays(new Timestamp(lastSeen), new Timestamp((new Date()).getTime())); if (days < 1) { + return lang("today", sender); + } else if (Math.round(days) == 1) { + return lang("1.color.day", sender, ChatColor.GRAY); + } else { + return lang("many.color.days", sender, Math.round(days), ChatColor.GRAY); + } + } public String getLastSeenDaysString(@Nullable Player viewer) { + return getLastSeenDaysString((CommandSender) viewer); + } /** * Returns number of days since the player was last seen */ public double getLastSeenDays() { + return Dates.differenceInDays(new Timestamp(lastSeen), new Timestamp((new Date()).getTime())); + } @Placeholder("total_kills") public int getTotalKills() { + return getRivalKills() + getCivilianKills() + getNeutralKills() + getAllyKills(); + } /** @@ -278,7 +344,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("rival_kills") public int getRivalKills() { + return kills.getOrDefault(Kill.Type.RIVAL, 0); + } /** @@ -287,7 +355,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param rivalKills the rivalKills to set */ public void setRivalKills(int rivalKills) { + kills.put(Kill.Type.RIVAL, rivalKills); + } /** @@ -295,7 +365,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Deprecated public void addRivalKill() { + setRivalKills(getRivalKills() + 1); + } /** @@ -305,7 +377,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("civilian_kills") public int getCivilianKills() { + return kills.getOrDefault(Kill.Type.CIVILIAN, 0); + } /** @@ -314,7 +388,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param civilianKills the civilianKills to set */ public void setCivilianKills(int civilianKills) { + kills.put(Kill.Type.CIVILIAN, civilianKills); + } /** @@ -322,7 +398,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Deprecated public void addCivilianKill() { + setCivilianKills(getCivilianKills() + 1); + } /** @@ -332,7 +410,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("neutral_kills") public int getNeutralKills() { + return kills.getOrDefault(Kill.Type.NEUTRAL, 0); + } /** @@ -341,7 +421,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param neutralKills the neutralKills to set */ public void setNeutralKills(int neutralKills) { + kills.put(Kill.Type.NEUTRAL, neutralKills); + } /** @@ -349,23 +431,31 @@ public class ClanPlayer implements Serializable, Comparable { */ @Deprecated public void addNeutralKill() { + setNeutralKills(getNeutralKills() + 1); + } public void setAllyKills(int allyKills) { + kills.put(Kill.Type.ALLY, allyKills); + } @Placeholder("ally_kills") public int getAllyKills() { + return kills.getOrDefault(Kill.Type.ALLY, 0); + } /** * Adds one kill to this player (does not update to db) */ public void addKill(Kill.Type type) { + kills.compute(type, (t, c) -> c == null ? 1 : c + 1); + } /** @@ -375,16 +465,21 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("is_friendlyfire_on") public boolean isFriendlyFire() { + return friendlyFire; + } /** - * Sets whether this player is allowing friendly fire (does not update clanplayer to db) + * Sets whether this player is allowing friendly fire (does not update + * clanplayer to db) * * @param friendlyFire the friendlyFire to set */ public void setFriendlyFire(boolean friendlyFire) { + this.friendlyFire = friendlyFire; + } /** @@ -393,7 +488,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the vote */ public @Nullable VoteResult getVote() { + return vote; + } /** @@ -402,7 +499,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param vote the vote to set */ public void setVote(@Nullable VoteResult vote) { + this.vote = vote; + } /** @@ -412,7 +511,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("deaths") public int getDeaths() { + return deaths; + } /** @@ -421,30 +522,40 @@ public class ClanPlayer implements Serializable, Comparable { * @param deaths the deaths to set */ public void setDeaths(int deaths) { + this.deaths = deaths; + } /** - * Adds one death to this player (does not update clanplayer to db) + * Adds one death to this player (does not update clanplayer to db) */ public void addDeath() { + setDeaths(getDeaths() + 1); + } /** - * Returns weighted kill score for this player (kills multiplied by the different weights) + * Returns weighted kill score for this player (kills multiplied by the + * different weights) */ @Placeholder("weighted_kills") public double getWeightedKills() { + SettingsManager settings = SimpleClans.getInstance().getSettingsManager(); - double kills = getRivalKills() * settings.getDouble(KILL_WEIGHTS_RIVAL) + - getNeutralKills() * settings.getDouble(KILL_WEIGHTS_NEUTRAL) + - getAllyKills() * settings.getDouble(KILL_WEIGHTS_ALLY) + - getCivilianKills() * settings.getDouble(KILL_WEIGHTS_CIVILIAN); + double kills = getRivalKills() * settings.getDouble(KILL_WEIGHTS_RIVAL) + + getNeutralKills() * settings.getDouble(KILL_WEIGHTS_NEUTRAL) + + getAllyKills() * settings.getDouble(KILL_WEIGHTS_ALLY) + + getCivilianKills() * settings.getDouble(KILL_WEIGHTS_CIVILIAN); if (kills < 0) { + return 0; + } + return kills; + } /** @@ -453,22 +564,29 @@ public class ClanPlayer implements Serializable, Comparable { @Placeholder(value = "kdr", resolver = "kdr") @Placeholder(value = "topplayers_position", resolver = "ranking_position") public float getKDR() { + int totalDeaths = getDeaths(); if (totalDeaths == 0) { + totalDeaths = 1; + } return ((float) getWeightedKills()) / ((float) totalDeaths); + } /** - * Returns the player's join date to his current clan in milliseconds, 0 if not in a clan + * Returns the player's join date to his current clan in milliseconds, 0 if not + * in a clan * * @return the joinDate */ public long getJoinDate() { + return joinDate; + } /** @@ -477,7 +595,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param joinDate the joinDate to set */ public void setJoinDate(long joinDate) { + this.joinDate = joinDate; + } /** @@ -485,10 +605,15 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("join_date") public String getJoinDateString() { + if (joinDate == 0) { + return ""; + } + return DateFormat.formatDateTime(joinDate); + } /** @@ -497,7 +622,9 @@ public class ClanPlayer implements Serializable, Comparable { @Placeholder("lastseen") @NotNull public String getLastSeenString() { + return getLastSeenString(null); + } /** @@ -505,14 +632,21 @@ public class ClanPlayer implements Serializable, Comparable { * @return a string representation of the last seen date */ public String getLastSeenString(@Nullable Player viewer) { + return getLastSeenString((CommandSender) viewer); + } public String getLastSeenString(@Nullable CommandSender sender) { + if (!VanishUtils.isVanished(sender, this)) { + return lang("online", sender); + } + return DateFormat.formatDateTime(lastSeen); + } /** @@ -520,8 +654,10 @@ public class ClanPlayer implements Serializable, Comparable { */ @Placeholder("inactive_days") public int getInactiveDays() { + Timestamp now = new Timestamp((new Date()).getTime()); return (int) Math.floor(Dates.differenceInDays(new Timestamp(getLastSeen()), now)); + } /** @@ -530,7 +666,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the PackedPastClans */ public String getPackedPastClans() { + return String.join("|", getPastClans()); + } /** @@ -539,15 +677,19 @@ public class ClanPlayer implements Serializable, Comparable { * @param packedPastClans the packedPastClans to set */ public void setPackedPastClans(String packedPastClans) { + String[] clans = packedPastClans.split("\\|"); Collections.addAll(pastClans, clans); + } /** * Adds a past clan to the player (does not update the clanplayer to db) */ public void addPastClan(String tag) { + getPastClans().add(tag); + } /** @@ -556,34 +698,42 @@ public class ClanPlayer implements Serializable, Comparable { * @param tag is the clan's colored tag */ public void removePastClan(String tag) { + getPastClans().remove(tag); + } /** * @param sep the separator - * @return a separator delimited string with the color tags for all past clans this player has been in + * @return a separator delimited string with the color tags for all past clans + * this player has been in */ @NotNull public String getPastClansString(@NotNull String sep) { + return getPastClansString(sep, null); + } /** * @param sep the separator * @param viewer the Player viewing the clan's string - * @return a separator delimited string with the color tags for all past clans this player has been in + * @return a separator delimited string with the color tags for all past clans + * this player has been in */ @NotNull public String getPastClansString(String sep, @Nullable Player viewer) { + if (getPastClans().isEmpty()) { + return lang("none", viewer); + } SettingsManager settings = SimpleClans.getInstance().getSettingsManager(); - return getPastClans().stream(). - sorted(Collections.reverseOrder()). - limit(settings.getInt(PAST_CLANS_LIMIT)). - collect(Collectors.joining(sep)); + return getPastClans().stream().sorted(Collections.reverseOrder()).limit(settings.getInt(PAST_CLANS_LIMIT)) + .collect(Collectors.joining(sep)); + } /** @@ -592,7 +742,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the pastClans */ public Set getPastClans() { + return pastClans; + } /** @@ -601,7 +753,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the resign times */ public Map getResignTimes() { + return resignTimes; + } /** @@ -610,29 +764,42 @@ public class ClanPlayer implements Serializable, Comparable { * @return the time in millis */ public Long getResignTime(String tag) { + return resignTimes.get(tag); + } /** * Sets the resign times (does not update to db) */ public void setResignTimes(@Nullable Map resignTimes) { + if (resignTimes != null) { + final int cooldown = SimpleClans.getInstance().getSettingsManager().getInt(REJOIN_COOLDOWN); resignTimes.forEach((k, v) -> { + long timePassed = Instant.ofEpochMilli(v).until(Instant.now(), ChronoUnit.MINUTES); if (timePassed < cooldown) { + this.resignTimes.put(k, v); + } + }); + } + } /** * Adds the clan to the resign times map */ public void addResignTime(String tag) { - if (tag != null) resignTimes.put(tag, System.currentTimeMillis()); + + if (tag != null) + resignTimes.put(tag, System.currentTimeMillis()); + } /** @@ -643,7 +810,9 @@ public class ClanPlayer implements Serializable, Comparable { @Nullable @Placeholder(value = "in_clan", resolver = "not_null_return") public Clan getClan() { + return clan; + } /** @@ -652,37 +821,49 @@ public class ClanPlayer implements Serializable, Comparable { * @param clan the clan to set */ public void setClan(@Nullable Clan clan) { + if (clan == null) { + tag = ""; + } else { + tag = clan.getTag(); + } this.clan = clan; + } /** - * Returns this player's clan's tag. Empty string if he's not in a clan. + * Returns this player's clan's tag. Empty string if he's not in a clan. * * @return the tag */ @Placeholder("tag") public String getTag() { + return tag; + } /** - * Returns this player's clan's tag label. Empty string if he's not in a clan. + * Returns this player's clan's tag label. Empty string if he's not in a clan. * * @return the tag */ @Placeholder("tag_label") public String getTagLabel() { + if (clan == null) { + return ""; + } return clan.getTagLabel(isLeader()); + } /** @@ -693,7 +874,9 @@ public class ClanPlayer implements Serializable, Comparable { @Placeholder(value = "is_trusted", resolver = "member_status") @Placeholder(value = "is_member", resolver = "member_status") public boolean isTrusted() { + return leader || trusted; + } /** @@ -702,7 +885,9 @@ public class ClanPlayer implements Serializable, Comparable { * @param trusted the trusted to set */ public void setTrusted(boolean trusted) { + this.trusted = trusted; + } /** @@ -711,7 +896,9 @@ public class ClanPlayer implements Serializable, Comparable { * @return the flags */ public String getFlags() { + return flags.toJSONString(); + } /** @@ -720,118 +907,167 @@ public class ClanPlayer implements Serializable, Comparable { * @param flagString the flags to set */ public void setFlags(String flagString) { + flags = new Flags(flagString); + } @Placeholder(value = "clanchat_player_color", resolver = "player_color") @Placeholder(value = "allychat_player_color", resolver = "player_color") public @NotNull Channel getChannel() { + String channelName = flags.getString("channel"); try { + if (channelName != null) { + return Channel.valueOf(channelName); + } + } catch (IllegalArgumentException ignored) { + } + return Channel.NONE; + } @Deprecated public boolean isGlobalChat() { + return false; + } @Deprecated public boolean isAllyChat() { + return true; + } @Deprecated public boolean isClanChat() { + return true; + } @Deprecated public void setGlobalChat(boolean globalChat) { + } @Deprecated public void setAllyChat(boolean allyChat) { + } @Deprecated public void setClanChat(boolean clanChat) { + } public void setChannel(@NotNull Channel channel) { + flags.put("channel", channel.toString()); + } @Placeholder("is_bb_enabled") public boolean isBbEnabled() { + return flags.getBoolean("bb-enabled", true); + } public void setBbEnabled(boolean bbEnabled) { + flags.put("bb-enabled", bbEnabled); SimpleClans.getInstance().getStorageManager().updateClanPlayer(this); + } @Placeholder("is_invite_enabled") public boolean isInviteEnabled() { + return flags.getBoolean("invite", true); + } public void setInviteEnabled(boolean inviteEnabled) { + flags.put("invite", inviteEnabled); SimpleClans.getInstance().getStorageManager().updateClanPlayer(this); + } @Deprecated public boolean isCapeEnabled() { + return false; + } @Deprecated public void setCapeEnabled(boolean capeEnabled) { + } @Placeholder("is_tag_enabled") public boolean isTagEnabled() { + return flags.getBoolean("hide-tag", true); + } public void setTagEnabled(boolean tagEnabled) { + flags.put("hide-tag", tagEnabled); SimpleClans.getInstance().getStorageManager().updateClanPlayer(this); SimpleClans.getInstance().getClanManager().updateDisplayName(toPlayer()); + } @Deprecated public boolean isUseChatShortcut() { + return false; + } @Placeholder("rank_displayname") public String getRankDisplayName() { + if (clan != null) { + Rank r = clan.getRank(getRankId()); if (r != null) { + return r.getDisplayName(); + } + } + return ""; + } @Placeholder("has_rank") public boolean hasRank() { + return !getRankId().isEmpty(); + } @Placeholder("rank") public @NotNull String getRankId() { + return flags.getString("rank", ""); + } /** @@ -839,7 +1075,9 @@ public class ClanPlayer implements Serializable, Comparable { */ @Deprecated public String getRank() { + return getRankDisplayName(); + } /** @@ -848,42 +1086,59 @@ public class ClanPlayer implements Serializable, Comparable { * @param rank the rank id */ public void setRank(@Nullable String rank) { + flags.put("rank", rank == null ? "" : rank); + } public @Nullable Locale getLocale() { + return locale; + } public void setLocale(@Nullable Locale locale) { + this.locale = locale; + } public @Nullable Player toPlayer() { + if (uniqueId != null) { + return Bukkit.getPlayer(uniqueId); + } else { + return Bukkit.getPlayer(displayName); + } + } public void mute(Channel channel, boolean b) { + switch (channel) { + case CLAN: clanChatMute = b; break; case ALLY: allyChatMute = b; - } - } + } + + } /** * @deprecated use {@link ClanPlayer#mute(Channel, boolean)} */ @Deprecated public void setMuted(boolean b) { + clanChatMute = b; + } /** @@ -891,45 +1146,60 @@ public class ClanPlayer implements Serializable, Comparable { */ @Deprecated public void setMutedAlly(boolean b) { + allyChatMute = b; + } @Placeholder("is_muted") public boolean isMuted() { + return clanChatMute; + } @Placeholder("is_mutedally") public boolean isMutedAlly() { + return allyChatMute; + } public void disallow(@NotNull Action action, @NotNull String landId) { + String key = "allow-" + action.name(); List allowed = flags.getStringList(key); if (allowed.remove(landId)) { + flags.put(key, allowed); + } + } public void allow(@NotNull Action action, @NotNull String landId) { + String key = "allow-" + action.name(); List allowed = flags.getStringList(key); if (!allowed.contains(landId)) { + allowed.add(landId); flags.put(key, allowed); + } + } public boolean isAllowed(@NotNull Action action, @NotNull String landId) { + String key = "allow-" + action.name(); List allowed = flags.getStringList(key); return allowed.contains(landId); + } public enum Channel { - CLAN, - ALLY, - NONE + CLAN, ALLY, NONE } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanRequest.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanRequest.java index 8200a9a3..53620408 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanRequest.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ClanRequest.java @@ -1,10 +1,10 @@ -package net.sacredlabyrinth.phaed.simpleclans; - -/** - * Clan Requests - * @author phaed - */ -public enum ClanRequest -{ - DEMOTE, PROMOTE, DISBAND, INVITE, CREATE_ALLY, BREAK_RIVALRY, START_WAR, END_WAR, RENAME -} +package net.sacredlabyrinth.phaed.simpleclans; + +/** + * Clan Requests + * + * @author phaed + */ +public enum ClanRequest { + DEMOTE, PROMOTE, DISBAND, INVITE, CREATE_ALLY, BREAK_RIVALRY, START_WAR, END_WAR, RENAME +} diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Dates.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Dates.java index f1146c8d..dea38e0e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Dates.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Dates.java @@ -13,121 +13,190 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class Dates { private Dates() { + } public static double differenceInMonths(Timestamp date1, Timestamp date2) { + return differenceInMonths(new Date(date1.getTime()), new Date(date2.getTime())); + } public static double differenceInYears(Timestamp date1, Timestamp date2) { + return differenceInYears(new Date(date1.getTime()), new Date(date2.getTime())); + } public static double differenceInDays(Timestamp date1, Timestamp date2) { + return differenceInDays(new Date(date1.getTime()), new Date(date2.getTime())); + } public static double differenceInHours(Timestamp date1, Timestamp date2) { + return differenceInHours(new Date(date1.getTime()), new Date(date2.getTime())); + } public static double differenceInMinutes(Timestamp date1, Timestamp date2) { + return differenceInMinutes(new Date(date1.getTime()), new Date(date2.getTime())); + } public static double differenceInSeconds(Timestamp date1, Timestamp date2) { + return differenceInSeconds(new Date(date1.getTime()), new Date(date2.getTime())); + } public static double differenceInMonths(Date date1, Date date2) { + return differenceInYears(date1, date2) * 12; + } public static double differenceInYears(Date date1, Date date2) { + double days = differenceInDays(date1, date2); return days / 365.2425; + } public static double differenceInDays(Date date1, Date date2) { + return differenceInHours(date1, date2) / 24.0; + } public static double differenceInHours(Date date1, Date date2) { + return differenceInMinutes(date1, date2) / 60.0; + } public static double differenceInMinutes(Date date1, Date date2) { + return differenceInSeconds(date1, date2) / 60.0; + } public static double differenceInSeconds(Date date1, Date date2) { + return differenceInMilliseconds(date1, date2) / 1000.0; + } private static double differenceInMilliseconds(Date date1, Date date2) { + return Math.abs(getTimeInMilliseconds(date1) - getTimeInMilliseconds(date2)); + } private static long getTimeInMilliseconds(Date date) { + Calendar cal = Calendar.getInstance(); cal.setTime(date); return cal.getTimeInMillis() + cal.getTimeZone().getOffset(cal.getTimeInMillis()); + } /** *

* authors: RoboMWM, LaxWasHere *

+ * * @param seconds the time in seconds - * @param depth Max amount of detail (e.g. only display days and hours if set to 1 and seconds {@literal >} 1 day) - * @return the string representation of the amount of time labeled as days, hours, minutes, seconds + * @param depth Max amount of detail (e.g. only display days and hours if set + * to 1 and seconds {@literal >} 1 day) + * @return the string representation of the amount of time labeled as days, + * hours, minutes, seconds */ public static String formatTime(Long seconds, int depth) { + if (seconds == null || seconds < 1) { + return lang("bb.moments"); + } if (seconds < 60) { + return seconds + lang("bb.seconds"); + } if (seconds < 3600) { + long count = (long) Math.ceil(seconds / 60f); String res; if (count > 1) { + res = count + lang("bb.minutes"); + } else { + res = lang("bb.one.minute"); + } + long remaining = seconds % 60; if (depth > 0 && remaining >= 5) { + return res + ", " + formatTime(remaining, --depth); + } + return res; + } + if (seconds < 86400) { + long count = (long) Math.ceil(seconds / 3600f); String res; if (count > 1) { + res = count + lang("bb.hours"); + } else { + res = lang("bb.one.hour"); + } + if (depth > 0) { + return res + ", " + formatTime(seconds % 3600, --depth); + } + return res; + } + long count = (long) Math.ceil(seconds / 86400f); String res; if (count > 1) { + res = count + lang("bb.days"); + } else { + res = lang("bb.one.day"); + } + if (depth > 0) { + return res + ", " + formatTime(seconds % 86400, --depth); + } + return res; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Flags.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Flags.java index df0e02a5..b2764ae7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Flags.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Flags.java @@ -15,73 +15,115 @@ public class Flags { private final JsonObject flags; public Flags(@Nullable String json) { + if (json != null && !json.isEmpty()) { + flags = gson.fromJson(json, JsonObject.class); + } else { + flags = new JsonObject(); + } + } @NotNull public List getStringList(@NotNull String key) { + JsonElement object = flags.get(key); ArrayList list = new ArrayList<>(); if (object != null && object.isJsonArray()) { + for (JsonElement element : object.getAsJsonArray()) { + list.add(element.getAsString()); + } + } + return list; + } @Nullable public String getString(@NotNull String key) { + JsonElement element = flags.get(key); if (element == null || element.isJsonNull()) { + return null; + } + return element.getAsString(); + } @NotNull public String getString(@NotNull String key, @NotNull String def) { + String string = getString(key); if (string == null) { + return def; + } + return string; + } @NotNull public Number getNumber(@NotNull String key) { + JsonElement element = flags.get(key); if (element == null || element.isJsonNull()) { + return 0; + } + return element.getAsNumber(); + } public boolean getBoolean(@NotNull String key) { + return getBoolean(key, false); + } public boolean getBoolean(@NotNull String key, boolean def) { + JsonElement element = flags.get(key); if (element == null || element.isJsonNull()) { + return def; + } + return element.getAsBoolean(); + } public void put(@NotNull String key, @NotNull List value) { + flags.add(key, gson.toJsonTree(value)); + } public void put(@NotNull String key, @NotNull Object object) { + flags.add(key, gson.toJsonTree(object)); + } public String toJSONString() { + return flags.toString(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Helper.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Helper.java index fb6971e3..4c88dfdc 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Helper.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Helper.java @@ -41,78 +41,103 @@ public final class Helper { private static final Gson GSON = new Gson(); private static final Type RANKS_TYPE = TypeToken.getParameterized(List.class, Rank.class).getType(); private static final Type RESIGN_TYPE = TypeToken.getParameterized(Map.class, String.class, Long.class).getType(); + private Helper() { + } @NotNull public static Locale forLanguageTag(@Nullable String languageTag) { + Locale defaultLanguage = SimpleClans.getInstance().getSettingsManager().getLanguage(); if (languageTag == null) { + return defaultLanguage; + } + return Locale.forLanguageTag(languageTag); + } @Contract("null -> null") @Nullable public static String toLanguageTag(@Nullable Locale locale) { + return locale != null ? locale.toLanguageTag() : null; + } public static Set getPathsIn(String path, Predicate filter) { + Set files = new LinkedHashSet<>(); String packagePath = path.replace(".", "/"); try { + URI uri = SimpleClans.class.getProtectionDomain().getCodeSource().getLocation().toURI(); FileSystem fileSystem = FileSystems.newFileSystem(URI.create("jar:" + uri), Collections.emptyMap()); - files = Files.walk(fileSystem.getPath(packagePath)). - filter(Objects::nonNull). - filter(filter). - collect(Collectors.toSet()); + files = Files.walk(fileSystem.getPath(packagePath)).filter(Objects::nonNull).filter(filter) + .collect(Collectors.toSet()); fileSystem.close(); + } catch (URISyntaxException | IOException ex) { - SimpleClans.getInstance().getLogger(). - log(Level.WARNING, "An error occurred while trying to load files: " + ex.getMessage(), ex); + + SimpleClans.getInstance().getLogger().log(Level.WARNING, + "An error occurred while trying to load files: " + ex.getMessage(), ex); + } return files; + } public static Set> getClasses(String packageName) { + Set> classes = new LinkedHashSet<>(); Predicate filter = entry -> { + String path = entry.getFileName().toString(); return !path.contains("$") && path.endsWith(".class"); + }; for (Path filesPath : getPathsIn(packageName, filter)) { + // Compatibility with different Java versions String path = filesPath.toString(); if (path.charAt(0) == '/') { + path = path.substring(1); + } String fileName = path.replace("/", ".").split(".class")[0]; try { + Class clazz = Class.forName(fileName); classes.add(clazz); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } return classes; + } @SuppressWarnings("unchecked") public static Set> getSubTypesOf(String packageName, Class type) { - return getClasses(packageName).stream(). - filter(type::isAssignableFrom). - map(aClass -> ((Class) aClass)). - collect(Collectors.toSet()); + + return getClasses(packageName).stream().filter(type::isAssignableFrom) + .map(aClass -> ((Class) aClass)).collect(Collectors.toSet()); + } /** @@ -122,12 +147,17 @@ public final class Helper { * @return a list of ranks or null if the JSON String is null/empty */ public static @Nullable List ranksFromJson(@Nullable String json) { + if (json != null && !json.isEmpty()) { + JsonObject object = GSON.fromJson(json, JsonObject.class); JsonElement ranks = object.get("ranks"); return GSON.fromJson(ranks, RANKS_TYPE); + } + return null; + } /** @@ -137,14 +167,21 @@ public final class Helper { * @return the default rank or null if not found and/or it does not exist */ public static @Nullable String defaultRankFromJson(@Nullable String json) { + if (json != null && !json.isEmpty()) { + JsonObject object = GSON.fromJson(json, JsonObject.class); JsonElement defaultRank = object.get("defaultRank"); if (defaultRank != null && !defaultRank.isJsonNull()) { + return defaultRank.getAsString(); + } + } + return null; + } /** @@ -155,6 +192,7 @@ public final class Helper { * @return a JSON String */ public static String ranksToJson(List ranks, @Nullable String defaultRank) { + if (ranks == null) ranks = new ArrayList<>(); @@ -162,6 +200,7 @@ public final class Helper { object.add("ranks", GSON.toJsonTree(ranks)); object.addProperty("defaultRank", defaultRank); return object.toString(); + } /** @@ -171,7 +210,9 @@ public final class Helper { * @return a JSON String */ public static String resignTimesToJson(Map resignTimes) { + return GSON.toJson(resignTimes); + } /** @@ -181,10 +222,15 @@ public final class Helper { * @return a map */ public static @Nullable Map resignTimesFromJson(String json) { + if (json != null && !json.isEmpty()) { + return GSON.fromJson(json, RESIGN_TYPE); + } + return null; + } /** @@ -195,17 +241,26 @@ public final class Helper { * @return the delay in seconds */ public static long getDelayTo(int hour, int minute) { - if (hour < 0 || hour > 23) hour = 1; - if (minute < 0 || minute > 59) minute = 0; + + if (hour < 0 || hour > 23) + hour = 1; + if (minute < 0 || minute > 59) + minute = 0; LocalDateTime now = LocalDateTime.now(); LocalDateTime d = LocalDateTime.of(now.toLocalDate(), LocalTime.of(hour, minute)); long delay; if (now.isAfter(d)) { + delay = now.until(d.plusDays(1), ChronoUnit.SECONDS); + } else { + delay = now.until(d, ChronoUnit.SECONDS); + } + return delay; + } /** @@ -215,14 +270,18 @@ public final class Helper { * @return */ public static String getColorName(String playerName) { + List players = SimpleClans.getInstance().getServer().matchPlayer(playerName); if (players.size() == 1) { + PermissionsManager pm = SimpleClans.getInstance().getPermissionsManager(); return pm.getPrefix(players.get(0)) + players.get(0).getName() + pm.getSuffix(players.get(0)); + } return playerName; + } /** @@ -232,10 +291,12 @@ public final class Helper { * @return */ public static List fromArrayToList(String... values) { + List results = new ArrayList<>(); Collections.addAll(results, values); results.remove(""); return results; + } /** @@ -246,20 +307,24 @@ public final class Helper { */ @Deprecated public static Set fromArrayToSet(String... values) { + HashSet results = new HashSet<>(); Collections.addAll(results, values); results.remove(""); return results; + } /** - * Converts {@literal ArrayList} to string array + * Converts {@literal ArrayList} to string array * * @param list * @return */ public static String[] toArray(List list) { + return list.toArray(new String[0]); + } /** @@ -268,12 +333,17 @@ public final class Helper { * @return */ public static String[] fromPermissionArray() { + RankPermission[] permissions = RankPermission.values(); String[] sa = new String[permissions.length]; for (int i = 0; i < permissions.length; i++) { + sa[i] = permissions[i].toString(); + } + return sa; + } /** @@ -283,7 +353,9 @@ public final class Helper { * @return */ public static String cleanTag(String tag) { + return stripColors(tag).toLowerCase(); + } /** @@ -293,12 +365,17 @@ public final class Helper { * @return */ public static String generatePageSeparator(String sep) { + String out = ""; for (int i = 0; i < 320; i++) { + out += sep; + } + return out; + } /** @@ -308,15 +385,21 @@ public final class Helper { * @return */ public static List stripOffLinePlayers(List in) { + List out = new ArrayList<>(); for (ClanPlayer cp : in) { + if (cp.toPlayer() != null) { + out.add(cp); + } + } return out; + } /** @@ -326,10 +409,15 @@ public final class Helper { * @return */ public static String escapeQuotes(@Nullable String str) { + if (str == null) { + return ""; + } + return str.replace("'", "''"); + } /** @@ -339,7 +427,9 @@ public final class Helper { * @return */ public static String toLocationString(Location loc) { + return loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + " " + loc.getWorld().getName(); + } /** @@ -349,14 +439,19 @@ public final class Helper { * @return the Map sorted */ public static > Map sortByValue(Map map) { + LinkedList> entryList = new LinkedList<>(map.entrySet()); entryList.sort(Entry.comparingByValue()); Map result = new LinkedHashMap<>(); for (Entry entry : entryList) { + result.put(entry.getKey(), entry.getValue()); + } + return result; + } /** @@ -366,24 +461,41 @@ public final class Helper { * @return formatted message */ public static String formatMaxInactiveDays(int max) { + if (max <= 0) { + return "∞"; + } else { + return String.valueOf(max); + } + } @NotNull public static String getFormattedClanStatus(Clan clan, CommandSender sender) { + ArrayList statuses = new ArrayList<>(); if (clan.isPermanent()) { + statuses.add(lang("permanent", sender)); + } + if (clan.isVerified()) { + statuses.add(lang("verified", sender)); + } else { + statuses.add(lang("unverified", sender)); + } + return String.join(", ", statuses); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Kill.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Kill.java index 082d379e..84b6ea63 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Kill.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Kill.java @@ -4,39 +4,54 @@ import java.time.LocalDateTime; public class Kill { - private final ClanPlayer killer; - private final ClanPlayer victim; - private final LocalDateTime time; - - public Kill(ClanPlayer killer, ClanPlayer victim, LocalDateTime time) { - this.killer = killer; - this.victim = victim; - this.time = time; - } + private final ClanPlayer killer; + private final ClanPlayer victim; + private final LocalDateTime time; - public ClanPlayer getKiller() { - return killer; - } + public Kill(ClanPlayer killer, ClanPlayer victim, LocalDateTime time) { - public ClanPlayer getVictim() { - return victim; - } + this.killer = killer; + this.victim = victim; + this.time = time; + + } + + public ClanPlayer getKiller() { + + return killer; + + } + + public ClanPlayer getVictim() { + + return victim; + + } + + public LocalDateTime getTime() { + + return time; + + } + + public enum Type { + + CIVILIAN("c"), RIVAL("r"), NEUTRAL("n"), ALLY("a"); + + Type(String shortName) { + + this.shortName = shortName; + + } + + private final String shortName; + + public String getShortname() { + + return shortName; + + } + + } - public LocalDateTime getTime() { - return time; - } - - public enum Type { - CIVILIAN("c"), RIVAL("r"), NEUTRAL("n"), ALLY("a"); - - Type(String shortName) { - this.shortName = shortName; - } - - private final String shortName; - - public String getShortname() { - return shortName; - } - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/PermissionLevel.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/PermissionLevel.java index eeb52eab..607ad493 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/PermissionLevel.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/PermissionLevel.java @@ -1,5 +1,5 @@ package net.sacredlabyrinth.phaed.simpleclans; public enum PermissionLevel { - LEADER, TRUSTED + LEADER, TRUSTED } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Rank.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Rank.java index 57933d9d..64e20f11 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Rank.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Rank.java @@ -6,102 +6,137 @@ import java.util.HashSet; import java.util.Set; /** -* -* @author RoinujNosde -*/ + * + * @author RoinujNosde + */ public class Rank implements Comparable { - - private String name; - private String displayName; - private Set permissions; - - public Rank(String name) { - setName(name); - permissions = new HashSet<>(); - setDisplayName(displayName); - } - - public Rank(String name, @Nullable String displayName, Set permissions) { - setName(name); - setDisplayName(displayName); - setPermissions(permissions); - } - - public void setName(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException("name cannot be null or empty"); - } - this.name = name; - } - public void setDisplayName(@Nullable String displayName) { - if (displayName == null || displayName.isEmpty()) { - displayName = name; - } - this.displayName = displayName; - } - - public void setPermissions(Set permissions) { - if (permissions == null) { - permissions = new HashSet<>(); - } - this.permissions = permissions; - } + private String name; + private String displayName; + private Set permissions; - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } + public Rank(String name) { - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Rank other = (Rank) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } + setName(name); + permissions = new HashSet<>(); + setDisplayName(displayName); - /** - * Returns the rank's permissions - * - * @return - */ - public Set getPermissions() { - return permissions; - } + } - /** - * Returns the rank's display name - * - * @return - */ - public String getDisplayName() { - return displayName; - } + public Rank(String name, @Nullable String displayName, Set permissions) { - /** - * Returns the rank's name - * - * @return - */ - public String getName() { - return name; - } + setName(name); + setDisplayName(displayName); + setPermissions(permissions); + + } + + public void setName(String name) { + + if (name == null || name.isEmpty()) { + + throw new IllegalArgumentException("name cannot be null or empty"); + + } + + this.name = name; + + } + + public void setDisplayName(@Nullable String displayName) { + + if (displayName == null || displayName.isEmpty()) { + + displayName = name; + + } + + this.displayName = displayName; + + } + + public void setPermissions(Set permissions) { + + if (permissions == null) { + + permissions = new HashSet<>(); + + } + + this.permissions = permissions; + + } + + @Override + public int hashCode() { + + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Rank other = (Rank) obj; + if (name == null) { + + if (other.name != null) + return false; + + } else if (!name.equals(other.name)) + return false; + + return true; + + } + + /** + * Returns the rank's permissions + * + * @return + */ + public Set getPermissions() { + + return permissions; + + } + + /** + * Returns the rank's display name + * + * @return + */ + public String getDisplayName() { + + return displayName; + + } + + /** + * Returns the rank's name + * + * @return + */ + public String getName() { + + return name; + + } + + @Override + public int compareTo(Rank other) { + + return Integer.compare(permissions.size(), other.permissions.size()); + + } - @Override - public int compareTo(Rank other) { - return Integer.compare(permissions.size(), other.permissions.size()); - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/RankPermission.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/RankPermission.java index 71be34aa..12a88f16 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/RankPermission.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/RankPermission.java @@ -10,81 +10,96 @@ import org.jetbrains.annotations.Nullable; */ public enum RankPermission { - ALLY_ADD("simpleclans.leader.ally", PermissionLevel.LEADER), - ALLY_CHAT("simpleclans.member.ally", PermissionLevel.TRUSTED), - ALLY_REMOVE("simpleclans.leader.ally", PermissionLevel.LEADER), - BANK_BALANCE("simpleclans.member.bank", PermissionLevel.TRUSTED), - BANK_DEPOSIT("simpleclans.member.bank", PermissionLevel.LEADER), - BANK_WITHDRAW("simpleclans.member.bank", PermissionLevel.LEADER), - BB_ADD("simpleclans.member.bb-add", PermissionLevel.TRUSTED), - BB_CLEAR("simpleclans.leader.bb-clear", PermissionLevel.LEADER), - COORDS("simpleclans.member.coords", PermissionLevel.TRUSTED), - FEE_ENABLE("simpleclans.leader.fee", PermissionLevel.LEADER), - FEE_SET("simpleclans.leader.fee", PermissionLevel.LEADER), - FEE_BYPASS("", PermissionLevel.LEADER), - REGROUP_HOME("simpleclans.leader.regroup.home", PermissionLevel.LEADER), - REGROUP_ME("simpleclans.leader.regroup.me", PermissionLevel.LEADER), - HOME_SET("simpleclans.leader.home-set", PermissionLevel.LEADER), - HOME_TP("simpleclans.member.home", PermissionLevel.TRUSTED), - INVITE("simpleclans.leader.invite", PermissionLevel.LEADER), - KICK("simpleclans.leader.kick", PermissionLevel.LEADER), - MODTAG("simpleclans.leader.modtag", PermissionLevel.LEADER), - RANK_DISPLAYNAME("simpleclans.leader.rank.setdisplayname", PermissionLevel.LEADER), - RANK_LIST("simpleclans.leader.rank.list", PermissionLevel.LEADER), - RIVAL_ADD("simpleclans.leader.rival", PermissionLevel.LEADER), - RIVAL_REMOVE("simpleclans.leader.rival", PermissionLevel.LEADER), - WAR_END("simpleclans.leader.war", PermissionLevel.LEADER), - WAR_START("simpleclans.leader.war", PermissionLevel.LEADER), - STATS("simpleclans.member.stats", PermissionLevel.TRUSTED), - VITALS("simpleclans.member.vitals", PermissionLevel.TRUSTED), - KILLS("simpleclans.member.kills", PermissionLevel.TRUSTED), - DESCRIPTION("simpleclans.leader.description", PermissionLevel.LEADER), - MOSTKILLED("simpleclans.mod.mostkilled", PermissionLevel.TRUSTED), - FRIENDLYFIRE("simpleclans.leader.ff", PermissionLevel.LEADER), - SETBANNER("simpleclans.leader.setbanner", PermissionLevel.LEADER); + ALLY_ADD("simpleclans.leader.ally", PermissionLevel.LEADER), + ALLY_CHAT("simpleclans.member.ally", PermissionLevel.TRUSTED), + ALLY_REMOVE("simpleclans.leader.ally", PermissionLevel.LEADER), + BANK_BALANCE("simpleclans.member.bank", PermissionLevel.TRUSTED), + BANK_DEPOSIT("simpleclans.member.bank", PermissionLevel.LEADER), + BANK_WITHDRAW("simpleclans.member.bank", PermissionLevel.LEADER), + BB_ADD("simpleclans.member.bb-add", PermissionLevel.TRUSTED), + BB_CLEAR("simpleclans.leader.bb-clear", PermissionLevel.LEADER), + COORDS("simpleclans.member.coords", PermissionLevel.TRUSTED), + FEE_ENABLE("simpleclans.leader.fee", PermissionLevel.LEADER), + FEE_SET("simpleclans.leader.fee", PermissionLevel.LEADER), FEE_BYPASS("", PermissionLevel.LEADER), + REGROUP_HOME("simpleclans.leader.regroup.home", PermissionLevel.LEADER), + REGROUP_ME("simpleclans.leader.regroup.me", PermissionLevel.LEADER), + HOME_SET("simpleclans.leader.home-set", PermissionLevel.LEADER), + HOME_TP("simpleclans.member.home", PermissionLevel.TRUSTED), + INVITE("simpleclans.leader.invite", PermissionLevel.LEADER), + KICK("simpleclans.leader.kick", PermissionLevel.LEADER), + MODTAG("simpleclans.leader.modtag", PermissionLevel.LEADER), + RANK_DISPLAYNAME("simpleclans.leader.rank.setdisplayname", PermissionLevel.LEADER), + RANK_LIST("simpleclans.leader.rank.list", PermissionLevel.LEADER), + RIVAL_ADD("simpleclans.leader.rival", PermissionLevel.LEADER), + RIVAL_REMOVE("simpleclans.leader.rival", PermissionLevel.LEADER), + WAR_END("simpleclans.leader.war", PermissionLevel.LEADER), + WAR_START("simpleclans.leader.war", PermissionLevel.LEADER), + STATS("simpleclans.member.stats", PermissionLevel.TRUSTED), + VITALS("simpleclans.member.vitals", PermissionLevel.TRUSTED), + KILLS("simpleclans.member.kills", PermissionLevel.TRUSTED), + DESCRIPTION("simpleclans.leader.description", PermissionLevel.LEADER), + MOSTKILLED("simpleclans.mod.mostkilled", PermissionLevel.TRUSTED), + FRIENDLYFIRE("simpleclans.leader.ff", PermissionLevel.LEADER), + SETBANNER("simpleclans.leader.setbanner", PermissionLevel.LEADER); - private final String bukkitPermission; - private final PermissionLevel permissionLevel; + private final String bukkitPermission; + private final PermissionLevel permissionLevel; - RankPermission(String bukkitPermission, PermissionLevel permissionLevel) { - this.bukkitPermission = bukkitPermission; - this.permissionLevel = permissionLevel; - } + RankPermission(String bukkitPermission, PermissionLevel permissionLevel) { - /** - * - * @return the Bukkit equivalent to this rank permission - */ - public String getBukkitPermission() { - return bukkitPermission; - } + this.bukkitPermission = bukkitPermission; + this.permissionLevel = permissionLevel; - /** - * - * @return the PermissionLevel - * - */ - public PermissionLevel getPermissionLevel() { - return permissionLevel; - } + } - @Override - public String toString() { - return super.toString().replace("_", ".").toLowerCase(); - } + /** + * + * @return the Bukkit equivalent to this rank permission + */ + public String getBukkitPermission() { + + return bukkitPermission; + + } + + /** + * + * @return the PermissionLevel + * + */ + public PermissionLevel getPermissionLevel() { + + return permissionLevel; + + } + + @Override + public String toString() { + + return super.toString().replace("_", ".").toLowerCase(); + + } + + /** + * + * @param permission the permission + * @return true if this is a valid rank permission + */ + @Contract("null -> false") + public static boolean isValid(@Nullable String permission) { + + for (RankPermission p : values()) { + + if (p.toString().equalsIgnoreCase(permission)) { + + return true; + + } + + } + + return false; + + } - /** - * - * @param permission the permission - * @return true if this is a valid rank permission - */ - @Contract("null -> false") - public static boolean isValid(@Nullable String permission) { - for (RankPermission p : values()) { - if (p.toString().equalsIgnoreCase(permission)) { - return true; - } - } - return false; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Request.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Request.java index 13043f4d..ff335494 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Request.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/Request.java @@ -1,184 +1,244 @@ -package net.sacredlabyrinth.phaed.simpleclans; - -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.REQUEST_MAX; - -/** - * @author phaed - */ -public final class Request { - private List acceptors = new ArrayList<>(); - private Clan clan; - private String msg; - private String target; - private ClanRequest type; - private ClanPlayer requester; - private int askCount; - - public Request(ClanRequest type, - @Nullable List acceptors, - ClanPlayer requester, - String target, - Clan clan, - String msg) { - this.type = type; - this.target = target; - this.clan = clan; - this.msg = msg; - if (acceptors != null) { - this.acceptors = acceptors; - } - this.requester = requester; - - cleanVotes(); - } - - /** - * @return the type - */ - public ClanRequest getType() { - return type; - } - - /** - * @param type the type to set - */ - public void setType(ClanRequest type) { - this.type = type; - } - - /** - * @return the acceptors - */ - public List getAcceptors() { - return Collections.unmodifiableList(acceptors); - } - - /** - * @param acceptors the acceptors to set - */ - public void setAcceptors(List acceptors) { - this.acceptors = acceptors; - } - - /** - * @return the clan - */ - public Clan getClan() { - return clan; - } - - /** - * @param clan the clan to set - */ - public void setClan(Clan clan) { - this.clan = clan; - } - - /** - * @return the msg - */ - public String getMsg() { - return msg; - } - - /** - * @param msg the msg to set - */ - public void setMsg(String msg) { - this.msg = msg; - } - - /** - * @return the target - */ - public String getTarget() { - return target; - } - - /** - * @param target the target to set - */ - public void setTarget(String target) { - this.target = target; - } - - public void vote(String playerName, VoteResult vote) { - for (ClanPlayer cp : acceptors) { - if (cp.getName().equalsIgnoreCase(playerName)) { - cp.setVote(vote); - } - } - } - - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public boolean votingFinished() { - for (ClanPlayer cp : acceptors) { - if (cp.getVote() == null) { - return false; - } - } - - return true; - } - - public List getDenies() { - List out = new ArrayList<>(); - - for (ClanPlayer cp : acceptors) { - if (cp.getVote() != null && cp.getVote().equals(VoteResult.DENY)) { - out.add(cp.getName()); - } - } - - return out; - } - - public List getAccepts() { - List out = new ArrayList<>(); - - for (ClanPlayer cp : acceptors) { - if (cp.getVote() != null && cp.getVote().equals(VoteResult.ACCEPT)) { - out.add(cp.getName()); - } - } - - return out; - } - - /** - * Cleans votes - */ - public void cleanVotes() { - for (ClanPlayer cp : acceptors) { - cp.setVote(null); - } - } - - /** - * @return the requester - */ - public ClanPlayer getRequester() { - return requester; - } - - /** - * @param requester the requester to set - */ - public void setRequester(ClanPlayer requester) { - this.requester = requester; - } - - public void incrementAskCount() { - askCount += 1; - } - - public boolean reachedRequestLimit() { - return askCount > SimpleClans.getInstance().getSettingsManager().getInt(REQUEST_MAX); - } -} +package net.sacredlabyrinth.phaed.simpleclans; + +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.REQUEST_MAX; + +/** + * @author phaed + */ +public final class Request { + + private List acceptors = new ArrayList<>(); + private Clan clan; + private String msg; + private String target; + private ClanRequest type; + private ClanPlayer requester; + private int askCount; + + public Request(ClanRequest type, @Nullable List acceptors, ClanPlayer requester, String target, + Clan clan, String msg) + { + + this.type = type; + this.target = target; + this.clan = clan; + this.msg = msg; + if (acceptors != null) { + + this.acceptors = acceptors; + + } + + this.requester = requester; + + cleanVotes(); + + } + + /** + * @return the type + */ + public ClanRequest getType() { + + return type; + + } + + /** + * @param type the type to set + */ + public void setType(ClanRequest type) { + + this.type = type; + + } + + /** + * @return the acceptors + */ + public List getAcceptors() { + + return Collections.unmodifiableList(acceptors); + + } + + /** + * @param acceptors the acceptors to set + */ + public void setAcceptors(List acceptors) { + + this.acceptors = acceptors; + + } + + /** + * @return the clan + */ + public Clan getClan() { + + return clan; + + } + + /** + * @param clan the clan to set + */ + public void setClan(Clan clan) { + + this.clan = clan; + + } + + /** + * @return the msg + */ + public String getMsg() { + + return msg; + + } + + /** + * @param msg the msg to set + */ + public void setMsg(String msg) { + + this.msg = msg; + + } + + /** + * @return the target + */ + public String getTarget() { + + return target; + + } + + /** + * @param target the target to set + */ + public void setTarget(String target) { + + this.target = target; + + } + + public void vote(String playerName, VoteResult vote) { + + for (ClanPlayer cp : acceptors) { + + if (cp.getName().equalsIgnoreCase(playerName)) { + + cp.setVote(vote); + + } + + } + + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public boolean votingFinished() { + + for (ClanPlayer cp : acceptors) { + + if (cp.getVote() == null) { + + return false; + + } + + } + + return true; + + } + + public List getDenies() { + + List out = new ArrayList<>(); + + for (ClanPlayer cp : acceptors) { + + if (cp.getVote() != null && cp.getVote().equals(VoteResult.DENY)) { + + out.add(cp.getName()); + + } + + } + + return out; + + } + + public List getAccepts() { + + List out = new ArrayList<>(); + + for (ClanPlayer cp : acceptors) { + + if (cp.getVote() != null && cp.getVote().equals(VoteResult.ACCEPT)) { + + out.add(cp.getName()); + + } + + } + + return out; + + } + + /** + * Cleans votes + */ + public void cleanVotes() { + + for (ClanPlayer cp : acceptors) { + + cp.setVote(null); + + } + + } + + /** + * @return the requester + */ + public ClanPlayer getRequester() { + + return requester; + + } + + /** + * @param requester the requester to set + */ + public void setRequester(ClanPlayer requester) { + + this.requester = requester; + + } + + public void incrementAskCount() { + + askCount += 1; + + } + + public boolean reachedRequestLimit() { + + return askCount > SimpleClans.getInstance().getSettingsManager().getInt(REQUEST_MAX); + + } + +} diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java index 4974d945..3c80dad8 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java @@ -1,363 +1,478 @@ -package net.sacredlabyrinth.phaed.simpleclans; - -import co.aikar.commands.BukkitCommandIssuer; -import net.sacredlabyrinth.phaed.simpleclans.commands.SCCommandManager; -import net.sacredlabyrinth.phaed.simpleclans.hooks.papi.SimpleClansExpansion; -import net.sacredlabyrinth.phaed.simpleclans.language.LanguageResource; -import net.sacredlabyrinth.phaed.simpleclans.listeners.*; -import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger; -import net.sacredlabyrinth.phaed.simpleclans.loggers.CSVBankLogger; -import net.sacredlabyrinth.phaed.simpleclans.managers.*; -import net.sacredlabyrinth.phaed.simpleclans.migrations.BbMigration; -import net.sacredlabyrinth.phaed.simpleclans.migrations.ChatFormatMigration; -import net.sacredlabyrinth.phaed.simpleclans.migrations.LanguageMigration; -import net.sacredlabyrinth.phaed.simpleclans.proxy.BungeeManager; -import net.sacredlabyrinth.phaed.simpleclans.proxy.ProxyManager; -import net.sacredlabyrinth.phaed.simpleclans.tasks.*; -import net.sacredlabyrinth.phaed.simpleclans.ui.InventoryController; -import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils; -import net.sacredlabyrinth.phaed.simpleclans.utils.TagValidator; -import net.sacredlabyrinth.phaed.simpleclans.utils.UpdateChecker; -import net.sacredlabyrinth.phaed.simpleclans.uuid.UUIDMigration; -import org.bstats.bukkit.Metrics; -import org.bstats.charts.SimplePie; -import org.bstats.charts.SingleLineChart; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; -import static org.bukkit.Bukkit.getPluginManager; - -/** - * @author Phaed - */ -public class SimpleClans extends JavaPlugin { - - private final ArrayList messages = new ArrayList<>(); - - private static SimpleClans instance; - private static LanguageResource languageResource; - private static final Logger logger = Logger.getLogger("SimpleClans"); - private SCCommandManager commandManager; - private ClanManager clanManager; - private RequestManager requestManager; - private StorageManager storageManager; - private SettingsManager settingsManager; - private PermissionsManager permissionsManager; - private TeleportManager teleportManager; - private ProtectionManager protectionManager; - private ChatManager chatManager; - private ProxyManager proxyManager; - private boolean hasUUID; - private static final Pattern ACF_PLACEHOLDER_PATTERN = Pattern.compile("\\{(?[a-zA-Z]+?)}"); - - private BankLogger bankLogger; - private TagValidator tagValidator; - - /** - * @return the logger - */ - @Deprecated - public static Logger getLog() { - return logger; - } - - public static void debug(String msg) { - //instance may be null during tests - if (getInstance() == null || getInstance().getSettingsManager().is(DEBUG)) { - logger.log(Level.INFO, msg); - } - } - - /** - * @return the instance - */ - public static SimpleClans getInstance() { - return instance; - } - - @Deprecated - public static void log(String msg, Object... arg) { - if (arg == null || arg.length == 0) { - logger.log(Level.INFO, msg); - } else { - logger.log(Level.INFO, MessageFormat.format(msg, arg)); - } - } - - @Override - public void onEnable() { - instance = this; - new LanguageMigration(this).migrate(); - settingsManager = new SettingsManager(this); - new BbMigration(settingsManager); - new ChatFormatMigration(settingsManager); - languageResource = new LanguageResource(); - this.hasUUID = UUIDMigration.canReturnUUID(); - - permissionsManager = new PermissionsManager(); - requestManager = new RequestManager(); - clanManager = new ClanManager(); - proxyManager = new BungeeManager(this); - storageManager = new StorageManager(); - teleportManager = new TeleportManager(); - protectionManager = new ProtectionManager(); - protectionManager.registerListeners(); - chatManager = new ChatManager(this); - registerEvents(); - permissionsManager.loadPermissions(); - commandManager = new SCCommandManager(this); - bankLogger = new CSVBankLogger(this); - - tagValidator = new TagValidator(settingsManager, permissionsManager); - - logStatus(); - startTasks(); - startMetrics(); - hookIntoPAPI(); - new UpdateChecker(this).check(); - } - - private void logStatus() { - getLogger().info("Multithreading: " + settingsManager.is(PERFORMANCE_USE_THREADS)); - getLogger().info("BungeeCord: " + settingsManager.is(PERFORMANCE_USE_BUNGEECORD)); - getLogger().info("HEX support: " + ChatUtils.HEX_COLOR_SUPPORT); - getLogger().info("Help us translate SimpleClans to your language! " + - "Access https://crowdin.com/project/simpleclans/"); - } - - private void registerEvents() { - PluginManager pm = getServer().getPluginManager(); - pm.registerEvents(new PlayerDeath(this), this); - pm.registerEvents(new SCPlayerListener(this), this); - pm.registerEvents(new InventoryController(), this); - pm.registerEvents(new TamableMobsSharing(this), this); - pm.registerEvents(new PvPOnlyInWar(this), this); - pm.registerEvents(new FriendlyFire(this), this); - } - - private void hookIntoPAPI() { - if (getPluginManager().getPlugin("PlaceholderAPI") != null) { - getLogger().info("PlaceholderAPI found. Registering hook..."); - new SimpleClansExpansion(this).register(); - } - } - - private void startMetrics() { - Metrics metrics = new Metrics(this, 7131); - SettingsManager sm = getSettingsManager(); - ClanManager cm = getClanManager(); - String on = "enabled"; - String off = "disabled"; - metrics.addCustomChart(new SingleLineChart("clans", () -> cm.getClans().size())); - metrics.addCustomChart(new SingleLineChart("clan_players", () -> cm.getAllClanPlayers().size())); - metrics.addCustomChart(new SimplePie("language", () -> sm.getLanguage().toString())); - metrics.addCustomChart(new SimplePie("machine_language", () -> Locale.getDefault().toString())); - metrics.addCustomChart(new SimplePie("language_chooser", () -> sm.is(LANGUAGE_SELECTOR) ? on : off)); - metrics.addCustomChart(new SimplePie("database", () -> sm.is(MYSQL_ENABLE) ? "MySQL" : "SQLite")); - metrics.addCustomChart(new SimplePie("save_periodically", () -> sm.is(PERFORMANCE_SAVE_PERIODICALLY) ? on : off)); - metrics.addCustomChart(new SimplePie("save_interval", () -> sm.getString(PERFORMANCE_SAVE_INTERVAL))); - metrics.addCustomChart(new SimplePie("upkeep", () -> sm.is(ECONOMY_UPKEEP_ENABLED) ? on : off)); - metrics.addCustomChart(new SimplePie("member_fee", () -> sm.is(ECONOMY_MEMBER_FEE_ENABLED) ? on : off)); - metrics.addCustomChart(new SimplePie("rejoin_cooldown", () -> sm.is(ENABLE_REJOIN_COOLDOWN) ? on : off)); - metrics.addCustomChart(new SimplePie("clan_verification", () -> sm.is(REQUIRE_VERIFICATION) ? on : off)); - metrics.addCustomChart(new SimplePie("money_per_kill", () -> sm.is(ECONOMY_MONEY_PER_KILL) ? on : off)); - metrics.addCustomChart(new SimplePie("threads", () -> sm.is(PERFORMANCE_USE_THREADS) ? on : off)); - metrics.addCustomChart(new SimplePie("bungeecord", () -> sm.is(PERFORMANCE_USE_BUNGEECORD) ? on : off)); - metrics.addCustomChart(new SimplePie("discord_chat", () -> sm.is(DISCORDCHAT_ENABLE) ? on : off)); - metrics.addCustomChart(new SimplePie("default_rank", () -> sm.getString(CLAN_DEFAULT_RANK).isEmpty() ? off : on)); - } - - private void startTasks() { - if (getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) { - new SaveDataTask().start(); - } - if (getSettingsManager().is(ECONOMY_MEMBER_FEE_ENABLED)) { - new CollectFeeTask().start(); - } - if (getSettingsManager().is(ECONOMY_UPKEEP_ENABLED)) { - new CollectUpkeepTask().start(); - new UpkeepWarningTask().start(); - } - if (getSettingsManager().is(PERFORMANCE_HEAD_CACHING)) { - new PlayerHeadCacheTask(this).start(); - } - } - - @Override - public void onDisable() { - if (getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) { - getStorageManager().saveModified(); - } - getStorageManager().closeConnection(); - getPermissionsManager().savePermissions(); - getSettingsManager().loadAndSave(); - } - - /** - * @return the clanManager - */ - public ClanManager getClanManager() { - return clanManager; - } - - /** - * @return the requestManager - */ - public RequestManager getRequestManager() { - return requestManager; - } - - /** - * @return the storageManager - */ - public StorageManager getStorageManager() { - return storageManager; - } - - /** - * @return the settingsManager - */ - public SettingsManager getSettingsManager() { - return settingsManager; - } - - /** - * @return the permissionsManager - */ - @NotNull - public PermissionsManager getPermissionsManager() { - return permissionsManager; - } - - public SCCommandManager getCommandManager() { - return commandManager; - } - - public ProtectionManager getProtectionManager() { - return protectionManager; - } - - public ChatManager getChatManager() { - return chatManager; - } - - public ProxyManager getProxyManager() { - return proxyManager; - } - - public BankLogger getBankLogger() { - return bankLogger; - } - - /** - * @param key the path within the language file - * @return the lang - */ - @Deprecated - public String getLang(@NotNull String key) { - return getLang(key, null); - } - - @Deprecated - public String getLang(@NotNull String key, @Nullable Player player) { - return lang(key, player); - } - - @Nullable - public static String optionalLang(@NotNull String key, @Nullable ClanPlayer clanPlayer, Object... arguments) { - Locale locale = instance.getSettingsManager().getLanguage(); - if (clanPlayer != null && clanPlayer.getLocale() != null && instance.getSettingsManager().is(LANGUAGE_SELECTOR)) { - locale = clanPlayer.getLocale(); - } - - String lang = languageResource.getLang(key, locale); - if (lang == null) { - return null; - } - String message = ChatUtils.parseColors(lang); - // contains acf placeholders like {commandprefix} - if (ACF_PLACEHOLDER_PATTERN.matcher(message).find()) { - return message; - } - return MessageFormat.format(message, arguments); - } - - @Nullable - public static String optionalLang(@NotNull String key, @Nullable Player player, Object... arguments) { - ClanPlayer clanPlayer = null; - if (player != null) { - clanPlayer = instance.getClanManager().getAnyClanPlayer(player.getUniqueId()); - } - return optionalLang(key, clanPlayer, arguments); - } - - @NotNull - public static String lang(@NotNull String key, @Nullable Player player, Object... arguments) { - String lang = optionalLang(key, player, arguments); - return (lang == null) ? key : lang; - } - - @NotNull - public static String lang(@NotNull String key, @Nullable ClanPlayer clanPlayer, Object... arguments) { - String lang = optionalLang(key, clanPlayer, arguments); - return (lang == null) ? key : lang; - } - - @NotNull - public static String lang(@NotNull String key, @Nullable CommandSender sender, Object... arguments) { - if (sender instanceof Player) { - return lang(key, (Player) sender, arguments); - } else { - return lang(key, (Player) null, arguments); - } - } - - @NotNull - public static String lang(@NotNull String key, @Nullable BukkitCommandIssuer issuer, Object... arguments) { - if (issuer != null) { - return lang(key, issuer.getIssuer(), arguments); - } - return lang(key, arguments); - } - - @NotNull - public static String lang(@NotNull String key, Object... arguments) { - return lang(key, (Player) null, arguments); - } - - public TeleportManager getTeleportManager() { - return teleportManager; - } - - @Deprecated - public List getMessages() { - return messages; - } - - @Deprecated - public boolean hasUUID() { - return this.hasUUID; - } - - @Deprecated - public void setUUID(boolean trueOrFalse) { - this.hasUUID = trueOrFalse; - } - - public TagValidator getTagValidator() { - return tagValidator; - } -} +package net.sacredlabyrinth.phaed.simpleclans; + +import co.aikar.commands.BukkitCommandIssuer; +import net.sacredlabyrinth.phaed.simpleclans.commands.SCCommandManager; +import net.sacredlabyrinth.phaed.simpleclans.hooks.papi.SimpleClansExpansion; +import net.sacredlabyrinth.phaed.simpleclans.language.LanguageResource; +import net.sacredlabyrinth.phaed.simpleclans.listeners.*; +import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger; +import net.sacredlabyrinth.phaed.simpleclans.loggers.CSVBankLogger; +import net.sacredlabyrinth.phaed.simpleclans.managers.*; +import net.sacredlabyrinth.phaed.simpleclans.migrations.BbMigration; +import net.sacredlabyrinth.phaed.simpleclans.migrations.ChatFormatMigration; +import net.sacredlabyrinth.phaed.simpleclans.migrations.LanguageMigration; +import net.sacredlabyrinth.phaed.simpleclans.proxy.BungeeManager; +import net.sacredlabyrinth.phaed.simpleclans.proxy.ProxyManager; +import net.sacredlabyrinth.phaed.simpleclans.tasks.*; +import net.sacredlabyrinth.phaed.simpleclans.ui.InventoryController; +import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils; +import net.sacredlabyrinth.phaed.simpleclans.utils.TagValidator; +import net.sacredlabyrinth.phaed.simpleclans.utils.UpdateChecker; +import net.sacredlabyrinth.phaed.simpleclans.uuid.UUIDMigration; +import org.bstats.bukkit.Metrics; +import org.bstats.charts.SimplePie; +import org.bstats.charts.SingleLineChart; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; +import static org.bukkit.Bukkit.getPluginManager; + +/** + * @author Phaed + */ +public class SimpleClans extends JavaPlugin { + + private final ArrayList messages = new ArrayList<>(); + + private static SimpleClans instance; + private static LanguageResource languageResource; + private static final Logger logger = Logger.getLogger("SimpleClans"); + private SCCommandManager commandManager; + private ClanManager clanManager; + private RequestManager requestManager; + private StorageManager storageManager; + private SettingsManager settingsManager; + private PermissionsManager permissionsManager; + private TeleportManager teleportManager; + private ProtectionManager protectionManager; + private ChatManager chatManager; + private ProxyManager proxyManager; + private boolean hasUUID; + private static final Pattern ACF_PLACEHOLDER_PATTERN = Pattern.compile("\\{(?[a-zA-Z]+?)}"); + + private BankLogger bankLogger; + private TagValidator tagValidator; + + /** + * @return the logger + */ + @Deprecated + public static Logger getLog() { + + return logger; + + } + + public static void debug(String msg) { + + // instance may be null during tests + if (getInstance() == null || getInstance().getSettingsManager().is(DEBUG)) { + + logger.log(Level.INFO, msg); + + } + + } + + /** + * @return the instance + */ + public static SimpleClans getInstance() { + + return instance; + + } + + @Deprecated + public static void log(String msg, Object... arg) { + + if (arg == null || arg.length == 0) { + + logger.log(Level.INFO, msg); + + } else { + + logger.log(Level.INFO, MessageFormat.format(msg, arg)); + + } + + } + + @Override + public void onEnable() { + + instance = this; + new LanguageMigration(this).migrate(); + settingsManager = new SettingsManager(this); + new BbMigration(settingsManager); + new ChatFormatMigration(settingsManager); + languageResource = new LanguageResource(); + this.hasUUID = UUIDMigration.canReturnUUID(); + + permissionsManager = new PermissionsManager(); + requestManager = new RequestManager(); + clanManager = new ClanManager(); + proxyManager = new BungeeManager(this); + storageManager = new StorageManager(); + teleportManager = new TeleportManager(); + protectionManager = new ProtectionManager(); + protectionManager.registerListeners(); + chatManager = new ChatManager(this); + registerEvents(); + permissionsManager.loadPermissions(); + commandManager = new SCCommandManager(this); + bankLogger = new CSVBankLogger(this); + + tagValidator = new TagValidator(settingsManager, permissionsManager); + + logStatus(); + startTasks(); + startMetrics(); + hookIntoPAPI(); + new UpdateChecker(this).check(); + + } + + private void logStatus() { + + getLogger().info("Multithreading: " + settingsManager.is(PERFORMANCE_USE_THREADS)); + getLogger().info("BungeeCord: " + settingsManager.is(PERFORMANCE_USE_BUNGEECORD)); + getLogger().info("HEX support: " + ChatUtils.HEX_COLOR_SUPPORT); + getLogger().info( + "Help us translate SimpleClans to your language! " + "Access https://crowdin.com/project/simpleclans/"); + + } + + private void registerEvents() { + + PluginManager pm = getServer().getPluginManager(); + pm.registerEvents(new PlayerDeath(this), this); + pm.registerEvents(new SCPlayerListener(this), this); + pm.registerEvents(new InventoryController(), this); + pm.registerEvents(new TamableMobsSharing(this), this); + pm.registerEvents(new PvPOnlyInWar(this), this); + pm.registerEvents(new FriendlyFire(this), this); + + } + + private void hookIntoPAPI() { + + if (getPluginManager().getPlugin("PlaceholderAPI") != null) { + + getLogger().info("PlaceholderAPI found. Registering hook..."); + new SimpleClansExpansion(this).register(); + + } + + } + + private void startMetrics() { + + Metrics metrics = new Metrics(this, 7131); + SettingsManager sm = getSettingsManager(); + ClanManager cm = getClanManager(); + String on = "enabled"; + String off = "disabled"; + metrics.addCustomChart(new SingleLineChart("clans", () -> cm.getClans().size())); + metrics.addCustomChart(new SingleLineChart("clan_players", () -> cm.getAllClanPlayers().size())); + metrics.addCustomChart(new SimplePie("language", () -> sm.getLanguage().toString())); + metrics.addCustomChart(new SimplePie("machine_language", () -> Locale.getDefault().toString())); + metrics.addCustomChart(new SimplePie("language_chooser", () -> sm.is(LANGUAGE_SELECTOR) ? on : off)); + metrics.addCustomChart(new SimplePie("database", () -> sm.is(MYSQL_ENABLE) ? "MySQL" : "SQLite")); + metrics.addCustomChart( + new SimplePie("save_periodically", () -> sm.is(PERFORMANCE_SAVE_PERIODICALLY) ? on : off)); + metrics.addCustomChart(new SimplePie("save_interval", () -> sm.getString(PERFORMANCE_SAVE_INTERVAL))); + metrics.addCustomChart(new SimplePie("upkeep", () -> sm.is(ECONOMY_UPKEEP_ENABLED) ? on : off)); + metrics.addCustomChart(new SimplePie("member_fee", () -> sm.is(ECONOMY_MEMBER_FEE_ENABLED) ? on : off)); + metrics.addCustomChart(new SimplePie("rejoin_cooldown", () -> sm.is(ENABLE_REJOIN_COOLDOWN) ? on : off)); + metrics.addCustomChart(new SimplePie("clan_verification", () -> sm.is(REQUIRE_VERIFICATION) ? on : off)); + metrics.addCustomChart(new SimplePie("money_per_kill", () -> sm.is(ECONOMY_MONEY_PER_KILL) ? on : off)); + metrics.addCustomChart(new SimplePie("threads", () -> sm.is(PERFORMANCE_USE_THREADS) ? on : off)); + metrics.addCustomChart(new SimplePie("bungeecord", () -> sm.is(PERFORMANCE_USE_BUNGEECORD) ? on : off)); + metrics.addCustomChart(new SimplePie("discord_chat", () -> sm.is(DISCORDCHAT_ENABLE) ? on : off)); + metrics.addCustomChart( + new SimplePie("default_rank", () -> sm.getString(CLAN_DEFAULT_RANK).isEmpty() ? off : on)); + + } + + private void startTasks() { + + if (getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) { + + new SaveDataTask().start(); + + } + + if (getSettingsManager().is(ECONOMY_MEMBER_FEE_ENABLED)) { + + new CollectFeeTask().start(); + + } + + if (getSettingsManager().is(ECONOMY_UPKEEP_ENABLED)) { + + new CollectUpkeepTask().start(); + new UpkeepWarningTask().start(); + + } + + if (getSettingsManager().is(PERFORMANCE_HEAD_CACHING)) { + + new PlayerHeadCacheTask(this).start(); + + } + + } + + @Override + public void onDisable() { + + if (getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) { + + getStorageManager().saveModified(); + + } + + getStorageManager().closeConnection(); + getPermissionsManager().savePermissions(); + getSettingsManager().loadAndSave(); + + } + + /** + * @return the clanManager + */ + public ClanManager getClanManager() { + + return clanManager; + + } + + /** + * @return the requestManager + */ + public RequestManager getRequestManager() { + + return requestManager; + + } + + /** + * @return the storageManager + */ + public StorageManager getStorageManager() { + + return storageManager; + + } + + /** + * @return the settingsManager + */ + public SettingsManager getSettingsManager() { + + return settingsManager; + + } + + /** + * @return the permissionsManager + */ + @NotNull + public PermissionsManager getPermissionsManager() { + + return permissionsManager; + + } + + public SCCommandManager getCommandManager() { + + return commandManager; + + } + + public ProtectionManager getProtectionManager() { + + return protectionManager; + + } + + public ChatManager getChatManager() { + + return chatManager; + + } + + public ProxyManager getProxyManager() { + + return proxyManager; + + } + + public BankLogger getBankLogger() { + + return bankLogger; + + } + + /** + * @param key the path within the language file + * @return the lang + */ + @Deprecated + public String getLang(@NotNull String key) { + + return getLang(key, null); + + } + + @Deprecated + public String getLang(@NotNull String key, @Nullable Player player) { + + return lang(key, player); + + } + + @Nullable + public static String optionalLang(@NotNull String key, @Nullable ClanPlayer clanPlayer, Object... arguments) { + + Locale locale = instance.getSettingsManager().getLanguage(); + if (clanPlayer != null && clanPlayer.getLocale() != null + && instance.getSettingsManager().is(LANGUAGE_SELECTOR)) + { + + locale = clanPlayer.getLocale(); + + } + + String lang = languageResource.getLang(key, locale); + if (lang == null) { + + return null; + + } + + String message = ChatUtils.parseColors(lang); + // contains acf placeholders like {commandprefix} + if (ACF_PLACEHOLDER_PATTERN.matcher(message).find()) { + + return message; + + } + + return MessageFormat.format(message, arguments); + + } + + @Nullable + public static String optionalLang(@NotNull String key, @Nullable Player player, Object... arguments) { + + ClanPlayer clanPlayer = null; + if (player != null) { + + clanPlayer = instance.getClanManager().getAnyClanPlayer(player.getUniqueId()); + + } + + return optionalLang(key, clanPlayer, arguments); + + } + + @NotNull + public static String lang(@NotNull String key, @Nullable Player player, Object... arguments) { + + String lang = optionalLang(key, player, arguments); + return (lang == null) ? key : lang; + + } + + @NotNull + public static String lang(@NotNull String key, @Nullable ClanPlayer clanPlayer, Object... arguments) { + + String lang = optionalLang(key, clanPlayer, arguments); + return (lang == null) ? key : lang; + + } + + @NotNull + public static String lang(@NotNull String key, @Nullable CommandSender sender, Object... arguments) { + + if (sender instanceof Player) { + + return lang(key, (Player) sender, arguments); + + } else { + + return lang(key, (Player) null, arguments); + + } + + } + + @NotNull + public static String lang(@NotNull String key, @Nullable BukkitCommandIssuer issuer, Object... arguments) { + + if (issuer != null) { + + return lang(key, issuer.getIssuer(), arguments); + + } + + return lang(key, arguments); + + } + + @NotNull + public static String lang(@NotNull String key, Object... arguments) { + + return lang(key, (Player) null, arguments); + + } + + public TeleportManager getTeleportManager() { + + return teleportManager; + + } + + @Deprecated + public List getMessages() { + + return messages; + + } + + @Deprecated + public boolean hasUUID() { + + return this.hasUUID; + + } + + @Deprecated + public void setUUID(boolean trueOrFalse) { + + this.hasUUID = trueOrFalse; + + } + + public TagValidator getTagValidator() { + + return tagValidator; + + } + +} diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/StringSimplifier.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/StringSimplifier.java index 5bff810c..12d2b514 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/StringSimplifier.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/StringSimplifier.java @@ -8,76 +8,109 @@ import java.util.regex.Pattern; public class StringSimplifier { private StringSimplifier() { + } public static final char DEFAULT_REPLACE_CHAR = '-'; public static final String DEFAULT_REPLACE = String.valueOf(DEFAULT_REPLACE_CHAR); private static final ImmutableMap NONDIACRITICS = ImmutableMap.builder() - //Remove crap strings with no sematics + // Remove crap strings with no sematics .put(".", "").put("\"", "").put("'", "") - //Keep relevant characters as seperation - .put(" ", DEFAULT_REPLACE).put("]", DEFAULT_REPLACE).put("[", DEFAULT_REPLACE).put(")", DEFAULT_REPLACE).put("(", DEFAULT_REPLACE).put("=", DEFAULT_REPLACE).put("!", DEFAULT_REPLACE).put("/", DEFAULT_REPLACE).put("\\", DEFAULT_REPLACE).put("&", DEFAULT_REPLACE).put(",", DEFAULT_REPLACE).put("?", DEFAULT_REPLACE).put("°", DEFAULT_REPLACE) //Remove ?? is diacritic? - .put("|", DEFAULT_REPLACE).put("<", DEFAULT_REPLACE).put(">", DEFAULT_REPLACE).put(";", DEFAULT_REPLACE).put(":", DEFAULT_REPLACE).put("_", DEFAULT_REPLACE).put("#", DEFAULT_REPLACE).put("~", DEFAULT_REPLACE).put("+", DEFAULT_REPLACE).put("*", DEFAULT_REPLACE) + // Keep relevant characters as seperation + .put(" ", DEFAULT_REPLACE).put("]", DEFAULT_REPLACE).put("[", DEFAULT_REPLACE).put(")", DEFAULT_REPLACE) + .put("(", DEFAULT_REPLACE).put("=", DEFAULT_REPLACE).put("!", DEFAULT_REPLACE).put("/", DEFAULT_REPLACE) + .put("\\", DEFAULT_REPLACE).put("&", DEFAULT_REPLACE).put(",", DEFAULT_REPLACE).put("?", DEFAULT_REPLACE) + .put("°", DEFAULT_REPLACE) // Remove ?? is diacritic? + .put("|", DEFAULT_REPLACE).put("<", DEFAULT_REPLACE).put(">", DEFAULT_REPLACE).put(";", DEFAULT_REPLACE) + .put(":", DEFAULT_REPLACE).put("_", DEFAULT_REPLACE).put("#", DEFAULT_REPLACE).put("~", DEFAULT_REPLACE) + .put("+", DEFAULT_REPLACE).put("*", DEFAULT_REPLACE) - //Replace non-diacritics as their equivalent characters + // Replace non-diacritics as their equivalent characters .put("\u0141", "l") // BiaLystock .put("\u0142", "l") // Bialystock - .put("ß", "ss").put("æ", "ae").put("ø", "o").put("©", "c").put("\u00D0", "d") // All Ð ð from http://de.wikipedia.org/wiki/%C3%90 - .put("\u00F0", "d").put("\u0110", "d").put("\u0111", "d").put("\u0189", "d").put("\u0256", "d").put("\u00DE", "th") // thorn Þ + .put("ß", "ss").put("æ", "ae").put("ø", "o").put("©", "c").put("\u00D0", "d") // All Ð ð from + // http://de.wikipedia.org/wiki/%C3%90 + .put("\u00F0", "d").put("\u0110", "d").put("\u0111", "d").put("\u0189", "d").put("\u0256", "d") + .put("\u00DE", "th") // thorn Þ .put("\u00FE", "th") // thorn þ .build(); - public static String simplifiedString(String orig) { + String str = orig; if (str == null) { + return null; + } + str = stripDiacritics(str); str = stripNonDiacritics(str); if (str.length() == 0) { + // Ugly special case to work around non-existing empty strings // in Oracle. Store original crapstring as simplified. // It would return an empty string if Oracle could store it. return orig; + } + return str.toLowerCase(); + } private static String stripNonDiacritics(String orig) { + StringBuffer ret = new StringBuffer(); String lastchar = null; for (int i = 0; i < orig.length(); i++) { + String source = orig.substring(i, i + 1); String replace = NONDIACRITICS.get(source); String toReplace = replace == null ? String.valueOf(source) : replace; if (DEFAULT_REPLACE.equals(lastchar) && DEFAULT_REPLACE.equals(toReplace)) { + toReplace = ""; + } else { + lastchar = toReplace; + } + ret.append(toReplace); + } + if (ret.length() > 0 && DEFAULT_REPLACE_CHAR == ret.charAt(ret.length() - 1)) { + ret.deleteCharAt(ret.length() - 1); + } + return ret.toString(); + } /* - Special regular expression character ranges relevant for simplification -> see http://docstore.mik.ua/orelly/perl/prog3/ch05_04.htm - InCombiningDiacriticalMarks: special marks that are part of "normal" ä, ö, î etc.. - IsSk: Symbol, Modifier see http://www.fileformat.info/info/unicode/category/Sk/list.htm - IsLm: Letter, Modifier see http://www.fileformat.info/info/unicode/category/Lm/list.htm + * Special regular expression character ranges relevant for simplification -> + * see http://docstore.mik.ua/orelly/perl/prog3/ch05_04.htm + * InCombiningDiacriticalMarks: special marks that are part of "normal" ä, ö, î + * etc.. IsSk: Symbol, Modifier see + * http://www.fileformat.info/info/unicode/category/Sk/list.htm IsLm: Letter, + * Modifier see http://www.fileformat.info/info/unicode/category/Lm/list.htm */ - public static final Pattern DIACRITICS_AND_FRIENDS = Pattern.compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+"); - + public static final Pattern DIACRITICS_AND_FRIENDS = Pattern + .compile("[\\p{InCombiningDiacriticalMarks}\\p{IsLm}\\p{IsSk}]+"); private static String stripDiacritics(String str) { + str = Normalizer.normalize(str, Normalizer.Form.NFD); str = DIACRITICS_AND_FRIENDS.matcher(str).replaceAll(""); return str; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/TeleportState.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/TeleportState.java index 2c2a0996..5e53c7af 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/TeleportState.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/TeleportState.java @@ -5,7 +5,6 @@ import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; - public class TeleportState { private final OfflinePlayer offlinePlayer; @@ -16,25 +15,32 @@ public class TeleportState { private boolean processing; public TeleportState(Player player, Location destination, String clanName, int counter) { + this.offlinePlayer = player; this.destination = destination; this.origin = player.getLocation(); this.clanName = clanName; this.counter = counter; + } - public Location getLocation() { + return this.origin; + } public boolean isTeleportTime() { + if (this.counter > 1) { + this.counter--; return false; + } return true; + } /** @@ -43,7 +49,9 @@ public class TeleportState { * @return the player */ public @Nullable Player getPlayer() { - return offlinePlayer.getPlayer(); + + return offlinePlayer.getPlayer(); + } /** @@ -52,27 +60,39 @@ public class TeleportState { * @return the counter */ public int getCounter() { + return this.counter; + } public void setCounter(int counter) { + this.counter = counter; + } public String getClanName() { + return this.clanName; + } public Location getDestination() { + return this.destination; + } public boolean isProcessing() { + return this.processing; + } public void setProcessing(boolean processing) { + this.processing = processing; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/VoteResult.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/VoteResult.java index 20bb128b..42aca1ff 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/VoteResult.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/VoteResult.java @@ -1,10 +1,10 @@ -package net.sacredlabyrinth.phaed.simpleclans; - -/** - * Possible vote values - * - * @author cc_madelg - */ -public enum VoteResult { - ACCEPT, DENY -} +package net.sacredlabyrinth.phaed.simpleclans; + +/** + * Possible vote values + * + * @author cc_madelg + */ +public enum VoteResult { + ACCEPT, DENY +} diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/War.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/War.java index 83c2618c..a79e1ba7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/War.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/War.java @@ -8,42 +8,64 @@ import java.util.List; import java.util.Map; public class War { + private final Map clans = new HashMap<>(); public War(@NotNull Clan clan1, @NotNull Clan clan2) { + clans.put(clan1, 0); clans.put(clan2, 0); + } public List getClans() { + return new ArrayList<>(clans.keySet()); + } public int getTotalCasualties() { + return clans.values().stream().mapToInt(value -> value).sum(); + } public int getCasualties(@NotNull Clan clan) { + return clans.getOrDefault(clan, 0); + } public void increaseCasualties(@NotNull Clan clan) { + clans.computeIfPresent(clan, (c, i) -> i + 1); + } @Override public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof War) { + return clans.equals(((War) obj).clans); + } + return false; + } @Override public int hashCode() { + return clans.hashCode(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/ChatHandler.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/ChatHandler.java index 201ecb82..b16fb1e2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/ChatHandler.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/ChatHandler.java @@ -15,4 +15,5 @@ public interface ChatHandler { void sendMessage(SCMessage message); boolean canHandle(SCMessage.Source source); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/SCMessage.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/SCMessage.java index 383c22c0..ea1e40a2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/SCMessage.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/SCMessage.java @@ -23,68 +23,97 @@ public class SCMessage implements Cloneable { * @param content The content of message * @param receivers The clan players, who will receive the content */ - public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel, - @NotNull ClanPlayer sender, String content, @NotNull List receivers) { + public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel, @NotNull ClanPlayer sender, + String content, @NotNull List receivers) + { + this.source = source; this.channel = channel; this.sender = sender; this.content = content; this.receivers = receivers; + } /** * Creates a new SCMessage without receivers * - * @see SCMessage#SCMessage(Source, ClanPlayer.Channel, ClanPlayer, String, List) instantiate with initial receievers + * @see SCMessage#SCMessage(Source, ClanPlayer.Channel, ClanPlayer, String, + * List) instantiate with initial receievers */ - public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel, @NotNull ClanPlayer sender, String content) { + public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel, @NotNull ClanPlayer sender, + String content) + { + this(source, channel, sender, content, new ArrayList<>()); + } public ClanPlayer.Channel getChannel() { + return channel; + } public ClanPlayer getSender() { + return sender; + } public String getContent() { + return content; + } public Source getSource() { + return source; + } public List getReceivers() { + return receivers; + } public void setContent(@NotNull String content) { + this.content = content; + } public void setReceivers(@NotNull List receivers) { + this.receivers = receivers; + } @Override public SCMessage clone() { + try { + return (SCMessage) super.clone(); + } catch (CloneNotSupportedException e) { - throw new Error(); //never thrown + + throw new Error(); // never thrown + } + } /** - * The place where the message came from. - * Used by ChatHandlers to know which SCMessages they can handle. + * The place where the message came from. Used by ChatHandlers to know which + * SCMessages they can handle. * * @see ChatHandler initiate the handler */ public enum Source { SPIGOT, DISCORD, PROXY } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/DiscordChatHandler.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/DiscordChatHandler.java index fcee22a0..ccea9c30 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/DiscordChatHandler.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/DiscordChatHandler.java @@ -18,14 +18,18 @@ import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.SPIGOT import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.DISCORDCHAT_FORMAT_TO; /** - * Handles delivering messages from {@link Source#SPIGOT} to {@link Source#DISCORD}. + * Handles delivering messages from {@link Source#SPIGOT} to + * {@link Source#DISCORD}. */ public class DiscordChatHandler implements ChatHandler { @Override public void sendMessage(@NotNull SCMessage message) { + if (message.getChannel() != CLAN) { + return; + } String format = settingsManager.getString(DISCORDCHAT_FORMAT_TO); @@ -33,16 +37,22 @@ public class DiscordChatHandler implements ChatHandler { Clan clan = message.getSender().getClan(); if (clan == null) { + return; + } DiscordHook discordHook = Objects.requireNonNull(chatManager.getDiscordHook(), "DiscordHook cannot be null"); Optional channel = discordHook.getCachedChannel(clan.getTag()); channel.ifPresent(textChannel -> DiscordUtil.sendMessage(textChannel, formattedMessage)); + } @Override public boolean canHandle(SCMessage.Source source) { + return source == SPIGOT && chatManager.isDiscordHookEnabled(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/ProxyChatHandler.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/ProxyChatHandler.java index e636685b..7131d236 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/ProxyChatHandler.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/ProxyChatHandler.java @@ -10,11 +10,16 @@ public class ProxyChatHandler implements ChatHandler { @Override public void sendMessage(SCMessage message) { + plugin.getProxyManager().sendMessage(message); + } @Override public boolean canHandle(Source source) { + return source == Source.SPIGOT && settingsManager.is(PERFORMANCE_USE_BUNGEECORD); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpigotChatHandler.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpigotChatHandler.java index 42a3972c..1e1d262e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpigotChatHandler.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpigotChatHandler.java @@ -18,20 +18,26 @@ public class SpigotChatHandler implements ChatHandler { @Override public void sendMessage(SCMessage message) { + /* - TODO: Make it async, change Type to Channel in 3.0 - */ + * TODO: Make it async, change Type to Channel in 3.0 + */ new BukkitRunnable() { + @Override public void run() { + ChatEvent event = new ChatEvent(message.getContent(), message.getSender(), message.getReceivers(), ChatEvent.Type.valueOf(message.getChannel().name())); getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } - message.setContent(stripColorsAndFormatsPerPermission(message.getSender(),event.getMessage())); + + message.setContent(stripColorsAndFormatsPerPermission(message.getSender(), event.getMessage())); ConfigField configField = ConfigField.valueOf(String.format("%sCHAT_FORMAT", message.getSource() == DISCORD ? "DISCORD" : message.getChannel())); @@ -42,33 +48,53 @@ public class SpigotChatHandler implements ChatHandler { plugin.getLogger().info(ChatUtils.stripColors(formattedMessage)); for (ClanPlayer cp : message.getReceivers()) { + ChatBlock.sendMessage(cp, formattedMessage); + } + } + }.runTask(plugin); + } private String stripColorsAndFormatsPerPermission(ClanPlayer sender, String message) { + if (!permissionsManager.has(sender.toPlayer(), "simpleclans.member.chat.color")) { + message = stripColors(message); + } + if (!permissionsManager.has(sender.toPlayer(), "simpleclans.member.chat.format")) { + message = stripFormats(message); + } + return message; + } private String stripColors(String message) { + return message.replaceAll("[§&][0-9a-fA-FxX]", ""); + } private String stripFormats(String message) { + return message.replaceAll("[§&][k-orK-OR]", ""); + } @Override public boolean canHandle(SCMessage.Source source) { + return source == SPIGOT || (source == PROXY && settingsManager.is(PERFORMANCE_USE_BUNGEECORD)) || (source == DISCORD && chatManager.isDiscordHookEnabled()); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpyChatHandler.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpyChatHandler.java index f17a3f3e..be2094d4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpyChatHandler.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/chat/handlers/SpyChatHandler.java @@ -18,14 +18,16 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.PERFORMANCE_USE_BUNGEECORD; /** - * Handles delivering messages from {@link Source#SPIGOT} or {@link Source#DISCORD} to internal spy chat. + * Handles delivering messages from {@link Source#SPIGOT} or + * {@link Source#DISCORD} to internal spy chat. */ public class SpyChatHandler implements ChatHandler { @Override public void sendMessage(SCMessage message) { - ConfigField formatField = ConfigField.valueOf(String.format("%sCHAT_SPYFORMAT", - message.getSource() == DISCORD ? "DISCORD" : message.getChannel())); + + ConfigField formatField = ConfigField.valueOf( + String.format("%sCHAT_SPYFORMAT", message.getSource() == DISCORD ? "DISCORD" : message.getChannel())); String format = settingsManager.getString(formatField); message.setContent(ChatUtils.stripColors(message.getContent())); String formattedMessage = chatManager.parseChatFormat(format, message); @@ -35,21 +37,24 @@ public class SpyChatHandler implements ChatHandler { // Don't send a duplicate message if a spy is inside the clan onlineSpies.removeAll(message.getReceivers()); onlineSpies.forEach(receiver -> ChatBlock.sendMessage(receiver, formattedMessage)); + } @Override public boolean canHandle(SCMessage.Source source) { + return source == SPIGOT || (source == PROXY && settingsManager.is(PERFORMANCE_USE_BUNGEECORD)) || (source == DISCORD && chatManager.isDiscordHookEnabled()); + } private List getOnlineSpies() { - return new ArrayList<>(Bukkit.getOnlinePlayers()).stream(). - filter(Objects::nonNull). - filter(player -> permissionsManager.has(player, "simpleclans.admin.all-seeing-eye")). - map(player -> plugin.getClanManager().getCreateClanPlayer(player.getUniqueId())). - filter(Objects::nonNull). - filter(clanPlayer -> !clanPlayer.isMuted()). - collect(Collectors.toList()); + + return new ArrayList<>(Bukkit.getOnlinePlayers()).stream().filter(Objects::nonNull) + .filter(player -> permissionsManager.has(player, "simpleclans.admin.all-seeing-eye")) + .map(player -> plugin.getClanManager().getCreateClanPlayer(player.getUniqueId())) + .filter(Objects::nonNull).filter(clanPlayer -> !clanPlayer.isMuted()).collect(Collectors.toList()); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanInput.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanInput.java index e58c37ba..e56e3482 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanInput.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanInput.java @@ -10,23 +10,34 @@ public class ClanInput { private final Clan clan; public ClanInput(@NotNull Clan clan) { + this.clan = clan; + } public Clan getClan() { + return clan; + } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; ClanInput clanInput = (ClanInput) o; return clan.equals(clanInput.clan); + } @Override public int hashCode() { + return Objects.hash(clan); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanPlayerInput.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanPlayerInput.java index e9d05c64..c4727d04 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanPlayerInput.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/ClanPlayerInput.java @@ -10,23 +10,34 @@ public class ClanPlayerInput { private final ClanPlayer clanPlayer; public ClanPlayerInput(@NotNull ClanPlayer clanPlayer) { + this.clanPlayer = clanPlayer; + } public ClanPlayer getClanPlayer() { + return clanPlayer; + } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; ClanPlayerInput that = (ClanPlayerInput) o; return clanPlayer.equals(that.clanPlayer); + } @Override public int hashCode() { + return Objects.hash(clanPlayer); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/SCCommandManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/SCCommandManager.java index f011522f..2cf31145 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/SCCommandManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/SCCommandManager.java @@ -36,17 +36,21 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.optionalLang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; public class SCCommandManager extends PaperCommandManager { + private final SimpleClans plugin; private static final List SUBCOMMANDS; private static final List COMPLETIONS; public SCCommandManager(@NotNull SimpleClans plugin) { + super(plugin); this.plugin = plugin; configure(); + } private void configure() { + enableUnstableAPI("help"); registerDependencies(); addReplacements(); @@ -55,9 +59,11 @@ public class SCCommandManager extends PaperCommandManager { registerConditions(); registerCompletions(); defaultHelpPerPage = plugin.getSettingsManager().getInt(HELP_SIZE); + } private void registerDependencies() { + registerDependency(ClanManager.class, plugin.getClanManager()); registerDependency(SettingsManager.class, plugin.getSettingsManager()); registerDependency(StorageManager.class, plugin.getStorageManager()); @@ -65,175 +71,259 @@ public class SCCommandManager extends PaperCommandManager { registerDependency(RequestManager.class, plugin.getRequestManager()); registerDependency(ProtectionManager.class, plugin.getProtectionManager()); registerDependency(ChatManager.class, plugin.getChatManager()); + } private void registerCompletions() { - Set> completions = - Helper.getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands.completions", - AbstractCompletion.class); + + Set> completions = Helper + .getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands.completions", AbstractCompletion.class); plugin.getLogger().info(String.format("Registering %d command completions...", completions.size())); for (Class c : completions) { + if (Modifier.isAbstract(c.getModifiers())) { + continue; + } + try { + AbstractCompletion obj = c.getConstructor(SimpleClans.class).newInstance(plugin); if (obj instanceof AbstractStaticCompletion) { + getCommandCompletions().registerStaticCompletion(obj.getId(), ((AbstractStaticCompletion) obj).getCompletions()); + } + if (obj instanceof AbstractAsyncCompletion) { + getCommandCompletions().registerAsyncCompletion(obj.getId(), (AbstractAsyncCompletion) obj); + } + if (obj instanceof AbstractSyncCompletion) { + getCommandCompletions().registerCompletion(obj.getId(), ((AbstractSyncCompletion) obj)); + } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Error registering completion", ex); + } + } + } @SuppressWarnings("unchecked") private void registerConditions() { - Set> conditions = - Helper.getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands.conditions", - AbstractCondition.class); + + Set> conditions = Helper + .getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands.conditions", AbstractCondition.class); plugin.getLogger().info(String.format("Registering %d command conditions...", conditions.size())); for (Class c : conditions) { + if (Modifier.isAbstract(c.getModifiers())) { + continue; + } + try { + AbstractCondition obj = c.getConstructor(SimpleClans.class).newInstance(plugin); if (obj instanceof AbstractParameterCondition) { + @SuppressWarnings("rawtypes") AbstractParameterCondition condition = ((AbstractParameterCondition) obj); getCommandConditions().addCondition(condition.getType(), condition.getId(), condition); + } + if (obj instanceof AbstractCommandCondition) { + AbstractCommandCondition condition = ((AbstractCommandCondition) obj); getCommandConditions().addCondition(condition.getId(), condition); + } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Error registering condition", ex); + } + } + } - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) private void registerContexts() { - Set> resolvers = - Helper.getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands.contexts", - AbstractContextResolver.class); + + Set> resolvers = Helper.getSubTypesOf( + "net.sacredlabyrinth.phaed.simpleclans.commands.contexts", AbstractContextResolver.class); plugin.getLogger().info(String.format("Registering %d command contexts...", resolvers.size())); for (Class cr : resolvers) { + if (Modifier.isAbstract(cr.getModifiers())) { + continue; + } + try { + AbstractContextResolver obj = cr.getConstructor(SimpleClans.class).newInstance(plugin); if (obj instanceof AbstractIssuerOnlyContextResolver) { - getCommandContexts().registerIssuerOnlyContext(obj.getType(), ((AbstractIssuerOnlyContextResolver) obj)); + + getCommandContexts().registerIssuerOnlyContext(obj.getType(), + ((AbstractIssuerOnlyContextResolver) obj)); + } + if (obj instanceof AbstractInputOnlyContextResolver) { + getCommandContexts().registerContext(obj.getType(), ((AbstractInputOnlyContextResolver) obj)); + } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Error registering context", ex); + } + } + } private void registerCommands() { + boolean forceCommandPriority = plugin.getSettingsManager().is(COMMANDS_FORCE_PRIORITY); - Set> commands = Helper.getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands", BaseCommand.class); + Set> commands = Helper + .getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.commands", BaseCommand.class); plugin.getLogger().info(String.format("Registering %d base commands...", commands.size())); for (Class c : commands) { - //ACF already registers nested classes + + // ACF already registers nested classes if (c.isMemberClass() || Modifier.isStatic(c.getModifiers())) { + continue; + } + try { + BaseCommand baseCommand = c.getConstructor().newInstance(); registerCommand(baseCommand, forceCommandPriority); + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Error registering command", ex); + } + } + } private void addReplacements() { + SettingsManager sm = plugin.getSettingsManager(); - getCommandReplacements().addReplacements( - "basic_conditions", "not_blacklisted|not_banned", - "clan", sm.getString(COMMANDS_CLAN), - "deny", sm.getString(COMMANDS_DENY) + "|deny", - "more", sm.getString(COMMANDS_MORE), - "ally_chat", sm.getString(COMMANDS_ALLY), - "accept", sm.getString(COMMANDS_ACCEPT) + "|accept", - "clan_chat", sm.getString(COMMANDS_CLAN_CHAT) - ); + getCommandReplacements().addReplacements("basic_conditions", "not_blacklisted|not_banned", "clan", + sm.getString(COMMANDS_CLAN), "deny", sm.getString(COMMANDS_DENY) + "|deny", "more", + sm.getString(COMMANDS_MORE), "ally_chat", sm.getString(COMMANDS_ALLY), "accept", + sm.getString(COMMANDS_ACCEPT) + "|accept", "clan_chat", sm.getString(COMMANDS_CLAN_CHAT)); SUBCOMMANDS.forEach(s -> processReplacement(s, "", ".command", true)); COMPLETIONS.forEach(s -> processReplacement(s, "compl:", ".completion", false)); + } @Override public BukkitLocales getLocales() { + if (this.locales == null) { + this.locales = new BukkitLocales(this) { @Nullable private Player getPlayer(CommandIssuer issuer) { + if (issuer != null) { + return Bukkit.getPlayer(issuer.getUniqueId()); + } + return null; + } @Override @Nullable public String getOptionalMessage(CommandIssuer issuer, MessageKey key) { + return optionalLang(key.getKey(), getPlayer(issuer)); + } @Override @NotNull public String getMessage(CommandIssuer issuer, MessageKeyProvider key) { + return lang(key.getMessageKey().getKey(), getPlayer(issuer)); + } + }; - //this.locales.loadLanguages(); + + // this.locales.loadLanguages(); } + return this.locales; + } private void processReplacement(String key, String prefix, String suffix, boolean hasFallback) { + String replacement = optionalLang(key + suffix, (ClanPlayer) null); if (replacement == null) { + replacement = key; + } replacement = replacement.replace(" ", ""); if (hasFallback) { + replacement = replacement + "|" + key; + } getCommandReplacements().addReplacement(prefix + key, replacement); + } static { - SUBCOMMANDS = Arrays.asList("setbanner", "resetkdr", "place", "rank", "home", "war", "regroup", - "mostkilled", "kills", "globalff", "reload", "unban", "ban", "verify", "disband", "resign", "ff", - "clanff", "demote", "promote", "untrust", "trust", "purge", "fee", "bank", "kick", "invite", "toggle", - "modtag", "bb", "display", "clear", "rival", "ally", "add", "remove", "stats", "coords", "vitals", "rivalries", + + SUBCOMMANDS = Arrays.asList("setbanner", "resetkdr", "place", "rank", "home", "war", "regroup", "mostkilled", + "kills", "globalff", "reload", "unban", "ban", "verify", "disband", "resign", "ff", "clanff", "demote", + "promote", "untrust", "trust", "purge", "fee", "bank", "kick", "invite", "toggle", "modtag", "bb", + "display", "clear", "rival", "ally", "add", "remove", "stats", "coords", "vitals", "rivalries", "alliances", "leaderboard", "allow", "block", "auto", "check", "assign", "unassign", "delete", "me", "setdisplayname", "permissions", "tag", "deposit", "withdraw", "set", "status", "tp", "all", "everyone", "lookup", "roster", "profile", "list", "create", "description", "start", "end", "admin", "help", "mod", "setdefault", "removedefault", "land", "break", "interact", "place_block", "damage", "interact_entity", - "container", "permanent", "take", "give", "join", "leave", "mute", "confirm", "balance", "discord", "rename", "locale"); + "container", "permanent", "take", "give", "join", "leave", "mute", "confirm", "balance", "discord", + "rename", "locale"); COMPLETIONS = Arrays.asList("tag", "name"); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/AllyChatCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/AllyChatCommand.java index a6964a4f..5c650935 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/AllyChatCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/AllyChatCommand.java @@ -29,40 +29,59 @@ public class AllyChatCommand extends BaseCommand { @Default @HelpSearchTags("chat") public void sendMessage(ClanPlayer cp, @Name("message") String message) { + chatManager.processChat(SPIGOT, ALLY, cp, message); + } @Subcommand("%join") public void join(ClanPlayer clanPlayer) { + if (clanPlayer.getChannel() == ALLY) { + ChatBlock.sendMessage(clanPlayer, lang("already.joined.ally.chat")); return; + } clanPlayer.setChannel(ALLY); storageManager.updateClanPlayer(clanPlayer); ChatBlock.sendMessage(clanPlayer, lang("joined.ally.chat")); + } @Subcommand("%leave") public void leave(ClanPlayer clanPlayer) { + if (clanPlayer.getChannel() == ALLY) { + clanPlayer.setChannel(NONE); storageManager.updateClanPlayer(clanPlayer); ChatBlock.sendMessage(clanPlayer, lang("left.ally.chat", clanPlayer)); + } else { + ChatBlock.sendMessage(clanPlayer, lang("chat.didnt.join", clanPlayer)); + } + } @Subcommand("%mute") public void mute(ClanPlayer clanPlayer) { + if (!clanPlayer.isMutedAlly()) { + clanPlayer.mute(ALLY, true); ChatBlock.sendMessage(clanPlayer, lang("muted.ally.chat", clanPlayer)); + } else { + clanPlayer.mute(ALLY, false); ChatBlock.sendMessage(clanPlayer, lang("unmuted.ally.chat", clanPlayer)); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BankCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BankCommand.java index 7054e586..f02b231d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BankCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BankCommand.java @@ -24,6 +24,7 @@ import static org.bukkit.ChatColor.RED; @Subcommand("%bank") @Conditions("%basic_conditions|economy|verified") public class BankCommand extends BaseCommand { + @Dependency private PermissionsManager permissions; @@ -32,7 +33,9 @@ public class BankCommand extends BaseCommand { @Conditions("rank:name=BANK_BALANCE") @Description("{@@command.description.bank.status}") public void bankStatus(Player player, Clan clan) { + player.sendMessage(AQUA + lang("clan.balance", player, clan.getBalanceFormatted())); + } @Subcommand("%withdraw %all") @@ -40,7 +43,9 @@ public class BankCommand extends BaseCommand { @Conditions("rank:name=BANK_WITHDRAW") @Description("{@@command.description.bank.withdraw.all}") public void bankWithdraw(Player player, Clan clan) { + processWithdraw(player, clan, clan.getBalance()); + } @Subcommand("%withdraw") @@ -48,40 +53,57 @@ public class BankCommand extends BaseCommand { @Conditions("rank:name=BANK_WITHDRAW") @Description("{@@command.description.bank.withdraw.amount}") public void bankWithdraw(Player player, Clan clan, double amount) { + processWithdraw(player, clan, amount); + } private void processWithdraw(Player player, Clan clan, double amount) { + if (!clan.isAllowWithdraw()) { + String message = getCurrentCommandManager().getCommandReplacements() .replace(lang("withdraw.not.allowed", player)); ChatBlock.sendMessage(player, RED + message); return; + } + amount = Math.abs(amount); /* - TODO: Remove at SimpleClans 3.0 + * TODO: Remove at SimpleClans 3.0 */ BankWithdrawEvent event = new BankWithdrawEvent(player, clan, amount); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } + /* * —————————————————————————————————— */ BankOperator operator = new BankOperator(player, permissions.playerGetMoney(player)); switch (clan.withdraw(operator, COMMAND, amount)) { + case SUCCESS: if (permissions.grantPlayer(player, amount)) { + player.sendMessage(AQUA + lang("player.clan.withdraw", player, CurrencyFormat.format(amount))); - clan.addBb(player.getName(), lang("bb.clan.withdraw", CurrencyFormat.format(amount), player.getName())); + clan.addBb(player.getName(), + lang("bb.clan.withdraw", CurrencyFormat.format(amount), player.getName())); + } else { + clan.setBalance(operator, REVERT, BankLogger.Operation.WITHDRAW, clan.getBalance() + amount); + } case NOT_ENOUGH_BALANCE: player.sendMessage(lang("clan.bank.not.enough.money", player)); + } + } @Subcommand("%deposit %all") @@ -89,7 +111,9 @@ public class BankCommand extends BaseCommand { @Conditions("rank:name=BANK_DEPOSIT") @Description("{@@command.description.bank.deposit.all}") public void bankDeposit(Player player, Clan clan) { + processDeposit(player, clan, permissions.playerGetMoney(player)); + } @Subcommand("%deposit") @@ -97,44 +121,63 @@ public class BankCommand extends BaseCommand { @Conditions("rank:name=BANK_DEPOSIT") @Description("{@@command.description.bank.deposit.amount}") public void bankDeposit(Player player, Clan clan, double amount) { + processDeposit(player, clan, amount); + } private void processDeposit(Player player, Clan clan, double amount) { + if (!clan.isAllowDeposit()) { + String message = getCurrentCommandManager().getCommandReplacements() .replace(lang("deposit.not.allowed", player)); ChatBlock.sendMessage(player, RED + message); return; + } + amount = Math.abs(amount); /* - TODO: Remove at SimpleClans 3.0 + * TODO: Remove at SimpleClans 3.0 */ BankDepositEvent event = new BankDepositEvent(player, clan, amount); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } /* * —————————————————————————————————— */ if (!permissions.playerHasMoney(player, amount)) { + player.sendMessage(AQUA + lang("not.sufficient.money", player, CurrencyFormat.format(amount))); return; + } + BankOperator operator = new BankOperator(player, permissions.playerGetMoney(player)); EconomyResponse response = clan.deposit(operator, COMMAND, amount); if (response == EconomyResponse.SUCCESS) { + if (permissions.chargePlayer(player, amount)) { + player.sendMessage(AQUA + lang("player.clan.deposit", player, CurrencyFormat.format(amount))); clan.addBb(player.getName(), lang("bb.clan.deposit", CurrencyFormat.format(amount), player.getName())); + } else { - //Reverts the deposit if something went wrong with Vault + + // Reverts the deposit if something went wrong with Vault clan.setBalance(operator, REVERT, BankLogger.Operation.DEPOSIT, clan.getBalance() - amount); + } + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BbCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BbCommand.java index 114bdce5..d8af85bd 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BbCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/BbCommand.java @@ -29,8 +29,10 @@ public class BbCommand extends BaseCommand { @CommandPermission("simpleclans.member.bb") @Description("{@@command.description.bb.display}") public void display(Player sender) { + Clan clan = Objects.requireNonNull(cm.getClanByPlayerUniqueId(sender.getUniqueId())); clan.displayBb(sender); + } @Subcommand("%bb %clear") @@ -38,9 +40,11 @@ public class BbCommand extends BaseCommand { @Conditions("rank:name=BB_CLEAR") @Description("{@@command.description.bb.clear}") public void clear(Player player) { + Clan clan = Objects.requireNonNull(cm.getClanByPlayerUniqueId(player.getUniqueId())); clan.clearBb(); ChatBlock.sendMessage(player, RED + lang("cleared.bb", player)); + } @Subcommand("%bb %add") @@ -48,9 +52,12 @@ public class BbCommand extends BaseCommand { @Conditions("rank:name=BB_ADD") @Description("{@@command.description.bb.post}") public void postMessage(Player player, @Name("message") String msg) { + Clan clan = Objects.requireNonNull(cm.getClanByPlayerUniqueId(player.getUniqueId())); clan.addBb(lang("bulletin.board.message", player.getName(), msg)); clan.displayBb(player); storage.updateClan(clan); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ChatCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ChatCommand.java index 3e12fff0..d59ee6af 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ChatCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ChatCommand.java @@ -26,40 +26,59 @@ public class ChatCommand extends BaseCommand { @Default @HelpSearchTags("chat") public void sendMessage(ClanPlayer cp, @Name("message") String message) { + chatManager.processChat(SPIGOT, CLAN, cp, message); + } @Subcommand("%join") public void join(ClanPlayer clanPlayer) { + if (clanPlayer.getChannel() == CLAN) { + ChatBlock.sendMessage(clanPlayer, lang("already.joined.clan.chat")); return; + } clanPlayer.setChannel(CLAN); storageManager.updateClanPlayer(clanPlayer); ChatBlock.sendMessage(clanPlayer, lang("joined.clan.chat")); + } @Subcommand("%leave") public void leave(ClanPlayer clanPlayer) { + if (clanPlayer.getChannel() == CLAN) { + clanPlayer.setChannel(NONE); storageManager.updateClanPlayer(clanPlayer); ChatBlock.sendMessage(clanPlayer, lang("left.clan.chat", clanPlayer)); + } else { + ChatBlock.sendMessage(clanPlayer, lang("chat.didnt.join", clanPlayer)); + } + } @Subcommand("%mute") public void mute(ClanPlayer clanPlayer) { + if (!clanPlayer.isMuted()) { + clanPlayer.mute(CLAN, true); ChatBlock.sendMessage(clanPlayer, lang("muted.clan.chat", clanPlayer)); + } else { + clanPlayer.mute(CLAN, false); ChatBlock.sendMessage(clanPlayer, lang("unmuted.clan.chat", clanPlayer)); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ClanCommands.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ClanCommands.java index 40f37ba7..dd515431 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ClanCommands.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ClanCommands.java @@ -26,6 +26,7 @@ import static org.bukkit.ChatColor.RED; @CommandAlias("%clan") @Conditions("%basic_conditions") public class ClanCommands extends BaseCommand { + @Dependency private SimpleClans plugin; @Dependency @@ -46,22 +47,34 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rank:name=WAR_START") @Description("{@@command.description.war.start}") @CommandCompletion("@rivals") - public void startWar(Player player, ClanPlayer requester, Clan requestClan, @Conditions("can_war_target") @Name("clan") ClanInput targetClanInput) { + public void startWar(Player player, ClanPlayer requester, Clan requestClan, + @Conditions("can_war_target") @Name("clan") ClanInput targetClanInput) + { + Clan targetClan = targetClanInput.getClan(); List onlineLeaders = Helper.stripOffLinePlayers(requestClan.getLeaders()); if (settings.is(WAR_START_REQUEST_ENABLED)) { + if (!onlineLeaders.isEmpty()) { + requestManager.addWarStartRequest(requester, targetClan, requestClan); - ChatBlock.sendMessage(player, AQUA + lang("leaders.have.been.asked.to.accept.the.war.request", - player, targetClan.getName())); + ChatBlock.sendMessage(player, + AQUA + lang("leaders.have.been.asked.to.accept.the.war.request", player, targetClan.getName())); + } else { + ChatBlock.sendMessage(player, RED + lang("at.least.one.leader.accept.the.alliance", player)); + } + } else { + protectionManager.addWar(requester, requestClan, targetClan); + } + } @Subcommand("%war %end") @@ -70,13 +83,19 @@ public class ClanCommands extends BaseCommand { @Description("{@@command.description.war.end}") @CommandCompletion("@warring_clans") public void endWar(ClanPlayer cp, Clan issuerClan, @Name("clan") ClanInput other) { + Clan war = other.getClan(); if (issuerClan.isWarring(war.getTag())) { + requestManager.addWarEndRequest(cp, war, issuerClan); ChatBlock.sendMessage(cp, AQUA + lang("leaders.asked.to.end.rivalry", cp, war.getName())); + } else { + ChatBlock.sendMessage(cp, RED + lang("clans.not.at.war", cp)); + } + } @Subcommand("%modtag") @@ -84,29 +103,37 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rank:name=MODTAG") @Description("{@@command.description.modtag}") public void modtag(Player player, Clan clan, @Single @Name("tag") String tag) { + TagChangeEvent event = new TagChangeEvent(player, clan, tag); plugin.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } + tag = event.getNewTag(); String cleanTag = Helper.cleanTag(tag); Optional validationError = plugin.getTagValidator().validate(player, tag); if (validationError.isPresent()) { + ChatBlock.sendMessage(player, validationError.get()); return; + } if (!cleanTag.equals(clan.getTag())) { - ChatBlock.sendMessage(player, RED + lang("you.can.only.modify.the.color.and.case.of.the.tag", - player)); + + ChatBlock.sendMessage(player, RED + lang("you.can.only.modify.the.color.and.case.of.the.tag", player)); return; + } clan.addBb(player.getName(), lang("tag.changed.to.0", ChatUtils.parseColors(tag))); clan.changeClanTag(tag); cm.updateDisplayName(player); + } @Subcommand("%setbanner") @@ -114,16 +141,20 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rank:name=SETBANNER") @Description("{@@command.description.setbanner}") public void setbanner(Player player, Clan clan) { + @SuppressWarnings("deprecation") ItemStack hand = player.getItemInHand(); if (!hand.getType().toString().contains("BANNER")) { + ChatBlock.sendMessageKey(player, "you.must.hold.a.banner"); return; + } clan.setBanner(hand); storage.updateClan(clan); ChatBlock.sendMessageKey(player, "you.changed.clan.banner"); + } @Subcommand("%invite") @@ -132,40 +163,60 @@ public class ClanCommands extends BaseCommand { @Conditions("rank:name=INVITE") @Description("{@@command.description.invite}") public void invite(Player sender, ClanPlayer cp, Clan clan, - @Conditions("not_banned|not_in_clan|online:ignore_vanished") @Name("player") ClanPlayerInput invited) { + @Conditions("not_banned|not_in_clan|online:ignore_vanished") @Name("player") ClanPlayerInput invited) + { + if (!invited.getClanPlayer().isInviteEnabled()) { + ChatBlock.sendMessage(sender, RED + lang("invitedplayer.invite.off", sender)); return; + } + Player invitedPlayer = invited.getClanPlayer().toPlayer(); - if (invitedPlayer == null) return; - if (!permissions.has(invitedPlayer, "simpleclans.member.can-join")) { - ChatBlock.sendMessage(sender, RED + - lang("the.player.doesn.t.not.have.the.permissions.to.join.clans", sender)); + if (invitedPlayer == null) return; + if (!permissions.has(invitedPlayer, "simpleclans.member.can-join")) { + + ChatBlock.sendMessage(sender, + RED + lang("the.player.doesn.t.not.have.the.permissions.to.join.clans", sender)); + return; + } + if (invitedPlayer.getUniqueId().equals(sender.getUniqueId())) { + ChatBlock.sendMessage(sender, RED + lang("you.cannot.invite.yourself", sender)); return; + } + long minutesBeforeRejoin = cm.getMinutesBeforeRejoin(invited.getClanPlayer(), clan); if (minutesBeforeRejoin != 0) { - ChatBlock.sendMessage(sender, RED + - lang("the.player.must.wait.0.before.joining.your.clan.again", sender, minutesBeforeRejoin)); + + ChatBlock.sendMessage(sender, + RED + lang("the.player.must.wait.0.before.joining.your.clan.again", sender, minutesBeforeRejoin)); return; + } if (clan.getSize() >= settings.getInt(CLAN_MAX_MEMBERS) && settings.getInt(CLAN_MAX_MEMBERS) > 0) { + ChatBlock.sendMessage(sender, RED + lang("the.clan.members.reached.limit", sender)); return; + } + if (!cm.purchaseInvite(sender)) { + return; + } requestManager.addInviteRequest(cp, invitedPlayer.getName(), clan); - ChatBlock.sendMessage(sender, AQUA + lang("has.been.asked.to.join", - sender, invitedPlayer.getName(), clan.getName())); + ChatBlock.sendMessage(sender, + AQUA + lang("has.been.asked.to.join", sender, invitedPlayer.getName(), clan.getName())); + } @Subcommand("%fee %check") @@ -173,11 +224,12 @@ public class ClanCommands extends BaseCommand { @CommandPermission("simpleclans.member.fee-check") @Description("{@@command.description.fee.check}") public void checkFee(Player player, Clan clan) { - ChatBlock.sendMessage(player, AQUA - + lang("the.fee.is.0.and.its.current.value.is.1", player, clan.isMemberFeeEnabled() ? - lang("fee.enabled", player) : lang("fee.disabled", player), - clan.getMemberFee() - )); + + ChatBlock.sendMessage(player, + AQUA + lang("the.fee.is.0.and.its.current.value.is.1", player, + clan.isMemberFeeEnabled() ? lang("fee.enabled", player) : lang("fee.disabled", player), + clan.getMemberFee())); + } @Subcommand("%fee %set") @@ -185,19 +237,25 @@ public class ClanCommands extends BaseCommand { @Conditions("rank:name=FEE_SET|change_fee") @Description("{@@command.description.fee.set}") public void setFee(Player player, Clan clan, @Name("fee") double fee) { + fee = Math.abs(fee); double maxFee = settings.getDouble(ECONOMY_MAX_MEMBER_FEE); if (fee > maxFee) { - ChatBlock.sendMessage(player, RED - + lang("max.fee.allowed.is.0", player, CurrencyFormat.format(maxFee))); + + ChatBlock.sendMessage(player, RED + lang("max.fee.allowed.is.0", player, CurrencyFormat.format(maxFee))); return; + } + if (cm.purchaseMemberFeeSet(player)) { + clan.setMemberFee(fee); clan.addBb(player.getName(), lang("bb.fee.set", CurrencyFormat.format(fee))); ChatBlock.sendMessage(player, AQUA + lang("fee.set", player)); storage.updateClan(clan); + } + } @Subcommand("%clanff %allow") @@ -205,18 +263,22 @@ public class ClanCommands extends BaseCommand { @Conditions("rank:name=FRIENDLYFIRE") @Description("{@@command.description.clanff.allow}") public void allowClanFf(Player player, Clan clan) { + clan.addBb(player.getName(), lang("clan.wide.friendly.fire.is.allowed")); clan.setFriendlyFire(true); storage.updateClan(clan); + } @Subcommand("%clanff %block") @CommandPermission("simpleclans.leader.ff") @Description("{@@command.description.clanff.block}") public void blockClanFf(Player player, Clan clan) { + clan.addBb(player.getName(), lang("clan.wide.friendly.fire.blocked")); clan.setFriendlyFire(false); storage.updateClan(clan); + } @Subcommand("%description") @@ -224,19 +286,27 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rank:name=DESCRIPTION") @Description("{@@command.description.description}") public void setDescription(Player player, Clan clan, @Name("description") String description) { + if (description.length() < settings.getInt(CLAN_MIN_DESCRIPTION_LENGTH)) { - ChatBlock.sendMessage(player, RED + lang("your.clan.description.must.be.longer.than", - player, settings.getInt(CLAN_MIN_DESCRIPTION_LENGTH))); + + ChatBlock.sendMessage(player, RED + lang("your.clan.description.must.be.longer.than", player, + settings.getInt(CLAN_MIN_DESCRIPTION_LENGTH))); return; + } + if (description.length() > settings.getInt(CLAN_MAX_DESCRIPTION_LENGTH)) { - ChatBlock.sendMessage(player, RED + lang("your.clan.description.cannot.be.longer.than", - player, settings.getInt(CLAN_MAX_DESCRIPTION_LENGTH))); + + ChatBlock.sendMessage(player, RED + lang("your.clan.description.cannot.be.longer.than", player, + settings.getInt(CLAN_MAX_DESCRIPTION_LENGTH))); return; + } + clan.setDescription(description); ChatBlock.sendMessage(player, AQUA + lang("description.changed", player)); storage.updateClan(clan); + } @Subcommand("%rival %add") @@ -244,25 +314,40 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rivable|minimum_to_rival|rank:name=RIVAL_ADD") @CommandCompletion("@clans:hide_own") @Description("{@@command.description.rival.add}") - public void addRival(Player player, Clan issuerClan, @Conditions("verified|different") @Name("clan") ClanInput rival) { + public void addRival(Player player, Clan issuerClan, + @Conditions("verified|different") @Name("clan") ClanInput rival) + { + Clan rivalInput = rival.getClan(); if (settings.isUnrivable(rivalInput.getTag())) { + ChatBlock.sendMessage(player, RED + lang("the.clan.cannot.be.rivaled", player)); return; + } + if (!issuerClan.reachedRivalLimit()) { + if (!issuerClan.isRival(rivalInput.getTag())) { + issuerClan.addRival(rivalInput); - rivalInput.addBb(player.getName(), lang("has.initiated.a.rivalry", issuerClan.getName(), - rivalInput.getName()), false); - issuerClan.addBb(player.getName(), lang("has.initiated.a.rivalry", player.getName(), - rivalInput.getName())); + rivalInput.addBb(player.getName(), + lang("has.initiated.a.rivalry", issuerClan.getName(), rivalInput.getName()), false); + issuerClan.addBb(player.getName(), + lang("has.initiated.a.rivalry", player.getName(), rivalInput.getName())); + } else { + ChatBlock.sendMessage(player, RED + lang("your.clans.are.already.rivals", player)); + } + } else { + ChatBlock.sendMessage(player, RED + lang("rival.limit.reached", player)); + } + } @Subcommand("%rival %remove") @@ -270,18 +355,22 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rank:name=RIVAL_REMOVE") @CommandCompletion("@rivals") @Description("{@@command.description.rival.remove}") - public void removeRival(Player player, - ClanPlayer cp, - Clan issuerClan, - @Conditions("different") @Name("clan") ClanInput rival) { + public void removeRival(Player player, ClanPlayer cp, Clan issuerClan, + @Conditions("different") @Name("clan") ClanInput rival) + { + Clan rivalInput = rival.getClan(); if (issuerClan.isRival(rivalInput.getTag())) { + requestManager.addRivalryBreakRequest(cp, rivalInput, issuerClan); - ChatBlock.sendMessage(player, AQUA + lang("leaders.asked.to.end.rivalry", player, - rivalInput.getName())); + ChatBlock.sendMessage(player, AQUA + lang("leaders.asked.to.end.rivalry", player, rivalInput.getName())); + } else { + ChatBlock.sendMessage(player, RED + lang("your.clans.are.not.rivals", player)); + } + } @Subcommand("%ally %add") @@ -289,37 +378,48 @@ public class ClanCommands extends BaseCommand { @Conditions("verified|rank:name=ALLY_ADD|minimum_to_ally") @CommandCompletion("@clans:hide_own") @Description("{@@command.description.ally.add}") - public void addAlly(Player player, - ClanPlayer cp, - Clan issuerClan, - @Conditions("verified|different") @Name("clan") ClanInput other) { + public void addAlly(Player player, ClanPlayer cp, Clan issuerClan, + @Conditions("verified|different") @Name("clan") ClanInput other) + { + Clan input = other.getClan(); if (issuerClan.isAlly(input.getTag())) { + ChatBlock.sendMessage(player, RED + lang("your.clans.are.already.allies", player)); return; + } + int maxAlliances = settings.getInt(CLAN_MAX_ALLIANCES); if (maxAlliances != -1) { + if (issuerClan.getAllies().size() >= maxAlliances) { + ChatBlock.sendMessage(player, lang("your.clan.reached.max.alliances", player)); return; + } + if (input.getAllies().size() >= maxAlliances) { + ChatBlock.sendMessage(player, lang("other.clan.reached.max.alliances", player)); return; + } + } List onlineLeaders = Helper.stripOffLinePlayers(issuerClan.getLeaders()); if (onlineLeaders.isEmpty()) { - ChatBlock.sendMessage(player, RED + lang("at.least.one.leader.accept.the.alliance", - player)); + + ChatBlock.sendMessage(player, RED + lang("at.least.one.leader.accept.the.alliance", player)); return; + } requestManager.addAllyRequest(cp, input, issuerClan); - ChatBlock.sendMessage(player, AQUA + lang("leaders.have.been.asked.for.an.alliance", - player, input.getName())); + ChatBlock.sendMessage(player, AQUA + lang("leaders.have.been.asked.for.an.alliance", player, input.getName())); + } @Subcommand("%ally %remove") @@ -327,13 +427,16 @@ public class ClanCommands extends BaseCommand { @CommandPermission("simpleclans.leader.ally") @Description("{@@command.description.ally.remove}") @CommandCompletion("@allied_clans") - public void removeAlly(Player player, Clan issuerClan, @Conditions("different|allied_clan") @Name("clan") ClanInput ally) { + public void removeAlly(Player player, Clan issuerClan, + @Conditions("different|allied_clan") @Name("clan") ClanInput ally) + { + Clan allyInput = ally.getClan(); issuerClan.removeAlly(allyInput); - allyInput.addBb(player.getName(), lang("has.broken.the.alliance", issuerClan.getName(), - allyInput.getName()), false); - issuerClan.addBb(player.getName(), lang("has.broken.the.alliance", player.getName(), - allyInput.getName())); + allyInput.addBb(player.getName(), lang("has.broken.the.alliance", issuerClan.getName(), allyInput.getName()), + false); + issuerClan.addBb(player.getName(), lang("has.broken.the.alliance", player.getName(), allyInput.getName())); + } @Subcommand("%kick") @@ -342,22 +445,28 @@ public class ClanCommands extends BaseCommand { @Conditions("rank:name=KICK") @Description("{@@command.description.kick}") public void kick(@Conditions("clan_member") Player sender, - @Conditions("same_clan") @Name("member") ClanPlayerInput other) { + @Conditions("same_clan") @Name("member") ClanPlayerInput other) + { + ClanPlayer clanPlayer = other.getClanPlayer(); if (sender.getUniqueId().equals(clanPlayer.getUniqueId())) { + ChatBlock.sendMessage(sender, RED + lang("you.cannot.kick.yourself", sender)); return; + } Clan clan = cm.getClanByPlayerUniqueId(sender.getUniqueId()); if (Objects.requireNonNull(clan).isLeader(clanPlayer.getUniqueId())) { + ChatBlock.sendMessage(sender, RED + lang("you.cannot.kick.another.leader", sender)); return; + } - clan.addBb(sender.getName(), lang("has.been.kicked.by", clanPlayer.getName(), - sender.getName(), sender)); + clan.addBb(sender.getName(), lang("has.been.kicked.by", clanPlayer.getName(), sender.getName(), sender)); clan.removePlayerFromClan(clanPlayer.getUniqueId()); + } @Subcommand("%resign %confirm") @@ -365,19 +474,27 @@ public class ClanCommands extends BaseCommand { @Description("{@@command.description.resign}") @HelpSearchTags("leave") public void resignConfirm(Player player, ClanPlayer cp, Clan clan) { + if (clan.isPermanent() || !clan.isLeader(player) || clan.getLeaders().size() > 1) { + clan.addBb(player.getName(), lang("0.has.resigned", player.getName())); cp.addResignTime(clan.getTag()); clan.removePlayerFromClan(player.getUniqueId()); ChatBlock.sendMessage(cp, AQUA + lang("resign.success", player)); + } else if (clan.isLeader(player) && clan.getLeaders().size() == 1) { + clan.disband(player, true, false); ChatBlock.sendMessage(cp, RED + lang("clan.has.been.disbanded", player, clan.getName())); + } else { - ChatBlock.sendMessage(cp, RED + - lang("last.leader.cannot.resign.you.must.appoint.another.leader.or.disband.the.clan", player)); + + ChatBlock.sendMessage(cp, RED + + lang("last.leader.cannot.resign.you.must.appoint.another.leader.or.disband.the.clan", player)); + } + } @Subcommand("%resign") @@ -385,6 +502,9 @@ public class ClanCommands extends BaseCommand { @Description("{@@command.description.resign}") @HelpSearchTags("leave") public void resign(@Conditions("clan_member") Player player) { + new SCConversation(plugin, player, new ResignPrompt()).begin(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/DataCommands.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/DataCommands.java index 20d25117..94480f79 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/DataCommands.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/DataCommands.java @@ -16,6 +16,7 @@ import static org.bukkit.ChatColor.RED; @CommandAlias("%clan") @Conditions("%basic_conditions|verified") public class DataCommands extends BaseCommand { + @Dependency private SimpleClans plugin; @@ -24,8 +25,10 @@ public class DataCommands extends BaseCommand { @Conditions("rank:name=VITALS") @Description("{@@command.description.vitals}") public void vitals(CommandSender sender, Clan clan) { + Vitals vitals = new Vitals(plugin, sender, clan); vitals.send(); + } @Subcommand("%stats") @@ -33,24 +36,30 @@ public class DataCommands extends BaseCommand { @Conditions("rank:name=STATS") @Description("{@@command.description.stats}") public void stats(Player player, Clan clan) { + ClanStats stats = new ClanStats(plugin, player, clan); stats.send(); + } @Subcommand("%profile") @CommandPermission("simpleclans.member.profile") @Description("{@@command.description.profile}") public void profile(CommandSender sender, Clan clan) { + ClanProfile p = new ClanProfile(plugin, sender, clan); p.send(); + } @Subcommand("%roster") @CommandPermission("simpleclans.member.roster") @Description("{@@command.description.roster}") public void roster(Player player, Clan clan) { + ClanRoster r = new ClanRoster(plugin, player, clan); r.send(); + } @Subcommand("%coords") @@ -59,11 +68,17 @@ public class DataCommands extends BaseCommand { @HelpSearchTags("local location") @Description("{@@command.description.coords}") public void coords(Player player, Clan clan) { + if (VanishUtils.getNonVanished(player, clan).size() == 1) { + ChatBlock.sendMessage(player, RED + lang("you.are.the.only.member.online", player)); return; + } + ClanCoords c = new ClanCoords(plugin, player, clan); c.send(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/HomeCommands.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/HomeCommands.java index 820aefa8..e81ab9d2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/HomeCommands.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/HomeCommands.java @@ -22,6 +22,7 @@ import static org.bukkit.ChatColor.*; @CommandAlias("%clan") @Conditions("%basic_conditions|verified") public class HomeCommands extends BaseCommand { + @Dependency private SimpleClans plugin; @Dependency @@ -38,23 +39,32 @@ public class HomeCommands extends BaseCommand { @Conditions("rank:name=REGROUP_ME") @Description("{@@command.description.regroup.me}") public void regroupMe(Player player, ClanPlayer cp, Clan clan) { + if (!settings.is(ALLOW_REGROUP)) { + ChatBlock.sendMessage(player, RED + lang("insufficient.permissions", player)); return; + } processRegroup(player, cp, clan, player.getLocation()); + } private void processRegroup(Player player, ClanPlayer cp, Clan clan, Location location) { - HomeRegroupEvent homeRegroupEvent = new HomeRegroupEvent(clan, cp, VanishUtils.getNonVanished(player, clan), location); + + HomeRegroupEvent homeRegroupEvent = new HomeRegroupEvent(clan, cp, VanishUtils.getNonVanished(player, clan), + location); plugin.getServer().getPluginManager().callEvent(homeRegroupEvent); if (homeRegroupEvent.isCancelled() || !cm.purchaseHomeRegroup(player)) { + return; + } plugin.getTeleportManager().teleport(player, clan, location); + } @Subcommand("%regroup %home") @@ -62,12 +72,17 @@ public class HomeCommands extends BaseCommand { @Conditions("rank:name=REGROUP_HOME") @Description("{@@command.description.regroup.home}") public void regroupHome(Player player, ClanPlayer cp, @Conditions("can_teleport") Clan clan) { + if (!settings.is(ALLOW_REGROUP)) { + ChatBlock.sendMessage(player, RED + lang("insufficient.permissions", player)); return; + } + Location location = clan.getHomeLocation(); processRegroup(player, cp, clan, location); + } @Subcommand("%home") @@ -75,11 +90,15 @@ public class HomeCommands extends BaseCommand { @Conditions("rank:name=HOME_TP") @Description("{@@command.description.home.tp}") public void teleport(Player player, @Conditions("can_teleport") Clan clan, ClanPlayer cp) { + Location homeLocation = clan.getHomeLocation(); if (cm.purchaseHomeTeleport(player)) { + plugin.getTeleportManager().addPlayer(player, homeLocation, clan.getName()); + } + } @Subcommand("%home %clear") @@ -87,20 +106,27 @@ public class HomeCommands extends BaseCommand { @Conditions("rank:name=HOME_SET") @Description("{@@command.description.home.clear}") public void clear(Player player, ClanPlayer cp, Clan clan) { - if (settings.is(CLAN_HOMEBASE_CAN_BE_SET_ONLY_ONCE) && clan.getHomeLocation() != null && - !permissions.has(player, "simpleclans.mod.home")) { + + if (settings.is(CLAN_HOMEBASE_CAN_BE_SET_ONLY_ONCE) && clan.getHomeLocation() != null + && !permissions.has(player, "simpleclans.mod.home")) + { + ChatBlock.sendMessage(player, RED + lang("home.base.only.once", player)); return; + } PlayerHomeClearEvent event = new PlayerHomeClearEvent(clan, cp); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } clan.setHomeLocation(null); ChatBlock.sendMessage(player, AQUA + lang("hombase.cleared", player)); + } @Subcommand("%home %set") @@ -108,26 +134,40 @@ public class HomeCommands extends BaseCommand { @CommandPermission("simpleclans.leader.home-set") @Description("{@@command.description.home.set}") public void set(Player player, ClanPlayer cp, Clan clan) { - if (settings.is(CLAN_HOMEBASE_CAN_BE_SET_ONLY_ONCE) && clan.getHomeLocation() != null && - !permissions.has(player, "simpleclans.mod.home")) { + + if (settings.is(CLAN_HOMEBASE_CAN_BE_SET_ONLY_ONCE) && clan.getHomeLocation() != null + && !permissions.has(player, "simpleclans.mod.home")) + { + ChatBlock.sendMessage(player, RED + lang("home.base.only.once", player)); return; + } + if (settings.is(LAND_SET_BASE_ONLY_IN_LAND)) { + if (!protection.isOwner(player, player.getLocation())) { + ChatBlock.sendMessageKey(player, "you.can.only.set.base.in.your.land"); return; + } + } + PlayerHomeSetEvent homeSetEvent = new PlayerHomeSetEvent(clan, cp, player.getLocation()); plugin.getServer().getPluginManager().callEvent(homeSetEvent); if (homeSetEvent.isCancelled() || !cm.purchaseHomeTeleportSet(player)) { + return; + } clan.setHomeLocation(player.getLocation()); - ChatBlock.sendMessage(player, AQUA + lang("hombase.set", player, YELLOW + - Helper.toLocationString(player.getLocation()))); + ChatBlock.sendMessage(player, + AQUA + lang("hombase.set", player, YELLOW + Helper.toLocationString(player.getLocation()))); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LandCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LandCommand.java index 2370ab7c..de8ad7e2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LandCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LandCommand.java @@ -28,151 +28,212 @@ public class LandCommand extends BaseCommand { private SettingsManager settings; private Set getLands(ClanPlayer cp, Location location) { + Player player = Objects.requireNonNull(cp.toPlayer()); if (settings.is(LAND_EDIT_ALL_LANDS)) { + return protection.getLands(player, location); + } else { + return protection.getLandsAt(location).stream().filter(l -> l.getOwners().contains(player.getUniqueId())) .collect(Collectors.toSet()); + } + } @Subcommand("%allow") public class AllowCommand extends BaseCommand { private void allow(ClanPlayer cp, ProtectionManager.Action action, Location location) { + allow(cp, action, location, true); + } private void allow(ClanPlayer cp, ProtectionManager.Action action, Location location, boolean notify) { + for (Land land : getLands(cp, location)) { + cp.allow(action, land.getId()); + } + if (notify) { + ChatBlock.sendMessageKey(cp, "land.allowed.action"); + } + } @Subcommand("%container") @Description("{@@command.description.land.allow.container}") @CommandPermission("simpleclans.member.land.allow.container") public void container(Player player, ClanPlayer cp) { + allow(cp, ProtectionManager.Action.CONTAINER, player.getLocation()); + } @Subcommand("%place") @Description("{@@command.description.land.allow.place}") @CommandPermission("simpleclans.member.land.allow.place") public void place(Player player, ClanPlayer cp) { + allow(cp, ProtectionManager.Action.PLACE, player.getLocation()); + } @Subcommand("%damage") @Description("{@@command.description.land.allow.damage}") @CommandPermission("simpleclans.member.land.allow.damage") public void damage(Player player, ClanPlayer cp) { + allow(cp, ProtectionManager.Action.DAMAGE, player.getLocation()); + } @Subcommand("%interact_entity") @Description("{@@command.description.land.allow.interact_entity}") @CommandPermission("simpleclans.member.land.allow.interact_entity") public void interactEntity(Player player, ClanPlayer cp) { + allow(cp, ProtectionManager.Action.INTERACT_ENTITY, player.getLocation()); + } @Subcommand("%interact") @Description("{@@command.description.land.allow.interact}") @CommandPermission("simpleclans.member.land.allow.interact") public void interact(Player player, ClanPlayer cp) { + allow(cp, ProtectionManager.Action.INTERACT, player.getLocation()); + } @Subcommand("%break") @Description("{@@command.description.land.allow.break}") @CommandPermission("simpleclans.member.land.allow.break") public void allowBreak(Player player, ClanPlayer cp) { + allow(cp, ProtectionManager.Action.BREAK, player.getLocation()); + } @Subcommand("%all") @Description("{@@command.description.land.allow.all}") @CommandPermission("simpleclans.member.land.allow.all") public void all(Player player, ClanPlayer cp) { + for (ProtectionManager.Action action : ProtectionManager.Action.values()) { + allow(cp, action, player.getLocation(), false); + } + ChatBlock.sendMessageKey(player, "land.allowed.all.actions"); + } + } @Subcommand("%block") public class BlockCommand extends BaseCommand { private void block(ClanPlayer cp, ProtectionManager.Action action, Location location) { + block(cp, action, location, true); + } private void block(ClanPlayer cp, ProtectionManager.Action action, Location location, boolean notify) { + for (Land land : getLands(cp, location)) { + cp.disallow(action, land.getId()); + } + if (notify) { + ChatBlock.sendMessageKey(cp, "land.blocked.action"); + } + } @Subcommand("%container") @Description("{@@command.description.land.block.container}") @CommandPermission("simpleclans.member.land.block.container") public void container(Player player, ClanPlayer cp) { + block(cp, ProtectionManager.Action.CONTAINER, player.getLocation()); + } @Subcommand("%place") @Description("{@@command.description.land.block.place}") @CommandPermission("simpleclans.member.land.block.place") public void place(Player player, ClanPlayer cp) { + block(cp, ProtectionManager.Action.PLACE, player.getLocation()); + } @Subcommand("%damage") @Description("{@@command.description.land.block.damage}") @CommandPermission("simpleclans.member.land.block.damage") public void damage(Player player, ClanPlayer cp) { + block(cp, ProtectionManager.Action.DAMAGE, player.getLocation()); + } @Subcommand("%interact_entity") @Description("{@@command.description.land.block.interact_entity}") @CommandPermission("simpleclans.member.land.block.interact_entity") public void interactEntity(Player player, ClanPlayer cp) { + block(cp, ProtectionManager.Action.INTERACT_ENTITY, player.getLocation()); + } @Subcommand("%interact") @Description("{@@command.description.land.block.interact}") @CommandPermission("simpleclans.member.land.block.interact") public void interact(Player player, ClanPlayer cp) { + block(cp, ProtectionManager.Action.INTERACT, player.getLocation()); + } @Subcommand("%break") @Description("{@@command.description.land.block.break}") @CommandPermission("simpleclans.member.land.block.break") public void blockBreak(Player player, ClanPlayer cp) { + block(cp, ProtectionManager.Action.BREAK, player.getLocation()); + } @Subcommand("%all") @Description("{@@command.description.land.block.all}") @CommandPermission("simpleclans.member.land.block.all") public void all(Player player, ClanPlayer cp) { + protection.getLandsAt(player.getLocation()); for (ProtectionManager.Action action : ProtectionManager.Action.values()) { + block(cp, action, player.getLocation(), false); + } + ChatBlock.sendMessageKey(player, "land.blocked.all.actions"); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LeaderCommands.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LeaderCommands.java index ac9b1fb1..e96eb331 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LeaderCommands.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/LeaderCommands.java @@ -45,100 +45,136 @@ public class LeaderCommands extends BaseCommand { @CommandCompletion("@clan_leaders") @CommandPermission("simpleclans.leader.demote") @Description("{@@command.description.demote}") - public void demote(Player player, - ClanPlayer cp, - Clan clan, - @Conditions("same_clan") @Name("leader") ClanPlayerInput other) { + public void demote(Player player, ClanPlayer cp, Clan clan, + @Conditions("same_clan") @Name("leader") ClanPlayerInput other) + { + ClanPlayer otherCp = other.getClanPlayer(); if (!clan.enoughLeadersOnlineToDemote(otherCp)) { + ChatBlock.sendMessage(player, RED + lang("not.enough.leaders.online.to.vote.on.demotion", player)); return; + } + if (!clan.isLeader(otherCp.getUniqueId())) { + ChatBlock.sendMessage(player, RED + lang("player.is.not.a.leader.of.your.clan", player)); return; + } + if (clan.getLeaders().size() > 2 && settings.is(CLAN_CONFIRMATION_FOR_DEMOTE)) { + requestManager.addDemoteRequest(cp, otherCp.getName(), clan); - ChatBlock.sendMessage(player, AQUA + lang("demotion.vote.has.been.requested.from.all.leaders", - player)); + ChatBlock.sendMessage(player, AQUA + lang("demotion.vote.has.been.requested.from.all.leaders", player)); return; + } + clan.addBb(player.getName(), lang("demoted.back.to.member", otherCp.getName())); clan.demote(otherCp.getUniqueId()); + } @Subcommand("%promote") @CommandPermission("simpleclans.leader.promote") @CommandCompletion("@clan_non_leaders") @Description("{@@command.description.promote}") - public void promote(Player player, - Clan clan, - ClanPlayer cp, - @Conditions("online|same_clan") @Name("member") ClanPlayerInput other) { + public void promote(Player player, Clan clan, ClanPlayer cp, + @Conditions("online|same_clan") @Name("member") ClanPlayerInput other) + { + Player otherPl = Objects.requireNonNull(other.getClanPlayer().toPlayer()); if (!permissions.has(otherPl, "simpleclans.leader.promotable")) { - ChatBlock.sendMessage(player, RED + lang("the.player.does.not.have.the.permissions.to.lead.a.clan", - player)); + + ChatBlock.sendMessage(player, + RED + lang("the.player.does.not.have.the.permissions.to.lead.a.clan", player)); return; + } + if (otherPl.getUniqueId().equals(player.getUniqueId())) { + ChatBlock.sendMessage(player, RED + lang("you.cannot.promote.yourself", player)); return; + } + if (clan.isLeader(otherPl.getUniqueId())) { + ChatBlock.sendMessage(player, RED + lang("the.player.is.already.a.leader", player)); return; + } + if (settings.is(CLAN_CONFIRMATION_FOR_PROMOTE) && clan.getLeaders().size() > 1) { + requestManager.requestAllLeaders(cp, ClanRequest.PROMOTE, otherPl.getName(), "asking.for.the.promotion", player.getName(), otherPl.getName()); - ChatBlock.sendMessage(player, AQUA + lang("promotion.vote.has.been.requested.from.all.leaders", - player)); + ChatBlock.sendMessage(player, AQUA + lang("promotion.vote.has.been.requested.from.all.leaders", player)); return; + } clan.addBb(player.getName(), lang("promoted.to.leader", otherPl.getName())); clan.promote(otherPl.getUniqueId()); + } @Subcommand("%disband") @CommandPermission("simpleclans.leader.disband") @Description("{@@command.description.disband}") public void disband(Player player, ClanPlayer cp, Clan clan) { + if (clan.getLeaders().size() != 1) { + requestManager.requestAllLeaders(cp, ClanRequest.DISBAND, clan.getTag(), "asking.to.disband", player.getName()); - ChatBlock.sendMessage(player, AQUA + - lang("clan.disband.vote.has.been.requested.from.all.leaders", player)); + ChatBlock.sendMessage(player, AQUA + lang("clan.disband.vote.has.been.requested.from.all.leaders", player)); return; + } new SCConversation(plugin, player, new DisbandPrompt()).begin(); + } @Subcommand("%verify") @CommandPermission("simpleclans.leader.verify") @Description("{@@command.description.verify}") public void verify(Player player, Clan clan) { + if (clan.isVerified()) { + ChatBlock.sendMessageKey(player, "your.clan.already.verified"); return; + } + if (!settings.is(ECONOMY_PURCHASE_CLAN_VERIFY)) { + ChatBlock.sendMessageKey(player, "staff.member.verify.clan"); return; + } + int minToVerify = settings.getInt(CLAN_MIN_TO_VERIFY); if (minToVerify > clan.getMembers().size()) { + ChatBlock.sendMessage(player, lang("your.clan.must.have.members.to.verify", player, minToVerify)); return; + } + if (cm.purchaseVerification(player)) { + clan.verifyClan(); clan.addBb(player.getName(), lang("clan.0.has.been.verified", clan.getName())); ChatBlock.sendMessage(player, AQUA + lang("the.clan.has.been.verified", player)); + } + } @Subcommand("%trust") @@ -146,23 +182,34 @@ public class LeaderCommands extends BaseCommand { @CommandCompletion("@clan_members") @Description("{@@command.description.trust}") public void trust(Player player, Clan clan, @Conditions("same_clan") @Name("member") ClanPlayerInput trusted) { + ClanPlayer trustedInput = trusted.getClanPlayer(); if (player.getUniqueId().equals(trustedInput.getUniqueId())) { + ChatBlock.sendMessage(player, RED + lang("you.cannot.trust.yourself", player)); return; + } + if (clan.isLeader(trustedInput.getUniqueId())) { + ChatBlock.sendMessage(player, RED + lang("leaders.are.already.trusted", player)); return; + } + if (trustedInput.isTrusted()) { + ChatBlock.sendMessage(player, ChatColor.RED + lang("this.player.is.already.trusted", player)); return; + } - clan.addBb(player.getName(), lang("has.been.given.trusted.status.by", trustedInput.getName(), - player.getName())); + + clan.addBb(player.getName(), + lang("has.been.given.trusted.status.by", trustedInput.getName(), player.getName())); trustedInput.setTrusted(true); storage.updateClanPlayer(trustedInput); + } @Subcommand("%untrust") @@ -170,24 +217,34 @@ public class LeaderCommands extends BaseCommand { @CommandCompletion("@clan_members") @Description("{@@command.description.untrust}") public void untrust(Player player, Clan clan, @Conditions("same_clan") @Name("member") ClanPlayerInput trusted) { + ClanPlayer trustedInput = trusted.getClanPlayer(); if (trustedInput.getUniqueId().equals(player.getUniqueId())) { + ChatBlock.sendMessage(player, RED + lang("you.cannot.untrust.yourself", player)); return; - } - if (clan.isLeader(trustedInput.getUniqueId())) { - ChatBlock.sendMessage(player, RED + lang("leaders.cannot.be.untrusted", player)); - return; - } - if (!trustedInput.isTrusted()) { - ChatBlock.sendMessage(player, RED + lang("this.player.is.already.untrusted", player)); - return; + } - clan.addBb(player.getName(), lang("has.been.given.untrusted.status.by", trustedInput.getName(), - player.getName())); + if (clan.isLeader(trustedInput.getUniqueId())) { + + ChatBlock.sendMessage(player, RED + lang("leaders.cannot.be.untrusted", player)); + return; + + } + + if (!trustedInput.isTrusted()) { + + ChatBlock.sendMessage(player, RED + lang("this.player.is.already.untrusted", player)); + return; + + } + + clan.addBb(player.getName(), + lang("has.been.given.untrusted.status.by", trustedInput.getName(), player.getName())); trustedInput.setTrusted(false); storage.updateClanPlayer(trustedInput); + } @Subcommand("%rename") @@ -195,34 +252,49 @@ public class LeaderCommands extends BaseCommand { @CommandCompletion("@nothing") @Description("{@@command.description.rename}") public void rename(Player player, ClanPlayer cp, Clan clan, @Name("name") String clanName) { + if (clanName.contains("&")) { + ChatBlock.sendMessageKey(cp, "your.clan.name.cannot.contain.color.codes"); return; + } + boolean bypass = plugin.getPermissionsManager().has(player, "simpleclans.mod.bypass"); if (!bypass) { + if (ChatUtils.stripColors(clanName).length() > plugin.getSettingsManager().getInt(CLAN_MAX_LENGTH)) { - ChatBlock.sendMessage(player, RED + lang("your.clan.name.cannot.be.longer.than.characters", - player, plugin.getSettingsManager().getInt(CLAN_MAX_LENGTH))); + + ChatBlock.sendMessage(player, RED + lang("your.clan.name.cannot.be.longer.than.characters", player, + plugin.getSettingsManager().getInt(CLAN_MAX_LENGTH))); return; + } + if (ChatUtils.stripColors(clanName).length() <= plugin.getSettingsManager().getInt(CLAN_MIN_LENGTH)) { - ChatBlock.sendMessage(player, RED + lang("your.clan.name.must.be.longer.than.characters", - player, plugin.getSettingsManager().getInt(CLAN_MIN_LENGTH))); + + ChatBlock.sendMessage(player, RED + lang("your.clan.name.must.be.longer.than.characters", player, + plugin.getSettingsManager().getInt(CLAN_MIN_LENGTH))); return; + } + } if (clan.getLeaders().size() != 1) { - requestManager.requestAllLeaders(cp, ClanRequest.RENAME, clanName, "asking.to.rename", cp.getName(), clanName); + + requestManager.requestAllLeaders(cp, ClanRequest.RENAME, clanName, "asking.to.rename", cp.getName(), + clanName); ChatBlock.sendMessageKey(cp, "rename.vote.has.been.requested.from.all.leaders"); return; + } clan.setName(clanName); storage.updateClan(clan); ChatBlock.sendMessageKey(cp, "you.have.successfully.renamed.your.clan", clanName); + } @Subcommand("%discord %create") @@ -230,36 +302,56 @@ public class LeaderCommands extends BaseCommand { @Description("{@@command.description.discord.create}") @Conditions("verified") public void discord(Player player, Clan clan) { + DiscordHook discordHook = chatManager.getDiscordHook(); if (discordHook == null) { + ChatBlock.sendMessageKey(player, "discordhook.is.disabled"); return; + } double amount = settings.getDouble(ECONOMY_DISCORD_CREATION_PRICE); if (settings.is(ECONOMY_PURCHASE_DISCORD_CREATE)) { + if (!permissions.playerHasMoney(player, amount)) { + player.sendMessage(AQUA + lang("not.sufficient.money", player, CurrencyFormat.format(amount))); return; + } if (!permissions.chargePlayer(player, amount, DISCORD_CREATION)) { + return; + } + } try { + discordHook.createChannel(clan.getTag()); ChatBlock.sendMessageKey(player, "discord.created.successfully"); + } catch (DiscordHookException ex) { + // Return player's money if clan creation went wrong if (settings.is(ECONOMY_PURCHASE_DISCORD_CREATE)) { + permissions.grantPlayer(player, amount, DISCORD_CREATION); + } + String messageKey = ex.getMessageKey(); if (messageKey != null) { + ChatBlock.sendMessage(player, RED + lang(messageKey)); + } + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/RankCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/RankCommand.java index 339c8557..0278a46a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/RankCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/RankCommand.java @@ -40,25 +40,30 @@ public class RankCommand extends BaseCommand { @CommandPermission("simpleclans.leader.rank.assign") @CommandCompletion("@clan_members @ranks") @Description("{@@command.description.rank.assign}") - public void assign(ClanPlayer player, - Clan clan, - @Name("member") @Conditions("same_clan") ClanPlayerInput member, - @Name("rank") Rank rank) { + public void assign(ClanPlayer player, Clan clan, @Name("member") @Conditions("same_clan") ClanPlayerInput member, + @Name("rank") Rank rank) + { + ClanPlayer memberInput = member.getClanPlayer(); - PlayerRankUpdateEvent event = new PlayerRankUpdateEvent(player, memberInput, clan, clan.getRank(memberInput.getRankId()), rank); + PlayerRankUpdateEvent event = new PlayerRankUpdateEvent(player, memberInput, clan, + clan.getRank(memberInput.getRankId()), rank); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) + return; if (memberInput.getRankId().equals(rank.getName())) { + ChatBlock.sendMessage(player, lang("player.already.has.that.rank", player)); return; + } memberInput.setRank(rank.getName()); storage.updateClanPlayer(memberInput); ChatBlock.sendMessage(player, AQUA + lang("player.rank.changed", player)); + } @Subcommand("%unassign") @@ -66,26 +71,33 @@ public class RankCommand extends BaseCommand { @CommandCompletion("@clan_members") @Description("{@@command.description.rank.unassign}") public void unassign(ClanPlayer player, Clan clan, @Conditions("same_clan") @Name("member") ClanPlayerInput cp) { + ClanPlayer memberInput = cp.getClanPlayer(); - PlayerRankUpdateEvent event = new PlayerRankUpdateEvent(player, memberInput, clan, clan.getRank(memberInput.getRankId()), null); + PlayerRankUpdateEvent event = new PlayerRankUpdateEvent(player, memberInput, clan, + clan.getRank(memberInput.getRankId()), null); Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; + if (event.isCancelled()) + return; memberInput.setRank(null); storage.updateClanPlayer(memberInput); ChatBlock.sendMessage(player, AQUA + lang("player.unassigned.from.rank", player)); + } @Subcommand("%create") @CommandPermission("simpleclans.leader.rank.create") @Description("{@@command.description.rank.create}") public void create(Player player, Clan clan) { + SCConversation conversation = new SCConversation(plugin, player, new CreateRankNamePrompt(), 60); - conversation.addConversationCanceller(new RequestCanceller(player, RED + lang("rank.create.request.cancelled", player))); + conversation.addConversationCanceller( + new RequestCanceller(player, RED + lang("rank.create.request.cancelled", player))); conversation.getContext().setSessionData("clan", clan); conversation.begin(); + } @Subcommand("%delete") @@ -93,49 +105,66 @@ public class RankCommand extends BaseCommand { @CommandCompletion("@ranks") @Description("{@@command.description.rank.delete}") public void delete(Player player, Clan clan, @Name("rank") Rank rank) { + DeleteRankEvent event = new DeleteRankEvent(player, clan, rank); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { + clan.deleteRank(rank.getName()); storage.updateClan(clan, true); ChatBlock.sendMessage(player, AQUA + lang("rank.0.deleted", player, rank.getDisplayName())); + } + } @Subcommand("%list") @CommandPermission("simpleclans.leader.rank.list") @Description("{@@command.description.rank.list}") public void list(Player player, Clan clan) { + List ranks = clan.getRanks(); if (ranks.isEmpty()) { + ChatBlock.sendMessage(player, RED + lang("no.ranks", player)); return; + } ranks.sort(Comparator.reverseOrder()); ChatBlock.sendMessage(player, AQUA + lang("clans.ranks", player)); int count = 1; for (Rank rank : ranks) { + ChatBlock.sendMessage(player, AQUA + lang("ranks.list.item", player, count, ChatUtils.parseColors(rank.getDisplayName()) + AQUA, rank.getName())); count++; + } + } @Subcommand("%setdisplayname") @CommandPermission("simpleclans.leader.rank.setdisplayname") @CommandCompletion("@ranks @nothing") @Description("{@@command.description.rank.setdisplayname}") - public void setDisplayName(Player player, Clan clan, @Name("rank") Rank rank, @Name("displayname") String displayName) { + public void setDisplayName(Player player, Clan clan, @Name("rank") Rank rank, + @Name("displayname") String displayName) + { + if (displayName.contains("&") && !permissions.has(player, "simpleclans.leader.coloredrank")) { + ChatBlock.sendMessage(player, RED + lang("you.cannot.set.colored.ranks", player)); return; + } + rank.setDisplayName(displayName); storage.updateClan(clan, true); ChatBlock.sendMessage(player, ChatColor.AQUA + lang("rank.displayname.updated", player)); + } @Subcommand("%setdefault") @@ -143,28 +172,35 @@ public class RankCommand extends BaseCommand { @CommandCompletion("@ranks") @Description("{@@command.description.rank.setdefault}") public void setDefault(Player player, Clan clan, @Name("rank") Rank rank) { + clan.setDefaultRank(rank.getName()); ChatBlock.sendMessage(player, AQUA + lang("rank.setdefault", player, rank.getDisplayName())); + } @Subcommand("%removedefault") @CommandPermission("simpleclans.leader.rank.removedefault") @Description("{@@command.description.rank.removedefault}") public void removeDefault(Player player, Clan clan) { + clan.setDefaultRank(null); ChatBlock.sendMessage(player, AQUA + lang("rank.removedefault", player)); + } @Subcommand("%permissions") public class PermissionsCommand extends BaseCommand { + private final String validPermissionsToMessage = String.join(",", Helper.fromPermissionArray()); @Default @CommandPermission("simpleclans.leader.rank.permissions.available") @Description("{@@command.description.rank.permissions.available}") public void availablePermissions(Player player) { + ChatBlock.sendMessage(player, AQUA + lang("available.rank.permissions", player)); ChatBlock.sendMessage(player, AQUA + validPermissionsToMessage); + } @Default @@ -172,43 +208,52 @@ public class RankCommand extends BaseCommand { @CommandCompletion("@ranks") @Description("{@@command.description.rank.permissions.rank}") public void list(Player player, @Name("rank") Rank rank) { + Set permissions = rank.getPermissions(); if (permissions.isEmpty()) { + ChatBlock.sendMessage(player, RED + lang("rank.no.permissions", player)); return; + } + ChatBlock.sendMessage(player, AQUA + lang("rank.0.permissions", player, rank.getDisplayName())); ChatBlock.sendMessage(player, AQUA + String.join(",", permissions)); + } @Subcommand("%add") @CommandPermission("simpleclans.leader.rank.permissions.add") @CommandCompletion("@ranks @rank_permissions") @Description("{@@command.description.rank.permissions.add}") - public void add(Player player, - Clan clan, - @Name("rank") Rank rank, - @Values("@rank_permissions") @Name("permission") String permission) { + public void add(Player player, Clan clan, @Name("rank") Rank rank, + @Values("@rank_permissions") @Name("permission") String permission) + { + Set permissions = rank.getPermissions(); permissions.add(permission); - ChatBlock.sendMessage(player, AQUA + lang("permission.0.added.to.rank.1", player, permission, - rank.getDisplayName())); + ChatBlock.sendMessage(player, + AQUA + lang("permission.0.added.to.rank.1", player, permission, rank.getDisplayName())); storage.updateClan(clan, true); + } @Subcommand("%remove") @CommandCompletion("@ranks @rank_permissions") @CommandPermission("simpleclans.leader.rank.permissions.remove") @Description("{@@command.description.rank.permissions.remove}") - public void remove(Player player, - Clan clan, - @Name("rank") Rank rank, - @Values("@rank_permissions") @Name("permission") String permission) { + public void remove(Player player, Clan clan, @Name("rank") Rank rank, + @Values("@rank_permissions") @Name("permission") String permission) + { + Set permissions = rank.getPermissions(); permissions.remove(permission); - ChatBlock.sendMessage(player, AQUA + lang("permission.0.removed.from.rank.1", player, - permission, rank.getDisplayName())); + ChatBlock.sendMessage(player, + AQUA + lang("permission.0.removed.from.rank.1", player, permission, rank.getDisplayName())); storage.updateClan(clan, true); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ToggleCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ToggleCommand.java index bcd290a3..72b52762 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ToggleCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/clan/ToggleCommand.java @@ -24,19 +24,23 @@ public class ToggleCommand extends BaseCommand { @Conditions("verified") public class Verified extends BaseCommand { - + @Subcommand("%bb") @CommandPermission("simpleclans.member.bb-toggle") @Description("{@@command.description.toggle.bb}") public void bb(Player player, ClanPlayer cp) { + toggle(player, "bbon", "bboff", cp.isBbEnabled(), cp::setBbEnabled); + } @Subcommand("%tag") @CommandPermission("simpleclans.member.tag-toggle") @Description("{@@command.description.toggle.tag}") public void tag(Player player, ClanPlayer cp) { + toggle(player, "tagon", "tagoff", cp.isTagEnabled(), cp::setTagEnabled); + } @Subcommand("%deposit") @@ -44,10 +48,11 @@ public class ToggleCommand extends BaseCommand { @Conditions("leader") @Description("{@@command.description.toggle.deposit}") public void deposit(Player player, Clan clan) { - toggle(player, "depositon", "depositoff", clan.isAllowDeposit(), - clan::setAllowDeposit); + + toggle(player, "depositon", "depositoff", clan.isAllowDeposit(), clan::setAllowDeposit); storage.updateClan(clan); + } @Subcommand("%fee") @@ -55,10 +60,11 @@ public class ToggleCommand extends BaseCommand { @Conditions("rank:name=FEE_ENABLE|change_fee") @Description("{@@command.description.toggle.fee}") public void fee(Player player, Clan clan) { - toggle(player, "feeon", "feeoff", clan.isMemberFeeEnabled(), - clan::setMemberFeeEnabled); + + toggle(player, "feeon", "feeoff", clan.isMemberFeeEnabled(), clan::setMemberFeeEnabled); storage.updateClan(clan); + } @Subcommand("%withdraw") @@ -66,26 +72,34 @@ public class ToggleCommand extends BaseCommand { @Conditions("leader") @Description("{@@command.description.toggle.withdraw}") public void withdraw(Player player, Clan clan) { - toggle(player, "withdrawon", "withdrawoff", clan.isAllowWithdraw(), - clan::setAllowWithdraw); + + toggle(player, "withdrawon", "withdrawoff", clan.isAllowWithdraw(), clan::setAllowWithdraw); storage.updateClan(clan); + } + } @Subcommand("%invite") @CommandPermission("simpleclans.anyone.invite-toggle") @Description("{@@command.description.toggle.invite}") public void invite(Player player, ClanPlayer cp) { + toggle(player, "inviteon", "inviteoff", cp.isInviteEnabled(), cp::setInviteEnabled); + } private void toggle(CommandSender sender, String onMessageKey, String offMessageKey, boolean status, - Consumer consumer) { + Consumer consumer) + { + String messageOn = AQUA + lang(onMessageKey, sender); String messageOff = AQUA + lang(offMessageKey, sender); ChatBlock.sendMessage(sender, status ? messageOff : messageOn); consumer.accept(!status); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractAsyncCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractAsyncCompletion.java index 9348ffee..00689152 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractAsyncCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractAsyncCompletion.java @@ -6,8 +6,13 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.jetbrains.annotations.NotNull; public abstract class AbstractAsyncCompletion extends AbstractCompletion - implements AsyncCommandCompletionHandler { + implements AsyncCommandCompletionHandler +{ + public AbstractAsyncCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractCompletion.java index b7b22683..092a184f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractCompletion.java @@ -10,7 +10,10 @@ public abstract class AbstractCompletion implements IdentifiableCompletion { protected final ClanManager clanManager; public AbstractCompletion(@NotNull SimpleClans plugin) { + this.plugin = plugin; this.clanManager = plugin.getClanManager(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractStaticCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractStaticCompletion.java index 5857aadc..fa168468 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractStaticCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractStaticCompletion.java @@ -8,7 +8,9 @@ import java.util.Collection; public abstract class AbstractStaticCompletion extends AbstractCompletion { public AbstractStaticCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @NotNull diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractSyncCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractSyncCompletion.java index de4c5edf..e43223e7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractSyncCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AbstractSyncCompletion.java @@ -6,8 +6,13 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.jetbrains.annotations.NotNull; public abstract class AbstractSyncCompletion extends AbstractCompletion - implements CommandCompletionHandler { + implements CommandCompletionHandler +{ + public AbstractSyncCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllLeadersCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllLeadersCompletion.java index f0b708fc..74dff3be 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllLeadersCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllLeadersCompletion.java @@ -11,19 +11,26 @@ import java.util.stream.Collectors; @SuppressWarnings("unused") public class AllLeadersCompletion extends AbstractSyncCompletion { + public AllLeadersCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext context) throws InvalidCommandArgument { - return clanManager - .getAllClanPlayers().stream().filter(ClanPlayer::isLeader).map(ClanPlayer::getName) + + return clanManager.getAllClanPlayers().stream().filter(ClanPlayer::isLeader).map(ClanPlayer::getName) .collect(Collectors.toList()); + } @Override public @NotNull String getId() { + return "all_leaders"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllNonLeadersCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllNonLeadersCompletion.java index ac76c3b3..be7b4c35 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllNonLeadersCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AllNonLeadersCompletion.java @@ -11,19 +11,26 @@ import java.util.stream.Collectors; @SuppressWarnings("unused") public class AllNonLeadersCompletion extends AbstractSyncCompletion { + public AllNonLeadersCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext context) throws InvalidCommandArgument { - return clanManager - .getAllClanPlayers().stream().filter(cp -> !cp.isLeader() && cp.getClan() != null) + + return clanManager.getAllClanPlayers().stream().filter(cp -> !cp.isLeader() && cp.getClan() != null) .map(ClanPlayer::getName).collect(Collectors.toList()); + } @Override public @NotNull String getId() { + return "all_non_leaders"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AlliedClansCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AlliedClansCompletion.java index 129806f7..bc689330 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AlliedClansCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/AlliedClansCompletion.java @@ -12,24 +12,37 @@ import java.util.Collections; @SuppressWarnings("unused") public class AlliedClansCompletion extends AbstractSyncCompletion { + public AlliedClansCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext context) throws InvalidCommandArgument { + Player player = context.getPlayer(); if (player != null) { + Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + return clan.getAllies(); + } + } + return Collections.emptyList(); + } @Override public @NotNull String getId() { + return "allied_clans"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanLeadersCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanLeadersCompletion.java index 2e2b5b01..cb0f8749 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanLeadersCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanLeadersCompletion.java @@ -13,24 +13,37 @@ import java.util.Collections; import java.util.stream.Collectors; public class ClanLeadersCompletion extends AbstractSyncCompletion { + public ClanLeadersCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + Player player = c.getPlayer(); if (player != null) { + Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + return clan.getLeaders().stream().map(ClanPlayer::getName).collect(Collectors.toList()); + } + } + return Collections.emptyList(); + } @Override public @NotNull String getId() { + return "clan_leaders"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanMembersCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanMembersCompletion.java index e3ef6ec7..931c148e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanMembersCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanMembersCompletion.java @@ -15,28 +15,44 @@ import java.util.stream.Collectors; @SuppressWarnings("unused") public class ClanMembersCompletion extends AbstractSyncCompletion { + public ClanMembersCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + Player player = c.getPlayer(); if (player != null) { + Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + List list = clan.getMembers().stream().map(ClanPlayer::getName).collect(Collectors.toList()); if (c.hasConfig("hide_own")) { + list.remove(player.getName()); + } + return list; + } + } + return Collections.emptyList(); + } @Override public @NotNull String getId() { + return "clan_members"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanNonLeadersCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanNonLeadersCompletion.java index 7eafba6b..de54ca25 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanNonLeadersCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClanNonLeadersCompletion.java @@ -14,23 +14,37 @@ import java.util.stream.Collectors; @SuppressWarnings("unused") public class ClanNonLeadersCompletion extends AbstractSyncCompletion { + public ClanNonLeadersCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + Player player = c.getPlayer(); if (player != null) { + Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + return clan.getNonLeaders().stream().map(ClanPlayer::getName).collect(Collectors.toList()); + } + } - return Collections.emptyList(); } + + return Collections.emptyList(); + + } @Override public @NotNull String getId() { + return "clan_non_leaders"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClansCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClansCompletion.java index cf1876fb..d53e8de4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClansCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ClansCompletion.java @@ -13,34 +13,55 @@ import java.util.List; import java.util.stream.Collectors; public class ClansCompletion extends AbstractSyncCompletion { + public ClansCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + List clans = clanManager.getClans(); if (c.hasConfig("has_home")) { + clans.removeIf(clan -> clan.getHomeLocation() == null); + } + if (c.hasConfig("unverified")) { + clans.removeIf(Clan::isVerified); + } + if (c.hasConfig("hide_own")) { + Clan clan = getClan(c.getIssuer()); if (clan != null) { + clans.remove(clan); + } + } + return clans.stream().map(Clan::getTag).collect(Collectors.toList()); + } @Override public @NotNull String getId() { + return "clans"; + } private @Nullable Clan getClan(CommandIssuer issuer) { + return clanManager.getClanByPlayerUniqueId(issuer.getUniqueId()); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/IdentifiableCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/IdentifiableCompletion.java index 6c5233df..c2e62226 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/IdentifiableCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/IdentifiableCompletion.java @@ -6,4 +6,5 @@ public interface IdentifiableCompletion { @NotNull String getId(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ListTypeCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ListTypeCompletion.java index 56823e97..2c31493d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ListTypeCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/ListTypeCompletion.java @@ -10,19 +10,26 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; @SuppressWarnings("unused") public class ListTypeCompletion extends AbstractStaticCompletion { + public ListTypeCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull Collection getCompletions() { - return Arrays.asList( - lang("list.type.size"), lang("list.type.kdr"), lang("list.type.name"), + + return Arrays.asList(lang("list.type.size"), lang("list.type.kdr"), lang("list.type.name"), lang("list.type.founded"), lang("list.type.active")); + } @Override public @NotNull String getId() { + return "clan_list_type"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/LocaleCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/LocaleCompletion.java index d2cb4ba1..d4456919 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/LocaleCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/LocaleCompletion.java @@ -14,18 +14,25 @@ public class LocaleCompletion extends AbstractStaticCompletion { private final List availableLocales; public LocaleCompletion(@NotNull SimpleClans plugin) { + super(plugin); - availableLocales = LanguageResource.getAvailableLocales().stream(). - map(locale -> locale.toLanguageTag().replace("-", "_")).collect(Collectors.toList()); + availableLocales = LanguageResource.getAvailableLocales().stream() + .map(locale -> locale.toLanguageTag().replace("-", "_")).collect(Collectors.toList()); + } @Override public @NotNull Collection getCompletions() { + return availableLocales; + } @Override public @NotNull String getId() { + return "locales"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/NonMembersCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/NonMembersCompletion.java index 41a50e9f..5b12e69d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/NonMembersCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/NonMembersCompletion.java @@ -13,27 +13,42 @@ import java.util.Collection; @SuppressWarnings("unused") public class NonMembersCompletion extends AbstractSyncCompletion { + public NonMembersCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "non_members"; + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + Collection onlinePlayers = new ArrayList<>(); for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + boolean vanished = VanishUtils.isVanished(c.getSender(), onlinePlayer); - if (clanManager.getClanByPlayerUniqueId(onlinePlayer.getUniqueId()) != null || (c.hasConfig("ignore_vanished") && vanished)) { + if (clanManager.getClanByPlayerUniqueId(onlinePlayer.getUniqueId()) != null + || (c.hasConfig("ignore_vanished") && vanished)) + { + continue; + } + onlinePlayers.add(onlinePlayer.getName()); + } return onlinePlayers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/OrderCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/OrderCompletion.java index c3c9299f..f57b5832 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/OrderCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/OrderCompletion.java @@ -10,17 +10,25 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; @SuppressWarnings("unused") public class OrderCompletion extends AbstractStaticCompletion { + public OrderCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull Collection getCompletions() { + return Arrays.asList(lang("list.order.asc"), lang("list.order.desc")); + } @Override public @NotNull String getId() { + return "order"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RankPermissionsCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RankPermissionsCompletion.java index fd5f6006..94d45657 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RankPermissionsCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RankPermissionsCompletion.java @@ -9,17 +9,25 @@ import java.util.Collection; @SuppressWarnings("unused") public class RankPermissionsCompletion extends AbstractStaticCompletion { + public RankPermissionsCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull Collection getCompletions() { + return Arrays.asList(Helper.fromPermissionArray()); + } @Override public @NotNull String getId() { + return "rank_permissions"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RanksCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RanksCompletion.java index 5b55b650..d5e5d8d6 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RanksCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RanksCompletion.java @@ -13,23 +13,37 @@ import java.util.Collections; import java.util.stream.Collectors; public class RanksCompletion extends AbstractSyncCompletion { + public RanksCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext context) throws InvalidCommandArgument { + Player player = context.getPlayer(); if (player != null) { + Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + return clan.getRanks().stream().map(Rank::getName).collect(Collectors.toList()); + } + } - return Collections.emptyList(); } + + return Collections.emptyList(); + + } @Override public @NotNull String getId() { + return "ranks"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RivalsCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RivalsCompletion.java index 9dd2ea8f..523fe610 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RivalsCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/RivalsCompletion.java @@ -12,24 +12,37 @@ import java.util.Collections; @SuppressWarnings("unused") public class RivalsCompletion extends AbstractSyncCompletion { + public RivalsCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + Player player = c.getPlayer(); if (player != null) { + Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + return clan.getRivals(); + } + } + return Collections.emptyList(); + } @Override public @NotNull String getId() { + return "rivals"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/WarringClansCompletion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/WarringClansCompletion.java index c642aa10..cd0cbec9 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/WarringClansCompletion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/completions/WarringClansCompletion.java @@ -13,24 +13,37 @@ import java.util.stream.Collectors; @SuppressWarnings("unused") public class WarringClansCompletion extends AbstractSyncCompletion { + public WarringClansCompletion(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Collection getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument { + if (c.getIssuer().isPlayer()) { + Player player = c.getPlayer(); Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if (clan != null) { + return clan.getWarringClans().stream().map(Clan::getTag).collect(Collectors.toList()); + } + } + return Collections.emptyList(); + } @Override public @NotNull String getId() { + return "warring_clans"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCommandCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCommandCondition.java index 9d3e1378..bea6d01c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCommandCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCommandCondition.java @@ -5,8 +5,14 @@ import co.aikar.commands.CommandConditions; import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.jetbrains.annotations.NotNull; -public abstract class AbstractCommandCondition extends AbstractCondition implements CommandConditions.Condition { +public abstract class AbstractCommandCondition extends AbstractCondition + implements CommandConditions.Condition +{ + public AbstractCommandCondition(@NotNull SimpleClans plugin) { + super(plugin); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCondition.java index b0a5f3c0..df657e80 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractCondition.java @@ -14,11 +14,14 @@ public abstract class AbstractCondition implements IdentifiableCondition { protected final ProtectionManager protectionManager; public AbstractCondition(@NotNull SimpleClans plugin) { + this.plugin = plugin; permissionsManager = plugin.getPermissionsManager(); clanManager = plugin.getClanManager(); requestManager = plugin.getRequestManager(); settingsManager = plugin.getSettingsManager(); protectionManager = plugin.getProtectionManager(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractParameterCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractParameterCondition.java index 4466836d..0af44f3d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractParameterCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AbstractParameterCondition.java @@ -6,11 +6,16 @@ import co.aikar.commands.CommandConditions; import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.jetbrains.annotations.NotNull; -public abstract class AbstractParameterCondition extends AbstractCondition implements CommandConditions.ParameterCondition { +public abstract class AbstractParameterCondition extends AbstractCondition + implements CommandConditions.ParameterCondition +{ + public AbstractParameterCondition(@NotNull SimpleClans plugin) { + super(plugin); + } public abstract Class getType(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AlliedClanCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AlliedClanCondition.java index e04d7c29..d1f09c5e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AlliedClanCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/AlliedClanCondition.java @@ -11,28 +11,40 @@ import static org.bukkit.ChatColor.RED; @SuppressWarnings("unused") public class AlliedClanCondition extends AbstractParameterCondition { + public AlliedClanCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, - ClanInput value) throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanInput value) throws InvalidCommandArgument + { + BukkitCommandIssuer issuer = context.getIssuer(); Clan clan = Conditions.assertClanMember(clanManager, issuer); if (!clan.isAlly(value.getClan().getTag())) { + throw new ConditionFailedException(RED + lang("your.clans.are.not.allies", issuer)); + } + } @Override public @NotNull String getId() { + return "allied_clan"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChangeFeeCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChangeFeeCondition.java index 8753ddeb..99cf0f13 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChangeFeeCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChangeFeeCondition.java @@ -19,38 +19,57 @@ public class CanChangeFeeCondition extends AbstractCommandCondition { private static final float HOUR_IN_MINUTES = 60; public CanChangeFeeCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + LocalDateTime now = LocalDateTime.now(); LocalDateTime collectTime = getCollectTime(); long interval = now.until(collectTime, MINUTES); if (interval <= settingsManager.getInt(ECONOMY_MEMBER_FEE_LAST_MINUTE_CHANGE_INTERVAL) * HOUR_IN_MINUTES) { + BukkitCommandIssuer issuer = context.getIssuer(); String error = lang("cannot.change.member.fee.now", issuer); if (interval <= 60) { + error += lang("cannot.change.member.fee.minutes", issuer, interval); + } else { + error += lang("cannot.change.member.fee.hours", issuer, Math.ceil(interval / HOUR_IN_MINUTES)); + } + throw new ConditionFailedException(error); + } + } private LocalDateTime getCollectTime() { + LocalDateTime now = LocalDateTime.now(); LocalDateTime collectTime = now.withHour(settingsManager.getInt(TASKS_COLLECT_FEE_HOUR)) .withMinute(settingsManager.getInt(TASKS_COLLECT_FEE_MINUTE)); if (collectTime.isBefore(now)) { + collectTime = collectTime.plusDays(1); + } + return collectTime; + } @Override public @NotNull String getId() { + return "change_fee"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChatCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChatCondition.java index 9b2a121d..acd365a0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChatCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanChatCondition.java @@ -11,21 +11,31 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField; public class CanChatCondition extends AbstractCommandCondition { + public CanChatCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + String type = context.getConfigValue("type", (String) null).toUpperCase(); ConfigField chatEnabled = ConfigField.valueOf(type + "CHAT_ENABLE"); if (!settingsManager.is(chatEnabled)) { + throw new ConditionFailedException(lang(type.toLowerCase() + ".chat.disabled", context.getIssuer())); + } + } @Override public @NotNull String getId() { + return "can_chat"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanVoteCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanVoteCondition.java index 0857322a..ea7da200 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanVoteCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanVoteCondition.java @@ -17,33 +17,54 @@ import static org.bukkit.ChatColor.RED; public class CanVoteCondition extends AbstractCommandCondition { public CanVoteCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Player player = Conditions.assertPlayer(context.getIssuer()); ClanPlayer cp = clanManager.getCreateClanPlayer(player.getUniqueId()); Clan clan = cp.getClan(); if (clan != null) { + if (!requestManager.hasRequest(clan.getTag())) { + throw new ConditionFailedException(lang("nothing.to.vote", player)); + } + if (!clan.isLeader(player)) { + throw new ConditionFailedException(RED + lang("no.leader.permissions", player)); + } + if (cp.getVote() != null) { + throw new ConditionFailedException(RED + lang("you.have.already.voted", player)); + } + } else { + if (!requestManager.hasRequest(player.getName().toLowerCase())) { + throw new ConditionFailedException(lang("nothing.to.vote", player)); + } + } + } @Override public @NotNull String getId() { + return "can_vote"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanWarTargetCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanWarTargetCondition.java index 57ff4518..68eaa8e3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanWarTargetCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/CanWarTargetCondition.java @@ -11,41 +11,59 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.WAR_START_REQUEST_ENABLED; public class CanWarTargetCondition extends AbstractParameterCondition { + public CanWarTargetCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanInput.class; + } @Override - public void validateCondition(ConditionContext context, BukkitCommandExecutionContext execContext, ClanInput target) throws InvalidCommandArgument { + public void validateCondition(ConditionContext context, + BukkitCommandExecutionContext execContext, ClanInput target) throws InvalidCommandArgument + { + BukkitCommandIssuer issuer = execContext.getIssuer(); Clan issuerClan = Conditions.assertClanMember(clanManager, issuer); Clan targetClan = target.getClan(); if (!issuerClan.isRival(targetClan.getTag())) { + throw new ConditionFailedException(lang("you.can.only.start.war.with.rivals", issuer)); + } if (issuerClan.isWarring(targetClan)) { + throw new ConditionFailedException(lang("clans.already.at.war", issuer)); + } boolean isWarRequestEnabled = settingsManager.is(WAR_START_REQUEST_ENABLED); int maxDifference = settingsManager.getInt(WAR_MAX_MEMBERS_DIFFERENCE); if (!isWarRequestEnabled && maxDifference >= 0) { + int difference = Math.abs(issuerClan.getOnlineMembers().size() - targetClan.getOnlineMembers().size()); if (difference > maxDifference) throw new ConditionFailedException(lang("you.cant.start.war.online.members.difference", issuer)); + } + } @Override public @NotNull String getId() { + return "can_war_target"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/ClanMemberCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/ClanMemberCondition.java index dbd91d71..d8c79041 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/ClanMemberCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/ClanMemberCondition.java @@ -10,24 +10,34 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class ClanMemberCondition extends AbstractParameterCondition { + public ClanMemberCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanPlayer.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, ClanPlayer value) - throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanPlayer value) throws InvalidCommandArgument + { + Conditions.assertClanMember(clanManager, context.getIssuer()); + } @Override public @NotNull String getId() { + return "clan_member"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/Conditions.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/Conditions.java index 51b8ca39..b8d3f0a6 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/Conditions.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/Conditions.java @@ -11,27 +11,38 @@ import org.jetbrains.annotations.NotNull; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class Conditions { + private Conditions() { + } @NotNull - public static Clan assertClanMember(@NotNull ClanManager clanManager, - @NotNull BukkitCommandIssuer issuer) { + public static Clan assertClanMember(@NotNull ClanManager clanManager, @NotNull BukkitCommandIssuer issuer) { + Conditions.assertPlayer(issuer); Clan clan = clanManager.getClanByPlayerUniqueId(issuer.getUniqueId()); if (clan == null) { + throw new ConditionFailedException(lang("not.a.member.of.any.clan", issuer)); + } + return clan; + } @NotNull public static Player assertPlayer(@NotNull BukkitCommandIssuer issuer) { + Player player = issuer.getPlayer(); if (player == null) { + throw new ConditionFailedException(MessageKeys.NOT_ALLOWED_ON_CONSOLE); + } + return player; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/DifferentClanCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/DifferentClanCondition.java index 97fdf4eb..3cd34a76 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/DifferentClanCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/DifferentClanCondition.java @@ -13,31 +13,46 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class DifferentClanCondition extends AbstractParameterCondition { public DifferentClanCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, - ClanInput value) throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanInput value) throws InvalidCommandArgument + { + if (execContext.getIssuer().isPlayer()) { + Player player = execContext.getPlayer(); ClanPlayer cp = clanManager.getAnyClanPlayer(player.getUniqueId()); if (cp != null && cp.getClan() != null) { + if (value.getClan().equals(cp.getClan())) { + throw new ConditionFailedException(lang("cannot.be.same.clan", player)); + } + } + } + } @Override public @NotNull String getId() { + return "different"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/EconomyEnabledCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/EconomyEnabledCondition.java index f0937a57..473309f5 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/EconomyEnabledCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/EconomyEnabledCondition.java @@ -13,19 +13,27 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class EconomyEnabledCondition extends AbstractCommandCondition { public EconomyEnabledCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + if (!permissionsManager.hasEconomy()) { + throw new ConditionFailedException(lang("economy.disabled", context.getIssuer())); + } } @Override public @NotNull String getId() { + return "economy"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/IdentifiableCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/IdentifiableCondition.java index 3107c457..7ab39709 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/IdentifiableCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/IdentifiableCondition.java @@ -3,6 +3,8 @@ package net.sacredlabyrinth.phaed.simpleclans.commands.conditions; import org.jetbrains.annotations.NotNull; public interface IdentifiableCondition { + @NotNull String getId(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputClanMemberCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputClanMemberCondition.java index b38085db..fade2589 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputClanMemberCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputClanMemberCondition.java @@ -9,27 +9,38 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static org.bukkit.ChatColor.RED; public class InputClanMemberCondition extends AbstractParameterCondition { + public InputClanMemberCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanPlayerInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, ClanPlayerInput value) - throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanPlayerInput value) throws InvalidCommandArgument + { + if (value.getClanPlayer().getClan() == null) { - throw new ConditionFailedException(RED + lang("player.not.a.member.of.any.clan", - execContext.getSender())); + + throw new ConditionFailedException(RED + lang("player.not.a.member.of.any.clan", execContext.getSender())); + } + } @Override public @NotNull String getId() { + return "clan_member"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputVerifiedCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputVerifiedCondition.java index 4364b978..d53c2854 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputVerifiedCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/InputVerifiedCondition.java @@ -11,26 +11,36 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class InputVerifiedCondition extends AbstractParameterCondition { public InputVerifiedCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, - ClanInput value) - throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanInput value) throws InvalidCommandArgument + { + if (!value.getClan().isVerified() && !context.getIssuer().hasPermission("simpleclans.mod.bypass")) { + throw new ConditionFailedException(lang("other.clan.not.verified", execContext.getSender())); + } + } @Override public @NotNull String getId() { + return "verified"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LandSharingCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LandSharingCondition.java index 34a41f87..cf808a32 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LandSharingCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LandSharingCondition.java @@ -14,18 +14,27 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class LandSharingCondition extends AbstractCommandCondition { public LandSharingCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + if (!settingsManager.is(LAND_SHARING)) { + throw new ConditionFailedException(lang("land.sharing.disabled", context.getIssuer())); + } + } @Override public @NotNull String getId() { + return "land_sharing"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LeaderCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LeaderCondition.java index 599eb0b3..0ef6d29e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LeaderCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/LeaderCondition.java @@ -14,21 +14,31 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; @SuppressWarnings("unused") public class LeaderCondition extends AbstractCommandCondition { + public LeaderCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Player player = Conditions.assertPlayer(context.getIssuer()); Clan clan = Conditions.assertClanMember(clanManager, context.getIssuer()); if (!clan.isLeader(player)) { + throw new ConditionFailedException(ChatColor.RED + lang("no.leader.permissions", player)); + } + } @Override public @NotNull String getId() { + return "leader"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MemberFeeEnabledCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MemberFeeEnabledCondition.java index 01b6814f..6e537158 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MemberFeeEnabledCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MemberFeeEnabledCondition.java @@ -12,20 +12,30 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.ECONOMY_MEMBER_FEE_ENABLED; public class MemberFeeEnabledCondition extends AbstractCommandCondition { + public MemberFeeEnabledCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + if (!settingsManager.is(ECONOMY_MEMBER_FEE_ENABLED)) { - throw new ConditionFailedException(ChatColor.RED + lang("disabled.command", - context.getIssuer().getIssuer())); + + throw new ConditionFailedException( + ChatColor.RED + lang("disabled.command", context.getIssuer().getIssuer())); + } + } @Override public @NotNull String getId() { + return "member_fee_enabled"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToAllyCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToAllyCondition.java index b873ca55..0f462b56 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToAllyCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToAllyCondition.java @@ -14,21 +14,31 @@ import static org.bukkit.ChatColor.RED; @SuppressWarnings("unused") public class MinimumToAllyCondition extends AbstractCommandCondition { + public MinimumToAllyCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Clan clan = Conditions.assertClanMember(clanManager, context.getIssuer()); if (clan.getSize() < settingsManager.getInt(CLAN_MIN_SIZE_TO_SET_ALLY)) { - throw new ConditionFailedException(RED + - lang("minimum.to.make.alliance", context.getIssuer(), settingsManager.getInt(CLAN_MIN_SIZE_TO_SET_ALLY))); + + throw new ConditionFailedException(RED + lang("minimum.to.make.alliance", context.getIssuer(), + settingsManager.getInt(CLAN_MIN_SIZE_TO_SET_ALLY))); + } + } @Override public @NotNull String getId() { + return "minimum_to_ally"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToRivalCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToRivalCondition.java index 831a92d8..f2ac7dd0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToRivalCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/MinimumToRivalCondition.java @@ -14,22 +14,32 @@ import static org.bukkit.ChatColor.RED; @SuppressWarnings("unused") public class MinimumToRivalCondition extends AbstractCommandCondition { + public MinimumToRivalCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + BukkitCommandIssuer issuer = context.getIssuer(); Clan clan = Conditions.assertClanMember(clanManager, issuer); if (clan.getSize() < settingsManager.getInt(CLAN_MIN_SIZE_TO_SET_RIVAL)) { - throw new ConditionFailedException(RED + lang("min.players.rivalries", issuer, - settingsManager.getInt(CLAN_MIN_SIZE_TO_SET_RIVAL))); + + throw new ConditionFailedException( + RED + lang("min.players.rivalries", issuer, settingsManager.getInt(CLAN_MIN_SIZE_TO_SET_RIVAL))); + } + } @Override public @NotNull String getId() { + return "minimum_to_rival"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedCondition.java index d1d717d7..ba88cbc3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedCondition.java @@ -12,23 +12,36 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; @SuppressWarnings("unused") public class NotBannedCondition extends AbstractCommandCondition { + public NotBannedCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + if (!context.getIssuer().isPlayer()) { + return; + } + Player player = context.getIssuer().getPlayer(); if (settingsManager.isBanned(context.getIssuer().getUniqueId())) { + throw new ConditionFailedException(lang("banned", player)); + } + } @Override public @NotNull String getId() { + return "not_banned"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedInputCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedInputCondition.java index 842a61a2..016220d2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedInputCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBannedInputCondition.java @@ -14,27 +14,38 @@ import static org.bukkit.ChatColor.RED; public class NotBannedInputCondition extends AbstractParameterCondition { public NotBannedInputCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanPlayerInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, ClanPlayerInput value) - throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanPlayerInput value) throws InvalidCommandArgument + { + UUID uniqueId = value.getClanPlayer().getUniqueId(); if (settingsManager.isBanned(uniqueId)) { - throw new ConditionFailedException(RED + lang("this.player.is.banned.from.using.clan.commands", - execContext.getSender())); + + throw new ConditionFailedException( + RED + lang("this.player.is.banned.from.using.clan.commands", execContext.getSender())); + } + } @Override public @NotNull String getId() { + return "not_banned"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBlacklistedCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBlacklistedCondition.java index 8d69b8c4..e76fb62c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBlacklistedCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotBlacklistedCondition.java @@ -15,24 +15,37 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class NotBlacklistedCondition extends AbstractCommandCondition { public NotBlacklistedCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Player player = context.getIssuer().getPlayer(); if (player != null) { + World world = player.getLocation().getWorld(); if (world != null) { + if (settingsManager.getStringList(BLACKLISTED_WORLDS).contains(world.getName())) { + throw new ConditionFailedException(); + } + } + } + } @Override public @NotNull String getId() { + return "not_blacklisted"; + } + } \ No newline at end of file diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotInClanCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotInClanCondition.java index 5676959b..4bf85475 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotInClanCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/NotInClanCondition.java @@ -14,28 +14,39 @@ import static org.bukkit.ChatColor.RED; public class NotInClanCondition extends AbstractParameterCondition { public NotInClanCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanPlayerInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, ClanPlayerInput value) - throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanPlayerInput value) throws InvalidCommandArgument + { + ClanPlayer clanPlayer = value.getClanPlayer(); debug(String.format("NotInClanCondition -> %s %s", clanPlayer.getName(), clanPlayer.getUniqueId())); if (clanPlayer.getClan() != null) { - throw new ConditionFailedException(RED + lang("the.player.is.already.member.of.another.clan", - execContext.getSender())); + + throw new ConditionFailedException( + RED + lang("the.player.is.already.member.of.another.clan", execContext.getSender())); + } + } @Override public @NotNull String getId() { + return "not_in_clan"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OnlineCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OnlineCondition.java index 691d4d37..e7564278 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OnlineCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OnlineCondition.java @@ -15,33 +15,48 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class OnlineCondition extends AbstractParameterCondition { public OnlineCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanPlayerInput.class; + } @Override - public void validateCondition(ConditionContext context, BukkitCommandExecutionContext execContext, ClanPlayerInput value) throws InvalidCommandArgument { + public void validateCondition(ConditionContext context, + BukkitCommandExecutionContext execContext, ClanPlayerInput value) throws InvalidCommandArgument + { + ClanPlayer clanPlayer = value.getClanPlayer(); debug(String.format("OnlineCondition -> %s %s", clanPlayer.getName(), clanPlayer.getUniqueId())); Player player = clanPlayer.toPlayer(); if (player != null) { + boolean isVanished = VanishUtils.isVanished(execContext.getSender(), player); if (!isVanished || !context.hasConfig("ignore_vanished")) { + return; + } + } throw new ConditionFailedException(lang("other.player.must.be.online", execContext.getSender())); + } @Override @NotNull public String getId() { + return "online"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OwnLandCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OwnLandCondition.java index cd5614d1..52fcbd9a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OwnLandCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/OwnLandCondition.java @@ -12,20 +12,30 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; @SuppressWarnings("unused") public class OwnLandCondition extends AbstractCommandCondition { + public OwnLandCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Player player = Conditions.assertPlayer(context.getIssuer()); if (protectionManager.getLands(player, player.getLocation()).isEmpty()) { + throw new ConditionFailedException(lang("you.do.not.own.lands", player)); + } + } @Override public @NotNull String getId() { + return "own_land"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/PlayerClanMemberCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/PlayerClanMemberCondition.java index a2b82734..9b5acb9f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/PlayerClanMemberCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/PlayerClanMemberCondition.java @@ -12,25 +12,35 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.debug; @SuppressWarnings("unused") public class PlayerClanMemberCondition extends AbstractParameterCondition { + public PlayerClanMemberCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return Player.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, - Player value) throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, Player value) throws InvalidCommandArgument + { + debug(String.format("PlayerClanMemberCondition -> %s %s", value.getName(), value.getUniqueId())); Conditions.assertClanMember(clanManager, context.getIssuer()); + } @Override public @NotNull String getId() { + return "clan_member"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RankPermissionCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RankPermissionCondition.java index 4f1067bf..1c19fba1 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RankPermissionCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RankPermissionCondition.java @@ -13,25 +13,37 @@ import org.jetbrains.annotations.NotNull; public class RankPermissionCondition extends AbstractCommandCondition { public RankPermissionCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + String name = context.getConfigValue("name", (String) null); Player player = context.getIssuer().getPlayer(); if (player == null || name == null) { + return; + } + RankPermission rankPermission = net.sacredlabyrinth.phaed.simpleclans.RankPermission.valueOf(name); if (!permissionsManager.has(player, rankPermission, true)) { + throw new ConditionFailedException(); + } + } @Override public @NotNull String getId() { + return "rank"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RivableCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RivableCondition.java index fc6432e8..0638e4a5 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RivableCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/RivableCondition.java @@ -12,21 +12,31 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static org.bukkit.ChatColor.RED; @SuppressWarnings("unused") -public class RivableCondition extends AbstractCommandCondition{ +public class RivableCondition extends AbstractCommandCondition { + public RivableCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Clan clan = Conditions.assertClanMember(clanManager, context.getIssuer()); if (clan.isUnrivable()) { + throw new ConditionFailedException(RED + lang("your.clan.cannot.create.rivals", context.getIssuer())); + } + } @Override public @NotNull String getId() { + return "rivable"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SameClanCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SameClanCondition.java index a00aa7aa..aa8fcf23 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SameClanCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SameClanCondition.java @@ -10,29 +10,40 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; @SuppressWarnings("unused") public class SameClanCondition extends AbstractParameterCondition { + public SameClanCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanPlayerInput.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, - ClanPlayerInput value) throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, ClanPlayerInput value) throws InvalidCommandArgument + { + BukkitCommandIssuer issuer = context.getIssuer(); Clan clan = Conditions.assertClanMember(clanManager, issuer); - if (value == null || value.getClanPlayer().getClan() == null || - !value.getClanPlayer().getClan().equals(clan)) { + if (value == null || value.getClanPlayer().getClan() == null || !value.getClanPlayer().getClan().equals(clan)) { + throw new ConditionFailedException(lang("the.player.is.not.a.member.of.your.clan", issuer)); + } + } @Override public @NotNull String getId() { + return "same_clan"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SenderClanMemberCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SenderClanMemberCondition.java index 18edb191..95fcf034 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SenderClanMemberCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/SenderClanMemberCondition.java @@ -10,16 +10,23 @@ import org.jetbrains.annotations.NotNull; public class SenderClanMemberCondition extends AbstractCommandCondition { public SenderClanMemberCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Conditions.assertClanMember(clanManager, context.getIssuer()); + } @Override public @NotNull String getId() { + return "clan_member"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportCondition.java index 25126a46..ad8524cd 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportCondition.java @@ -12,31 +12,45 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class TeleportCondition extends AbstractParameterCondition { public TeleportCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return Clan.class; + } @Override public void validateCondition(ConditionContext context, - BukkitCommandExecutionContext execContext, - Clan value) throws InvalidCommandArgument { + BukkitCommandExecutionContext execContext, Clan value) throws InvalidCommandArgument + { + Player player = execContext.getPlayer(); if (value.getHomeLocation() == null) { + throw new ConditionFailedException(lang("hombase.not.set", player)); + } + Flags flags = new Flags(value.getFlags()); String homeServer = flags.getString("homeServer", ""); if (!homeServer.isEmpty() && !plugin.getProxyManager().getServerName().equals(homeServer)) { + throw new ConditionFailedException(lang("home.set.in.different.server")); + } + } @Override public @NotNull String getId() { + return "can_teleport"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportInputCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportInputCondition.java index 5e269fbf..90c4c6db 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportInputCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/TeleportInputCondition.java @@ -11,21 +11,32 @@ import org.jetbrains.annotations.NotNull; public class TeleportInputCondition extends AbstractParameterCondition { public TeleportInputCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return ClanInput.class; + } @Override - public void validateCondition(ConditionContext context, BukkitCommandExecutionContext execContext, ClanInput value) throws InvalidCommandArgument { + public void validateCondition(ConditionContext context, + BukkitCommandExecutionContext execContext, ClanInput value) throws InvalidCommandArgument + { + new TeleportCondition(plugin).validateCondition(context, execContext, value.getClan()); + } @Override public @NotNull String getId() { + return "can_teleport"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/VerifiedCondition.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/VerifiedCondition.java index 980bc7c0..09e2a1cf 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/VerifiedCondition.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/conditions/VerifiedCondition.java @@ -14,20 +14,28 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class VerifiedCondition extends AbstractCommandCondition { public VerifiedCondition(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public void validateCondition(ConditionContext context) throws InvalidCommandArgument { + Clan clan = Conditions.assertClanMember(clanManager, context.getIssuer()); if (!clan.isVerified()) { - throw new ConditionFailedException(lang("clan.is.not.verified", - context.getIssuer())); + + throw new ConditionFailedException(lang("clan.is.not.verified", context.getIssuer())); + } + } @Override public @NotNull String getId() { + return "verified"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractContextResolver.java index 41e44bf2..a0ca37e7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractContextResolver.java @@ -10,9 +10,12 @@ public abstract class AbstractContextResolver { protected final @NotNull ClanManager clanManager; public AbstractContextResolver(@NotNull SimpleClans plugin) { + this.plugin = plugin; clanManager = plugin.getClanManager(); + } public abstract Class getType(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractInputOnlyContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractInputOnlyContextResolver.java index 913a579c..a8a95b7c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractInputOnlyContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractInputOnlyContextResolver.java @@ -6,8 +6,13 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.jetbrains.annotations.NotNull; public abstract class AbstractInputOnlyContextResolver extends AbstractContextResolver - implements ContextResolver { + implements ContextResolver +{ + public AbstractInputOnlyContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractIssuerOnlyContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractIssuerOnlyContextResolver.java index d4380657..43206518 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractIssuerOnlyContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/AbstractIssuerOnlyContextResolver.java @@ -6,8 +6,13 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import org.jetbrains.annotations.NotNull; public abstract class AbstractIssuerOnlyContextResolver extends AbstractContextResolver - implements IssuerOnlyContextResolver { + implements IssuerOnlyContextResolver +{ + public AbstractIssuerOnlyContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanContextResolver.java index 6508f63d..fc960d94 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanContextResolver.java @@ -8,17 +8,25 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class ClanContextResolver extends AbstractIssuerOnlyContextResolver { + public ClanContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Clan getContext(BukkitCommandExecutionContext c) throws InvalidCommandArgument { + return Contexts.assertClanMember(clanManager, c.getIssuer()); + } @Override public Class getType() { + return Clan.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanInputContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanInputContextResolver.java index ebbfdef6..88a71505 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanInputContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanInputContextResolver.java @@ -12,23 +12,33 @@ import static org.bukkit.ChatColor.RED; @SuppressWarnings("unused") public class ClanInputContextResolver extends AbstractInputOnlyContextResolver { + public ClanInputContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public ClanInput getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument { + String arg = context.popFirstArg(); Clan clan = clanManager.getClan(arg); if (clan == null) { - throw new InvalidCommandArgument(RED + lang("the.clan.does.not.exist", context.getSender()), - false); + + throw new InvalidCommandArgument(RED + lang("the.clan.does.not.exist", context.getSender()), false); + } + return new ClanInput(clan); + } @Override public Class getType() { + return ClanInput.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerContextResolver.java index 6c772503..2ab6479f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerContextResolver.java @@ -9,18 +9,26 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class ClanPlayerContextResolver extends AbstractIssuerOnlyContextResolver { + public ClanPlayerContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public ClanPlayer getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument { + Player player = Contexts.assertPlayer(context.getIssuer()); return clanManager.getCreateClanPlayer(player.getUniqueId()); + } @Override public Class getType() { + return ClanPlayer.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerInputContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerInputContextResolver.java index 63a850d0..c62684ae 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerInputContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/ClanPlayerInputContextResolver.java @@ -21,32 +21,45 @@ public class ClanPlayerInputContextResolver extends AbstractInputOnlyContextReso private final Pattern validUsername; public ClanPlayerInputContextResolver(@NotNull SimpleClans plugin) { + super(plugin); validUsername = Pattern.compile(plugin.getSettingsManager().getString(USERNAME_REGEX)); + } @Override public ClanPlayerInput getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument { + String arg = context.popFirstArg(); if (!validUsername.matcher(arg).matches()) { + throw new InvalidCommandArgument(MinecraftMessageKeys.IS_NOT_A_VALID_NAME, "{name}", arg); + } ClanPlayer cp = clanManager.getAnyClanPlayer(arg); if (cp == null) { + Player player = Bukkit.getPlayer(arg); if (player == null) { + throw new InvalidCommandArgument(lang("user.hasnt.played.before", context.getSender())); + } + cp = clanManager.getCreateClanPlayer(player.getUniqueId()); + } return new ClanPlayerInput(cp); + } @Override public Class getType() { + return ClanPlayerInput.class; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/Contexts.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/Contexts.java index 2462c39c..1fa72848 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/Contexts.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/Contexts.java @@ -13,34 +13,52 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class Contexts { private Contexts() { + } @NotNull - public static Clan assertClanMember(@NotNull ClanManager clanManager, - @NotNull BukkitCommandIssuer issuer) { + public static Clan assertClanMember(@NotNull ClanManager clanManager, @NotNull BukkitCommandIssuer issuer) { + assertPlayer(issuer); Clan clan = clanManager.getClanByPlayerUniqueId(issuer.getUniqueId()); if (clan == null) { + throw new InvalidCommandArgument(lang("not.a.member.of.any.clan", issuer), false); + } + return clan; + } @NotNull public static Player assertPlayer(@NotNull BukkitCommandIssuer issuer) { + Player player = issuer.getPlayer(); if (player == null) { + throw new InvalidCommandArgument(NOT_ALLOWED_ON_CONSOLE, false); + } + return player; + } public static void validateMinMax(Number val, Number minValue, Number maxValue) throws InvalidCommandArgument { + if (maxValue != null && val.doubleValue() > maxValue.doubleValue()) { + throw new InvalidCommandArgument(PLEASE_SPECIFY_AT_MOST, "{max}", String.valueOf(maxValue)); + } + if (minValue != null && val.doubleValue() < minValue.doubleValue()) { + throw new InvalidCommandArgument(PLEASE_SPECIFY_AT_LEAST, "{min}", String.valueOf(minValue)); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoubleContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoubleContextResolver.java index 9a7cef8f..5673c93e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoubleContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoubleContextResolver.java @@ -5,12 +5,18 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class DoubleContextResolver extends DoublePrimitiveContextResolver { + public DoubleContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return Double.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoublePrimitiveContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoublePrimitiveContextResolver.java index 2446f2ab..c4ae4cf0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoublePrimitiveContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/DoublePrimitiveContextResolver.java @@ -12,28 +12,40 @@ import static net.sacredlabyrinth.phaed.simpleclans.commands.contexts.Contexts.v public class DoublePrimitiveContextResolver extends AbstractInputOnlyContextResolver { public DoublePrimitiveContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Double getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument { + String number = context.popFirstArg(); try { + double val = Double.parseDouble(number); if (!Double.isFinite(val)) { + throw new NumberFormatException(); + } + validateMinMax(val, Double.MIN_VALUE, Double.MAX_VALUE); return val; + } catch (NumberFormatException e) { + throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", number); + } + } @Override public Class getType() { + return double.class; + } - } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatContextResolver.java index 5f2666e2..926fec82 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatContextResolver.java @@ -5,12 +5,18 @@ import org.jetbrains.annotations.NotNull; @SuppressWarnings("unused") public class FloatContextResolver extends FloatPrimitiveContextResolver { + public FloatContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Class getType() { + return Float.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatPrimitiveContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatPrimitiveContextResolver.java index f791c1fe..a2346674 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatPrimitiveContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/FloatPrimitiveContextResolver.java @@ -10,27 +10,42 @@ import static net.sacredlabyrinth.phaed.simpleclans.commands.contexts.Contexts.v @SuppressWarnings("unused") public class FloatPrimitiveContextResolver extends AbstractInputOnlyContextResolver { + public FloatPrimitiveContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Float getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument { + String number = context.popFirstArg(); try { + float val = Float.parseFloat(number); if (!Float.isFinite(val)) { + throw new NumberFormatException(); + } + validateMinMax(val, Float.MIN_VALUE, Float.MAX_VALUE); return val; + } catch (NumberFormatException e) { + throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", number); + } + } @Override public Class getType() { + return float.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/RankContextResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/RankContextResolver.java index 0b0add40..53a8aabc 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/RankContextResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/contexts/RankContextResolver.java @@ -12,24 +12,34 @@ import static org.bukkit.ChatColor.RED; @SuppressWarnings("unused") public class RankContextResolver extends AbstractInputOnlyContextResolver { + public RankContextResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public Rank getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument { + Clan clan = Contexts.assertClanMember(clanManager, context.getIssuer()); String rankName = context.isLastArg() ? context.joinArgs() : context.popFirstArg(); Rank rank = clan.getRank(rankName); if (rank == null) { - throw new InvalidCommandArgument(RED + lang("rank.0.does.not.exist", context.getIssuer(), rankName), - false); + + throw new InvalidCommandArgument(RED + lang("rank.0.does.not.exist", context.getIssuer(), rankName), false); + } + return rank; + } @Override public Class getType() { + return Rank.class; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Alliances.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Alliances.java index 31e79e26..73368d3f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Alliances.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Alliances.java @@ -18,34 +18,44 @@ import static org.bukkit.ChatColor.DARK_GRAY; public class Alliances extends Sendable { public Alliances(@NotNull SimpleClans plugin, @NotNull CommandSender sender) { + super(plugin, sender); + } @Override public void send() { + List clans = cm.getClans(); cm.sortClansByKDR(clans); sendHeader(); for (Clan clan : clans) { + if (!clan.isVerified()) { + continue; + } chatBlock.addRow(" " + AQUA + clan.getName(), clan.getAllyString(DARK_GRAY + ", ", sender)); + } sendBlock(); + } private void sendHeader() { + ChatBlock.sendBlank(sender); - ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + - lang("alliances", sender) + " " + headColor + - Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + lang("alliances", sender) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); chatBlock.setAlignment("l", "l"); chatBlock.addRow(" " + headColor + lang("clan", sender), lang("allies", sender)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanCoords.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanCoords.java index 60454c07..785c70e8 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanCoords.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanCoords.java @@ -22,19 +22,25 @@ public class ClanCoords extends Sendable { private final Clan clan; public ClanCoords(@NotNull SimpleClans plugin, @NotNull Player player, @NotNull Clan clan) { + super(plugin, player); this.player = player; this.clan = clan; + } private void populateRows() { + Map> rows = new TreeMap<>(); for (ClanPlayer cpm : VanishUtils.getNonVanished(player, clan)) { + Player p = cpm.toPlayer(); if (p != null) { - String name = (cpm.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) : (cpm.isTrusted() ? - sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR))) + cpm.getName(); + + String name = (cpm.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) + : (cpm.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR))) + + cpm.getName(); Location loc = p.getLocation(); int distance = (int) Math.ceil(loc.toVector().distance(player.getLocation().toVector())); String coords = loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ(); @@ -46,31 +52,43 @@ public class ClanCoords extends Sendable { cols.add(WHITE + "" + coords); cols.add(world); rows.put(distance, cols); + } + } + for (List col : rows.values()) { + chatBlock.addRow(col.get(0), col.get(1), col.get(2), col.get(3)); + } + } private void configureAndSendHeader() { + chatBlock.setFlexibility(true, false, false, false); chatBlock.setAlignment("l", "c", "c", "c"); ChatBlock.sendBlank(player); - ChatBlock.saySingle(player, sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + - lang("coords", player) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(player, + sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + lang("coords", player) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(player); chatBlock.addRow(" " + headColor + lang("name", player), lang("distance", player), lang("coords.upper", player), lang("world", player)); + } @Override public void send() { + configureAndSendHeader(); populateRows(); sendBlock(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanList.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanList.java index 4835d8d8..9d91f17c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanList.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanList.java @@ -23,76 +23,106 @@ public class ClanList extends Sendable { private final @Nullable String type; private final @Nullable String order; - public ClanList(@NotNull SimpleClans plugin, - @NotNull CommandSender sender, - @Nullable String type, - @Nullable String order) { + public ClanList(@NotNull SimpleClans plugin, @NotNull CommandSender sender, @Nullable String type, + @Nullable String order) + { + super(plugin, sender); this.type = type; this.order = order; + } @Override public void send() { + List clans = getListableClans(); if (clans.isEmpty()) { + ChatBlock.sendMessage(sender, RED + lang("no.clans.have.been.created", sender)); return; + } + RankingNumberResolver> ranking = getRankingResolver(clans, type, order); sendHeader(clans); for (Clan clan : clans) { + addLine(ranking, clan); + } sendBlock(); + } private RankingNumberResolver> getRankingResolver(List clans, - @Nullable String type, - @Nullable String order) { + @Nullable String type, @Nullable String order) + { + boolean ascending = order == null || lang("list.order.asc").equalsIgnoreCase(order); if (type == null) { + type = sm.getString(LIST_DEFAULT_ORDER_BY); + } + if (type.equalsIgnoreCase(lang("list.type.size"))) { + return new RankingNumberResolver<>(clans, Clan::getSize, order != null && ascending, ORDINAL); + } + if (type.equalsIgnoreCase(lang("list.type.active"))) { + return new RankingNumberResolver<>(clans, Clan::getLastUsed, order != null && ascending, ORDINAL); + } + if (type.equalsIgnoreCase(lang("list.type.founded"))) { + return new RankingNumberResolver<>(clans, Clan::getFounded, ascending, ORDINAL); + } + if (type.equalsIgnoreCase(lang("list.type.name"))) { + return new RankingNumberResolver<>(clans, Clan::getName, ascending, ORDINAL); + } + return new RankingNumberResolver<>(clans, clan -> KDRFormat.toBigDecimal(clan.getTotalKDR()), order != null && ascending, sm.getRankingType()); + } @NotNull private List getListableClans() { + List clans = plugin.getClanManager().getClans(); clans = clans.stream().filter(clan -> clan.isVerified() || sm.is(SHOW_UNVERIFIED_ON_LIST)) .collect(Collectors.toList()); return clans; + } private void sendHeader(List clans) { + ChatBlock.sendBlank(sender); - ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + lang("clans.lower", sender) - + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + lang("clans.lower", sender) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); ChatBlock.sendMessage(sender, headColor + lang("total.clans", sender) + " " + subColor + clans.size()); ChatBlock.sendBlank(sender); chatBlock.setAlignment("c", "l", "c", "c"); chatBlock.setFlexibility(false, true, false, false); - chatBlock.addRow(" " + headColor + lang("rank", sender), lang("name", sender), - lang("kdr", sender), lang("members", sender)); + chatBlock.addRow(" " + headColor + lang("rank", sender), lang("name", sender), lang("kdr", sender), + lang("members", sender)); + } private void addLine(RankingNumberResolver> ranking, Clan clan) { + String tag = sm.getColored(CLANCHAT_BRACKET_COLOR) + sm.getString(CLANCHAT_BRACKET_LEFT) + sm.getColored(TAG_DEFAULT_COLOR) + clan.getColorTag() + sm.getColored(CLANCHAT_BRACKET_COLOR) + sm.getString(CLANCHAT_BRACKET_RIGHT); @@ -102,5 +132,7 @@ public class ClanList extends Sendable { String kdr = clan.isVerified() ? YELLOW + "" + KDRFormat.format(clan.getTotalKDR()) : ""; chatBlock.addRow(" " + ranking.getRankingNumber(clan), fullname, kdr, size); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanProfile.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanProfile.java index 280cf86c..cea59d47 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanProfile.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanProfile.java @@ -16,15 +16,17 @@ public class ClanProfile extends Sendable { private final Clan clan; public ClanProfile(@NotNull SimpleClans plugin, @NotNull CommandSender sender, @NotNull Clan clan) { + super(plugin, sender); this.clan = clan; + } @Override public void send() { + String message = lang("clan.profile").replace("%clan_name%", clan.getName()) - .replace("%clan_color_tag%", clan.getColorTag()) - .replace("%clan_description%", getDescription()) + .replace("%clan_color_tag%", clan.getColorTag()).replace("%clan_description%", getDescription()) .replace("%clan_status%", Helper.getFormattedClanStatus(clan, sender)) .replace("%clan_leaders%", clan.getLeadersString(sm.getColored(PAGE_LEADER_COLOR), subColor + ", ")) .replace("%clan_online_count%", String.valueOf(VanishUtils.getNonVanished(sender, clan).size())) @@ -43,16 +45,22 @@ public class ClanProfile extends Sendable { .replace("%clan_inactive_days%", String.valueOf(clan.getInactiveDays())) .replace("%clan_max_inactive_days%", Helper.formatMaxInactiveDays(clan.getMaxInactiveDays())); sender.sendMessage(message); + } @NotNull private String getFeeEnabled() { + return clan.isMemberFeeEnabled() ? lang("fee.enabled", sender) : lang("fee.disabled", sender); + } @NotNull private String getDescription() { - return clan.getDescription() != null && !clan.getDescription().isEmpty() ? clan.getDescription() : - lang("no.description", sender); + + return clan.getDescription() != null && !clan.getDescription().isEmpty() ? clan.getDescription() + : lang("no.description", sender); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanRoster.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanRoster.java index b42a2c86..e83b6505 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanRoster.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanRoster.java @@ -17,55 +17,72 @@ public class ClanRoster extends Sendable { private final Clan clan; public ClanRoster(@NotNull SimpleClans plugin, @NotNull CommandSender sender, @NotNull Clan clan) { + super(plugin, sender); this.clan = clan; + } @Override public void send() { + configureAndSendHeader(); addLeaders(); addMembers(); sendBlock(); + } private void addMembers() { + List members = clan.getNonLeaders(); plugin.getClanManager().sortClanPlayersByLastSeen(members); for (ClanPlayer cp : members) { - String name = (cp.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR)) + cp.getName(); - String lastSeen = VanishUtils.isVanished(sender, cp) ? WHITE + cp.getLastSeenDaysString(sender) : GREEN + lang("online", sender); + + String name = (cp.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR)) + + cp.getName(); + String lastSeen = VanishUtils.isVanished(sender, cp) ? WHITE + cp.getLastSeenDaysString(sender) + : GREEN + lang("online", sender); chatBlock.addRow(" " + name, YELLOW + ChatUtils.parseColors(cp.getRankDisplayName()) + RESET, lastSeen); + } + } private void addLeaders() { + List leaders = clan.getLeaders(); plugin.getClanManager().sortClanPlayersByLastSeen(leaders); for (ClanPlayer cp : leaders) { + String name = sm.getColored(PAGE_LEADER_COLOR) + cp.getName(); - String lastSeen = VanishUtils.isVanished(sender, cp) ? WHITE + cp.getLastSeenDaysString(sender) : - GREEN + lang("online", sender); + String lastSeen = VanishUtils.isVanished(sender, cp) ? WHITE + cp.getLastSeenDaysString(sender) + : GREEN + lang("online", sender); chatBlock.addRow(" " + name, YELLOW + ChatUtils.parseColors(cp.getRankDisplayName()) + RESET, lastSeen); + } + } private void configureAndSendHeader() { + ChatBlock.sendBlank(sender); - ChatBlock.saySingle(sender, sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + - lang("roster", sender) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(sender, + sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + lang("roster", sender) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); - ChatBlock.sendMessage(sender, headColor + lang("legend", sender) + " " + sm.getColored(PAGE_LEADER_COLOR) + - lang("leader", sender) + headColor + ", " + sm.getColored(PAGE_TRUSTED_COLOR) + lang("trusted", sender) + - headColor + ", " + sm.getColored(PAGE_UNTRUSTED_COLOR) + lang("untrusted", sender)); + ChatBlock.sendMessage(sender, + headColor + lang("legend", sender) + " " + sm.getColored(PAGE_LEADER_COLOR) + lang("leader", sender) + + headColor + ", " + sm.getColored(PAGE_TRUSTED_COLOR) + lang("trusted", sender) + headColor + + ", " + sm.getColored(PAGE_UNTRUSTED_COLOR) + lang("untrusted", sender)); ChatBlock.sendBlank(sender); chatBlock.setFlexibility(false, true, false, true); - chatBlock.addRow(" " + headColor + lang("player", sender), lang("rank", sender), - lang("seen", sender)); + chatBlock.addRow(" " + headColor + lang("player", sender), lang("rank", sender), lang("seen", sender)); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanStats.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanStats.java index ce5efcdf..133cf244 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanStats.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/ClanStats.java @@ -17,12 +17,15 @@ public class ClanStats extends Sendable { private final Clan clan; public ClanStats(@NotNull SimpleClans plugin, @NotNull CommandSender sender, @NotNull Clan clan) { + super(plugin, sender); this.clan = clan; + } @Override public void send() { + configureAndSendHeader(); List leaders = clan.getLeaders(); @@ -34,36 +37,47 @@ public class ClanStats extends Sendable { addRows(members); sendBlock(); + } private void configureAndSendHeader() { - ChatBlock.saySingle(sender, sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + - lang("stats", sender) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + + ChatBlock.saySingle(sender, sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + + lang("stats", sender) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); - ChatBlock.sendMessage(sender, headColor + lang("kdr", sender) + " = " + subColor + - lang("kill.death.ratio", sender)); - ChatBlock.sendMessage(sender, headColor + lang("weights", sender) + " = " + lang("rival", sender) - + ": " + subColor + sm.getDouble(KILL_WEIGHTS_RIVAL) + headColor + " " + lang("neutral", sender) + ": " + subColor + - sm.getDouble(KILL_WEIGHTS_NEUTRAL) + headColor + " " + lang("civilian", sender) + ": " + subColor + - sm.getDouble(KILL_WEIGHTS_CIVILIAN)); + ChatBlock.sendMessage(sender, + headColor + lang("kdr", sender) + " = " + subColor + lang("kill.death.ratio", sender)); + ChatBlock.sendMessage(sender, + headColor + lang("weights", sender) + " = " + lang("rival", sender) + ": " + subColor + + sm.getDouble(KILL_WEIGHTS_RIVAL) + headColor + " " + lang("neutral", sender) + ": " + subColor + + sm.getDouble(KILL_WEIGHTS_NEUTRAL) + headColor + " " + lang("civilian", sender) + ": " + + subColor + sm.getDouble(KILL_WEIGHTS_CIVILIAN)); ChatBlock.sendBlank(sender); chatBlock.setFlexibility(true, false, false, false, false, false, false); chatBlock.setAlignment("l", "c", "c", "c", "c", "c", "c"); - chatBlock.addRow(" " + headColor + lang("name", sender), lang("kdr", sender), - lang("rival", sender), lang("neutral", sender), lang("civilian.abbreviation", sender), - lang("deaths", sender)); + chatBlock.addRow(" " + headColor + lang("name", sender), lang("kdr", sender), lang("rival", sender), + lang("neutral", sender), lang("civilian.abbreviation", sender), lang("deaths", sender)); + } private void addRows(List clanPlayers) { + for (ClanPlayer cp : clanPlayers) { + String color; if (cp.isLeader()) { + color = sm.getColored(PAGE_LEADER_COLOR); + } else if (cp.isTrusted()) { + color = sm.getColored(PAGE_TRUSTED_COLOR); + } else { + color = sm.getColored(PAGE_UNTRUSTED_COLOR); + } NumberFormat formatter = NumberFormat.getInstance(cp.getLocale()); @@ -75,6 +89,9 @@ public class ClanStats extends Sendable { chatBlock.addRow(color + cp.getName(), YELLOW + kdr, WHITE + rival, GRAY + neutral, DARK_GRAY + civilian, DARK_RED + deaths); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Kills.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Kills.java index e1543b32..e42f65c3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Kills.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Kills.java @@ -20,44 +20,61 @@ public class Kills extends Sendable { private final String polled; public Kills(@NotNull SimpleClans plugin, @NotNull Player player, @NotNull String polled) { + super(plugin, player); this.player = player; this.polled = polled; + } @Override public void send() { + plugin.getStorageManager().getKillsPerPlayer(polled, data -> new BukkitRunnable() { + @Override public void run() { + if (data.isEmpty()) { + ChatBlock.sendMessage(player, ChatColor.RED + lang("nokillsfound", player)); return; + } + configureAndSendHeader(); addLines(data); sendBlock(); + } + }.runTask(plugin)); + } private void addLines(Map data) { + Map killsPerPlayer = Helper.sortByValue(data); for (Map.Entry playerKills : killsPerPlayer.entrySet()) { + int count = playerKills.getValue(); chatBlock.addRow(" " + playerKills.getKey(), ChatColor.AQUA + "" + count); + } + } private void configureAndSendHeader() { + chatBlock.setFlexibility(true, false); chatBlock.setAlignment("l", "c"); chatBlock.addRow(" " + headColor + lang("victim", player), lang("killcount", player)); - ChatBlock.saySingle(player, sm.getColored(PAGE_CLAN_NAME_COLOR) + polled + subColor - + " " + lang("kills", player) + " " + headColor + - Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(player, sm.getColored(PAGE_CLAN_NAME_COLOR) + polled + subColor + " " + + lang("kills", player) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(player); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Leaderboard.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Leaderboard.java index 80239cd4..27d58b78 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Leaderboard.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Leaderboard.java @@ -23,49 +23,62 @@ public class Leaderboard extends Sendable { private final List clanPlayers; public Leaderboard(@NotNull SimpleClans plugin, @NotNull CommandSender sender) { + super(plugin, sender); clanPlayers = cm.getAllClanPlayers(); - rankingResolver = new RankingNumberResolver<>(clanPlayers, - c -> KDRFormat.toBigDecimal(c.getKDR()), false, sm.getRankingType()); + rankingResolver = new RankingNumberResolver<>(clanPlayers, c -> KDRFormat.toBigDecimal(c.getKDR()), false, + sm.getRankingType()); + } @Override public void send() { + configureAndSendHeader(); addLines(); sendBlock(); + } private void addLines() { + for (ClanPlayer cp : clanPlayers) { + boolean online = !VanishUtils.isVanished(cp); - String name = (cp.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) : (cp.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : - sm.getColored(PAGE_UNTRUSTED_COLOR))) + cp.getName(); + String name = (cp.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) + : (cp.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR))) + + cp.getName(); String lastSeen = online ? GREEN + lang("online", sender) : WHITE + cp.getLastSeenDaysString(sender); String clanTag = WHITE + lang("free.agent", sender); if (cp.getClan() != null) { + clanTag = cp.getClan().getColorTag(); + } - chatBlock.addRow(" " + rankingResolver.getRankingNumber(cp), - name, YELLOW + "" + KDRFormat.format(cp.getKDR()), WHITE + clanTag, lastSeen); + chatBlock.addRow(" " + rankingResolver.getRankingNumber(cp), name, + YELLOW + "" + KDRFormat.format(cp.getKDR()), WHITE + clanTag, lastSeen); + } + } private void configureAndSendHeader() { + ChatBlock.sendBlank(sender); ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + lang("leaderboard.command", sender) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); - ChatBlock.sendMessage(sender, headColor + lang("total.clan.players.0", sender, subColor + - clanPlayers.size())); + ChatBlock.sendMessage(sender, headColor + lang("total.clan.players.0", sender, subColor + clanPlayers.size())); ChatBlock.sendBlank(sender); chatBlock.setAlignment("c", "l", "c", "c", "c", "c"); - chatBlock.addRow(" " + headColor + lang("rank", sender), lang("player", sender), - lang("kdr", sender), lang("clan", sender), lang("seen", sender)); + chatBlock.addRow(" " + headColor + lang("rank", sender), lang("player", sender), lang("kdr", sender), + lang("clan", sender), lang("seen", sender)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Lookup.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Lookup.java index 377f06de..3d6c8e4c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Lookup.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Lookup.java @@ -26,19 +26,22 @@ public class Lookup extends Sendable { private final Clan targetClan; public Lookup(@NotNull SimpleClans plugin, @NotNull CommandSender sender, @NotNull UUID targetUuid) { + super(plugin, sender); this.targetUuid = targetUuid; target = cm.getAnyClanPlayer(targetUuid); ClanPlayer senderCp = !isPlayer() ? null : cm.getClanPlayer(getPlayer().getUniqueId()); senderClan = senderCp == null ? null : senderCp.getClan(); targetClan = target != null ? target.getClan() : null; + } @Override public void send() { + if (target != null) { - String lookup = lang("player.lookup", sender) - .replace("%player_name%", target.getName()) + + String lookup = lang("player.lookup", sender).replace("%player_name%", target.getName()) .replace("%clan_name%", getClanName()) .replace("%player_rank%", ChatUtils.parseColors(target.getRankDisplayName())) .replace("%player_status%", getPlayerStatus()) @@ -52,81 +55,130 @@ public class Lookup extends Sendable { .replace("%player_last_seen%", target.getLastSeenString(sender)) .replace("%player_past_clans%", target.getPastClansString(headColor + ", ")) .replace("%player_inactive_days%", String.valueOf(target.getInactiveDays())) - .replace("%player_max_inactive_days%", Helper.formatMaxInactiveDays(sm.getInt(PURGE_INACTIVE_PLAYER_DAYS))) + .replace("%player_max_inactive_days%", + Helper.formatMaxInactiveDays(sm.getInt(PURGE_INACTIVE_PLAYER_DAYS))) .replace("%kill_type_line%", getKillTypeLine()); sender.sendMessage(lookup); + } else { + ChatBlock.sendMessage(sender, RED + lang("no.player.data.found", sender)); if (isOtherPlayer() && senderClan != null) { + ChatBlock.sendBlank(sender); ChatBlock.sendMessage(sender, lang("kill.type.civilian", sender, DARK_GRAY)); + } + } + } @NotNull private String getClanName() { + String clanName = lang("none", sender); if (targetClan != null) { - clanName = lang("player.lookup.clanname") - .replace("%clan_color_tag%", targetClan.getColorTag()) + + clanName = lang("player.lookup.clanname").replace("%clan_color_tag%", targetClan.getColorTag()) .replace("%clan_name%", targetClan.getName()); + } + return clanName; + } @NotNull private String getPlayerStatus() { + if (target == null || targetClan == null) { + return lang("free.agent", sender); + } + if (target.isLeader()) { + return sm.getColored(PAGE_LEADER_COLOR) + lang("leader", sender); + } + if (target.isTrusted()) { + return sm.getColored(PAGE_TRUSTED_COLOR) + lang("trusted", sender); + } + if (!target.getRankId().isEmpty()) { + return sm.getColored(PAGE_TRUSTED_COLOR) + lang("in.rank", sender); + } + return sm.getColored(PAGE_UNTRUSTED_COLOR) + lang("untrusted", sender); + } @NotNull private String getKillTypeLine() { + String killTypeLine = ""; if (isOtherPlayer()) { + String killType = GRAY + lang("neutral", sender); if (targetClan == null) { + killType = DARK_GRAY + lang("civilian", sender); + } else if (senderClan != null) { + if (senderClan.isRival(targetClan.getTag())) { + killType = WHITE + lang("rival", sender); + } + if (senderClan.equals(targetClan) || senderClan.isAlly(targetClan.getTag())) { + killType = RED + lang("ally", sender); + } + } killTypeLine = lang("player.lookup.killtype", sender).replace("%player_kill_type%", killType); + } + return killTypeLine; + } private boolean isPlayer() { + return sender instanceof Player; + } private boolean isOtherPlayer() { + if (isPlayer()) { + return !getPlayer().getUniqueId().equals(targetUuid); + } + return true; + } private Player getPlayer() { + return (Player) sender; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/MostKilled.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/MostKilled.java index fd0b02e6..a0d0b801 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/MostKilled.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/MostKilled.java @@ -19,18 +19,25 @@ public class MostKilled extends Sendable { private final Player player; public MostKilled(@NotNull SimpleClans plugin, @NotNull Player player) { + super(plugin, player); this.player = player; + } @Override public void send() { + plugin.getStorageManager().getMostKilled(data -> new BukkitRunnable() { + @Override public void run() { + if (data.isEmpty()) { + ChatBlock.sendMessage(player, RED + lang("nokillsfound", player)); return; + } sendHeader(); @@ -38,19 +45,27 @@ public class MostKilled extends Sendable { Map killsPerPlayer = Helper.sortByValue(data); for (Map.Entry attackerVictim : killsPerPlayer.entrySet()) { + addLine(attackerVictim); + } sendBlock(); + } + }.runTask(plugin)); + } private void addLine(Map.Entry attackerVictim) { + String[] split = attackerVictim.getKey().split(" "); if (split.length < 2) { + return; + } int count = attackerVictim.getValue(); @@ -58,16 +73,20 @@ public class MostKilled extends Sendable { String victim = split[1]; chatBlock.addRow(" " + WHITE + victim, AQUA + "" + count, YELLOW + attacker); + } private void sendHeader() { + chatBlock.setFlexibility(true, false, false); chatBlock.setAlignment("l", "c", "l"); - chatBlock.addRow(" " + headColor + lang("victim", player), headColor + - lang("killcount", player), headColor + lang("attacker", player)); + chatBlock.addRow(" " + headColor + lang("victim", player), headColor + lang("killcount", player), + headColor + lang("attacker", player)); - ChatBlock.saySingle(player, sm.getColored(SERVER_NAME) + subColor + " " + lang("mostkilled", - player) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(player, sm.getColored(SERVER_NAME) + subColor + " " + lang("mostkilled", player) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(player); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Rivalries.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Rivalries.java index 0f621cfb..e20c0b6f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Rivalries.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Rivalries.java @@ -17,36 +17,46 @@ import static org.bukkit.ChatColor.*; public class Rivalries extends Sendable { public Rivalries(@NotNull SimpleClans plugin, @NotNull CommandSender sender) { + super(plugin, sender); + } @Override public void send() { + List clans = cm.getClans(); cm.sortClansByKDR(clans); sendHeader(); for (Clan clan : clans) { + if (!clan.isVerified()) { + continue; + } chatBlock.addRow(" " + AQUA + clan.getName(), clan.getRivalString(DARK_GRAY + ", ", sender)); + } sendBlock(); + } private void sendHeader() { + ChatBlock.sendBlank(sender); - ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + - lang("rivalries", sender) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(sender, sm.getColored(SERVER_NAME) + subColor + " " + lang("rivalries", sender) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); - ChatBlock.sendMessage(sender, headColor + lang("legend", sender) + DARK_RED + " [" + - lang("war", sender) + "]"); + ChatBlock.sendMessage(sender, headColor + lang("legend", sender) + DARK_RED + " [" + lang("war", sender) + "]"); ChatBlock.sendBlank(sender); chatBlock.setAlignment("l", "l"); chatBlock.addRow(lang("clan", sender), lang("rivals", sender)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Sendable.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Sendable.java index e923745b..4cd770e0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Sendable.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Sendable.java @@ -20,28 +20,35 @@ public abstract class Sendable { protected final String headColor; protected final String subColor; - public Sendable(@NotNull SimpleClans plugin, @NotNull CommandSender sender) { + this.plugin = plugin; sm = plugin.getSettingsManager(); cm = plugin.getClanManager(); this.sender = sender; headColor = sm.getColored(PAGE_HEADINGS_COLOR); subColor = sm.getColored(PAGE_SUBTITLE_COLOR); + } protected void sendBlock() { + SettingsManager sm = plugin.getSettingsManager(); boolean more = chatBlock.sendBlock(sender, sm.getInt(PAGE_SIZE)); if (more) { + plugin.getStorageManager().addChatBlock(sender, chatBlock); ChatBlock.sendBlank(sender); - ChatBlock.sendMessage(sender, sm.getColored(PAGE_HEADINGS_COLOR) + lang("view.next.page", sender, - sm.getString(COMMANDS_MORE))); + ChatBlock.sendMessage(sender, + sm.getColored(PAGE_HEADINGS_COLOR) + lang("view.next.page", sender, sm.getString(COMMANDS_MORE))); + } + ChatBlock.sendBlank(sender); + } public abstract void send(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Vitals.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Vitals.java index 1d8db3a9..0ad97158 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Vitals.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/data/Vitals.java @@ -17,12 +17,15 @@ public class Vitals extends Sendable { private final Clan clan; public Vitals(@NotNull SimpleClans plugin, @NotNull CommandSender sender, @NotNull Clan clan) { + super(plugin, sender); this.clan = clan; + } @Override public void send() { + configureAndSendHeader(); List members = Helper.stripOffLinePlayers(clan.getLeaders()); @@ -35,37 +38,44 @@ public class Vitals extends Sendable { addRows(clan.getAllAllyMembers()); sendBlock(); + } private void configureAndSendHeader() { + ChatBlock.sendBlank(sender); - ChatBlock.saySingle(sender, sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + - lang("vitals", sender) + " " + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); + ChatBlock.saySingle(sender, + sm.getColored(PAGE_CLAN_NAME_COLOR) + clan.getName() + subColor + " " + lang("vitals", sender) + " " + + headColor + Helper.generatePageSeparator(sm.getString(PAGE_SEPARATOR))); ChatBlock.sendBlank(sender); - ChatBlock.sendMessage(sender, headColor + lang("weapons", sender) + ": " + - lang("0.s.sword.1.2.b.bow.3.4.a.arrow", sender, WHITE, DARK_GRAY, WHITE, DARK_GRAY, WHITE)); - ChatBlock.sendMessage(sender, headColor + lang("materials", sender) + ": " + AQUA + - lang("diamond", sender) + DARK_GRAY + ", " + YELLOW + lang("gold", sender) + DARK_GRAY + ", " - + GRAY + lang("stone", sender) + DARK_GRAY + ", " + WHITE + lang("iron", sender) + DARK_GRAY + - ", " + GOLD + lang("wood", sender)); + ChatBlock.sendMessage(sender, headColor + lang("weapons", sender) + ": " + + lang("0.s.sword.1.2.b.bow.3.4.a.arrow", sender, WHITE, DARK_GRAY, WHITE, DARK_GRAY, WHITE)); + ChatBlock.sendMessage(sender, + headColor + lang("materials", sender) + ": " + AQUA + lang("diamond", sender) + DARK_GRAY + ", " + + YELLOW + lang("gold", sender) + DARK_GRAY + ", " + GRAY + lang("stone", sender) + DARK_GRAY + + ", " + WHITE + lang("iron", sender) + DARK_GRAY + ", " + GOLD + lang("wood", sender)); ChatBlock.sendBlank(sender); chatBlock.setFlexibility(true, false, false, false, false, false); chatBlock.setAlignment("l", "l", "l", "c", "c", "c"); - chatBlock.addRow(" " + headColor + lang("name", sender), lang("health", sender), - lang("hunger", sender), lang("food", sender), lang("armor", sender), - lang("weapons", sender)); + chatBlock.addRow(" " + headColor + lang("name", sender), lang("health", sender), lang("hunger", sender), + lang("food", sender), lang("armor", sender), lang("weapons", sender)); + } - private void addRows(Collection players){ + private void addRows(Collection players) { + for (ClanPlayer cpm : players) { + Player p = cpm.toPlayer(); if (p != null) { - String name = (cpm.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) : (cpm.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) - : sm.getColored(PAGE_UNTRUSTED_COLOR))) + cpm.getName(); + + String name = (cpm.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) + : (cpm.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR))) + + cpm.getName(); String health = cm.getBar(p.getHealth()); String hunger = cm.getBar(p.getFoodLevel()); String armor = cm.getArmorString(p.getInventory()); @@ -73,7 +83,11 @@ public class Vitals extends Sendable { String food = cm.getFoodString(p.getInventory()); chatBlock.addRow(" " + name, RED + health, hunger, WHITE + food, armor, weapons); + } + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/general/GeneralCommands.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/general/GeneralCommands.java index 7f159386..5266c776 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/general/GeneralCommands.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/general/GeneralCommands.java @@ -54,12 +54,18 @@ public class GeneralCommands extends BaseCommand { @Description("{@@command.description.clan}") @HelpSearchTags("menu gui interface ui") public void main(CommandSender sender) { + if (sender instanceof Player && settings.is(ENABLE_GUI)) { + InventoryDrawer.open(new MainFrame((Player) sender)); + } else { + help(sender, new CommandHelp(getCurrentCommandManager(), getCurrentCommandManager().getRootCommand(getName()), getCurrentCommandIssuer())); + } + } @Subcommand("%locale") @@ -67,15 +73,19 @@ public class GeneralCommands extends BaseCommand { @Description("{@@command.description.locale}") @CommandCompletion("@locales") public void locale(ClanPlayer cp, @Values("@locales") @Name("locale") @Single String locale) { + if (!settings.is(LANGUAGE_SELECTOR)) { + ChatBlock.sendMessageKey(cp, "locale.is.prohibited"); return; + } cp.setLocale(Helper.forLanguageTag(locale.replace("_", "-"))); plugin.getStorageManager().updateClanPlayer(cp); ChatBlock.sendMessageKey(cp, "locale.has.been.changed"); + } @Subcommand("%create") @@ -83,27 +93,34 @@ public class GeneralCommands extends BaseCommand { @CommandCompletion("%compl:tag %compl:name") @Description("{@@command.description.create}") public void create(Player player, @Optional @Name("tag") String tag, @Optional @Name("name") String name) { + ClanPlayer cp = cm.getAnyClanPlayer(player.getUniqueId()); if (cp != null && cp.getClan() != null) { - ChatBlock.sendMessage(player, RED + lang("you.must.first.resign", player, - cp.getClan().getName())); + + ChatBlock.sendMessage(player, RED + lang("you.must.first.resign", player, cp.getClan().getName())); return; + } + HashMap initialData = new HashMap<>(); initialData.put(TAG_KEY, tag); initialData.put(NAME_KEY, name); SCConversation conversation = new SCConversation(plugin, player, new CreateClanTagPrompt(), initialData); - conversation.addConversationCanceller(new RequestCanceller(player, RED + lang("clan.create.request.cancelled", player))); + conversation.addConversationCanceller( + new RequestCanceller(player, RED + lang("clan.create.request.cancelled", player))); conversation.begin(); + } @Subcommand("%leaderboard") @CommandPermission("simpleclans.anyone.leaderboard") @Description("{@@command.description.leaderboard}") public void leaderboard(CommandSender sender) { + Leaderboard l = new Leaderboard(plugin, sender); l.send(); + } @Subcommand("%lookup") @@ -111,16 +128,20 @@ public class GeneralCommands extends BaseCommand { @CommandPermission("simpleclans.anyone.lookup") @Description("{@@command.description.lookup.other}") public void lookup(CommandSender sender, @Name("player") ClanPlayerInput player) { + Lookup l = new Lookup(plugin, sender, player.getClanPlayer().getUniqueId()); l.send(); + } @Subcommand("%lookup") @CommandPermission("simpleclans.member.lookup") @Description("{@@command.description.lookup}") public void lookup(Player sender) { + Lookup l = new Lookup(plugin, sender, sender.getUniqueId()); l.send(); + } @Subcommand("%kills") @@ -129,12 +150,17 @@ public class GeneralCommands extends BaseCommand { @CommandCompletion("@players") @Description("{@@command.description.kills}") public void kills(Player sender, @Optional @Name("player") ClanPlayerInput player) { + String name = sender.getName(); if (player != null) { + name = player.getClanPlayer().getName(); + } + Kills k = new Kills(plugin, sender, name); k.send(); + } @Subcommand("%profile") @@ -142,8 +168,10 @@ public class GeneralCommands extends BaseCommand { @CommandCompletion("@clans:hide_own") @Description("{@@command.description.profile.other}") public void profile(CommandSender sender, @Conditions("verified") @Name("clan") ClanInput clan) { + ClanProfile p = new ClanProfile(plugin, sender, clan.getClan()); p.send(); + } @Subcommand("%roster") @@ -151,110 +179,157 @@ public class GeneralCommands extends BaseCommand { @CommandPermission("simpleclans.anyone.roster") @Description("{@@command.description.roster.other}") public void roster(CommandSender sender, @Conditions("verified") @Name("clan") ClanInput clan) { + ClanRoster r = new ClanRoster(plugin, sender, clan.getClan()); r.send(); + } @Subcommand("%ff %allow") @CommandPermission("simpleclans.member.ff") @Description("{@@command.description.ff.allow}") public void allowPersonalFf(Player player, ClanPlayer cp) { + cp.setFriendlyFire(true); storage.updateClanPlayer(cp); ChatBlock.sendMessage(player, AQUA + lang("personal.friendly.fire.is.set.to.allowed", player)); + } @Subcommand("%ff %auto") @CommandPermission("simpleclans.member.ff") @Description("{@@command.description.ff.auto}") public void autoPersonalFf(Player player, ClanPlayer cp) { + cp.setFriendlyFire(false); storage.updateClanPlayer(cp); ChatBlock.sendMessage(player, AQUA + lang("friendy.fire.is.now.managed.by.your.clan", player)); + } @Subcommand("%resetkdr %confirm") @CommandPermission("simpleclans.vip.resetkdr") @Description("{@@command.description.resetkdr}") public void resetKdrConfirm(Player player, ClanPlayer cp) { + if (!settings.is(ALLOW_RESET_KDR)) { + ChatBlock.sendMessage(player, RED + lang("disabled.command", player)); return; + } + PlayerResetKdrEvent event = new PlayerResetKdrEvent(cp); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled() && cm.purchaseResetKdr(player)) { + cm.resetKdr(cp); ChatBlock.sendMessage(player, RED + lang("you.have.reseted.your.kdr", player)); + } + } @Subcommand("%resetkdr") @CommandPermission("simpleclans.vip.resetkdr") @Description("{@@command.description.resetkdr}") public void resetKdr(Player player, ClanPlayer cp) { + if (!settings.is(ALLOW_RESET_KDR)) { + ChatBlock.sendMessage(player, RED + lang("disabled.command", player)); + } else { + new SCConversation(plugin, player, new ResetKdrPrompt(cm), 60).begin(); + } + } @CommandAlias("%accept") @Description("{@@command.description.accept}") @Conditions("can_vote") public void accept(Player player, ClanPlayer cp) { + Clan clan = cp.getClan(); if (clan != null) { + clan.leaderAnnounce(GREEN + lang("voted.to.accept", player.getName())); + } + requestManager.accept(cp); + } @CommandAlias("%deny") @Description("{@@command.description.deny}") @Conditions("can_vote") public void deny(Player player, ClanPlayer cp) { + Clan clan = cp.getClan(); if (clan != null) { + clan.leaderAnnounce(RED + lang("has.voted.to.deny", player.getName())); + } + requestManager.deny(cp); + } @CommandAlias("%more") @Description("{@@command.description.more}") public void more(Player player) { + ChatBlock chatBlock = storage.getChatBlock(player); if (chatBlock == null || chatBlock.size() <= 0) { + ChatBlock.sendMessage(player, RED + lang("nothing.more.to.see", player)); return; + } chatBlock.sendBlock(player, settings.getInt(PAGE_SIZE)); if (chatBlock.size() > 0) { + ChatBlock.sendBlank(player); - ChatBlock.sendMessage(player, settings.getColored(PAGE_HEADINGS_COLOR) + lang("view.next.page", player, - settings.getString(COMMANDS_MORE))); + ChatBlock.sendMessage(player, settings.getColored(PAGE_HEADINGS_COLOR) + + lang("view.next.page", player, settings.getString(COMMANDS_MORE))); + } + ChatBlock.sendBlank(player); + } @CatchUnknown @Subcommand("%help") @Description("{@@command.description.help}") public void help(CommandSender sender, CommandHelp help) { - boolean inClan = sender instanceof Player && cm.getClanByPlayerUniqueId(((Player) sender).getUniqueId()) != null; + + boolean inClan = sender instanceof Player + && cm.getClanByPlayerUniqueId(((Player) sender).getUniqueId()) != null; for (HelpEntry helpEntry : help.getHelpEntries()) { - for (@SuppressWarnings("rawtypes") CommandParameter parameter : helpEntry.getParameters()) { + + for (@SuppressWarnings("rawtypes") + CommandParameter parameter : helpEntry.getParameters()) { + if (parameter.getType().equals(Clan.class) && !inClan) { + helpEntry.setSearchScore(0); + } + } + } + help.showHelp(); + } @Subcommand("%mostkilled") @@ -262,19 +337,25 @@ public class GeneralCommands extends BaseCommand { @Conditions("verified|rank:name=MOSTKILLED") @Description("{@@command.description.mostkilled}") public void mostKilled(Player player) { + MostKilled mk = new MostKilled(plugin, player); mk.send(); + } @Subcommand("%list %balance") @CommandPermission("simpleclans.anyone.list.balance") @Description("{@@command.description.list.balance}") public void listBalance(CommandSender sender) { + List clans = cm.getClans(); if (clans.isEmpty()) { + sender.sendMessage(RED + lang("no.clans.have.been.created", sender)); return; + } + clans.sort(Comparator.comparingDouble(Clan::getBalance).reversed()); sender.sendMessage(lang("clan.list.balance.header", sender, settings.getColored(SERVER_NAME), clans.size())); @@ -283,12 +364,15 @@ public class GeneralCommands extends BaseCommand { String leftBracket = settings.getColored(TAG_BRACKET_COLOR) + settings.getColored(TAG_BRACKET_LEFT); String rightBracket = settings.getColored(TAG_BRACKET_COLOR) + settings.getColored(TAG_BRACKET_RIGHT); for (int i = 0; i < 10 && i < clans.size(); i++) { + Clan clan = clans.get(i); String name = " " + (clan.isVerified() ? settings.getColored(PAGE_CLAN_NAME_COLOR) : GRAY) + clan.getName(); - String line = MessageFormat.format(lineFormat, i + 1, leftBracket, clan.getColorTag(), - rightBracket, name, clan.getBalanceFormatted()); + String line = MessageFormat.format(lineFormat, i + 1, leftBracket, clan.getColorTag(), rightBracket, name, + clan.getBalanceFormatted()); sender.sendMessage(line); + } + } @Subcommand("%list") @@ -296,25 +380,32 @@ public class GeneralCommands extends BaseCommand { @Description("{@@command.description.list}") @CommandCompletion("@clan_list_type @order") public void list(CommandSender sender, @Optional @Values("@clan_list_type") String type, - @Optional @Single @Values("@order") String order) { + @Optional @Single @Values("@order") String order) + { + ClanList list = new ClanList(plugin, sender, type, order); list.send(); + } @Subcommand("%rivalries") @CommandPermission("simpleclans.anyone.rivalries") @Description("{@@command.description.rivalries}") public void rivalries(CommandSender sender) { + Rivalries rivalries = new Rivalries(plugin, sender); rivalries.send(); + } @Subcommand("%alliances") @CommandPermission("simpleclans.anyone.alliances") @Description("{@@command.description.alliances}") public void alliances(CommandSender sender) { + Alliances a = new Alliances(plugin, sender); a.send(); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BankCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BankCommand.java index d1a713c7..074ed268 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BankCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BankCommand.java @@ -31,8 +31,11 @@ public class BankCommand extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.bank.admin.status}") public void status(CommandSender sender, @Name("clan") ClanInput clanInput) { + Clan clan = clanInput.getClan(); - ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.balance", sender, clan.getName(), clan.getBalanceFormatted())); + ChatBlock.sendMessage(sender, + AQUA + lang("clan.admin.balance", sender, clan.getName(), clan.getBalanceFormatted())); + } @Subcommand("%take") @@ -40,20 +43,27 @@ public class BankCommand extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.bank.admin.take}") public void take(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("amount") double amount) { + Clan clan = clanInput.getClan(); amount = Math.abs(amount); - BankOperator operator = new BankOperator(sender, sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0); + BankOperator operator = new BankOperator(sender, + sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0); EconomyResponse economyResponse = clan.withdraw(operator, ClanBalanceUpdateEvent.Cause.COMMAND, amount); switch (economyResponse) { + case SUCCESS: - ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.take", sender, CurrencyFormat.format(amount), clan.getName())); - clan.addBb(sender.getName(), lang("bb.clan.take", sender, CurrencyFormat.format(amount), sender.getName())); + ChatBlock.sendMessage(sender, + AQUA + lang("clan.admin.take", sender, CurrencyFormat.format(amount), clan.getName())); + clan.addBb(sender.getName(), + lang("bb.clan.take", sender, CurrencyFormat.format(amount), sender.getName())); break; case NOT_ENOUGH_BALANCE: sender.sendMessage(RED + lang("clan.admin.bank.not.enough.money", sender, clan.getName())); break; + } + } @Subcommand("%give") @@ -61,15 +71,21 @@ public class BankCommand extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.bank.admin.give}") public void give(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("amount") double amount) { + Clan clan = clanInput.getClan(); amount = Math.abs(amount); - BankOperator operator = new BankOperator(sender, sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0); + BankOperator operator = new BankOperator(sender, + sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0); EconomyResponse economyResponse = clan.deposit(operator, ClanBalanceUpdateEvent.Cause.COMMAND, amount); if (economyResponse == EconomyResponse.SUCCESS) { - ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.give", sender, CurrencyFormat.format(amount), clan.getName())); + + ChatBlock.sendMessage(sender, + AQUA + lang("clan.admin.give", sender, CurrencyFormat.format(amount), clan.getName())); clan.addBb(sender.getName(), lang("bb.clan.give", sender, CurrencyFormat.format(amount), sender.getName())); + } + } @Subcommand("%set") @@ -77,14 +93,22 @@ public class BankCommand extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.bank.admin.set}") public void set(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("amount") double amount) { + Clan clan = clanInput.getClan(); amount = Math.abs(amount); - BankOperator operator = new BankOperator(sender, sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0); + BankOperator operator = new BankOperator(sender, + sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0); - EconomyResponse response = clan.setBalance(operator, ClanBalanceUpdateEvent.Cause.COMMAND, BankLogger.Operation.SET, amount); + EconomyResponse response = clan.setBalance(operator, ClanBalanceUpdateEvent.Cause.COMMAND, + BankLogger.Operation.SET, amount); if (response == EconomyResponse.SUCCESS) { - ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.set", sender, clan.getName(), CurrencyFormat.format(amount))); + + ChatBlock.sendMessage(sender, + AQUA + lang("clan.admin.set", sender, clan.getName(), CurrencyFormat.format(amount))); clan.addBb(sender.getName(), lang("bb.clan.set", sender, CurrencyFormat.format(amount), sender.getName())); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BbCommand.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BbCommand.java index 92f3a498..ae05bd24 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BbCommand.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/BbCommand.java @@ -31,7 +31,9 @@ public class BbCommand extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.mod.bb.display}") public void display(Player sender, @Name("clan") ClanInput input) { + input.getClan().displayBb(sender); + } @Subcommand("%clear") @@ -39,8 +41,10 @@ public class BbCommand extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.mod.bb.clear}") public void clear(Player player, @Name("clan") ClanInput input) { + input.getClan().clearBb(); ChatBlock.sendMessage(player, RED + lang("cleared.bb", player)); + } @Subcommand("%add") @@ -48,10 +52,12 @@ public class BbCommand extends BaseCommand { @CommandCompletion("@clans @nothing") @Description("{@@command.description.mod.bb.post}") public void postMessage(Player player, @Name("clan") ClanInput input, @Name("message") String msg) { + Clan clan = input.getClan(); clan.addBb(lang("bulletin.board.message", player.getName(), msg)); clan.displayBb(player); storage.updateClan(clan); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/StaffCommands.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/StaffCommands.java index 53e000f6..bc522f72 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/StaffCommands.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/commands/staff/StaffCommands.java @@ -51,25 +51,37 @@ public class StaffCommands extends BaseCommand { @CommandCompletion("@players @clans") @HelpSearchTags("move put") @Description("{@@command.description.place}") - public void place(CommandSender sender, @Name("player") ClanPlayerInput cpInput, @Name("clan") ClanInput clanInput) { + public void place(CommandSender sender, @Name("player") ClanPlayerInput cpInput, + @Name("clan") ClanInput clanInput) + { + UUID uuid = cpInput.getClanPlayer().getUniqueId(); ClanPlayer oldCp = cm.getClanPlayer(uuid); Clan newClan = clanInput.getClan(); if (oldCp != null) { + Clan oldClan = Objects.requireNonNull(oldCp.getClan()); if (oldClan.equals(newClan)) { + ChatBlock.sendMessage(sender, lang("player.already.in.this.clan", sender)); return; + } + if (!oldClan.isPermanent() && oldClan.isLeader(uuid) && oldClan.getLeaders().size() <= 1) { + ChatBlock.sendMessage(sender, RED + lang("you.cannot.move.the.last.leader", sender)); return; + } else { + oldClan.addBb(oldCp.getName(), lang("0.has.resigned", oldCp.getName())); oldClan.removePlayerFromClan(uuid); + } + } ClanPlayer cp = cm.getCreateClanPlayer(uuid); @@ -77,42 +89,52 @@ public class StaffCommands extends BaseCommand { newClan.addBb(lang("joined.the.clan", cp.getName())); cm.serverAnnounce(lang("has.joined", cp.getName(), newClan.getName())); newClan.addPlayerToClan(cp); + } @Subcommand("%mod %modtag") @CommandPermission("simpleclans.mod.modtag") @Description("{@@command.description.modtag.other}") public void modtag(Player player, @Name("clan") ClanInput clanInput, @Single @Name("tag") String tag) { + Clan clan = clanInput.getClan(); TagChangeEvent event = new TagChangeEvent(player, clan, tag); plugin.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } + tag = event.getNewTag(); String cleanTag = Helper.cleanTag(tag); Optional validationError = plugin.getTagValidator().validate(player, tag); if (validationError.isPresent()) { + ChatBlock.sendMessage(player, validationError.get()); return; + } if (!cleanTag.equals(clan.getTag())) { - ChatBlock.sendMessage(player, RED + lang("you.can.only.modify.the.color.and.case.of.the.tag", - player)); + + ChatBlock.sendMessage(player, RED + lang("you.can.only.modify.the.color.and.case.of.the.tag", player)); return; + } clan.addBb(player.getName(), lang("tag.changed.to.0", ChatUtils.parseColors(tag))); clan.changeClanTag(tag); player.sendMessage(lang("0.tag.changed.to.1", player, clan.getTag(), tag)); + } @Subcommand("%admin %reload") @CommandPermission("simpleclans.admin.reload") @Description("{@@command.description.reload}") public void reload(CommandSender sender) { + storage.saveModified(); plugin.reloadConfig(); LanguageResource.clearCache(); @@ -121,11 +143,15 @@ public class StaffCommands extends BaseCommand { permissions.loadPermissions(); for (Clan clan : cm.getClans()) { + permissions.updateClanPermissions(clan); + } + Bukkit.getPluginManager().callEvent(new ReloadEvent(sender)); ChatBlock.sendMessage(sender, AQUA + lang("configuration.reloaded", sender)); + } @Subcommand("%mod %home %set") @@ -133,18 +159,22 @@ public class StaffCommands extends BaseCommand { @CommandCompletion("@clans") @Description("{@@command.description.mod.home.set}") public void homeSet(Player player, ClanPlayer cp, @Name("clan") ClanInput clanInput) { + Location loc = player.getLocation(); Clan clan = clanInput.getClan(); PlayerHomeSetEvent event = new PlayerHomeSetEvent(clan, cp, loc); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } clan.setHomeLocation(loc); - ChatBlock.sendMessage(player, AQUA + lang("hombase.mod.set", player, clan.getName()) + " " + - ChatColor.YELLOW + Helper.toLocationString(loc)); + ChatBlock.sendMessage(player, AQUA + lang("hombase.mod.set", player, clan.getName()) + " " + ChatColor.YELLOW + + Helper.toLocationString(loc)); + } @Subcommand("%mod %home %tp") @@ -152,7 +182,9 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.mod.hometp") @Description("{@@command.description.mod.home.tp}") public void homeTp(Player player, @Name("clan") @Conditions("can_teleport") ClanInput clan) { + plugin.getTeleportManager().teleportToHome(player, clan.getClan()); + } @Subcommand("%mod %ban") @@ -160,10 +192,13 @@ public class StaffCommands extends BaseCommand { @CommandCompletion("@players") @Description("{@@command.description.ban}") public void ban(CommandSender sender, @Name("player") ClanPlayerInput player) { + UUID uuid = player.getClanPlayer().getUniqueId(); if (settings.isBanned(uuid)) { + ChatBlock.sendMessage(sender, RED + lang("this.player.is.already.banned", sender)); return; + } cm.ban(uuid); @@ -171,8 +206,11 @@ public class StaffCommands extends BaseCommand { Player pl = sender.getServer().getPlayer(uuid); if (pl != null) { + ChatBlock.sendMessage(pl, AQUA + lang("you.banned", sender)); + } + } @Subcommand("%mod %unban") @@ -180,45 +218,62 @@ public class StaffCommands extends BaseCommand { @CommandCompletion("@players") @Description("{@@command.description.unban}") public void unban(CommandSender sender, @Name("player") ClanPlayerInput player) { + UUID uuid = player.getClanPlayer().getUniqueId(); if (!settings.isBanned(uuid)) { + ChatBlock.sendMessage(sender, RED + lang("this.player.is.not.banned", sender)); return; + } Player pl = Bukkit.getPlayer(uuid); if (pl != null) { + ChatBlock.sendMessage(pl, AQUA + lang("you.have.been.unbanned.from.clan.commands", sender)); + } settings.removeBanned(uuid); ChatBlock.sendMessage(sender, AQUA + lang("player.removed.from.the.banned.list", sender)); + } @Subcommand("%mod %globalff %allow") @CommandPermission("simpleclans.mod.globalff") @Description("{@@command.description.globalff.allow}") public void allowGlobalFf(CommandSender sender) { + if (settings.is(GLOBAL_FRIENDLY_FIRE)) { + ChatBlock.sendMessage(sender, AQUA + lang("global.friendly.fire.is.already.being.allowed", sender)); + } else { + settings.set(GLOBAL_FRIENDLY_FIRE, true); ChatBlock.sendMessage(sender, AQUA + lang("global.friendly.fire.is.set.to.allowed", sender)); + } + } @Subcommand("%mod %globalff %auto") @CommandPermission("simpleclans.mod.globalff") @Description("{@@command.description.globalff.auto}") public void autoGlobalFf(CommandSender sender) { + if (!settings.is(GLOBAL_FRIENDLY_FIRE)) { - ChatBlock.sendMessage(sender, AQUA + - lang("global.friendy.fire.is.already.being.managed.by.each.clan", sender)); + + ChatBlock.sendMessage(sender, + AQUA + lang("global.friendy.fire.is.already.being.managed.by.each.clan", sender)); + } else { + settings.set(GLOBAL_FRIENDLY_FIRE, false); - ChatBlock.sendMessage(sender, AQUA + lang("global.friendy.fire.is.now.managed.by.each.clan", - sender)); + ChatBlock.sendMessage(sender, AQUA + lang("global.friendy.fire.is.now.managed.by.each.clan", sender)); + } + } @Subcommand("%mod %verify") @@ -226,15 +281,21 @@ public class StaffCommands extends BaseCommand { @CommandCompletion("@clans:unverified") @Description("{@@command.description.mod.verify}") public void verify(CommandSender sender, @Name("clan") ClanInput clan) { + Clan clanInput = clan.getClan(); if (!clanInput.isVerified()) { + clanInput.verifyClan(); clanInput.addBb(sender.getName(), lang("clan.0.has.been.verified", clanInput.getName())); ChatBlock.sendMessage(sender, AQUA + lang("the.clan.has.been.verified", sender)); + } else { + ChatBlock.sendMessage(sender, RED + lang("the.clan.is.already.verified", sender)); + } + } @Subcommand("%admin %purge") @@ -242,17 +303,24 @@ public class StaffCommands extends BaseCommand { @CommandCompletion("@players") @Description("{@@command.description.purge}") public void purge(CommandSender sender, @Name("player") ClanPlayerInput player) { + Player onlinePlayer = player.getClanPlayer().toPlayer(); if (onlinePlayer != null && InventoryController.isRegistered(onlinePlayer)) { + onlinePlayer.closeInventory(); + } Clan clan = player.getClanPlayer().getClan(); if (clan != null && clan.getMembers().size() == 1) { + clan.disband(sender, false, false); + } + cm.deleteClanPlayer(player.getClanPlayer()); ChatBlock.sendMessage(sender, AQUA + lang("player.purged", sender)); + } @Subcommand("%mod %kick") @@ -260,16 +328,19 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.mod.kick") @CommandCompletion("@all_non_leaders|@all_leaders") public void kick(CommandSender sender, @Conditions("clan_member") @Name("player") ClanPlayerInput cp) { + ClanPlayer clanPlayer = cp.getClanPlayer(); Clan clan = Objects.requireNonNull(clanPlayer.getClan()); if (clanPlayer.isLeader() && clan.getLeaders().size() == 1) { + ChatBlock.sendMessageKey(sender, "cannot.kick.last.leader"); return; + } - clan.addBb(sender.getName(), lang("has.been.kicked.by", clanPlayer.getName(), - sender.getName(), sender)); + clan.addBb(sender.getName(), lang("has.been.kicked.by", clanPlayer.getName(), sender.getName(), sender)); clan.removePlayerFromClan(clanPlayer.getUniqueId()); + } @Subcommand("%mod %disband") @@ -277,30 +348,41 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.mod.disband") @Description("{@@command.description.mod.disband}") public void disband(CommandSender sender, @Name("clan") ClanInput clan) { + clan.getClan().disband(sender, true, true); + } @Subcommand("%admin %promote") @CommandCompletion("@all_non_leaders") @CommandPermission("simpleclans.admin.promote") @Description("{@@command.description.admin.promote}") - public void promote(CommandSender sender, @Conditions("online|clan_member") @Name("player") ClanPlayerInput promote) { + public void promote(CommandSender sender, + @Conditions("online|clan_member") @Name("player") ClanPlayerInput promote) + { + ClanPlayer clanPlayer = promote.getClanPlayer(); Player promotePl = Objects.requireNonNull(clanPlayer.toPlayer()); if (!permissions.has(promotePl, "simpleclans.leader.promotable")) { - ChatBlock.sendMessage(sender, RED + lang("the.player.does.not.have.the.permissions.to.lead.a.clan", - sender)); + + ChatBlock.sendMessage(sender, + RED + lang("the.player.does.not.have.the.permissions.to.lead.a.clan", sender)); return; + } + Clan clan = Objects.requireNonNull(clanPlayer.getClan()); if (clan.isLeader(promotePl)) { + ChatBlock.sendMessage(sender, RED + lang("the.player.is.already.a.leader", sender)); return; + } clan.addBb(sender.getName(), lang("promoted.to.leader", promotePl.getName())); clan.promote(promotePl.getUniqueId()); ChatBlock.sendMessage(sender, AQUA + lang("player.successfully.promoted", sender)); + } @Subcommand("%admin %demote") @@ -308,35 +390,49 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.admin.demote") @Description("{@@command.description.admin.demote}") public void demote(CommandSender sender, @Conditions("clan_member") @Name("leader") ClanPlayerInput other) { + ClanPlayer otherCp = other.getClanPlayer(); Clan clan = Objects.requireNonNull(otherCp.getClan()); if (!otherCp.isLeader()) { + ChatBlock.sendMessage(sender, RED + lang("player.is.not.a.leader", sender)); return; + } if (clan.getLeaders().size() == 1 && !clan.isPermanent()) { + ChatBlock.sendMessage(sender, RED + lang("you.cannot.demote.the.last.leader", sender)); return; + } + clan.demote(otherCp.getUniqueId()); clan.addBb(sender.getName(), lang("demoted.back.to.member", otherCp.getName())); ChatBlock.sendMessage(sender, AQUA + lang("player.successfully.demoted", sender)); + } @Subcommand("%admin %resetkdr %everyone") @CommandPermission("simpleclans.admin.resetkdr") @Description("{@@command.description.resetkdr.everyone}") public void resetKdr(CommandSender sender) { + for (ClanPlayer cp : cm.getAllClanPlayers()) { + PlayerResetKdrEvent event = new PlayerResetKdrEvent(cp); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { + cm.resetKdr(cp); + } + } + ChatBlock.sendMessage(sender, RED + lang("you.have.reseted.kdr.of.all.players", sender)); + } @Subcommand("%admin %resetkdr") @@ -344,13 +440,17 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.admin.resetkdr") @Description("{@@command.description.resetkdr.player}") public void resetKdr(CommandSender sender, @Name("player") ClanPlayerInput clanPlayer) { + ClanPlayer cp = clanPlayer.getClanPlayer(); PlayerResetKdrEvent event = new PlayerResetKdrEvent(cp); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { + cm.resetKdr(cp); ChatBlock.sendMessage(sender, RED + lang("you.have.reseted.0.kdr", sender, cp.getName())); + } + } @Subcommand("%admin %permanent") @@ -358,11 +458,14 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.admin.permanent") @Description("{@@command.description.admin.permanent}") public void togglePermanent(CommandSender sender, @Name("clan") ClanInput clanInput) { + Clan clan = clanInput.getClan(); boolean permanent = !clan.isPermanent(); clan.setPermanent(permanent); - clan.addBb(sender.getName(), lang((permanent) ? "permanent.status.enabled" : "permanent.status.disabled", sender.getName())); + clan.addBb(sender.getName(), + lang((permanent) ? "permanent.status.enabled" : "permanent.status.disabled", sender.getName())); ChatBlock.sendMessage(sender, AQUA + lang("you.have.toggled.permanent.status", sender, clan.getName())); + } @Subcommand("%mod %rename") @@ -370,22 +473,29 @@ public class StaffCommands extends BaseCommand { @CommandPermission("simpleclans.mod.rename") @Description("{@@command.description.mod.rename}") public void rename(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("name") String clanName) { + Clan clan = clanInput.getClan(); clan.setName(clanName); storage.updateClan(clan); ChatBlock.sendMessageKey(sender, "you.have.successfully.renamed.the.clan", clanName); + } @Subcommand("%mod %locale") @CommandPermission("simpleclans.mod.locale") @Description("{@@command.description.mod.locale}") @CommandCompletion("@locales") - public void locale(CommandSender sender, @Name("player") ClanPlayerInput input, @Values("@locales") @Name("locale") @Single String locale) { + public void locale(CommandSender sender, @Name("player") ClanPlayerInput input, + @Values("@locales") @Name("locale") @Single String locale) + { + ClanPlayer cp = input.getClanPlayer(); cp.setLocale(Helper.forLanguageTag(locale.replace("_", "-"))); plugin.getStorageManager().updateClanPlayer(cp); ChatBlock.sendMessage(sender, lang("locale.has.been.changed")); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ConfirmationPrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ConfirmationPrompt.java index e815e6a7..9bfca409 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ConfirmationPrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ConfirmationPrompt.java @@ -23,7 +23,9 @@ abstract public class ConfirmationPrompt extends StringPrompt { protected abstract Prompt confirm(ClanPlayer sender, Clan clan); protected Prompt decline(ClanPlayer sender) { + return new MessagePromptImpl(RED + lang(getDeclineTextKey(), sender)); + } protected abstract String getPromptTextKey(); @@ -33,14 +35,17 @@ abstract public class ConfirmationPrompt extends StringPrompt { @NotNull @Override public String getPromptText(@NotNull ConversationContext context) { + Player player = (Player) context.getForWhom(); List options = Arrays.asList(lang("yes", player), lang("cancel", player)); return RED + lang(getPromptTextKey(), player, options); + } @Override public Prompt acceptInput(@NotNull ConversationContext cc, @Nullable String input) { + final SimpleClans plugin = (SimpleClans) cc.getPlugin(); Player player = (Player) cc.getForWhom(); @@ -49,9 +54,13 @@ abstract public class ConfirmationPrompt extends StringPrompt { ClanPlayer cp = cm.getCreateClanPlayer(player.getUniqueId()); Clan clan = cp.getClan(); if (clan == null) { + return END_OF_CONVERSATION; + } return yes.equalsIgnoreCase(input) ? confirm(cp, clan) : decline(cp); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanNamePrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanNamePrompt.java index 89bcde71..7062ad53 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanNamePrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanNamePrompt.java @@ -4,7 +4,6 @@ import net.sacredlabyrinth.phaed.simpleclans.ChatBlock; import net.sacredlabyrinth.phaed.simpleclans.Clan; import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import net.sacredlabyrinth.phaed.simpleclans.events.PreCreateClanEvent; -import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager; import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils; import org.bukkit.Bukkit; import org.bukkit.conversations.ConversationContext; @@ -22,91 +21,127 @@ import static org.bukkit.ChatColor.AQUA; import static org.bukkit.ChatColor.RED; public class CreateClanNamePrompt extends StringPrompt { + public static final String NAME_KEY = "name"; @Override public @NotNull String getPromptText(@NotNull ConversationContext context) { + if (context.getSessionData(NAME_KEY) != null) { + return ""; + } + return lang("insert.clan.name", (Player) context.getForWhom()); + } @Override public boolean blocksForInput(@NotNull ConversationContext context) { + return context.getSessionData(NAME_KEY) == null; + } @Override public @Nullable Prompt acceptInput(@NotNull ConversationContext context, @Nullable String clanName) { + SimpleClans plugin = (SimpleClans) context.getPlugin(); Player player = (Player) context.getForWhom(); clanName = clanName != null ? clanName : (String) context.getSessionData(NAME_KEY); context.setSessionData(NAME_KEY, null); - if (plugin == null || clanName == null) return this; + if (plugin == null || clanName == null) + return this; Prompt errorPrompt = validateName(plugin, player, clanName); - if (errorPrompt != null) return errorPrompt; + if (errorPrompt != null) + return errorPrompt; String finalClanName = clanName; Bukkit.getScheduler().runTask(plugin, () -> { + String tag = (String) context.getSessionData(TAG_KEY); - //noinspection ConstantConditions + // noinspection ConstantConditions PreCreateClanEvent event = new PreCreateClanEvent(player, tag, finalClanName); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { + processClanCreation(plugin, player, tag, finalClanName); + } + }); return END_OF_CONVERSATION; + } private void processClanCreation(@NotNull SimpleClans plugin, @NotNull Player player, @NotNull String tag, - @NotNull String name) { + @NotNull String name) + { + if (plugin.getClanManager().purchaseCreation(player)) { + plugin.getClanManager().createClan(player, tag, name); Clan clan = plugin.getClanManager().getClan(tag); clan.addBb(player.getName(), lang("clan.created", name)); plugin.getStorageManager().updateClan(clan); if (!plugin.getSettingsManager().getString(CLAN_DEFAULT_RANK).isEmpty()) { + clan.setDefaultRank(plugin.getSettingsManager().getString(CLAN_DEFAULT_RANK)); - if (plugin.getSettingsManager().is(REQUIRE_VERIFICATION)) { + boolean verified = !plugin.getSettingsManager().is(REQUIRE_VERIFICATION) || plugin.getPermissionsManager().has(player, "simpleclans.mod.verify"); if (!verified) { - ChatBlock.sendMessage(player, AQUA + - lang("get.your.clan.verified.to.access.advanced.features", player)); + + ChatBlock.sendMessage(player, + AQUA + lang("get.your.clan.verified.to.access.advanced.features", player)); + } + } + } + } + } @Nullable private Prompt validateName(@NotNull SimpleClans plugin, @NotNull Player player, @NotNull String input) { + boolean bypass = plugin.getPermissionsManager().has(player, "simpleclans.mod.bypass"); if (!bypass) { + if (ChatUtils.stripColors(input).length() > plugin.getSettingsManager().getInt(CLAN_MAX_LENGTH)) { - return new MessagePromptImpl(RED + - lang("your.clan.name.cannot.be.longer.than.characters", player, - plugin.getSettingsManager().getInt(CLAN_MAX_LENGTH)), this); + + return new MessagePromptImpl(RED + lang("your.clan.name.cannot.be.longer.than.characters", player, + plugin.getSettingsManager().getInt(CLAN_MAX_LENGTH)), this); + } + if (ChatUtils.stripColors(input).length() <= plugin.getSettingsManager().getInt(CLAN_MIN_LENGTH)) { - return new MessagePromptImpl(RED + - lang("your.clan.name.must.be.longer.than.characters", player, - plugin.getSettingsManager().getInt(CLAN_MIN_LENGTH)), this); + + return new MessagePromptImpl(RED + lang("your.clan.name.must.be.longer.than.characters", player, + plugin.getSettingsManager().getInt(CLAN_MIN_LENGTH)), this); + } + } + if (input.contains("&")) { - return new MessagePromptImpl(RED + - lang("your.clan.name.cannot.contain.color.codes", player), this); + + return new MessagePromptImpl(RED + lang("your.clan.name.cannot.contain.color.codes", player), this); + } return null; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanTagPrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanTagPrompt.java index ee774996..d6d4c2f0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanTagPrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateClanTagPrompt.java @@ -15,45 +15,61 @@ import java.util.Optional; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class CreateClanTagPrompt extends StringPrompt { + public static final String TAG_KEY = "tag"; @Override public @NotNull String getPromptText(@NotNull ConversationContext context) { + Player forWhom = (Player) context.getForWhom(); if (context.getSessionData(TAG_KEY) != null) { + return ""; + } + return lang("insert.clan.tag", forWhom, lang("cancel", forWhom)); + } @Override public boolean blocksForInput(@NotNull ConversationContext context) { + return context.getSessionData(TAG_KEY) == null; + } @Override public @Nullable Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) { + Player player = (Player) context.getForWhom(); SimpleClans plugin = (SimpleClans) context.getPlugin(); input = input != null ? input : (String) context.getSessionData(TAG_KEY); context.setSessionData(TAG_KEY, null); - if (input == null || plugin == null) return this; + if (input == null || plugin == null) + return this; Prompt errorPrompt = validateTag(plugin, player, input); - if (errorPrompt != null) return errorPrompt; + if (errorPrompt != null) + return errorPrompt; context.setSessionData(TAG_KEY, input); return new CreateClanNamePrompt(); + } @Nullable private Prompt validateTag(SimpleClans plugin, Player player, @NotNull String clanTag) { + String cleanTag = ChatUtils.stripColors(clanTag); if (plugin.getClanManager().isClan(cleanTag)) { - return new MessagePromptImpl(ChatColor.RED + - lang("clan.with.this.tag.already.exists", player), this); + + return new MessagePromptImpl(ChatColor.RED + lang("clan.with.this.tag.already.exists", player), this); + } Optional validationError = plugin.getTagValidator().validate(player, clanTag); return validationError.map(error -> new MessagePromptImpl(error, this)).orElse(null); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateRankNamePrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateRankNamePrompt.java index e3447397..2e85f58c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateRankNamePrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/CreateRankNamePrompt.java @@ -17,19 +17,25 @@ import static org.bukkit.ChatColor.AQUA; import static org.bukkit.ChatColor.RED; public class CreateRankNamePrompt extends StringPrompt { + @Override public @NotNull String getPromptText(@NotNull ConversationContext context) { + Player forWhom = (Player) context.getForWhom(); return lang("insert.rank.name", forWhom, lang("cancel", forWhom)); + } @Override public @Nullable Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) { + SimpleClans plugin = (SimpleClans) context.getPlugin(); Player player = (Player) context.getForWhom(); Clan clan = (Clan) context.getSessionData("clan"); - if (clan == null || plugin == null) return END_OF_CONVERSATION; - if (input == null) return this; + if (clan == null || plugin == null) + return END_OF_CONVERSATION; + if (input == null) + return this; String rank = input.toLowerCase().replace(" ", "_"); PreCreateRankEvent event = new PreCreateRankEvent(player, clan, rank); @@ -37,16 +43,22 @@ public class CreateRankNamePrompt extends StringPrompt { rank = event.getRankName(); if (event.isCancelled()) { + return null; + } if (clan.hasRank(rank)) { + return new MessagePromptImpl(RED + lang("rank.already.exists", player), this); + } clan.createRank(rank); Bukkit.getServer().getPluginManager().callEvent(new CreateRankEvent(player, clan, clan.getRank(rank))); plugin.getStorageManager().updateClan(clan, true); return new MessagePromptImpl(AQUA + lang("rank.created", player)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/DisbandPrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/DisbandPrompt.java index 7da917da..c486921e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/DisbandPrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/DisbandPrompt.java @@ -11,22 +11,30 @@ public class DisbandPrompt extends ConfirmationPrompt { @Override protected Prompt confirm(ClanPlayer sender, Clan clan) { + if (clan.isPermanent()) { + return new MessagePromptImpl(RED + lang("cannot.disband.permanent", sender)); + } clan.disband(sender.toPlayer(), true, false); return new MessagePromptImpl(RED + lang("clan.has.been.disbanded", sender, clan.getName())); + } @Override protected String getPromptTextKey() { + return "disband.confirmation"; + } @Override protected String getDeclineTextKey() { + return "disband.request.cancelled"; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/InactivityCanceller.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/InactivityCanceller.java index bad9db62..3d2cbe16 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/InactivityCanceller.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/InactivityCanceller.java @@ -19,12 +19,17 @@ public class InactivityCanceller extends InactivityConversationCanceller { * @param timeoutSeconds The number of seconds of inactivity to wait. */ public InactivityCanceller(@NotNull Plugin plugin, int timeoutSeconds) { + super(plugin, timeoutSeconds); + } @Override protected void cancelling(@NotNull Conversation conversation) { + Player forWhom = (Player) conversation.getForWhom(); forWhom.spigot().sendMessage(new TextComponent(RED + lang("you.did.not.answer.in.time", forWhom))); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/MessagePromptImpl.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/MessagePromptImpl.java index cc73c196..541fbb36 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/MessagePromptImpl.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/MessagePromptImpl.java @@ -9,24 +9,35 @@ import org.jetbrains.annotations.NotNull; * @author roinujnosde */ public class MessagePromptImpl extends MessagePrompt { + private final String message; private Prompt nextPrompt; + public MessagePromptImpl(String message) { + this.message = message; + } public MessagePromptImpl(String message, Prompt nextPrompt) { + this(message); this.nextPrompt = nextPrompt; + } @Override protected Prompt getNextPrompt(@NotNull ConversationContext cc) { + return nextPrompt != null ? nextPrompt : END_OF_CONVERSATION; + } @Override public @NotNull String getPromptText(@NotNull ConversationContext cc) { + return message; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/RequestCanceller.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/RequestCanceller.java index 94883182..f469ac50 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/RequestCanceller.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/RequestCanceller.java @@ -16,33 +16,45 @@ public class RequestCanceller implements ConversationCanceller { private final String escapeSequence; public RequestCanceller(@NotNull String escapeSequence, @NotNull String cancelledMessage) { + this.escapeSequence = escapeSequence; this.cancelledMessage = cancelledMessage; + } public RequestCanceller(@NotNull CommandSender sender, @NotNull String cancelledMessage) { + this(lang("cancel", sender), cancelledMessage); + } @Override public void setConversation(@NotNull Conversation conversation) { + } @Override public boolean cancelBasedOnInput(@NotNull ConversationContext context, @NotNull String input) { + if (input.equalsIgnoreCase(escapeSequence)) { + context.getForWhom().sendRawMessage(cancelledMessage); return true; + } return false; + } - //a clone that is not a clone, nice one, Bukkit + // a clone that is not a clone, nice one, Bukkit @SuppressWarnings("MethodDoesntCallSuperMethod") @NotNull @Override public ConversationCanceller clone() { + return new RequestCanceller(this.escapeSequence, this.cancelledMessage); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResetKdrPrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResetKdrPrompt.java index 8f4d228b..cd0600b9 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResetKdrPrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResetKdrPrompt.java @@ -15,29 +15,41 @@ public class ResetKdrPrompt extends ConfirmationPrompt { private final ClanManager cm; public ResetKdrPrompt(ClanManager cm) { + this.cm = cm; + } @Override protected Prompt confirm(ClanPlayer sender, Clan clan) { + PlayerResetKdrEvent event = new PlayerResetKdrEvent(sender); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled() && cm.purchaseResetKdr(sender.toPlayer())) { + cm.resetKdr(sender); return new MessagePromptImpl(RED + lang("you.have.reseted.your.kdr", sender)); + } else { + return END_OF_CONVERSATION; + } + } @Override protected String getPromptTextKey() { + return "resetkdr.confirmation"; + } @Override protected String getDeclineTextKey() { + return "resetkdr.request.cancelled"; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResignPrompt.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResignPrompt.java index 7c917da6..27be31c0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResignPrompt.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/ResignPrompt.java @@ -15,27 +15,41 @@ public class ResignPrompt extends ConfirmationPrompt { @Override protected Prompt confirm(ClanPlayer sender, Clan clan) { + if (clan.isPermanent() || !sender.isLeader() || clan.getLeaders().size() > 1) { + clan.addBb(sender.getName(), lang("0.has.resigned", sender.getName())); sender.addResignTime(clan.getTag()); clan.removePlayerFromClan(sender.getUniqueId()); return new MessagePromptImpl(AQUA + lang("resign.success", sender)); + } else if (sender.isLeader() && clan.getLeaders().size() == 1) { + clan.disband(sender.toPlayer(), true, false); return new MessagePromptImpl(RED + lang("clan.has.been.disbanded", sender, clan.getName())); + } else { - return new MessagePromptImpl(RED + lang("last.leader.cannot.resign.you.must.appoint.another.leader.or.disband.the.clan", sender)); + + return new MessagePromptImpl(RED + + lang("last.leader.cannot.resign.you.must.appoint.another.leader.or.disband.the.clan", sender)); + } + } @Override protected String getPromptTextKey() { + return "resign.confirmation"; + } @Override protected String getDeclineTextKey() { + return "resign.request.cancelled"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/SCConversation.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/SCConversation.java index de332999..5c371cee 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/SCConversation.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/conversation/SCConversation.java @@ -14,41 +14,63 @@ import java.util.Map; import java.util.UUID; public class SCConversation extends Conversation { + private static final Map conversations = new HashMap<>(); public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt) { + this(plugin, forWhom, firstPrompt, new HashMap<>(), 10); + } - public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, int timeout) { + public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, + int timeout) + { + this(plugin, forWhom, firstPrompt, new HashMap<>(), timeout); + } - public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, @NotNull Map initialSessionData) { + public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, + @NotNull Map initialSessionData) + { + this(plugin, forWhom, firstPrompt, initialSessionData, 10); + } - public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, @NotNull Map initialSessionData, int timeout) { + public SCConversation(@NotNull Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, + @NotNull Map initialSessionData, int timeout) + { + super(plugin, forWhom, firstPrompt, initialSessionData); this.setLocalEchoEnabled(true); this.addConversationCanceller(new InactivityCanceller(plugin, timeout)); + } @Override public void begin() { + UUID uniqueId = ((Player) getForWhom()).getUniqueId(); SCConversation oldConversation = conversations.get(uniqueId); if (oldConversation != this && oldConversation != null) { + getForWhom().abandonConversation(oldConversation); + } conversations.put(uniqueId, this); super.begin(); + } public void addConversationCanceller(@NotNull ConversationCanceller canceller) { + canceller.setConversation(this); cancellers.add(canceller); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AddKillEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AddKillEvent.java index 855334a8..fa77a2c3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AddKillEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AddKillEvent.java @@ -7,41 +7,56 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; public class AddKillEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); private boolean cancelled = false; private final ClanPlayer victim; private final ClanPlayer attacker; public AddKillEvent(@NotNull ClanPlayer attacker, @NotNull ClanPlayer victim) { + this.attacker = attacker; this.victim = victim; + } @Override public boolean isCancelled() { + return cancelled; + } public ClanPlayer getAttacker() { + return attacker; + } public ClanPlayer getVictim() { - return victim; - } + return victim; + + } @Override public void setCancelled(boolean value) { + cancelled = value; + } @Override public @NotNull HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanAddEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanAddEvent.java index 2efc5169..7722fadf 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanAddEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanAddEvent.java @@ -15,24 +15,35 @@ public class AllyClanAddEvent extends Event { private final Clan clanSecond; public AllyClanAddEvent(Clan clanFirst, Clan clanSecond) { + this.clanFirst = clanFirst; this.clanSecond = clanSecond; + } public Clan getClanFirst() { + return this.clanFirst; + } public Clan getClanSecond() { + return this.clanSecond; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanRemoveEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanRemoveEvent.java index 464232b8..1bf186f7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanRemoveEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/AllyClanRemoveEvent.java @@ -15,24 +15,35 @@ public class AllyClanRemoveEvent extends Event { private final Clan clanSecond; public AllyClanRemoveEvent(Clan clanFirst, Clan clanSecond) { + this.clanFirst = clanFirst; this.clanSecond = clanSecond; + } public Clan getClanFirst() { + return this.clanFirst; + } public Clan getClanSecond() { + return this.clanSecond; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankDepositEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankDepositEvent.java index 52bb3383..97decf68 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankDepositEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankDepositEvent.java @@ -19,43 +19,62 @@ public class BankDepositEvent extends PlayerEvent implements Cancellable { private boolean cancelled; public BankDepositEvent(@NotNull Player who, @NotNull Clan clan, double amount) { + super(who); this.clan = clan; this.amount = amount; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public @NotNull Clan getClan() { + return clan; + } public double getOldBalance() { + return clan.getBalance(); + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } public double getAmount() { + return amount; + } public void setAmount(double amount) { + this.amount = amount; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankWithdrawEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankWithdrawEvent.java index 08fb3f17..21f70f82 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankWithdrawEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/BankWithdrawEvent.java @@ -19,44 +19,62 @@ public class BankWithdrawEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); public BankWithdrawEvent(@NotNull Player who, @NotNull Clan clan, double amount) { + super(who); this.clan = clan; this.amount = amount; + } public @NotNull Clan getClan() { + return clan; + } public double getOldBalance() { + return clan.getBalance(); + } public void setAmount(double amount) { + this.amount = amount; + } public double getAmount() { + return amount; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ChatEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ChatEvent.java index 1c28bb5b..3b225165 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ChatEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ChatEvent.java @@ -29,23 +29,32 @@ public class ChatEvent extends Event implements Cancellable { private boolean cancelled; public ChatEvent(String message, ClanPlayer sender, List receivers, Type type) { + if (message == null || sender == null || receivers == null || type == null) { + throw new IllegalArgumentException("none of the args can be null"); + } + this.message = message; this.sender = sender; this.receivers = receivers; this.type = type; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancel) { + cancelled = cancel; + } public enum Type { @@ -58,7 +67,9 @@ public class ChatEvent extends Event implements Cancellable { * @return the chat type */ public Type getType() { + return type; + } /** @@ -67,7 +78,9 @@ public class ChatEvent extends Event implements Cancellable { * @return an unmodifiable map of the placeholders */ public Map getPlaceholders() { + return Collections.unmodifiableMap(placeholders); + } /** @@ -75,21 +88,35 @@ public class ChatEvent extends Event implements Cancellable { * * @param placeholderName the placeholder name * @param value the String to be replaced - * @throws IllegalArgumentException if one of the args are null; if one of - * the args are empty; if the placeholder name equals "clan", "nick-color", - * "player", "rank" or "message" + * @throws IllegalArgumentException if one of the args are null; if one of the + * args are empty; if the placeholder name + * equals "clan", "nick-color", "player", + * "rank" or "message" */ public void addPlaceholder(String placeholderName, String value) { + if (placeholderName == null || value == null) { + throw new IllegalArgumentException("placeholderName or value must not be null"); + } + if (placeholderName.isEmpty() || value.isEmpty()) { + throw new IllegalArgumentException("placeholderName or value must not be empty"); + } - if (placeholderName.equalsIgnoreCase("clan") || placeholderName.equalsIgnoreCase("player") || placeholderName.equalsIgnoreCase("rank") || placeholderName.equalsIgnoreCase("message")) { + + if (placeholderName.equalsIgnoreCase("clan") || placeholderName.equalsIgnoreCase("player") + || placeholderName.equalsIgnoreCase("rank") || placeholderName.equalsIgnoreCase("message")) + { + throw new IllegalArgumentException("placeholderName must not be [clan, nick-color, player, rank, message]"); + } + placeholders.put(placeholderName, value); + } /** @@ -98,7 +125,9 @@ public class ChatEvent extends Event implements Cancellable { * @param placeholderName the placeholder name */ public void removePlaceholder(String placeholderName) { + placeholders.remove(placeholderName); + } /** @@ -107,7 +136,9 @@ public class ChatEvent extends Event implements Cancellable { * @return the receivers */ public List getReceivers() { + return receivers; + } /** @@ -116,10 +147,15 @@ public class ChatEvent extends Event implements Cancellable { * @param message the new message */ public void setMessage(String message) { + if (message == null) { + throw new IllegalArgumentException("message must not be null"); + } + this.message = message; + } /** @@ -128,7 +164,9 @@ public class ChatEvent extends Event implements Cancellable { * @return the message */ public String getMessage() { + return message; + } /** @@ -137,16 +175,22 @@ public class ChatEvent extends Event implements Cancellable { * @return the sender */ public ClanPlayer getSender() { + return sender; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanBalanceUpdateEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanBalanceUpdateEvent.java index 3a80f44d..fcb865df 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanBalanceUpdateEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanBalanceUpdateEvent.java @@ -18,44 +18,52 @@ public class ClanBalanceUpdateEvent extends Event implements Cancellable { private double newBalance; private boolean cancelled; - public ClanBalanceUpdateEvent(@NotNull BankOperator updater, - @NotNull Clan clan, - double balance, - double newBalance, - @NotNull Cause cause) { + public ClanBalanceUpdateEvent(@NotNull BankOperator updater, @NotNull Clan clan, double balance, double newBalance, + @NotNull Cause cause) + { + this.updater = updater; this.balance = balance; this.newBalance = newBalance; this.clan = clan; this.cause = cause; + } /** * @return the balance updater */ public @NotNull BankOperator getUpdater() { + return updater; + } /** * @return the Clan involved */ public @NotNull Clan getClan() { + return clan; + } /** * @return the Clan's current balance */ public double getBalance() { + return balance; + } /** * @return the Clan's new balance */ public double getNewBalance() { + return newBalance; + } /** @@ -65,47 +73,65 @@ public class ClanBalanceUpdateEvent extends Event implements Cancellable { * @throws IllegalArgumentException if newBalance is negative */ public void setNewBalance(double newBalance) { + if (newBalance < 0) { + throw new IllegalArgumentException("newBalance cannot be negative"); + } + this.newBalance = newBalance; + } /** * @return the update cause */ public @NotNull Cause getCause() { + return cause; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } /** - * @throws IllegalStateException if the cause of the event is {@link Cause#REVERT} + * @throws IllegalStateException if the cause of the event is + * {@link Cause#REVERT} */ @Override public void setCancelled(boolean isCancelled) { + if (getCause() == Cause.REVERT) { + throw new IllegalStateException("cannot cancel REVERT update"); + } + this.cancelled = isCancelled; + } public enum Cause { - UPKEEP, - MEMBER_FEE, + UPKEEP, MEMBER_FEE, /** * When a command such as /clan bank deposit causes the update */ @@ -119,7 +145,8 @@ public class ClanBalanceUpdateEvent extends Event implements Cancellable { */ INTERNAL, /** - * When the clan data is being loaded and the balance is set, usually on server start up or plugin reload + * When the clan data is being loaded and the balance is set, usually on server + * start up or plugin reload */ LOADING, /** @@ -127,4 +154,5 @@ public class ClanBalanceUpdateEvent extends Event implements Cancellable { */ REVERT } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanPlayerTeleportEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanPlayerTeleportEvent.java index 0cfc8c3f..50014e2d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanPlayerTeleportEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ClanPlayerTeleportEvent.java @@ -16,39 +16,56 @@ public class ClanPlayerTeleportEvent extends Event implements Cancellable { private final Location destination; public ClanPlayerTeleportEvent(ClanPlayer player, Location origin, Location destination) { + this.player = player; this.origin = origin; this.destination = destination; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancel) { + cancelled = cancel; + } public ClanPlayer getClanPlayer() { + return player; + } public Location getOrigin() { + return origin; + } public Location getDestination() { + return destination; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ComponentClickEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ComponentClickEvent.java index fce6c2bc..dd22e883 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ComponentClickEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ComponentClickEvent.java @@ -12,41 +12,57 @@ import org.jetbrains.annotations.NotNull; * @author RoinujNosde */ public class ComponentClickEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); private final SCFrame frame; private final SCComponent component; private boolean cancelled; public ComponentClickEvent(@NotNull Player who, @NotNull SCFrame frame, @NotNull SCComponent component) { + super(who); this.frame = frame; this.component = component; + } public @NotNull SCFrame getFrame() { + return frame; + } public @NotNull SCComponent getComponent() { + return component; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static @NotNull HandlerList getHandlerList() { + return HANDLER_LIST; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateClanEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateClanEvent.java index e80f9027..de0d3673 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateClanEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateClanEvent.java @@ -14,19 +14,28 @@ public class CreateClanEvent extends Event { private final Clan clan; public CreateClanEvent(Clan clan) { + this.clan = clan; + } public Clan getClan() { + return this.clan; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateRankEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateRankEvent.java index 016b48c1..7afa750a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateRankEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/CreateRankEvent.java @@ -17,27 +17,38 @@ public class CreateRankEvent extends PlayerEvent { private final Clan clan; public CreateRankEvent(Player who, Clan clan, Rank rank) { + super(who); this.clan = clan; this.rank = rank; + } @NotNull public Rank getRank() { + return rank; + } @NotNull public Clan getClan() { + return clan; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DeleteRankEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DeleteRankEvent.java index 23772083..2dadb13e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DeleteRankEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DeleteRankEvent.java @@ -19,35 +19,50 @@ public class DeleteRankEvent extends PlayerEvent implements Cancellable { private boolean cancelled; public DeleteRankEvent(Player who, Clan clan, Rank rank) { + super(who); this.rank = rank; this.clan = clan; + } public Rank getRank() { + return rank; + } public Clan getClan() { + return clan; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DisbandClanEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DisbandClanEvent.java index 6256ba87..7f84a67b 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DisbandClanEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/DisbandClanEvent.java @@ -17,27 +17,41 @@ public class DisbandClanEvent extends Event { private final Clan clan; public DisbandClanEvent(CommandSender sender, Clan clan) { + if (sender == null) { + sender = Bukkit.getConsoleSender(); + } + this.sender = sender; this.clan = clan; + } public Clan getClan() { + return this.clan; + } public CommandSender getSender() { + return sender; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/EconomyTransactionEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/EconomyTransactionEvent.java index 4d8891c1..3f75c3e7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/EconomyTransactionEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/EconomyTransactionEvent.java @@ -9,7 +9,9 @@ import org.jetbrains.annotations.NotNull; /** * This event is fired when money is granted or charged from a player's account. - *

Note: Cancelling this event will deny the transaction.

+ *

+ * Note: Cancelling this event will deny the transaction. + *

* * @see PermissionsManager#grantPlayer(OfflinePlayer, double, Cause) * @see PermissionsManager#chargePlayer(OfflinePlayer, double, Cause) @@ -24,48 +26,67 @@ public class EconomyTransactionEvent extends Event implements Cancellable { private final TransactionType transactionType; private boolean cancelled; - public EconomyTransactionEvent(@NotNull OfflinePlayer affected, double amount, - @NotNull Cause cause, @NotNull TransactionType transactionType) { + public EconomyTransactionEvent(@NotNull OfflinePlayer affected, double amount, @NotNull Cause cause, + @NotNull TransactionType transactionType) + { + this.player = affected; this.amount = amount; this.cause = cause; this.transactionType = transactionType; + } public OfflinePlayer getPlayer() { + return player; + } public double getAmount() { + return amount; + } public void setAmount(double amount) { + this.amount = amount; + } @NotNull public Cause getCause() { + return cause; + } @SuppressWarnings("unused") public TransactionType getTransactionType() { + return transactionType; + } @Override public @NotNull HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } @Override public boolean isCancelled() { + return cancelled; + } /** @@ -73,20 +94,14 @@ public class EconomyTransactionEvent extends Event implements Cancellable { */ @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } public enum Cause { - CLAN_CREATION, - CLAN_VERIFICATION, - CLAN_INVITATION, - CLAN_REGROUP, - CLAN_HOME_TELEPORT, - CLAN_HOME_TELEPORT_SET, - DISCORD_CREATION, - PLAYER_KILLED, - MEMBER_FEE_SET, - RESET_KDR + CLAN_CREATION, CLAN_VERIFICATION, CLAN_INVITATION, CLAN_REGROUP, CLAN_HOME_TELEPORT, CLAN_HOME_TELEPORT_SET, + DISCORD_CREATION, PLAYER_KILLED, MEMBER_FEE_SET, RESET_KDR } public enum TransactionType { diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/FrameOpenEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/FrameOpenEvent.java index 08e8228e..2de45b82 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/FrameOpenEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/FrameOpenEvent.java @@ -11,35 +11,49 @@ import org.jetbrains.annotations.NotNull; * @author RoinujNosde */ public class FrameOpenEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); private boolean cancelled; private final @NotNull SCFrame frame; public FrameOpenEvent(@NotNull Player viewer, @NotNull SCFrame frame) { + super(viewer); this.frame = frame; + } public @NotNull SCFrame getFrame() { + return frame; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static @NotNull HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/HomeRegroupEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/HomeRegroupEvent.java index 6fe92f85..86ab3208 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/HomeRegroupEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/HomeRegroupEvent.java @@ -29,40 +29,57 @@ public class HomeRegroupEvent extends Event implements Cancellable { private final Location loc; public HomeRegroupEvent(Clan clan, ClanPlayer cp, List cps, Location loc) { + this.clan = clan; this.cp = cp; this.cps = cps; this.loc = loc; + } - + public Clan getClan() { + return clan; + } - + public ClanPlayer getIssuer() { + return cp; + } - + public List getPlayers() { + return Collections.unmodifiableList(cps); + } @Override public HandlerList getHandlers() { + return handlers; + } - + public static HandlerList getHandlerList() { + return handlers; + } - + @Override public boolean isCancelled() { + return cancelled; + } - + @Override public void setCancelled(boolean cancel) { + cancelled = cancel; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerDemoteEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerDemoteEvent.java index d3eb7721..cd153544 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerDemoteEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerDemoteEvent.java @@ -16,24 +16,35 @@ public class PlayerDemoteEvent extends Event { private final ClanPlayer target; public PlayerDemoteEvent(Clan clan, ClanPlayer target) { + this.clan = clan; this.target = target; + } public Clan getClan() { + return this.clan; + } public ClanPlayer getClanPlayer() { + return this.target; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeClearEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeClearEvent.java index 67b75494..3973d7ff 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeClearEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeClearEvent.java @@ -16,36 +16,50 @@ public class PlayerHomeClearEvent extends Event implements Cancellable { private boolean cancelled; public PlayerHomeClearEvent(Clan clan, ClanPlayer cp) { + this.clan = clan; this.cp = cp; + } public Clan getClan() { + return clan; + } public ClanPlayer getCp() { + return cp; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } @NotNull @Override public HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeSetEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeSetEvent.java index 66e78dea..21dddb2c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeSetEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerHomeSetEvent.java @@ -20,39 +20,56 @@ public class PlayerHomeSetEvent extends Event implements Cancellable { private final Location loc; public PlayerHomeSetEvent(Clan clan, ClanPlayer cp, Location loc) { + this.clan = clan; this.cp = cp; this.loc = loc; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } public Clan getClan() { + return this.clan; + } public ClanPlayer getClanPlayer() { + return this.cp; + } public Location getLocation() { + return this.loc; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerJoinedClanEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerJoinedClanEvent.java index b608ca8f..959c26c5 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerJoinedClanEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerJoinedClanEvent.java @@ -16,24 +16,35 @@ public class PlayerJoinedClanEvent extends Event { private final ClanPlayer target; public PlayerJoinedClanEvent(Clan clan, ClanPlayer target) { + this.clan = clan; this.target = target; + } public Clan getClan() { + return this.clan; + } public ClanPlayer getClanPlayer() { + return this.target; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerKickedClanEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerKickedClanEvent.java index 352cfe36..3523abd3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerKickedClanEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerKickedClanEvent.java @@ -16,24 +16,35 @@ public class PlayerKickedClanEvent extends Event { private final ClanPlayer target; public PlayerKickedClanEvent(Clan clan, ClanPlayer target) { + this.clan = clan; this.target = target; + } public Clan getClan() { + return this.clan; + } public ClanPlayer getClanPlayer() { + return this.target; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerPromoteEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerPromoteEvent.java index b73975df..5f709b94 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerPromoteEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerPromoteEvent.java @@ -16,24 +16,35 @@ public class PlayerPromoteEvent extends Event { private final ClanPlayer target; public PlayerPromoteEvent(Clan clan, ClanPlayer target) { + this.clan = clan; this.target = target; + } public Clan getClan() { + return this.clan; + } public ClanPlayer getClanPlayer() { + return this.target; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerRankUpdateEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerRankUpdateEvent.java index abaa38e0..4e9b1e1a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerRankUpdateEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerRankUpdateEvent.java @@ -24,55 +24,77 @@ public class PlayerRankUpdateEvent extends Event implements Cancellable { private boolean cancelled; public PlayerRankUpdateEvent(@NotNull ClanPlayer issuer, @NotNull ClanPlayer target, @NotNull Clan clan, - @Nullable Rank oldRank, @Nullable Rank newRank) { + @Nullable Rank oldRank, @Nullable Rank newRank) + { + this.target = target; this.issuer = issuer; this.oldRank = oldRank; this.clan = clan; this.newRank = newRank; + } @Nullable public Rank getOldRank() { + return oldRank; + } @NotNull public Clan getClan() { + return clan; + } @Nullable public Rank getNewRank() { + return newRank; + } @NotNull public ClanPlayer getIssuer() { + return issuer; + } @NotNull public ClanPlayer getTarget() { + return target; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean isCancelled) { + this.cancelled = isCancelled; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerResetKdrEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerResetKdrEvent.java index c3e56f13..5ed1953f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerResetKdrEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PlayerResetKdrEvent.java @@ -21,7 +21,9 @@ public class PlayerResetKdrEvent extends Event implements Cancellable { * @param clanPlayer The ClanPlayer whose kill death rate going to be reset */ public PlayerResetKdrEvent(@NotNull ClanPlayer clanPlayer) { + this.clanPlayer = clanPlayer; + } /** @@ -31,26 +33,36 @@ public class PlayerResetKdrEvent extends Event implements Cancellable { */ @NotNull public ClanPlayer getClanPlayer() { + return clanPlayer; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateClanEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateClanEvent.java index 8a14fb29..9fce5c06 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateClanEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateClanEvent.java @@ -7,41 +7,57 @@ import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.NotNull; public class PreCreateClanEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); private boolean cancelled; private final String tag; private final String name; public PreCreateClanEvent(@NotNull Player who, @NotNull String tag, @NotNull String name) { + super(who); this.tag = tag; this.name = name; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public String getTag() { + return tag; + } public String getName() { + return name; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateRankEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateRankEvent.java index 6450ea2d..9a808d4a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateRankEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/PreCreateRankEvent.java @@ -18,41 +18,58 @@ public class PreCreateRankEvent extends PlayerEvent implements Cancellable { private boolean cancelled; public PreCreateRankEvent(Player who, Clan clan, String rankName) { + super(who); this.clan = clan; this.rankName = rankName; + } @NotNull public Clan getClan() { + return clan; + } @NotNull public String getRankName() { + return rankName; + } public void setRankName(@NotNull String rankName) { + this.rankName = rankName; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean isCancelled) { + this.cancelled = isCancelled; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ReloadEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ReloadEvent.java index cfd4c578..af78802d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ReloadEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/ReloadEvent.java @@ -6,25 +6,34 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; public class ReloadEvent extends Event { - + private static final HandlerList HANDLER_LIST = new HandlerList(); - + private final CommandSender sender; - + public ReloadEvent(CommandSender sender) { + this.sender = sender; + } - + public static @NotNull HandlerList getHandlerList() { + return HANDLER_LIST; + } - + @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } - + public CommandSender getSender() { + return sender; + } + } \ No newline at end of file diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestEvent.java index bd912339..4471288e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestEvent.java @@ -15,19 +15,28 @@ public class RequestEvent extends Event { private final Request RequestProcess; public RequestEvent(Request RequestProcess) { + this.RequestProcess = RequestProcess; + } public Request getRequest() { + return this.RequestProcess; + } @Override public @NotNull HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestFinishedEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestFinishedEvent.java index a8261be5..909d7b6e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestFinishedEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RequestFinishedEvent.java @@ -14,19 +14,28 @@ public class RequestFinishedEvent extends Event { private final Request RequestProcess; public RequestFinishedEvent(Request RequestProcess) { + this.RequestProcess = RequestProcess; + } public Request getRequest() { + return this.RequestProcess; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanAddEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanAddEvent.java index 58c0ec68..45d389b5 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanAddEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanAddEvent.java @@ -15,24 +15,35 @@ public class RivalClanAddEvent extends Event { private final Clan clanSecond; public RivalClanAddEvent(Clan clanFirst, Clan clanSecond) { + this.clanFirst = clanFirst; this.clanSecond = clanSecond; + } public Clan getClanFirst() { + return this.clanFirst; + } public Clan getClanSecond() { + return this.clanSecond; + } @Override public HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanRemoveEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanRemoveEvent.java index 735f6e2f..5049b9b2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanRemoveEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/RivalClanRemoveEvent.java @@ -16,24 +16,35 @@ public class RivalClanRemoveEvent extends Event { private final Clan clanSecond; public RivalClanRemoveEvent(Clan clanFirst, Clan clanSecond) { + this.clanFirst = clanFirst; this.clanSecond = clanSecond; + } public Clan getClanFirst() { + return this.clanFirst; + } public Clan getClanSecond() { + return this.clanSecond; + } @Override public @NotNull HandlerList getHandlers() { + return handlers; + } public static HandlerList getHandlerList() { + return handlers; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/TagChangeEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/TagChangeEvent.java index 079a0dcd..c0bdb535 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/TagChangeEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/TagChangeEvent.java @@ -15,39 +15,56 @@ public class TagChangeEvent extends PlayerEvent implements Cancellable { private boolean cancelled; public TagChangeEvent(@NotNull Player player, @NotNull Clan clan, @NotNull String newTag) { + super(player); this.clan = clan; this.newTag = newTag; + } public @NotNull Clan getClan() { + return clan; + } public @NotNull String getNewTag() { + return newTag; + } public void setNewTag(@NotNull String newTag) { + this.newTag = newTag; + } @Override public @NotNull HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancelled; + } @Override public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarEndEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarEndEvent.java index 42119be9..87a3375b 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarEndEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarEndEvent.java @@ -12,31 +12,42 @@ public class WarEndEvent extends Event { private final Reason reason; public WarEndEvent(@NotNull War war, @NotNull Reason reason) { + this.war = war; this.reason = reason; + } @NotNull public War getWar() { + return war; + } @NotNull public Reason getReason() { + return reason; + } @NotNull @Override public HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } public enum Reason { REQUEST, EXPIRATION } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarStartEvent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarStartEvent.java index 76557de7..1e9e3aa9 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarStartEvent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/events/WarStartEvent.java @@ -13,31 +13,44 @@ public class WarStartEvent extends Event implements Cancellable { private boolean cancel; public WarStartEvent(@NotNull War war) { + this.war = war; + } @NotNull public War getWar() { + return war; + } @NotNull @Override public HandlerList getHandlers() { + return HANDLER_LIST; + } public static HandlerList getHandlerList() { + return HANDLER_LIST; + } @Override public boolean isCancelled() { + return cancel; + } @Override public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/DiscordHook.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/DiscordHook.java index fd35761b..85cd2cf0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/DiscordHook.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/DiscordHook.java @@ -51,17 +51,17 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con * On server' startup: *

*
    - *
  • Creates categories and channels, respecting discord's limits.
  • - *
  • Removes invalid channels, resets permissions and roles.
  • + *
  • Creates categories and channels, respecting discord's limits.
  • + *
  • Removes invalid channels, resets permissions and roles.
  • *
*

* Manages events: *

*
    - *
  • Clan creation/deletion
  • - *
  • ClanPlayer joining/resigning
  • - *
  • Player linking/unlinking
  • - *
  • ClanPlayer promoting/demoting
  • + *
  • Clan creation/deletion
  • + *
  • ClanPlayer joining/resigning
  • + *
  • Player linking/unlinking
  • + *
  • ClanPlayer promoting/demoting
  • *
*

* Currently, works with clan chat only. @@ -80,50 +80,64 @@ public class DiscordHook implements Listener { private final List whitelist; public DiscordHook(SimpleClans plugin) { + this.plugin = plugin; settingsManager = plugin.getSettingsManager(); chatManager = plugin.getChatManager(); clanManager = plugin.getClanManager(); - textCategories = settingsManager.getStringList(DISCORDCHAT_TEXT_CATEGORY_IDS).stream(). - filter(this::categoryExists).collect(Collectors.toList()); + textCategories = settingsManager.getStringList(DISCORDCHAT_TEXT_CATEGORY_IDS).stream() + .filter(this::categoryExists).collect(Collectors.toList()); whitelist = settingsManager.getStringList(DISCORDCHAT_TEXT_WHITELIST); clanTags = clanManager.getClans().stream().map(Clan::getTag).collect(Collectors.toList()); setupDiscord(); + } @Subscribe public void onMessageReceived(DiscordGuildMessageReceivedEvent event) { + Optional channel = getCachedChannel(event.getChannel().getName()); if (channel.isPresent()) { + Message eventMessage = event.getMessage(); User Author = event.getAuthor(); TextChannel textChannel = channel.get(); UUID uuid = accountManager.getUuid(Author.getId()); if (uuid == null) { + sendPrivateMessage(textChannel, eventMessage, lang("you.did.not.link.your.account")); return; + } ClanPlayer clanPlayer = clanManager.getClanPlayer(uuid); if (clanPlayer == null) { + return; + } Clan clan = clanPlayer.getClan(); if (clan == null) { + return; + } if (!Objects.equals(textChannel.getName(), clan.getTag())) { + String channelLink = "<#" + textChannel.getId() + ">"; - sendPrivateMessage(textChannel, eventMessage, lang("cannot.send.discord.message", clanPlayer, channelLink)); + sendPrivateMessage(textChannel, eventMessage, + lang("cannot.send.discord.message", clanPlayer, channelLink)); return; + } + // DiscordSRV start String emojiBehavior = DiscordSRV.config().getString("DiscordChatChannelEmojiBehavior"); @@ -134,128 +148,178 @@ public class DiscordHook implements Listener { String message = MessageUtil.toLegacy(component); if (hideEmoji && StringUtils.isBlank(EmojiParser.removeAllEmojis(message))) { - DiscordSRV.debug("Ignoring message from " - + Author.getName() + - " because it became completely blank after removing unicode emojis"); + + DiscordSRV.debug("Ignoring message from " + Author.getName() + + " because it became completely blank after removing unicode emojis"); return; + } if (hideEmoji) { + // remove all emojis message = EmojiParser.removeAllEmojis(message); + } else if (nameEmoji) { + // parse emojis from unicode back to :code: message = EmojiParser.parseToAliases(message); + } + // DiscordSRV end chatManager.processChat(DISCORD, CLAN, clanPlayer, message); + } + } @EventHandler public void onClanDisband(DisbandClanEvent event) { + deleteChannel(event.getClan().getTag()); + } @EventHandler public void onClanCreate(CreateClanEvent event) { + try { + if (settingsManager.is(DISCORDCHAT_AUTO_CREATION)) { + createChannel(event.getClan().getTag()); + } + } catch (DiscordHookException ex) { - // Clan is not following the conditions, categories are fulled or discord reaches the limit, nothing to do here. + + // Clan is not following the conditions, categories are fulled or discord + // reaches the limit, nothing to do here. SimpleClans.debug(ex.getMessage()); + } + } @EventHandler public void onPlayerClanLeave(PlayerKickedClanEvent event) { + ClanPlayer clanPlayer = event.getClanPlayer(); Clan clan = event.getClan(); Member member = getMember(clanPlayer); if (member == null || clan == null) { + return; + } updateViewPermission(member, clan, REMOVE); updateLeaderRole(member, clanPlayer, REMOVE); + } @EventHandler public void onPlayerClanJoin(PlayerJoinedClanEvent event) { + ClanPlayer clanPlayer = event.getClanPlayer(); Clan clan = event.getClan(); Member member = getMember(clanPlayer); if (member == null || clan == null) { + return; + } if (!createChannelSilently(clanPlayer)) { + return; + } updateViewPermission(member, clan, ADD); + } @EventHandler public void onPlayerPromote(PlayerPromoteEvent event) { + ClanPlayer clanPlayer = event.getClanPlayer(); Member member = getMember(clanPlayer); if (member == null) { + return; + } updateLeaderRole(member, clanPlayer, ADD); + } @EventHandler public void onPlayerDemote(PlayerDemoteEvent event) { + ClanPlayer clanPlayer = event.getClanPlayer(); Member member = getMember(clanPlayer); if (member == null) { + return; + } updateLeaderRole(member, clanPlayer, REMOVE); + } @Subscribe public void onPlayerLinking(AccountLinkedEvent event) { + ClanPlayer clanPlayer = clanManager.getClanPlayer(event.getPlayer()); Member member = getGuild().getMember(event.getUser()); if (clanPlayer == null || member == null) { + return; + } Clan clan = clanPlayer.getClan(); if (clan == null) { + return; + } if (!createChannelSilently(clanPlayer)) { + return; + } updateViewPermission(member, clan, ADD); updateLeaderRole(member, clanPlayer, ADD); + } @Subscribe public void onPlayerUnlinking(AccountUnlinkedEvent event) { + ClanPlayer clanPlayer = clanManager.getClanPlayer(event.getPlayer()); Member member = getGuild().getMember(event.getDiscordUser()); if (clanPlayer == null || clanPlayer.getClan() == null || member == null) { + return; + } updateViewPermission(member, clanPlayer.getClan(), REMOVE); updateLeaderRole(member, clanPlayer, REMOVE); + } protected void setupDiscord() { - Map discordTagChannels = getChannels().stream(). - collect(Collectors.toMap(TextChannel::getName, textChannel -> textChannel)); + + Map discordTagChannels = getChannels().stream() + .collect(Collectors.toMap(TextChannel::getName, textChannel -> textChannel)); SimpleClans.debug("DiscordTagChannels before clearing: " + String.join(",", discordTagChannels.keySet())); clearChannels(discordTagChannels); @@ -266,11 +330,14 @@ public class DiscordHook implements Listener { SimpleClans.debug("ClanTags before creating: " + String.join(",", clanTags)); createChannels(discordTagChannels); SimpleClans.debug("ClanTags after creating: " + String.join(",", clanTags)); + } @NotNull public Guild getGuild() { + return DiscordSRV.getPlugin().getMainGuild(); + } /** @@ -278,39 +345,45 @@ public class DiscordHook implements Listener { */ @NotNull public Role getLeaderRole() { + Role role = getGuild().getRoleById(settingsManager.getString(DISCORDCHAT_LEADER_ID)); if (role == null || !role.getName().equals(settingsManager.getString(DISCORDCHAT_LEADER_ROLE))) { - role = getGuild().createRole(). - setName(settingsManager.getString(DISCORDCHAT_LEADER_ROLE)). - setColor(getLeaderColor()). - setMentionable(true). - complete(); + + role = getGuild().createRole().setName(settingsManager.getString(DISCORDCHAT_LEADER_ROLE)) + .setColor(getLeaderColor()).setMentionable(true).complete(); settingsManager.set(DISCORDCHAT_LEADER_ID, role.getId()); settingsManager.save(); + } return role; + } /** * @return A leader color from configuration */ public Color getLeaderColor() { - String[] colors = settingsManager.getString(DISCORDCHAT_LEADER_COLOR). - replaceAll("\\s", "").split(","); + + String[] colors = settingsManager.getString(DISCORDCHAT_LEADER_COLOR).replaceAll("\\s", "").split(","); try { + int red = Integer.parseInt(colors[0]); int green = Integer.parseInt(colors[1]); int blue = Integer.parseInt(colors[2]); int alpha = Integer.parseInt(colors[3]); return new Color(red, green, blue, alpha); + } catch (IllegalArgumentException ex) { + plugin.getLogger().warning("Color is invalid, using default color: " + ex.getMessage()); return Color.RED; + } + } /** @@ -320,80 +393,104 @@ public class DiscordHook implements Listener { */ @Nullable public Category createCategory() { + if (getGuild().getChannels().size() >= MAX_CHANNELS_PER_GUILD) { + return null; + } String categoryName = settingsManager.getString(DISCORDCHAT_TEXT_CATEGORY_FORMAT); Category category = null; try { - category = getGuild().createCategory(categoryName). - addRolePermissionOverride( - getGuild().getPublicRole().getIdLong(), - Collections.emptyList(), - Collections.singletonList(VIEW_CHANNEL)). - addMemberPermissionOverride(getGuild().getSelfMember().getIdLong(), - Arrays.asList(VIEW_CHANNEL, MANAGE_CHANNEL), - Collections.emptyList()). - submit().get(); + + category = getGuild().createCategory(categoryName) + .addRolePermissionOverride(getGuild().getPublicRole().getIdLong(), Collections.emptyList(), + Collections.singletonList(VIEW_CHANNEL)) + .addMemberPermissionOverride(getGuild().getSelfMember().getIdLong(), + Arrays.asList(VIEW_CHANNEL, MANAGE_CHANNEL), Collections.emptyList()) + .submit().get(); textCategories.add(category.getId()); settingsManager.set(DISCORDCHAT_TEXT_CATEGORY_IDS, textCategories); settingsManager.save(); + } catch (InterruptedException | ExecutionException ex) { - plugin.getLogger().log(Level.SEVERE, "Error while trying to create {0} category: " + - ex.getMessage(), categoryName); + + plugin.getLogger().log(Level.SEVERE, "Error while trying to create {0} category: " + ex.getMessage(), + categoryName); + } return category; + } /** * Creates a new {@link TextChannel} in available SimpleClans' categories, * otherwise creates one. * - *

Sets positive {@link Permission#VIEW_CHANNEL} permission to all linked clan members.

+ *

+ * Sets positive {@link Permission#VIEW_CHANNEL} permission to all linked clan + * members. + *

* * @param clanTag the clan tag - * @throws InvalidChannelException clan is not verified or permanent, - * no one member is linked or clan is not in the whitelist. + * @throws InvalidChannelException clan is not verified or permanent, no one + * member is linked or clan is not in the + * whitelist. * @throws ChannelExistsException if channel is already exist * @throws CategoriesLimitException if categories reached the limit. * @throws ChannelsLimitException if discord reached the channels limit. */ public void createChannel(@NotNull String clanTag) - throws InvalidChannelException, CategoriesLimitException, ChannelsLimitException, ChannelExistsException { + throws InvalidChannelException, CategoriesLimitException, ChannelsLimitException, ChannelExistsException + { + validateChannel(clanTag); Map discordClanPlayers = getDiscordPlayers(clanManager.getClan(clanTag)); if (getChannels().size() >= settingsManager.getInt(DISCORDCHAT_TEXT_LIMIT)) { + throw new ChannelsLimitException("Discord reached the channels limit", "discord.reached.channels.limit"); + } - Category availableCategory = getCachedCategories().stream(). - filter(category -> category.getTextChannels().size() < MAX_CHANNELS_PER_CATEGORY). - findAny().orElseGet(this::createCategory); + Category availableCategory = getCachedCategories().stream() + .filter(category -> category.getTextChannels().size() < MAX_CHANNELS_PER_CATEGORY).findAny() + .orElseGet(this::createCategory); if (availableCategory == null) { - throw new CategoriesLimitException("Discord reached the categories limit", "discord.reached.category.limit"); + + throw new CategoriesLimitException("Discord reached the categories limit", + "discord.reached.category.limit"); + } try { + availableCategory.createTextChannel(clanTag).complete(); - SimpleClans.debug(String.format("[%s] Creating a discord text channel for %s clan", Thread.currentThread().getId(), clanTag)); + SimpleClans.debug(String.format("[%s] Creating a discord text channel for %s clan", + Thread.currentThread().getId(), clanTag)); + } catch (ErrorResponseException ex) { + Response response = ex.getResponse(); - plugin.getLogger().warning(String.format("Could not create a channel for clan %s, error %d - %s", - clanTag, response.code, response.message)); + plugin.getLogger().warning(String.format("Could not create a channel for clan %s, error %d - %s", clanTag, + response.code, response.message)); return; + } for (Map.Entry entry : discordClanPlayers.entrySet()) { + // The map is formed from clan#getMembers (so the clan exists) - //noinspection ConstantConditions + // noinspection ConstantConditions updateViewPermission(entry.getValue(), entry.getKey().getClan(), ADD); updateLeaderRole(entry.getValue(), entry.getKey(), ADD); + } + } /** @@ -404,7 +501,10 @@ public class DiscordHook implements Listener { * @see #getCachedCategories() retreive categories. */ public Optional getCachedChannel(@NotNull String channelName) { - return getCachedChannels().stream().filter(textChannel -> textChannel.getName().equals(channelName)).findFirst(); + + return getCachedChannels().stream().filter(textChannel -> textChannel.getName().equals(channelName)) + .findFirst(); + } /** @@ -415,7 +515,9 @@ public class DiscordHook implements Listener { * @see #channelExists(String) */ public boolean categoryExists(String categoryId) { + return getGuild().getCategoryById(categoryId) != null; + } /** @@ -424,7 +526,9 @@ public class DiscordHook implements Listener { * @see #categoryExists(String) */ public boolean channelExists(String clanTag) { + return getChannel(clanTag).isPresent(); + } /** @@ -435,54 +539,70 @@ public class DiscordHook implements Listener { * @see #getCachedChannel(String) retreive the cached channel. */ public Optional getChannel(@NotNull String channelName) { + return getChannels().stream().filter(textChannel -> textChannel.getName().equals(channelName)).findAny(); + } /** - * Deletes channel from SimpleClans categories. - * If there are no channels, removes category as well. + * Deletes channel from SimpleClans categories. If there are no channels, + * removes category as well. * * @param channelName the channel name * @return true, if channel was deleted and false if not. */ @SuppressWarnings("UnusedReturnValue") public boolean deleteChannel(@NotNull String channelName) { + boolean deleted = false; if (channelExists(channelName)) { + for (Category category : getCachedCategories()) { + if (!category.getTextChannels().isEmpty()) { + for (TextChannel textChannel : category.getTextChannels()) { + if (textChannel.getName().equals(channelName)) { + textChannel.delete().complete(); deleted = true; break; + } + } if (category.getTextChannels().isEmpty()) { + textCategories.remove(category.getId()); settingsManager.set(DISCORDCHAT_TEXT_CATEGORY_IDS, textCategories); settingsManager.save(); category.delete().complete(); + } return deleted; + } + } + } return false; + } /** * @return categories from config */ public List getCachedCategories() { - return textCategories.stream(). - filter(this::categoryExists). - map(getGuild()::getCategoryById). - collect(Collectors.toList()); + + return textCategories.stream().filter(this::categoryExists).map(getGuild()::getCategoryById) + .collect(Collectors.toList()); + } /** @@ -491,7 +611,9 @@ public class DiscordHook implements Listener { * @return categories from guild */ public List getCategories() { + return getGuild().getCategoriesByName(settingsManager.getString(DISCORDCHAT_TEXT_CATEGORY_FORMAT), false); + } /** @@ -500,187 +622,283 @@ public class DiscordHook implements Listener { * @return all channels from guild */ public List getChannels() { - return getCategories().stream().map(Category::getTextChannels).flatMap(Collection::stream). - collect(Collectors.toList()); + + return getCategories().stream().map(Category::getTextChannels).flatMap(Collection::stream) + .collect(Collectors.toList()); + } /** * @return All channels in categories */ public List getCachedChannels() { - return getCachedCategories().stream().map(Category::getTextChannels).flatMap(Collection::stream). - collect(Collectors.toList()); + + return getCachedCategories().stream().map(Category::getTextChannels).flatMap(Collection::stream) + .collect(Collectors.toList()); + } @Nullable public Member getMember(@NotNull ClanPlayer clanPlayer) { + String discordId = accountManager.getDiscordId(clanPlayer.getUniqueId()); return DiscordUtil.getMemberById(discordId); + } private void clearChannels(Map discordTagChannels) { + // Removes abandoned channels ArrayList clansToDelete = new ArrayList<>(discordTagChannels.keySet()); clansToDelete.removeAll(clanTags); clansToDelete.forEach(clanChannel -> { + deleteChannel(clanChannel); discordTagChannels.remove(clanChannel); + }); // Removes invalid channels Iterator iterator = discordTagChannels.keySet().iterator(); while (iterator.hasNext()) { + String clanChannel = iterator.next(); try { + validateChannel(clanChannel); + } catch (InvalidChannelException ex) { + SimpleClans.debug(ex.getMessage()); deleteChannel(clanChannel); iterator.remove(); + } catch (ChannelExistsException | ChannelsLimitException ex) { + SimpleClans.debug(ex.getMessage()); + } + } + } private void resetPermissions(Map discordClanChannels) { + for (Map.Entry channelEntry : discordClanChannels.entrySet()) { + TextChannel channel = channelEntry.getValue(); Clan clan = clanManager.getClan(channelEntry.getKey()); Map discordPlayers = getDiscordPlayers(clan); for (Member member : discordPlayers.values()) { + PermissionOverride override = channel.getPermissionOverride(member); if (override != null) { + override.delete().queue(afterSuccess -> updateViewPermission(member, channel, ADD)); + } + } + } + } private void createChannels(Map discordClanChannels) { + if (!settingsManager.is(DISCORDCHAT_AUTO_CREATION)) { + return; + } // Removes already used discord channels from creation clanTags.removeAll(discordClanChannels.keySet()); for (String clan : clanTags) { + try { + createChannel(clan); + } catch (CategoriesLimitException | ChannelsLimitException ex) { + SimpleClans.debug(ex.getMessage()); break; + } catch (InvalidChannelException | ChannelExistsException ignored) { + // There is already debug on #clearChannels } + } + } @SuppressWarnings("ResultOfMethodCallIgnored") private void sendPrivateMessage(TextChannel textChannel, Message eventMessage, String message) { + RestAction privateChannelAction = eventMessage.getAuthor().openPrivateChannel(); - textChannel.deleteMessageById(eventMessage.getId()).queue(unused -> - privateChannelAction.flatMap(privateChannel -> privateChannel.sendMessage(message))); + textChannel.deleteMessageById(eventMessage.getId()) + .queue(unused -> privateChannelAction.flatMap(privateChannel -> privateChannel.sendMessage(message))); + } private void validateChannel(@NotNull String clanTag) - throws InvalidChannelException, ChannelExistsException, ChannelsLimitException { + throws InvalidChannelException, ChannelExistsException, ChannelsLimitException + { + Clan clan = clanManager.getClan(clanTag); if (clan == null) { + throw new InvalidChannelException(String.format("Clan %s is null", clanTag)); + } + if (!clan.isVerified() && !clan.isPermanent()) { + throw new InvalidChannelException(String.format("Clan %s is not verified or permanent", clanTag)); + } Map discordClanPlayers = getDiscordPlayers(clan); if (discordClanPlayers.isEmpty()) { + throw new InvalidChannelException(String.format("Clan %s doesn't have any linked players", clanTag), "your.clan.doesnt.have.any.linked.player"); + } if (discordClanPlayers.size() < settingsManager.getInt(DISCORDCHAT_MINIMUM_LINKED_PLAYERS)) { + throw new InvalidChannelException(String.format("Clan %s doesn't have minimum linked players", clanTag), "your.clan.doesnt.have.minimum.linked.player"); + } if (!whitelist.isEmpty() && !whitelist.contains(clan.getTag())) { + throw new InvalidChannelException(String.format("Clan %s is not listed on the whitelist", clanTag), "your.clan.is.not.on.the.whitelist"); + } if (channelExists(clanTag)) { + throw new ChannelExistsException(String.format("Channel %s is already exist", clanTag), "your.clan.already.has.channel"); + } + } @NotNull private Map getDiscordPlayers(@NotNull Clan clan) { + Map discordClanPlayers = new HashMap<>(); for (ClanPlayer cp : clan.getMembers()) { + Member member = getMember(cp); if (member != null) { + discordClanPlayers.put(cp, member); + } + } + return discordClanPlayers; + } private void updateLeaderRole(@NotNull Member member, @NotNull ClanPlayer clanPlayer, DiscordAction action) { + if (action == ADD && clanPlayer.isLeader()) { + getGuild().addRoleToMember(member, getLeaderRole()).queue(); - SimpleClans.debug(String.format("Added leader role to %s (%s) discord member", member.getNickname(), member.getId())); + SimpleClans.debug( + String.format("Added leader role to %s (%s) discord member", member.getNickname(), member.getId())); + } else { + getGuild().removeRoleFromMember(member, getLeaderRole()).queue(); - SimpleClans.debug(String.format("Revoked leader role from %s (%s) discord member", member.getNickname(), member.getId())); + SimpleClans.debug(String.format("Revoked leader role from %s (%s) discord member", member.getNickname(), + member.getId())); + } + } - private void updateViewPermission(@Nullable Member member, @NotNull GuildChannel channel, @NotNull DiscordAction action) { + private void updateViewPermission(@Nullable Member member, @NotNull GuildChannel channel, + @NotNull DiscordAction action) + { + if (member == null) { + return; + } if (action == ADD) { - channel.upsertPermissionOverride(member). - setPermissions(Collections.singletonList(VIEW_CHANNEL), Collections.emptyList()).queue(); - SimpleClans.debug(String.format("Added view permission to %s (%s) discord member", member.getNickname(), member.getId())); + + channel.upsertPermissionOverride(member) + .setPermissions(Collections.singletonList(VIEW_CHANNEL), Collections.emptyList()).queue(); + SimpleClans.debug(String.format("Added view permission to %s (%s) discord member", member.getNickname(), + member.getId())); + } else { + channel.getManager().removePermissionOverride(member).queue(); - SimpleClans.debug(String.format("Revoked view permission from %s (%s) discord member", member.getNickname(), member.getId())); + SimpleClans.debug(String.format("Revoked view permission from %s (%s) discord member", member.getNickname(), + member.getId())); + } + } private void updateViewPermission(@NotNull Member member, @NotNull Clan clan, DiscordAction action) { + String tag = clan.getTag(); Optional channel = getChannel(tag); if (channel.isPresent()) { + TextChannel textChannel = channel.get(); updateViewPermission(member, textChannel, action); + } + } @SuppressWarnings("BooleanMethodIsAlwaysInverted") private boolean createChannelSilently(ClanPlayer clanPlayer) { + Clan clan = clanPlayer.getClan(); if (clan == null || !settingsManager.is(DISCORDCHAT_AUTO_CREATION)) { + return false; + } try { + createChannel(clan.getTag()); + } catch (DiscordHookException ex) { - // Clan is not following the conditions, categories are fulled or discord reaches the limit, nothing to do here. + + // Clan is not following the conditions, categories are fulled or discord + // reaches the limit, nothing to do here. SimpleClans.debug(ex.getMessage()); + } return true; + } enum DiscordAction { ADD, REMOVE } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/CategoriesLimitException.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/CategoriesLimitException.java index b1c32f56..24b327ab 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/CategoriesLimitException.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/CategoriesLimitException.java @@ -1,8 +1,11 @@ package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions; public class CategoriesLimitException extends DiscordHookException { - + public CategoriesLimitException(String debugMessage, String messageKey) { + super(debugMessage, messageKey); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelExistsException.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelExistsException.java index 3fd579fb..b7abd1d2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelExistsException.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelExistsException.java @@ -3,6 +3,9 @@ package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions; public class ChannelExistsException extends DiscordHookException { public ChannelExistsException(String debugMessage, String messageKey) { + super(debugMessage, messageKey); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelsLimitException.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelsLimitException.java index d72601d5..3032b7ab 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelsLimitException.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/ChannelsLimitException.java @@ -3,6 +3,9 @@ package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions; public class ChannelsLimitException extends DiscordHookException { public ChannelsLimitException(String debugMessage, String messageKey) { + super(debugMessage, messageKey); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/DiscordHookException.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/DiscordHookException.java index f69e0cd6..16384d90 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/DiscordHookException.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/DiscordHookException.java @@ -15,18 +15,25 @@ public class DiscordHookException extends Exception { private String messageKey; public DiscordHookException(String debugMessage) { + super(debugMessage); + } public DiscordHookException(String debugMessage, String messageKey) { + super(debugMessage); this.messageKey = messageKey; + } /** * @return message key or null if this key is not used in-game */ public @Nullable String getMessageKey() { + return messageKey; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/InvalidChannelException.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/InvalidChannelException.java index 3850bbe3..6212d8cd 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/InvalidChannelException.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/discord/exceptions/InvalidChannelException.java @@ -3,10 +3,15 @@ package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions; public class InvalidChannelException extends DiscordHookException { public InvalidChannelException(String debugMessage, String messageKey) { + super(debugMessage, messageKey); + } public InvalidChannelException(String debugMessage) { + super(debugMessage); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/Placeholder.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/Placeholder.java index 925e19e3..d3f659e1 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/Placeholder.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/Placeholder.java @@ -8,6 +8,9 @@ import java.lang.annotation.*; public @interface Placeholder { String value(); + String resolver() default "method_return"; + String config() default ""; + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/PlaceholderResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/PlaceholderResolver.java index e8481239..d32f432f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/PlaceholderResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/PlaceholderResolver.java @@ -17,7 +17,9 @@ public abstract class PlaceholderResolver { protected final SimpleClans plugin; public PlaceholderResolver(@NotNull SimpleClans plugin) { + this.plugin = plugin; + } @NotNull @@ -27,7 +29,8 @@ public abstract class PlaceholderResolver { * Resolves the placeholder and returns its value * * @param player the player involved in the placeholder request - * @param object the subject of the Placeholder, usually a {@link Clan} or a {@link ClanPlayer} + * @param object the subject of the Placeholder, usually a {@link Clan} or + * a {@link ClanPlayer} * @param method the annotated method * @param placeholder the placeholder to resolve * @param config configuration for the resolver @@ -36,15 +39,23 @@ public abstract class PlaceholderResolver { */ @NotNull public abstract String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config); + @NotNull String placeholder, @NotNull Map config); @Nullable protected Object invoke(@NotNull Object object, @NotNull Method method, @NotNull String placeholder) { + try { + return method.invoke(object); + } catch (IllegalAccessException | InvocationTargetException e) { + plugin.getLogger().log(Level.SEVERE, String.format("Error parsing placeholder %s", placeholder), e); + } + return ""; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/SimpleClansExpansion.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/SimpleClansExpansion.java index 69fbf2cf..891624ef 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/SimpleClansExpansion.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/SimpleClansExpansion.java @@ -31,54 +31,73 @@ public class SimpleClansExpansion extends PlaceholderExpansion implements Relati private final ClanManager clanManager; public SimpleClansExpansion(SimpleClans plugin) { + this.plugin = plugin; clanManager = plugin.getClanManager(); registerResolvers(); + } @Override public @NotNull String getName() { + return plugin.getName(); + } @Override public @NotNull String getIdentifier() { + return getName().toLowerCase(); + } @Override public @NotNull String getAuthor() { + return plugin.getDescription().getAuthors().toString(); + } @Override public @NotNull String getVersion() { + return plugin.getDescription().getVersion(); + } @Override public boolean persist() { + return true; + } @Override public @NotNull List getPlaceholders() { + if (placeholders == null) { + this.placeholders = new ArrayList<>(); addPlaceholders("simpleclans_", ClanPlayer.class, placeholders); addPlaceholders("simpleclans_clan_", Clan.class, placeholders); + } + return placeholders; + } @Override public boolean canRegister() { - return true; - } + return true; + + } @Override public Map getDefaults() { + Map defaults = new HashMap<>(); defaults.put("color.rival", "&c"); @@ -86,144 +105,230 @@ public class SimpleClansExpansion extends PlaceholderExpansion implements Relati defaults.put("color.same_clan", "&a"); return defaults; + } @Override @Nullable public String onPlaceholderRequest(Player player1, Player player2, String params) { + if (player1 == null || player2 == null) { + return null; + } + if (params.equalsIgnoreCase("color")) { + ClanPlayer cp1 = clanManager.getClanPlayer(player1); if (cp1 == null) { + return ""; + } - //noinspection ConstantConditions -- getClanPlayer != null == getClan() != null + + // noinspection ConstantConditions -- getClanPlayer != null == getClan() != null if (cp1.getClan().isMember(player2)) { + return getString("color.same_clan", null); + } + if (cp1.isRival(player2)) { + return getString("color.rival", null); + } + if (cp1.isAlly(player2)) { + return getString("color.ally", null); + } + return ""; + } + return null; + } @Override public String onRequest(@Nullable OfflinePlayer player, @NotNull String params) { + ClanPlayer cp = null; if (player != null) { + cp = clanManager.getAnyClanPlayer(player.getUniqueId()); + } + if (cp == null) { + return ""; + } + Clan clan = cp.getClan(); Matcher matcher = TOP_CLANS_PATTERN.matcher(params); if (matcher.find()) { + int position = Integer.parseInt(matcher.group("position")); clan = getFromPosition(clanManager.getClans(), position, clanManager::sortClansByKDR); params = params.replace(matcher.group("strip"), ""); + } + matcher = TOP_PLAYERS_PATTERN.matcher(params); if (matcher.find()) { + int position = Integer.parseInt(matcher.group("position")); cp = getFromPosition(clanManager.getAllClanPlayers(), position, clanManager::sortClanPlayersByKDR); params = params.replace(matcher.group("strip"), ""); + } + return getValue(player, cp, clan, params); + } @Nullable private T getFromPosition(List list, int position, Consumer> sort) { + if (isPositionValid(list, position)) { + sort.accept(list); return list.get(position - 1); + } + return null; + } private boolean isPositionValid(@NotNull Collection collection, int position) { + return position >= 1 && position <= collection.size(); + } @NotNull private String getValue(@Nullable OfflinePlayer player, @Nullable ClanPlayer cp, @Nullable Clan clan, - @NotNull String placeholder) { + @NotNull String placeholder) + { + if (placeholder.startsWith("clan_")) { + placeholder = placeholder.replace("clan_", ""); return getValue(player, clan, placeholder); + } + return getValue(player, cp, placeholder); + } @NotNull private String getValue(@Nullable OfflinePlayer player, @Nullable Object object, @NotNull String placeholder) { + if (object != null) { + for (Method declaredMethod : object.getClass().getDeclaredMethods()) { + Placeholder[] annotations = declaredMethod.getAnnotationsByType(Placeholder.class); for (Placeholder p : annotations) { + if (p.value().equals(placeholder)) { + return resolve(player, object, declaredMethod, p.resolver(), placeholder, p.config()); + } + } + } + plugin.getLogger().warning(String.format("Placeholder %s not found", placeholder)); + } + return ""; + } private String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String resolverId, @NotNull String placeholder, @NotNull String config) { + @NotNull String resolverId, @NotNull String placeholder, @NotNull String config) + { + PlaceholderResolver resolver = RESOLVERS.get(resolverId); if (resolver != null) { + return resolver.resolve(player, object, method, placeholder, getConfigMap(config)); + } + plugin.getLogger().warning(String.format("Resolver %s for %s not found", resolverId, placeholder)); return ""; + } @NotNull private Map getConfigMap(@NotNull String config) { + HashMap map = new HashMap<>(); String[] elements = config.split(","); for (String element : elements) { + String[] keyAndValue = element.split(":"); map.put(keyAndValue[0], keyAndValue.length > 1 ? keyAndValue[1] : null); + } + return map; + } private void registerResolvers() { - Set> resolvers = - Helper.getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.hooks.papi.resolvers", - PlaceholderResolver.class); + + Set> resolvers = Helper + .getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.hooks.papi.resolvers", PlaceholderResolver.class); plugin.getLogger().info(String.format("Registering %d placeholder resolvers...", resolvers.size())); for (Class r : resolvers) { + try { + PlaceholderResolver resolver = r.getConstructor(SimpleClans.class).newInstance(plugin); RESOLVERS.put(resolver.getId(), resolver); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | - NoSuchMethodException e) { + + } catch (InstantiationException | IllegalAccessException | InvocationTargetException + | NoSuchMethodException e) + { + plugin.getLogger().log(Level.SEVERE, "Error registering placeholder resolver", e); + } + } + } private void addPlaceholders(String prefix, Class clazz, List placeholders) { + for (Method method : clazz.getDeclaredMethods()) { + Placeholder[] annotations = method.getAnnotationsByType(Placeholder.class); for (Placeholder annotation : annotations) { + placeholders.add("%" + prefix + annotation.value() + "%"); - //Commented because the list would be very long - //placeholders.add("%simpleclans_topplayers__" + annotation.value() + "%"); + + // Commented because the list would be very long + // placeholders.add("%simpleclans_topplayers__" + annotation.value() + + // "%"); } + } + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/KdrResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/KdrResolver.java index 95e5c7fc..96e3cc38 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/KdrResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/KdrResolver.java @@ -12,22 +12,34 @@ import java.util.Map; @SuppressWarnings("unused") public class KdrResolver extends PlaceholderResolver { + public KdrResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "kdr"; + } @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + Object result = invoke(object, method, placeholder); if (result instanceof Number) { + return KDRFormat.format(((Number) result).floatValue()); + } + return ""; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/ListSizeResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/ListSizeResolver.java index f7370305..a441a653 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/ListSizeResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/ListSizeResolver.java @@ -14,28 +14,42 @@ import java.util.Map; @SuppressWarnings("unused") public class ListSizeResolver extends PlaceholderResolver { + public ListSizeResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "list_size"; + } @SuppressWarnings("unchecked") @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + Object result = invoke(object, method, placeholder); String size = ""; if (result instanceof List) { + size = String.valueOf(((List) result).size()); if (config.containsKey("filter_vanished")) { - size = String.valueOf(VanishUtils.getNonVanished(player != null ? player.getPlayer() : null, - (List) result).size()); + + size = String.valueOf(VanishUtils + .getNonVanished(player != null ? player.getPlayer() : null, (List) result).size()); + } + } + return size; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MemberStatusResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MemberStatusResolver.java index cd8ecfbf..28b620f0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MemberStatusResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MemberStatusResolver.java @@ -15,28 +15,45 @@ import static me.clip.placeholderapi.PlaceholderAPIPlugin.booleanTrue; @SuppressWarnings("unused") public class MemberStatusResolver extends PlaceholderResolver { + public MemberStatusResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "member_status"; + } @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + boolean result = false; if (object instanceof ClanPlayer) { + ClanPlayer cp = (ClanPlayer) object; if (placeholder.equals("is_member")) { + result = cp.getClan() != null && !cp.isTrusted(); + } + if (placeholder.equals("is_trusted")) { + result = cp.getClan() != null && !cp.isLeader() && cp.isTrusted(); + } + } + return result ? booleanTrue() : booleanFalse(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MethodReturnResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MethodReturnResolver.java index 0406ebdd..1ce7aea0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MethodReturnResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/MethodReturnResolver.java @@ -14,24 +14,38 @@ import java.util.Map; public class MethodReturnResolver extends PlaceholderResolver { public MethodReturnResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "method_return"; + } @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + Object result = invoke(object, method, placeholder); if (result == null) { + return ""; + } + if (result instanceof Boolean) { + return ((Boolean) result) ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse(); + } + return String.valueOf(result); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/NotNullReturnResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/NotNullReturnResolver.java index e6c62053..6bf2df11 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/NotNullReturnResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/NotNullReturnResolver.java @@ -14,18 +14,27 @@ import static me.clip.placeholderapi.PlaceholderAPIPlugin.booleanTrue; @SuppressWarnings("unused") public class NotNullReturnResolver extends PlaceholderResolver { + public NotNullReturnResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "not_null_return"; + } @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + return invoke(object, method, placeholder) != null ? booleanTrue() : booleanFalse(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/PlayerColorResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/PlayerColorResolver.java index 480390fa..2b8fdfbd 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/PlayerColorResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/PlayerColorResolver.java @@ -19,54 +19,92 @@ public class PlayerColorResolver extends PlaceholderResolver { private final SettingsManager settings; public PlayerColorResolver(@NotNull SimpleClans plugin) { + super(plugin); settings = plugin.getSettingsManager(); + } @Override public @NotNull String getId() { + return "player_color"; + } @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + ClanPlayer cp = object instanceof ClanPlayer ? ((ClanPlayer) object) : null; - if (cp == null) return ""; + if (cp == null) + return ""; switch (placeholder) { + case "clanchat_player_color": { + return getClanChatColor(cp); + } case "allychat_player_color": { + return getAllyChatColor(cp); + } + } + return ""; + } private String getClanChatColor(ClanPlayer player) { + if (player.isLeader()) { + return settings.getColored(CLANCHAT_LEADER_COLOR); + } + if (player.isTrusted()) { + return settings.getColored(CLANCHAT_TRUSTED_COLOR); + } + if (player.getClan() != null) { + return settings.getColored(CLANCHAT_MEMBER_COLOR); + } + return ""; + } private String getAllyChatColor(ClanPlayer player) { + if (player.isLeader()) { + return settings.getColored(ALLYCHAT_LEADER_COLOR); + } + if (player.isTrusted()) { + return settings.getColored(ALLYCHAT_TRUSTED_COLOR); + } + if (player.getClan() != null) { + return settings.getColored(ALLYCHAT_MEMBER_COLOR); + } + return ""; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/RankingPositionResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/RankingPositionResolver.java index 0a4fdafb..3bc4fff3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/RankingPositionResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/papi/resolvers/RankingPositionResolver.java @@ -13,31 +13,45 @@ import java.util.List; import java.util.Map; public class RankingPositionResolver extends PlaceholderResolver { + public RankingPositionResolver(@NotNull SimpleClans plugin) { + super(plugin); + } @Override public @NotNull String getId() { + return "ranking_position"; + } @Override public @NotNull String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method, - @NotNull String placeholder, @NotNull Map config) { + @NotNull String placeholder, @NotNull Map config) + { + if (object instanceof Clan) { + List clans = plugin.getClanManager().getClans(); plugin.getClanManager().sortClansByKDR(clans); return String.valueOf(clans.indexOf(object) + 1); + } + if (object instanceof ClanPlayer) { + List clanPlayers = plugin.getClanManager().getAllClanPlayers(); plugin.getClanManager().sortClanPlayersByKDR(clanPlayers); return String.valueOf(clanPlayers.indexOf(object) + 1); + } return ""; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Coordinate.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Coordinate.java index 2cd130c5..7d6ddedb 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Coordinate.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Coordinate.java @@ -9,35 +9,49 @@ public class Coordinate { private final double x; private final double z; - public Coordinate(double x, double z) { + this.x = x; this.z = z; + } public Coordinate(Location location) { + this.x = location.getX(); this.z = location.getZ(); + } public double getX() { + return x; + } public double getZ() { + return z; + } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; Coordinate that = (Coordinate) o; return Double.compare(that.getX(), getX()) == 0 && Double.compare(that.getZ(), getZ()) == 0; + } @Override public int hashCode() { + return Objects.hash(getX(), getZ()); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Land.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Land.java index 57675e38..f369da65 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Land.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/Land.java @@ -11,39 +11,56 @@ public class Land { private final List coordinates; public Land(@NotNull String id, @NotNull Set owners) { + this(id, owners, Collections.emptyList()); + } public Land(@NotNull String id, @NotNull Set owners, @NotNull List coordinates) { + this.id = id; this.owners = owners; this.coordinates = coordinates; + } @NotNull public String getId() { + return id; + } @NotNull public Set getOwners() { + return owners; + } public @NotNull List getCoordinates() { + return coordinates; + } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; Land land = (Land) o; return id.equals(land.id); + } @Override public int hashCode() { + return Objects.hash(id); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/ProtectionProvider.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/ProtectionProvider.java index fdbf9ae9..f910affd 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/ProtectionProvider.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/ProtectionProvider.java @@ -14,7 +14,9 @@ import java.util.Set; public interface ProtectionProvider { default void register() { + SimpleClans.getInstance().getProtectionManager().registerProvider(this); + } void setup() throws LinkageError, Exception; @@ -30,11 +32,13 @@ public interface ProtectionProvider { void deleteLand(@NotNull String id, @NotNull World world); - @Nullable Class getCreateLandEvent(); + @Nullable + Class getCreateLandEvent(); @Nullable Player getPlayer(Event event); @Nullable String getRequiredPluginName(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/GriefPreventionProvider.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/GriefPreventionProvider.java index 2c38214e..7d7d8906 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/GriefPreventionProvider.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/GriefPreventionProvider.java @@ -31,107 +31,167 @@ public class GriefPreventionProvider implements ProtectionProvider, Listener { @Override public void setup() { + Bukkit.getPluginManager().registerEvents(this, SimpleClans.getInstance()); + } @Override public @NotNull Set getLandsAt(@NotNull Location location) { + Claim claim = GriefPrevention.instance.dataStore.getClaimAt(location, true, null); if (claim == null) { + return Collections.emptySet(); + } + return Collections.singleton(getLand(claim)); + } @Override public @NotNull Set getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) { + HashSet lands = new HashSet<>(); for (Claim claim : GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()).getClaims()) { + if (claim == null) { + continue; + } + lands.add(getLand(claim)); + } + return lands; + } @Override public @NotNull String getIdPrefix() { + return "gp"; + } @Override public void deleteLand(@NotNull String id, @NotNull World world) { + DataStore dataStore = GriefPrevention.instance.dataStore; Claim claim = dataStore.getClaim(Long.parseLong(id.replaceFirst(getIdPrefix(), ""))); if (claim != null) { + dataStore.deleteClaim(claim); + } + } @Override public @Nullable Class getCreateLandEvent() { + try { + return ClaimCreatedEvent.class; + } catch (NoClassDefFoundError error) { + return null; + } + } @Override public @Nullable Player getPlayer(Event event) { + if (event instanceof ClaimCreatedEvent) { + if (((ClaimCreatedEvent) event).getCreator() instanceof Player) { + return ((Player) ((ClaimCreatedEvent) event).getCreator()); + } + } + return null; + } @Override public @Nullable String getRequiredPluginName() { + return "GriefPrevention"; + } @Nullable private Land getLand(@Nullable Claim claim) { + if (claim == null) { + return null; + } + List coords = Arrays.asList(new Coordinate(claim.getLesserBoundaryCorner()), new Coordinate(claim.getGreaterBoundaryCorner())); return new Land(getIdPrefix() + claim.getID().toString(), Collections.singleton(getOwnerID(claim)), coords); + } @SuppressWarnings("deprecation") @NotNull private UUID getOwnerID(@NotNull Claim claim) { + try { + return claim.getOwnerID(); + } catch (NoSuchMethodError error) { + return Bukkit.getOfflinePlayer(claim.getOwnerName()).getUniqueId(); + } + } @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) private void onResize(ClaimResizeEvent event) { + ClanManager clanManager = SimpleClans.getInstance().getClanManager(); Land originalLand = getLand(event.getFrom()); Land newLand = getLand(event.getTo()); if (originalLand == null || newLand == null) { + return; + } + for (UUID owner : originalLand.getOwners()) { + ClanPlayer cp = clanManager.getAnyClanPlayer(owner); - if (cp == null) continue; + if (cp == null) + continue; for (ProtectionManager.Action action : ProtectionManager.Action.values()) { + if (cp.isAllowed(action, originalLand.getId())) { + cp.disallow(action, originalLand.getId()); cp.allow(action, newLand.getId()); + } + } + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/Landlord4Provider.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/Landlord4Provider.java deleted file mode 100644 index 65b01ea8..00000000 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/Landlord4Provider.java +++ /dev/null @@ -1,91 +0,0 @@ -package net.sacredlabyrinth.phaed.simpleclans.hooks.protection.providers; - -import biz.princeps.landlord.api.ILandLord; -import biz.princeps.landlord.api.IOwnedLand; -import biz.princeps.landlord.api.events.LandPreClaimEvent; -import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land; -import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.OfflinePlayer; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -@SuppressWarnings("unused") -public class Landlord4Provider implements ProtectionProvider { - - private ILandLord landlord; - - @Override - public void setup() throws LinkageError, Exception { - //noinspection ConstantConditions - landlord = (ILandLord) Bukkit.getPluginManager().getPlugin("Landlord"); - } - - @Override - public @NotNull Set getLandsAt(@NotNull Location location) { - IOwnedLand ownedLand = landlord.getWGManager().getRegion(location); - if (ownedLand == null) { - return Collections.emptySet(); - } - HashSet lands = new HashSet<>(); - lands.add(getLand(ownedLand)); - return lands; - } - - @Override - public @NotNull Set getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) { - HashSet lands = new HashSet<>(); - Set ownedLands = landlord.getWGManager().getRegions(player.getUniqueId(), world); - for (IOwnedLand ownedLand : ownedLands) { - lands.add(getLand(ownedLand)); - } - return lands; - } - - @Override - public @NotNull String getIdPrefix() { - return "ll"; - } - - @Override - public void deleteLand(@NotNull String id, @NotNull World world) { - id = id.replace(getIdPrefix(), ""); - - landlord.getWGManager().unclaim(world, id); - } - - @Override - public @Nullable Class getCreateLandEvent() { - return LandPreClaimEvent.class; - } - - @Override - public @Nullable Player getPlayer(Event event) { - if (!(event instanceof LandPreClaimEvent)) { - return null; - } - return ((LandPreClaimEvent) event).getPlayer(); - } - - @Override - public @Nullable String getRequiredPluginName() { - return "Landlord"; - } - - private @NotNull Land getLand(@NotNull IOwnedLand ownedLand) { - String id = getIdPrefix() + ownedLand.getName(); - HashSet owners = new HashSet<>(); - owners.add(ownedLand.getOwner()); - - return new Land(id, owners); - } -} diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/WorldGuard6Provider.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/WorldGuard6Provider.java index b87bbc75..705e0c1d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/WorldGuard6Provider.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/hooks/protection/providers/WorldGuard6Provider.java @@ -32,6 +32,7 @@ public class WorldGuard6Provider implements ProtectionProvider { @SuppressWarnings("JavaReflectionMemberAccess") @Override public void setup() throws NoSuchMethodException, ClassNotFoundException { + worldGuard = WorldGuardPlugin.inst(); getRegionManager = worldGuard.getClass().getMethod("getRegionManager", World.class); getApplicableRegions = RegionManager.class.getMethod("getApplicableRegions", Location.class); @@ -39,104 +40,160 @@ public class WorldGuard6Provider implements ProtectionProvider { Class blockVector = Class.forName("com.sk89q.worldedit.BlockVector2"); getX = blockVector.getMethod("getX"); getZ = blockVector.getMethod("getZ"); + } private @Nullable RegionManager getRegionManager(@Nullable World world) { + if (world != null) { + try { + return (RegionManager) getRegionManager.invoke(worldGuard, world); + } catch (IllegalAccessException | InvocationTargetException ignored) { + } + } + return null; + } private Set getApplicableRegions(RegionManager regionManager, Location location) { + try { + return ((ApplicableRegionSet) getApplicableRegions.invoke(regionManager, location)).getRegions(); + } catch (IllegalAccessException | InvocationTargetException e) { + return Collections.emptySet(); + } + } @NotNull private Land getLand(ProtectedRegion region) { + List coordinates = getCoordinates(region); return new Land(getIdPrefix() + region.getId(), region.getOwners().getUniqueIds(), coordinates); + } @NotNull private List getCoordinates(ProtectedRegion region) { + List coordinates = new ArrayList<>(); try { + List points = (List) getPoints.invoke(region); for (Object point : points) { + double x = (double) getX.invoke(point); double z = (double) getZ.invoke(point); coordinates.add(new Coordinate(x, z)); + } + } catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + } + return coordinates; + } @Override public @NotNull Set getLandsAt(@NotNull Location location) { + HashSet lands = new HashSet<>(); RegionManager regionManager = getRegionManager(location.getWorld()); if (regionManager != null) { + for (ProtectedRegion region : getApplicableRegions(regionManager, location)) { + lands.add(getLand(region)); + } + } + return lands; + } @Override public @NotNull Set getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) { + HashSet lands = new HashSet<>(); RegionManager regionManager = getRegionManager(world); if (regionManager != null) { + for (ProtectedRegion region : regionManager.getRegions().values()) { + if (!region.getOwners().getUniqueIds().contains(player.getUniqueId())) { + continue; + } + lands.add(getLand(region)); + } + } + return lands; + } @Override public @NotNull String getIdPrefix() { + return "wg"; + } @Override public void deleteLand(@NotNull String id, @NotNull World world) { + id = id.replaceFirst(getIdPrefix(), ""); RegionManager regionManager = getRegionManager(world); if (regionManager != null) { + regionManager.removeRegion(id); + } + } @Override public @Nullable Class getCreateLandEvent() { + return null; + } @Override public @Nullable Player getPlayer(Event event) { + return null; + } @Override public @Nullable String getRequiredPluginName() { + return "WorldGuard"; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/language/LanguageResource.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/language/LanguageResource.java index ce792831..1398c83e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/language/LanguageResource.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/language/LanguageResource.java @@ -19,166 +19,249 @@ import java.util.function.Predicate; */ public class LanguageResource { - private static final ResourceLoader DATA_FOLDER_LOADER = new ResourceLoader(SimpleClans.getInstance().getDataFolder()); + private static final ResourceLoader DATA_FOLDER_LOADER = new ResourceLoader( + SimpleClans.getInstance().getDataFolder()); private final Locale defaultLocale; private static List availableLocales; private static final Map TRANSLATION_STATUS = new HashMap<>(); public LanguageResource() { + this.defaultLocale = SimpleClans.getInstance().getSettingsManager().getLanguage(); + } @Nullable public String getLang(@NotNull String key, @NotNull Locale locale) { + if (!key.startsWith("acf-core.parameter.") && key.startsWith("acf")) { + return getACFLang(key, locale); + } + try { + ResourceBundle bundle = ResourceBundle.getBundle("messages", locale, DATA_FOLDER_LOADER, new ResourceControl(defaultLocale, false)); return bundle.getString(key); + } catch (MissingResourceException ignored) { + } + if (locale.equals(Locale.ENGLISH)) { + // English is the root messages.properties inside the jar locale = Locale.ROOT; + } + try { + ResourceBundle bundle = ResourceBundle.getBundle("messages", locale, SimpleClans.getInstance().getClass().getClassLoader(), new ResourceControl(defaultLocale)); return bundle.getString(key); + } catch (MissingResourceException ignored) { + } return null; + } @Nullable private String getACFMinecraftLang(@NotNull String key, @NotNull Locale locale) { + try { + ResourceBundle bundle = ResourceBundle.getBundle("acf-minecraft", locale, DATA_FOLDER_LOADER, new ResourceControl(defaultLocale, false)); return bundle.getString(key); + } catch (MissingResourceException ignored) { + } try { + ResourceBundle bundle = ResourceBundle.getBundle("acf-minecraft", locale, SimpleClans.getInstance().getClass().getClassLoader(), new ResourceControl(defaultLocale)); return bundle.getString(key); + } catch (MissingResourceException ignored) { + } return null; + } @Nullable private String getACFLang(@NotNull String key, @NotNull Locale locale) { + if (key.startsWith("acf-minecraft")) { + return getACFMinecraftLang(key, locale); + } + try { + ResourceBundle bundle = ResourceBundle.getBundle("acf-core", locale, DATA_FOLDER_LOADER, new ResourceControl(defaultLocale, false)); return bundle.getString(key); + } catch (MissingResourceException ignored) { + } try { + ResourceBundle bundle = ResourceBundle.getBundle("acf-core", locale, SimpleClans.getInstance().getClass().getClassLoader(), new ResourceControl(defaultLocale)); return bundle.getString(key); + } catch (MissingResourceException ignored) { + } return null; + } public static int getTranslationStatus(@NotNull Locale locale) { + if (locale.equals(Locale.ENGLISH)) { + return 100; + } + Integer lines = TRANSLATION_STATUS.get(locale); Integer englishLines = TRANSLATION_STATUS.get(Locale.ENGLISH); if (lines == null || englishLines == null) { + return -1; + } return Math.round((lines / englishLines.floatValue()) * 100); + } public static void clearCache() { + ResourceBundle.clearCache(DATA_FOLDER_LOADER); + } public static List getAvailableLocales() { + if (availableLocales != null) { + return availableLocales; + } + loadAvailableLocales(); return availableLocales; + } private static void loadAvailableLocales() { + ArrayList locales = new ArrayList<>(); Predicate filter = entry -> { + String path = (entry.getFileName() != null) ? entry.getFileName().toString() : ""; return path.startsWith("messages") && path.endsWith(".properties"); + }; for (Path filePath : Helper.getPathsIn("/", filter)) { + String fileName = filePath.getFileName().toString(); Locale locale = getLocaleByFileName(fileName); locales.add(locale); loadTranslationStatus(locale, fileName); + } locales.sort(Comparator.comparing(Locale::toLanguageTag)); availableLocales = locales; + } private static @NotNull Locale getLocaleByFileName(@NotNull String name) { + Locale locale; if (name.equalsIgnoreCase("messages.properties")) { + locale = Locale.ENGLISH; + } else { + String[] extensionSplit = name.split(".properties"); String[] split = extensionSplit[0].split("_"); if (split.length == 2) { + locale = new Locale(split[1]); + } else { + locale = new Locale(split[1], split[2]); + } + } + return locale; + } private static void loadTranslationStatus(@NotNull Locale locale, @NotNull String fileName) { + InputStream stream = SimpleClans.getInstance().getClass().getResourceAsStream("/" + fileName); - if (stream == null) return; + if (stream == null) + return; BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); int lineCount = 0; try { + while (true) { + String line = reader.readLine(); if (line == null) { + break; + } + if (!line.startsWith("#")) { + lineCount++; + } + } + } catch (IOException ex) { + lineCount = -1; + } + TRANSLATION_STATUS.put(locale, lineCount); + } static class ResourceLoader extends ClassLoader { @@ -186,21 +269,31 @@ public class LanguageResource { private final File dataFolder; public ResourceLoader(File dataFolder) { + this.dataFolder = dataFolder; + } @Override public URL getResource(String name) { + File file = new File(dataFolder, name); if (file.exists()) { + try { + return file.toURI().toURL(); + } catch (MalformedURLException ignored) { + } + } return null; + } + } static class ResourceControl extends ResourceBundle.Control { @@ -209,40 +302,58 @@ public class LanguageResource { private final boolean defaultAsFallback; public ResourceControl(@NotNull Locale defaultLocale) { + this.defaultLocale = defaultLocale; this.defaultAsFallback = true; + } public ResourceControl(@NotNull Locale defaultLocale, boolean defaultAsFallback) { + this.defaultLocale = defaultLocale; this.defaultAsFallback = defaultAsFallback; + } @Override public List getFormats(String baseName) { + if (baseName == null) { + throw new NullPointerException(); + } return Collections.singletonList("java.properties"); + } @Override public List getCandidateLocales(String baseName, Locale locale) { + List candidateLocales = new ArrayList<>(super.getCandidateLocales(baseName, locale)); if (!defaultAsFallback && candidateLocales.size() != 1) { + candidateLocales.remove(Locale.ROOT); + } + if (baseName.startsWith("acf") && !candidateLocales.contains(Locale.ENGLISH) && defaultAsFallback) { + candidateLocales.add(Locale.ENGLISH); + } + return candidateLocales; + } @Override @Nullable public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, - boolean reload) throws IOException { + boolean reload) throws IOException + { + String bundleName = toBundleName(baseName, locale); ResourceBundle bundle; @@ -252,40 +363,59 @@ public class LanguageResource { URL url = loader.getResource(resourceName); if (url == null) { + return null; + } URLConnection connection = url.openConnection(); if (reload) { + connection.setUseCaches(false); + } InputStreamReader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8); bundle = new PropertyResourceBundle(reader); reader.close(); + } else { + throw new IllegalArgumentException("unknown format: " + format); + } return bundle; - } + } @Override @Nullable public Locale getFallbackLocale(String baseName, Locale locale) { + if (!defaultAsFallback) { + return null; + } + Locale root = baseName.startsWith("acf") ? Locale.ENGLISH : Locale.ROOT; if (!locale.equals(defaultLocale) && !locale.equals(root)) { + return defaultLocale; + } + if (locale.equals(defaultLocale) && !defaultLocale.equals(root)) { + return root; + } return null; + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/Events.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/Events.java index 6d2965ca..feb71bc3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/Events.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/Events.java @@ -12,36 +12,51 @@ import org.jetbrains.annotations.Nullable; public final class Events { private Events() { + // Can't instantiate this class } @Nullable @Contract("null -> null") public static Player getAttacker(@Nullable EntityDamageEvent parentEvent) { + if (parentEvent instanceof EntityDamageByEntityEvent) { + EntityDamageByEntityEvent sub = (EntityDamageByEntityEvent) parentEvent; Entity damager = sub.getDamager(); if (damager instanceof Player) { + return (Player) damager; + } if (damager instanceof Projectile) { + Projectile projectile = (Projectile) damager; if (projectile.getShooter() instanceof Player) { + return (Player) projectile.getShooter(); + } + } if (damager instanceof TNTPrimed) { + Entity source = ((TNTPrimed) damager).getSource(); if (source instanceof Player) { + return (Player) source; + } } } + return null; + } + } \ No newline at end of file diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/FriendlyFire.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/FriendlyFire.java index 9e81630b..c7ecbb48 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/FriendlyFire.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/FriendlyFire.java @@ -24,19 +24,27 @@ public class FriendlyFire extends SCListener { private static final long WARN_DELAY = 10000; public FriendlyFire(@NotNull SimpleClans plugin) { + super(plugin); + } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onEntityDamage(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player) || isBlacklistedWorld(event.getEntity())) { + return; + } + Player victim = (Player) event.getEntity(); Player attacker = Events.getAttacker(event); if (attacker == null || attacker.getUniqueId().equals(victim.getUniqueId())) { + return; + } ClanPlayer vcp = plugin.getClanManager().getClanPlayer(victim); @@ -45,44 +53,63 @@ public class FriendlyFire extends SCListener { Clan attackerClan = plugin.getClanManager().getClanByPlayerUniqueId(attacker.getUniqueId()); process(event, attacker, vcp, victimClan, attackerClan); + } - private void process(EntityDamageEvent event, - Player attacker, - @Nullable ClanPlayer vcp, - @Nullable Clan victimClan, - @Nullable Clan attackerClan) { + private void process(EntityDamageEvent event, Player attacker, @Nullable ClanPlayer vcp, @Nullable Clan victimClan, + @Nullable Clan attackerClan) + { + if (vcp == null || victimClan == null || attackerClan == null) { + if (plugin.getSettingsManager().is(SAFE_CIVILIANS)) { + ChatBlock.sendMessageKey(attacker, "cannot.attack.civilians"); event.setCancelled(true); + } + return; + } - if (vcp.isFriendlyFire() || victimClan.isFriendlyFire() || plugin.getSettingsManager().is(GLOBAL_FRIENDLY_FIRE)) { + if (vcp.isFriendlyFire() || victimClan.isFriendlyFire() + || plugin.getSettingsManager().is(GLOBAL_FRIENDLY_FIRE)) + { + return; + } if (victimClan.equals(attackerClan)) { + warn(attacker, "cannot.attack.clan.member"); event.setCancelled(true); return; + } if (victimClan.isAlly(attackerClan.getTag())) { + warn(attacker, "cannot.attack.ally"); event.setCancelled(true); + } + } private void warn(Player attacker, String messageKey) { + long timestamp = warned.getOrDefault(attacker.getUniqueId(), 0L); long currentTimeMillis = System.currentTimeMillis(); if (timestamp + WARN_DELAY <= currentTimeMillis) { + ChatBlock.sendMessageKey(attacker, messageKey); warned.put(attacker.getUniqueId(), currentTimeMillis); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java index 0b4b7d2a..7c13dd78 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java @@ -53,220 +53,381 @@ public class LandProtection implements Listener { private final EventPriority priority; public LandProtection(@NotNull SimpleClans plugin) { + this.plugin = plugin; protectionManager = plugin.getProtectionManager(); clanManager = plugin.getClanManager(); settingsManager = plugin.getSettingsManager(); priority = EventPriority.valueOf(settingsManager.getString(WAR_LISTENERS_PRIORITY)); + } public void registerListeners() { + registerListener(BlockBreakEvent.class, (event, cancel) -> { + Block block = event.getBlock(); if (settingsManager.getIgnoredList(BREAK).contains(block.getType().name())) { + return; + } + if (protectionManager.can(BREAK, block.getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(HangingBreakByEntityEvent.class, (event, cancel) -> { + Entity remover = event.getRemover(); if (!(remover instanceof Player)) { + return; + } + if (protectionManager.can(BREAK, event.getEntity().getLocation(), ((Player) remover))) { + event.setCancelled(cancel); + } + }); registerListener(HangingPlaceEvent.class, (event, cancel) -> { + Player player = event.getPlayer(); if (player == null) { + return; + } + if (protectionManager.can(PLACE, event.getBlock().getLocation(), player)) { + event.setCancelled(cancel); + } + }); registerListener(StructureGrowEvent.class, (event, cancel) -> { + if (event.getPlayer() == null) { + return; + } + if (protectionManager.can(PLACE, event.getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(BlockPlaceEvent.class, (event, cancel) -> { + Block block = event.getBlock(); if (settingsManager.getIgnoredList(PLACE).contains(block.getType().name())) { + return; + } + if (protectionManager.can(PLACE, block.getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(PlayerBucketEmptyEvent.class, (event, cancel) -> { + Block block = event.getBlockClicked(); if (settingsManager.getIgnoredList(PLACE).contains(block.getType().name())) { + return; + } + if (protectionManager.can(PLACE, block.getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(PlayerBucketFillEvent.class, (event, cancel) -> { + Block block = event.getBlockClicked().getRelative(event.getBlockFace()); if (settingsManager.getIgnoredList(BREAK).contains(block.getType().name())) { + return; + } + if (protectionManager.can(BREAK, block.getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(VehicleDestroyEvent.class, (event, cancel) -> { + if (!(event.getAttacker() instanceof Player)) { + return; + } + if (protectionManager.can(BREAK, event.getVehicle().getLocation(), ((Player) event.getAttacker()))) { + event.setCancelled(cancel); + } + }); registerListener(EntityChangeBlockEvent.class, (event, cancel) -> { + if (!(event.getEntity() instanceof Player)) { + return; + } + if (protectionManager.can(BREAK, event.getBlock().getLocation(), ((Player) event.getEntity()))) { + event.setCancelled(cancel); + } + }); registerListener(EntityDamageByEntityEvent.class, (event, cancel) -> { + Player attacker = Events.getAttacker(event); if (attacker == null) { + return; + } + Player victim = event.getEntity() instanceof Player ? ((Player) event.getEntity()) : null; if (victim == null) { + return; + } + if (protectionManager.can(DAMAGE, event.getEntity().getLocation(), attacker, victim)) { + event.setCancelled(cancel); + } + }); registerListener(PlayerInteractAtEntityEvent.class, (event, cancel) -> { + if (protectionManager.can(INTERACT_ENTITY, event.getRightClicked().getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(PlayerInteractEntityEvent.class, (event, cancel) -> { + if (protectionManager.can(INTERACT_ENTITY, event.getRightClicked().getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); registerListener(VehicleExitEvent.class, (event, cancel) -> { + Vehicle vehicle = event.getVehicle(); if (vehicle instanceof Tameable && event.getExited() instanceof Player) { + if (protectionManager.can(INTERACT_ENTITY, vehicle.getLocation(), ((Player) event.getExited()))) { + event.setCancelled(cancel); + } + } + }); registerListener(InventoryOpenEvent.class, (event, cancel) -> { + InventoryHolder holder = event.getInventory().getHolder(); Location location = getLocation(holder); - if (holder instanceof Entity && holder == event.getPlayer()) return; - if (location == null) return; + if (holder instanceof Entity && holder == event.getPlayer()) + return; + if (location == null) + return; if (protectionManager.can(CONTAINER, location, ((Player) event.getPlayer()))) { + event.setCancelled(cancel); + } + }); registerListener(PlayerInteractEvent.class, (event, cancel) -> { + if (event.getClickedBlock() == null) { + return; + } + ProtectionManager.Action action = getInteractEventAction(event); if (protectionManager.can(action, event.getClickedBlock().getLocation(), event.getPlayer())) { + event.setUseInteractedBlock(cancel ? Result.DENY : Result.ALLOW); event.setUseItemInHand(cancel ? Result.DENY : Result.ALLOW); event.setCancelled(cancel); + } + }); registerListener(PlayerBedEnterEvent.class, (event, cancel) -> { + if (protectionManager.can(INTERACT, event.getBed().getLocation(), event.getPlayer())) { + event.setCancelled(cancel); + } + }); + } private void registerListener(Class clazz, BiConsumer listener) { + Bukkit.getPluginManager().registerEvent(clazz, this, EventPriority.LOWEST, (l, event) -> { + if (clazz.isInstance(event)) { + listener.accept(clazz.cast(event), true); + } + }, plugin, false); Bukkit.getPluginManager().registerEvent(clazz, this, priority, (l, event) -> { + if (clazz.isInstance(event)) { + listener.accept(clazz.cast(event), false); + } + }, plugin, false); + } public void registerCreateLandEvent(ProtectionProvider provider, @Nullable Class createLandEvent) { - if (createLandEvent == null) return; + + if (createLandEvent == null) + return; Bukkit.getPluginManager().registerEvent(createLandEvent, this, EventPriority.NORMAL, (listener, event) -> { + if (!createLandEvent.isInstance(event)) { + return; + } + Player player = provider.getPlayer(event); - if (player == null) return; + if (player == null) + return; Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId()); if ((clan == null || !clan.isLeader(player)) && settingsManager.is(LAND_CREATION_ONLY_LEADERS)) { + cancelWithMessage(player, event, "only.leaders.can.create.lands"); return; + } + if (settingsManager.is(LAND_CREATION_ONLY_ONE_PER_CLAN)) { + if (clan == null) { + cancelWithMessage(player, event, "only.clan.members.can.create.lands"); return; + } + for (ClanPlayer member : clan.getMembers()) { - Set lands = protectionManager.getLandsOf(Bukkit.getOfflinePlayer(member.getUniqueId()), player.getWorld()); + + Set lands = protectionManager.getLandsOf(Bukkit.getOfflinePlayer(member.getUniqueId()), + player.getWorld()); if (lands.size() > 0) { + cancelWithMessage(player, event, "only.one.land.per.clan"); return; + } + } + } + }, plugin, true); + } private void cancelWithMessage(Player player, Event event, String messageKey) { + if (!(event instanceof Cancellable)) { + return; + } + ChatBlock.sendMessageKey(player, messageKey); ((Cancellable) event).setCancelled(true); + } private @Nullable Location getLocation(@Nullable InventoryHolder holder) { + if (holder instanceof BlockState) { + return ((BlockState) holder).getLocation(); + } + if (holder instanceof DoubleChest) { + return ((DoubleChest) holder).getLocation(); + } + return null; + } @NotNull private ProtectionManager.Action getInteractEventAction(PlayerInteractEvent event) { + ProtectionManager.Action action; Block clickedBlock = event.getClickedBlock(); if (clickedBlock != null && clickedBlock.getState() instanceof InventoryHolder) { + action = CONTAINER; + } else { + action = INTERACT; + } + return action; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PlayerDeath.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PlayerDeath.java index e93ca107..a0a2ac6e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PlayerDeath.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PlayerDeath.java @@ -27,18 +27,24 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class PlayerDeath extends SCListener { public PlayerDeath(SimpleClans plugin) { + super(plugin); + } @EventHandler(priority = EventPriority.LOW) public void onEntityDeath(PlayerDeathEvent event) { + Player victim = event.getEntity(); if (isNPC(victim) || isBlacklistedWorld(victim)) { + return; + } Player attacker = Events.getAttacker(victim.getLastDamageCause()); - if (isInvalidKill(victim, attacker)) return; + if (isInvalidKill(victim, attacker)) + return; ClanPlayer victimCp = plugin.getClanManager().getCreateClanPlayer(victim.getUniqueId()); ClanPlayer attackerCp = plugin.getClanManager().getCreateClanPlayer(attacker.getUniqueId()); @@ -50,156 +56,248 @@ public class PlayerDeath extends SCListener { victimCp.addDeath(); plugin.getStorageManager().updateClanPlayer(victimCp); plugin.getStorageManager().updateClanPlayer(attackerCp); + } @EventHandler public void onWarDeath(PlayerDeathEvent event) { + Player player = event.getEntity(); Player killer = player.getKiller(); if (killer == null) { + return; + } + Clan victimClan = plugin.getClanManager().getClanByPlayerUniqueId(player.getUniqueId()); Clan killerClan = plugin.getClanManager().getClanByPlayerUniqueId(killer.getUniqueId()); War war = plugin.getProtectionManager().getWar(victimClan, killerClan); if (war == null || victimClan == null) { + return; + } + war.increaseCasualties(victimClan); + } private void classifyKill(@NotNull ClanPlayer victim, @NotNull ClanPlayer attacker) { + Clan victimClan = victim.getClan(); Clan attackerClan = attacker.getClan(); if (victimClan == null || attackerClan == null || !victimClan.isVerified() || !attackerClan.isVerified()) { + addKill(Kill.Type.CIVILIAN, attacker, victim); + } else if (attackerClan.isRival(victim.getTag())) { + addKill(Kill.Type.RIVAL, attacker, victim); + } else if (attackerClan.isAlly(victimClan.getTag()) || attackerClan.equals(victimClan)) { + addKill(Kill.Type.ALLY, attacker, victim); + } else { + addKill(Kill.Type.NEUTRAL, attacker, victim); + } + } private void giveMoneyReward(@NotNull ClanPlayer victim, @NotNull ClanPlayer attacker) { + if (!plugin.getSettingsManager().is(ECONOMY_MONEY_PER_KILL)) { + return; + } + Clan attackerClan = attacker.getClan(); if (attackerClan == null) { + return; + } + double reward = calculateReward(attacker, victim); if (reward != 0) { + for (ClanPlayer cp : attackerClan.getOnlineMembers()) { + double money = Math.round((reward / attacker.getClan().getOnlineMembers().size()) * 100D) / 100D; Player player = cp.toPlayer(); if (player == null) { + continue; + } - player.sendMessage(ChatColor.AQUA + lang("player.got.money", player, money, - victim.getName(), attacker.getKDR())); + + player.sendMessage( + ChatColor.AQUA + lang("player.got.money", player, money, victim.getName(), attacker.getKDR())); plugin.getPermissionsManager().grantPlayer(player, money, PLAYER_KILLED); + } + } + } @Contract("_, null -> true") private boolean isInvalidKill(@NotNull Player victim, @Nullable Player attacker) { + if (attacker == null || attacker.getUniqueId().equals(victim.getUniqueId())) { + SimpleClans.debug("Attacker is not a player or victim and attacker have the same UUID"); return true; + } if (SimpleClans.getInstance().getSettingsManager().is(KILL_WEIGHTS_DENY_SAME_IP_KILLS)) { + InetSocketAddress attackerAddress = attacker.getAddress(); InetSocketAddress victimAddress = victim.getAddress(); if (attackerAddress != null && victimAddress != null) { + if (attackerAddress.getHostString().equals(victimAddress.getHostString())) { + plugin.getLogger().log(Level.INFO, "Blocked same IP kill calculating: {0} killed {1}. IP: {2}", - new Object[]{attacker.getDisplayName(), victim.getDisplayName(), - attackerAddress.getHostString()}); + new Object[] + { attacker.getDisplayName(), victim.getDisplayName(), attackerAddress.getHostString() }); return true; + } + } + } - AddKillEvent addKillEvent = new AddKillEvent(plugin.getClanManager().getCreateClanPlayer( - attacker.getUniqueId()), plugin.getClanManager().getCreateClanPlayer(victim.getUniqueId())); + + AddKillEvent addKillEvent = new AddKillEvent( + plugin.getClanManager().getCreateClanPlayer(attacker.getUniqueId()), + plugin.getClanManager().getCreateClanPlayer(victim.getUniqueId())); Bukkit.getServer().getPluginManager().callEvent(addKillEvent); if (addKillEvent.isCancelled()) { + return true; + } String kdrExempt = "simpleclans.other.kdr-exempt"; PermissionsManager pm = plugin.getPermissionsManager(); return pm.has(attacker, kdrExempt) || pm.has(victim, kdrExempt); + } private void addKill(Kill.Type type, ClanPlayer attacker, ClanPlayer victim) { + if (type == null || attacker == null || victim == null) { + return; + } + final Kill kill = new Kill(attacker, victim, LocalDateTime.now()); if (plugin.getSettingsManager().is(KDR_ENABLE_KILL_DELAY) && plugin.getClanManager().isKillBeforeDelay(kill)) { + return; + } if (plugin.getSettingsManager().is(KDR_ENABLE_MAX_KILLS)) { + plugin.getStorageManager().getKillsPerPlayer(attacker.getName(), data -> { + final int max = plugin.getSettingsManager().getInt(KDR_MAX_KILLS_PER_VICTIM); Integer kills = data.get(kill.getVictim().getName()); if (kills != null) { + if (kills < max) { + saveKill(kill, type); + } + } else { + saveKill(kill, type); + } + }); - return; - } - saveKill(kill, type); + return; + + } + + saveKill(kill, type); + } - private void saveKill(Kill kill, Kill.Type type) { - plugin.getClanManager().addKill(kill); - ClanPlayer killer = kill.getKiller(); - ClanPlayer victim = kill.getVictim(); - killer.addKill(type); - plugin.getStorageManager().insertKill(killer, victim, type.getShortname(), kill.getTime()); - } + private void saveKill(Kill kill, Kill.Type type) { + + plugin.getClanManager().addKill(kill); + ClanPlayer killer = kill.getKiller(); + ClanPlayer victim = kill.getVictim(); + killer.addKill(type); + plugin.getStorageManager().insertKill(killer, victim, type.getShortname(), kill.getTime()); + + } private double calculateReward(@NotNull ClanPlayer attacker, @NotNull ClanPlayer victim) { + double reward; double multiplier = plugin.getSettingsManager().getDouble(ECONOMY_MONEY_PER_KILL_KDR_MULTIPLIER); double kdr = attacker.getKDR() * multiplier; Clan attackerClan = attacker.getClan(); Clan victimClan = victim.getClan(); if (attackerClan == null || !attackerClan.isVerified() || victimClan == null || !victimClan.isVerified()) { + return 0; + } + if (attackerClan.isRival(victimClan.getTag())) { + if (attackerClan.isWarring(victimClan)) { + reward = kdr * 4; - } else reward = kdr * 2; + + } else + reward = kdr * 2; + } else if (attackerClan.isAlly(victimClan.getTag())) { + reward = kdr * -1; + } else { + reward = kdr; + } + return reward; + } private boolean isNPC(Player player) { + if (player.hasMetadata("NPC")) { + SimpleClans.debug(String.format("%s has NPC metadata", player.getName())); return true; + } + if (Bukkit.getOfflinePlayer(player.getUniqueId()).getName() == null) { + SimpleClans.debug(String.format("%s has a null name", player.getUniqueId())); return true; + } + return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PvPOnlyInWar.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PvPOnlyInWar.java index cb0266ea..cc2ca7b4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PvPOnlyInWar.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/PvPOnlyInWar.java @@ -14,45 +14,66 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class PvPOnlyInWar extends SCListener { public PvPOnlyInWar(SimpleClans plugin) { + super(plugin); + } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onEntityDamage(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player) || isBlacklistedWorld(event.getEntity())) { + return; + } + Player victim = (Player) event.getEntity(); Player attacker = Events.getAttacker(event); if (attacker == null || victim.getUniqueId().equals(attacker.getUniqueId())) { + return; + } Clan attackerClan = plugin.getClanManager().getClanByPlayerUniqueId(attacker.getUniqueId()); Clan victimClan = plugin.getClanManager().getClanByPlayerUniqueId(victim.getUniqueId()); if (plugin.getSettingsManager().is(PVP_ONLY_WHILE_IN_WAR)) { + process(event, attacker, victim, attackerClan, victimClan); + } + } private void process(EntityDamageEvent event, Player attacker, Player victim, @Nullable Clan attackerClan, - @Nullable Clan victimClan) { + @Nullable Clan victimClan) + { + if (attackerClan == null || victimClan == null) { + ChatBlock.sendMessageKey(attacker, "must.be.in.clan.to.pvp", victim.getName()); event.setCancelled(true); return; + } if (plugin.getPermissionsManager().has(victim, "simpleclans.mod.nopvpinwar")) { + event.setCancelled(true); return; + } if (!attackerClan.isWarring(victimClan)) { + ChatBlock.sendMessageKey(attacker, "clans.not.at.war.pvp.denied", victimClan.getName()); event.setCancelled(true); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCListener.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCListener.java index 735b108b..2cec8a63 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCListener.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCListener.java @@ -13,17 +13,24 @@ public abstract class SCListener implements Listener { protected final SimpleClans plugin; public SCListener(SimpleClans plugin) { + this.plugin = plugin; + } public boolean isBlacklistedWorld(@NotNull Entity entity) { + List words = plugin.getSettingsManager().getStringList(ConfigField.BLACKLISTED_WORLDS); if (words.contains(entity.getWorld().getName())) { + SimpleClans.debug("Blacklisted world"); return true; + } + return false; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCPlayerListener.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCPlayerListener.java index 09f871a1..37b7dceb 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCPlayerListener.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/SCPlayerListener.java @@ -29,60 +29,91 @@ public class SCPlayerListener extends SCListener { private final SettingsManager settingsManager; public SCPlayerListener(@NotNull SimpleClans plugin) { + super(plugin); settingsManager = plugin.getSettingsManager(); registerChatListener(); + } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + String[] split = event.getMessage().substring(1).split(" "); String command = split[0]; if (settingsManager.is(CLANCHAT_TAG_BASED)) { + Clan clan = plugin.getClanManager().getClan(command); if (clan == null || !clan.isMember(event.getPlayer())) { + return; + } + String replaced = event.getMessage().replaceFirst(command, settingsManager.getString(COMMANDS_CLAN_CHAT)); event.setMessage(replaced); + } + } @EventHandler(priority = EventPriority.HIGH) public void handleChatTags(AsyncPlayerChatEvent event) { + Player player = event.getPlayer(); if (isBlacklistedWorld(player)) { + return; + } ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); String tagLabel = cp != null && cp.isTagEnabled() ? cp.getTagLabel() : null; if (settingsManager.is(CHAT_COMPATIBILITY_MODE) && settingsManager.is(DISPLAY_CHAT_TAGS)) { + if (tagLabel != null) { + if (player.getDisplayName().contains("{clan}")) { + player.setDisplayName(player.getDisplayName().replace("{clan}", tagLabel)); + } else if (event.getFormat().contains("{clan}")) { + event.setFormat(event.getFormat().replace("{clan}", tagLabel)); + } else { + String format = event.getFormat(); event.setFormat(tagLabel + format); + } + } else { + event.setFormat(event.getFormat().replace("{clan}", "")); event.setFormat(event.getFormat().replace("tagLabel", "")); + } + } else { + plugin.getClanManager().updateDisplayName(player); + } + } @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { + final Player player = event.getPlayer(); if (isBlacklistedWorld(player)) { + return; + } + ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(player.getUniqueId()); updatePlayerName(player); @@ -92,108 +123,159 @@ public class SCPlayerListener extends SCListener { plugin.getPermissionsManager().addPlayerPermissions(cp); if (settingsManager.is(BB_SHOW_ON_LOGIN) && cp.isBbEnabled() && cp.getClan() != null) { + cp.getClan().displayBb(player, settingsManager.getInt(BB_LOGIN_SIZE)); + } plugin.getPermissionsManager().addClanPermissions(cp); + } @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerRespawn(PlayerRespawnEvent event) { + Player player = event.getPlayer(); if (!settingsManager.is(TELEPORT_HOME_ON_SPAWN) || isBlacklistedWorld(player)) { + return; + } Clan clan = plugin.getClanManager().getClanByPlayerUniqueId(player.getUniqueId()); Location home; if (clan != null && (home = clan.getHomeLocation()) != null) { + String homeServer = new Flags(clan.getFlags()).getString("homeServer", ""); if (homeServer.isEmpty() || plugin.getProxyManager().getServerName().equals(homeServer)) { + event.setRespawnLocation(plugin.getTeleportManager().getSafe(home)); + } + } + } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { + ClanPlayer cp = plugin.getClanManager().getClanPlayer(event.getPlayer()); if (cp != null) { + Clan clan = Objects.requireNonNull(cp.getClan()); Bukkit.getScheduler().runTask(plugin, () -> { + if (clan.getOnlineMembers().isEmpty()) { + plugin.getProtectionManager().setWarExpirationTime(cp.getClan(), settingsManager.getMinutes(WAR_DISCONNECT_EXPIRATION_TIME)); + } + }); - } - if (isBlacklistedWorld(event.getPlayer())) { - return; + } + if (isBlacklistedWorld(event.getPlayer())) { + + return; + + } plugin.getPermissionsManager().removeClanPlayerPermissions(cp); plugin.getClanManager().updateLastSeen(event.getPlayer()); plugin.getRequestManager().endPendingRequest(event.getPlayer().getName()); + } @EventHandler public void onPlayerKick(PlayerKickEvent event) { + if (isBlacklistedWorld(event.getPlayer())) { + return; + } plugin.getClanManager().updateLastSeen(event.getPlayer()); + } private void registerChatListener() { + EventPriority priority = EventPriority.valueOf(settingsManager.getString(CLANCHAT_LISTENER_PRIORITY)); plugin.getServer().getPluginManager().registerEvent(AsyncPlayerChatEvent.class, this, priority, (l, e) -> { + if (!(e instanceof AsyncPlayerChatEvent)) { + return; + } + AsyncPlayerChatEvent event = (AsyncPlayerChatEvent) e; Player player = event.getPlayer(); ClanPlayer cp = plugin.getClanManager().getClanPlayer(player.getUniqueId()); if (cp == null || isBlacklistedWorld(player)) { + return; + } Channel channel = cp.getChannel(); if (channel != NONE) { + PermissionsManager pm = plugin.getPermissionsManager(); - if ((channel == Channel.ALLY && !pm.has(player, "simpleclans.member.ally")) || - (channel == CLAN && !pm.has(player, "simpleclans.member.chat"))) { + if ((channel == Channel.ALLY && !pm.has(player, "simpleclans.member.ally")) + || (channel == CLAN && !pm.has(player, "simpleclans.member.chat"))) + { + ChatBlock.sendMessage(player, ChatColor.RED + lang("insufficient.permissions", player)); return; + } + plugin.getChatManager().processChat(SPIGOT, channel, cp, event.getMessage()); event.setCancelled(true); + } + }, plugin, true); + } private void updatePlayerName(@NotNull final Player player) { + final ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); ClanPlayer duplicate = null; for (ClanPlayer other : plugin.getClanManager().getAllClanPlayers()) { + if (other.getName().equals(player.getName()) && !other.getUniqueId().equals(player.getUniqueId())) { + duplicate = other; break; + } + } if (duplicate != null) { + plugin.getLogger().warning(String.format("Found duplicate for %s, UUIDs: %s, %s", player.getName(), player.getUniqueId(), duplicate.getUniqueId())); duplicate.setName(duplicate.getUniqueId().toString()); plugin.getStorageManager().updatePlayerName(duplicate); + } + if (cp != null) { + cp.setName(player.getName()); plugin.getStorageManager().updatePlayerName(cp); + } + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/TamableMobsSharing.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/TamableMobsSharing.java index 9a3d5188..b7501d65 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/TamableMobsSharing.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/TamableMobsSharing.java @@ -24,67 +24,109 @@ public class TamableMobsSharing implements Listener { private final ClanManager clanManager; public TamableMobsSharing(@NotNull SimpleClans plugin) { + settings = plugin.getSettingsManager(); clanManager = plugin.getClanManager(); + } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onEntityDamage(EntityDamageByEntityEvent event) { + if (settings.is(TAMABLE_MOBS_SHARING)) { + if (event.getEntity() instanceof Wolf && event.getDamager() instanceof Player) { + ClanPlayer cp = clanManager.getAnyClanPlayer(event.getDamager().getUniqueId()); if (cp == null || cp.getClan() == null) { + return; + } + Wolf wolf = (Wolf) event.getEntity(); AnimalTamer owner = wolf.getOwner(); if (owner != null && cp.getClan().isMember(owner.getUniqueId())) { + // Sets the wolf to friendly if the attacker is one out of his clan wolf.setAngry(false); + } + } + } + } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onEntityTarget(EntityTargetLivingEntityEvent event) { + if (settings.is(TAMABLE_MOBS_SHARING)) { + if (event.getEntity() instanceof Tameable && event.getTarget() instanceof Player) { + ClanPlayer cp = clanManager.getAnyClanPlayer(event.getTarget().getUniqueId()); if (cp == null || cp.getClan() == null) { + return; + } + Tameable wolf = (Tameable) event.getEntity(); AnimalTamer owner = wolf.getOwner(); if (owner == null) { + return; + } + if (cp.getClan().isMember(owner.getUniqueId())) { + // cancels the event if the attacker is one out of his clan event.setCancelled(true); + } + } + } + } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onPlayerInteract(PlayerInteractEntityEvent event) { + if (settings.is(TAMABLE_MOBS_SHARING) && event.getRightClicked() instanceof Tameable) { + Player player = event.getPlayer(); ClanPlayer cp = clanManager.getAnyClanPlayer(player.getUniqueId()); if (cp == null || cp.getClan() == null) { + return; + } + Tameable tamed = (Tameable) event.getRightClicked(); if (tamed.getOwner() != null) { + if (tamed instanceof Wolf && !((Wolf) tamed).isSitting()) { + return; + } + if (cp.getClan().isMember(tamed.getOwner().getUniqueId())) { + tamed.setOwner(player); + } + } + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLog.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLog.java index d3c23233..105cf76e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLog.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLog.java @@ -18,6 +18,7 @@ import java.util.List; * @since 2.15.3 */ public class BankLog { + private final DecimalFormat decimalFormat = new DecimalFormat("##.##"); private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd - HH:mm"); @@ -29,21 +30,27 @@ public class BankLog { private final double amount; public BankLog(@NotNull BankOperator operator, @NotNull Clan clan, @NotNull EconomyResponse economyResponse, - @NotNull BankLogger.Operation operation, ClanBalanceUpdateEvent.Cause cause, double amount) { + @NotNull BankLogger.Operation operation, ClanBalanceUpdateEvent.Cause cause, double amount) + { + this.operator = operator; this.clan = clan; this.economyResponse = economyResponse; this.operation = operation; this.cause = cause; this.amount = amount; + } public static List getHeader() { - return Arrays.asList("Date", "Sender", "Clan Name", "Response", - "Operation", "Cause", "Sender Balance", "Amount", "Clan Balance"); + + return Arrays.asList("Date", "Sender", "Clan Name", "Response", "Operation", "Cause", "Sender Balance", + "Amount", "Clan Balance"); + } public List getValues() { + List values = new ArrayList<>(); values.add(dateFormat.format(new Date())); values.add(operator.getName()); @@ -56,29 +63,43 @@ public class BankLog { values.add(decimalFormat.format(clan.getBalance())); return values; + } public BankOperator getOperator() { + return operator; + } public Clan getClan() { + return clan; + } public EconomyResponse getEconomyResponse() { + return economyResponse; + } public BankLogger.Operation getOperation() { + return operation; + } public ClanBalanceUpdateEvent.Cause getCause() { + return cause; + } public double getAmount() { + return amount; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLogger.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLogger.java index b720b392..d8370de6 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLogger.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankLogger.java @@ -1,16 +1,17 @@ package net.sacredlabyrinth.phaed.simpleclans.loggers; /** - * The core interface for all bank loggers, - * which may log all economy actions, + * The core interface for all bank loggers, which may log all economy actions, * with its defining ({@link Operation}) * * @since 2.15.3 */ public interface BankLogger { + void log(BankLog log); enum Operation { DEPOSIT, WITHDRAW, SET } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankOperator.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankOperator.java index 2f06a002..02596f4b 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankOperator.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/BankOperator.java @@ -12,23 +12,34 @@ public class BankOperator { private final double balance; public BankOperator(@NotNull CommandSender sender, double balance) { + this(sender.getName(), balance); + } public BankOperator(@NotNull ClanPlayer sender, double balance) { + this(sender.getName(), balance); + } public BankOperator(@NotNull String name, double balance) { + this.name = name; this.balance = balance; + } public @NotNull String getName() { + return name; + } public double getBalance() { + return balance; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/CSVBankLogger.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/CSVBankLogger.java index 9aabdfb3..a00ccee2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/CSVBankLogger.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/loggers/CSVBankLogger.java @@ -17,13 +17,14 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con /** * Logs all bank actions to one CSV file per day. *

- * It accepts {@link BankLog} as a record - * and uses the format from {@link CSVFormatter} + * It accepts {@link BankLog} as a record and uses the format from + * {@link CSVFormatter} *

* Typical usage: + * *

{@code
- *     CSVBankLogger bankLogger = new CSVBankLogger(plugin);
- *     bankLogger.log(new BankLog(sender, clan, economyResponse, operation, cause, amount));
+ * CSVBankLogger bankLogger = new CSVBankLogger(plugin);
+ * bankLogger.log(new BankLog(sender, clan, economyResponse, operation, cause, amount));
  * }
* * @since 2.15.3 @@ -37,80 +38,116 @@ public class CSVBankLogger implements BankLogger { static final int FILE_COUNT = 1; public CSVBankLogger(SimpleClans plugin) { + this.plugin = plugin; if (!plugin.getSettingsManager().is(ECONOMY_BANK_LOG_ENABLED)) { + return; + } try { + FileHandler fh = new FileHandler(getFilePath(), FILE_SIZE, FILE_COUNT, true); fh.setFormatter(new CSVFormatter()); fh.setLevel(Level.INFO); fh.setEncoding("UTF-8"); logger.addHandler(fh); if (!plugin.getSettingsManager().is(DEBUG)) { + logger.setUseParentHandlers(false); + } + } catch (IOException e) { + e.printStackTrace(); + } + } @Override public void log(BankLog log) { + if (!plugin.getSettingsManager().is(ECONOMY_BANK_LOG_ENABLED)) { + return; + } logger.log(Level.INFO, toCSV(log)); + } @SuppressWarnings("ResultOfMethodCallIgnored") @NotNull String getFilePath() { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); String folderPath = plugin.getDataFolder().getPath() + File.separator + "logs" + File.separator + "bank"; String filePath = folderPath + File.separator + dateFormat.format(new Date()) + ".csv"; File folder = new File(folderPath); if (!folder.exists()) { + folder.mkdirs(); + } File file = new File(filePath); if (!file.exists()) { + try { + file.createNewFile(); makeHeader(file); + } catch (IOException e) { + e.printStackTrace(); + } + } return filePath; + } private void makeHeader(File file) throws FileNotFoundException { + try (PrintWriter pw = new PrintWriter(file)) { + pw.println(String.join(",", BankLog.getHeader())); + } + } private String toCSV(BankLog log) { + return String.join(",", log.getValues()); + } @NotNull public Logger getLogger() { + return logger; + } static class CSVFormatter extends Formatter { @Override public String format(LogRecord record) { + return record.getMessage() + "\n"; + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ChatManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ChatManager.java index 5ff9c84a..1141d896 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ChatManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ChatManager.java @@ -37,75 +37,106 @@ public final class ChatManager { private DiscordHook discordHook; public ChatManager(SimpleClans plugin) { + this.plugin = plugin; registerHandlers(); if (isDiscordHookEnabled()) { + DiscordSRV.api.subscribe(this); + } + } @Subscribe public void registerDiscord(DiscordReadyEvent event) { + discordHook = new DiscordHook(plugin); DiscordSRV.api.subscribe(discordHook); getPluginManager().registerEvents(discordHook, plugin); + } @Nullable public DiscordHook getDiscordHook() { + if (isDiscordHookEnabled()) { + // Manually instantiate, if JDA did load faster than SC if (discordHook == null && DiscordSRV.getPlugin().getJda().getStatus() == JDA.Status.CONNECTED) { + registerDiscord(new DiscordReadyEvent()); + } + } return discordHook; + } public void processChat(@NotNull SCMessage message) { + Clan clan = Objects.requireNonNull(message.getSender().getClan(), "Clan cannot be null"); List receivers = new ArrayList<>(); switch (message.getChannel()) { + case ALLY: if (!plugin.getSettingsManager().is(ALLYCHAT_ENABLE)) { + return; + } - receivers.addAll(getOnlineAllyMembers(clan).stream().filter(allyMember -> - !allyMember.isMutedAlly()).collect(Collectors.toList())); - receivers.addAll(clan.getOnlineMembers().stream().filter(onlineMember -> - !onlineMember.isMutedAlly()).collect(Collectors.toList())); + receivers.addAll(getOnlineAllyMembers(clan).stream().filter(allyMember -> !allyMember.isMutedAlly()) + .collect(Collectors.toList())); + receivers.addAll(clan.getOnlineMembers().stream().filter(onlineMember -> !onlineMember.isMutedAlly()) + .collect(Collectors.toList())); break; case CLAN: if (!plugin.getSettingsManager().is(CLANCHAT_ENABLE)) { + return; + } - receivers.addAll(clan.getOnlineMembers().stream().filter(member -> !member.isMuted()). - collect(Collectors.toList())); + receivers.addAll(clan.getOnlineMembers().stream().filter(member -> !member.isMuted()) + .collect(Collectors.toList())); + } + message.setReceivers(receivers); for (ChatHandler ch : handlers) { + if (ch.canHandle(message.getSource())) { + ch.sendMessage(message.clone()); + } + } + } - public void processChat(@NotNull Source source, @NotNull Channel channel, - @NotNull ClanPlayer clanPlayer, String message) { + public void processChat(@NotNull Source source, @NotNull Channel channel, @NotNull ClanPlayer clanPlayer, + String message) + { + Objects.requireNonNull(clanPlayer.getClan(), "Clan cannot be null"); processChat(new SCMessage(source, channel, clanPlayer, message)); + } public String parseChatFormat(String format, SCMessage message) { + return parseChatFormat(format, message, new HashMap<>()); + } public String parseChatFormat(String format, SCMessage message, Map placeholders) { + SettingsManager sm = plugin.getSettingsManager(); ClanPlayer sender = message.getSender(); @@ -114,14 +145,18 @@ public final class ChatManager { String trustedColor = sm.getColored(ConfigField.valueOf(message.getChannel() + "CHAT_TRUSTED_COLOR")); String rank = sender.getRankId().isEmpty() ? null : ChatUtils.parseColors(sender.getRankDisplayName()); - ConfigField configField = ConfigField.valueOf(String.format("%sCHAT_RANK", - message.getSource() == DISCORD ? "DISCORD" : message.getChannel())); + ConfigField configField = ConfigField.valueOf( + String.format("%sCHAT_RANK", message.getSource() == DISCORD ? "DISCORD" : message.getChannel())); String rankFormat = (rank != null) ? sm.getColored(configField).replace("%rank%", rank) : ""; if (placeholders != null) { + for (Map.Entry e : placeholders.entrySet()) { + format = format.replace("%" + e.getKey() + "%", e.getValue()); + } + } String parsedFormat = ChatUtils.parseColors(format) @@ -129,51 +164,72 @@ public final class ChatManager { .replace("%clean-tag%", sender.getClan().getTag()) .replace("%nick-color%", (sender.isLeader() ? leaderColor : sender.isTrusted() ? trustedColor : memberColor)) - .replace("%player%", sender.getName()) - .replace("%rank%", rankFormat); - parsedFormat = parseWithPapi(message.getSender(), parsedFormat) - .replace("%message%", message.getContent()); + .replace("%player%", sender.getName()).replace("%rank%", rankFormat); + parsedFormat = parseWithPapi(message.getSender(), parsedFormat).replace("%message%", message.getContent()); return parsedFormat; + } public boolean isDiscordHookEnabled() { + return getPluginManager().getPlugin("DiscordSRV") != null && plugin.getSettingsManager().is(DISCORDCHAT_ENABLE); + } private String parseWithPapi(ClanPlayer cp, String message) { + if (getPluginManager().getPlugin("PlaceholderAPI") == null) { + return message; + } + OfflinePlayer sender = Bukkit.getOfflinePlayer(cp.getUniqueId()); message = PlaceholderAPI.setPlaceholders(sender, message); // If there are still placeholders left, try to parse them // E.g. if the user has a placeholder as LuckPerms prefix/suffix if (message.contains("%")) { + message = PlaceholderAPI.setPlaceholders(sender, message); + } + return message; + } private void registerHandlers() { - Set> chatHandlers = - Helper.getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.chat.handlers", ChatHandler.class); + + Set> chatHandlers = Helper + .getSubTypesOf("net.sacredlabyrinth.phaed.simpleclans.chat.handlers", ChatHandler.class); plugin.getLogger().log(Level.INFO, "Registering {0} chat handlers...", chatHandlers.size()); for (Class handler : chatHandlers) { + try { + handlers.add(handler.getConstructor().newInstance()); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) { - plugin.getLogger().log(Level.SEVERE, "Error while trying to register {0}: " + - ex.getMessage(), handler.getSimpleName()); + + } catch (InstantiationException | IllegalAccessException | InvocationTargetException + | NoSuchMethodException ex) + { + + plugin.getLogger().log(Level.SEVERE, "Error while trying to register {0}: " + ex.getMessage(), + handler.getSimpleName()); + } + } + } private List getOnlineAllyMembers(Clan clan) { - return clan.getAllAllyMembers().stream(). - filter(allyPlayer -> allyPlayer.toPlayer() != null). - collect(Collectors.toList()); + + return clan.getAllAllyMembers().stream().filter(allyPlayer -> allyPlayer.toPlayer() != null) + .collect(Collectors.toList()); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ClanManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ClanManager.java index cad5c20a..9e19b642 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ClanManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ClanManager.java @@ -49,93 +49,126 @@ public final class ClanManager { * */ public ClanManager() { + plugin = SimpleClans.getInstance(); + } /** * Deletes all clans and clan players in memory */ public void cleanData() { + clans.clear(); clanPlayers.clear(); kills.clear(); + } /** * Adds a kill to the memory */ public void addKill(Kill kill) { + if (kill == null) { + return; + } List list = kills.computeIfAbsent(kill.getKiller(), k -> new ArrayList<>()); Iterator iterator = list.iterator(); while (iterator.hasNext()) { + Kill oldKill = iterator.next(); if (oldKill.getVictim().equals(kill.getKiller())) { + iterator.remove(); continue; + } // cleaning final int delay = plugin.getSettingsManager().getInt(KDR_DELAY_BETWEEN_KILLS); long timePassed = oldKill.getTime().until(LocalDateTime.now(), ChronoUnit.MINUTES); if (timePassed >= delay) { + iterator.remove(); + } + } list.add(kill); + } /** * Checks if this kill respects the delay */ public boolean isKillBeforeDelay(Kill kill) { + if (kill == null) { + return false; + } + List list = kills.get(kill.getKiller()); if (list == null) { + return false; + } for (Kill oldKill : list) { + if (oldKill.getVictim().equals(kill.getVictim())) { final int delay = plugin.getSettingsManager().getInt(KDR_DELAY_BETWEEN_KILLS); long timePassed = oldKill.getTime().until(kill.getTime(), ChronoUnit.MINUTES); if (timePassed < delay) { + return true; + } + } + } return false; + } /** * Import a clan into the in-memory store */ public void importClan(Clan clan) { + this.clans.put(clan.getTag(), clan); + } /** * Import a clan player into the in-memory store */ public void importClanPlayer(ClanPlayer cp) { + if (cp.getUniqueId() != null) { + this.clanPlayers.put(cp.getUniqueId(), cp); + } + } /** * Create a new clan */ public void createClan(Player player, String colorTag, String name) { + ClanPlayer cp = getCreateClanPlayer(player.getUniqueId()); boolean verified = !plugin.getSettingsManager().is(REQUIRE_VERIFICATION) @@ -153,64 +186,82 @@ public final class ClanManager { plugin.getRequestManager().deny(cp); // denies any previous invitation SimpleClans.getInstance().getPermissionsManager().updateClanPermissions(clan); SimpleClans.getInstance().getServer().getPluginManager().callEvent(new CreateClanEvent(clan)); + } /** * Reset a player's KDR */ public void resetKdr(ClanPlayer cp) { + cp.setCivilianKills(0); cp.setNeutralKills(0); cp.setRivalKills(0); cp.setAllyKills(0); cp.setDeaths(0); plugin.getStorageManager().updateClanPlayer(cp); + } /** * Delete a players data file */ public void deleteClanPlayer(ClanPlayer cp) { + Clan clan = cp.getClan(); if (clan != null) { + clan.removePlayerFromClan(cp.getUniqueId()); + } + clanPlayers.remove(cp.getUniqueId()); plugin.getStorageManager().deleteClanPlayer(cp); + } /** * Delete a player data from memory */ public void deleteClanPlayerFromMemory(UUID playerUniqueId) { + clanPlayers.remove(playerUniqueId); + } /** * Remove a clan from memory */ public void removeClan(String tag) { + clans.remove(tag); + } /** * Whether the tag belongs to a clan */ public boolean isClan(String tag) { + return clans.containsKey(Helper.cleanTag(tag)); + } /** * Returns the clan the tag belongs to */ public Clan getClan(String tag) { + return clans.get(Helper.cleanTag(tag)); + } @SuppressWarnings("deprecation") @Nullable public Clan getClanByPlayerName(String playerName) { + return getClanByPlayerUniqueId(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** @@ -220,125 +271,164 @@ public final class ClanManager { */ @Nullable public Clan getClanByPlayerUniqueId(UUID playerUniqueId) { + ClanPlayer cp = getClanPlayer(playerUniqueId); if (cp != null) { + return cp.getClan(); + } return null; + } /** * @return the clans */ public List getClans() { + return new ArrayList<>(clans.values()); + } /** * Returns the collection of all clan players, including the disabled ones */ public List getAllClanPlayers() { + return new ArrayList<>(clanPlayers.values()); + } /** - * Gets the ClanPlayer data object if a player is currently in a clan, null - * if he's not in a clan Used for BungeeCord Reload ClanPlayer and your Clan + * Gets the ClanPlayer data object if a player is currently in a clan, null if + * he's not in a clan Used for BungeeCord Reload ClanPlayer and your Clan */ @Deprecated public @Nullable ClanPlayer getClanPlayerJoinEvent(Player player) { + SimpleClans.getInstance().getStorageManager().importFromDatabaseOnePlayer(player); return getClanPlayer(player.getUniqueId()); + } /** - * Gets the ClanPlayer data object if a player is currently in a clan, null - * if he's not in a clan + * Gets the ClanPlayer data object if a player is currently in a clan, null if + * he's not in a clan */ public @Nullable ClanPlayer getClanPlayer(@NotNull OfflinePlayer player) { + return getClanPlayer(player.getUniqueId()); + } /** - * Gets the ClanPlayer data object if a player is currently in a clan, null - * if he's not in a clan + * Gets the ClanPlayer data object if a player is currently in a clan, null if + * he's not in a clan */ public @Nullable ClanPlayer getClanPlayer(@NotNull Player player) { + return getClanPlayer((OfflinePlayer) player); + } /** - * Gets the ClanPlayer data object if a player is currently in a clan, null - * if he's not in a clan + * Gets the ClanPlayer data object if a player is currently in a clan, null if + * he's not in a clan */ public @Nullable ClanPlayer getClanPlayer(UUID playerUniqueId) { + ClanPlayer cp = clanPlayers.get(playerUniqueId); if (cp == null) { + return null; + } if (cp.getClan() == null) { + return null; + } return cp; + } @SuppressWarnings("deprecation") @Nullable public ClanPlayer getClanPlayer(String playerName) { + return getClanPlayer(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** - * Gets the ClanPlayer data object if a player is currently in a clan, null - * if he's not in a clan + * Gets the ClanPlayer data object if a player is currently in a clan, null if + * he's not in a clan */ @Deprecated public @Nullable ClanPlayer getClanPlayerName(String playerName) { + UUID uuid = UUIDMigration.getForcedPlayerUUID(playerName); if (uuid == null) { + return null; + } ClanPlayer cp = clanPlayers.get(uuid); if (cp == null) { + return null; + } if (cp.getClan() == null) { + return null; + } return cp; + } /** - * Gets the ClanPlayer data object for the player, will retrieve disabled - * clan players as well, these are players who used to be in a clan but are - * not currently in one, their data file persists and can be accessed. their - * clan will be null though. + * Gets the ClanPlayer data object for the player, will retrieve disabled clan + * players as well, these are players who used to be in a clan but are not + * currently in one, their data file persists and can be accessed. their clan + * will be null though. */ @Nullable public ClanPlayer getAnyClanPlayer(UUID uuid) { + return clanPlayers.get(uuid); + } @SuppressWarnings("deprecation") @Nullable public ClanPlayer getAnyClanPlayer(String playerName) { + for (ClanPlayer cp : getAllClanPlayers()) { + if (cp.getName().equalsIgnoreCase(playerName)) { + return cp; + } + } + return null; + } /** @@ -346,47 +436,68 @@ public final class ClanManager { */ @Deprecated public @Nullable ClanPlayer getCreateClanPlayerUUID(String playerName) { + UUID playerUniqueId = UUIDMigration.getForcedPlayerUUID(playerName); if (playerUniqueId != null) { + return getCreateClanPlayer(playerUniqueId); + } else { + return null; + } + } /** * Gets the ClanPlayer object for the player, creates one if not found */ public ClanPlayer getCreateClanPlayer(UUID uuid) { + Objects.requireNonNull(uuid, "UUID must not be null"); if (clanPlayers.containsKey(uuid)) { + return clanPlayers.get(uuid); + } ClanPlayer cp = new ClanPlayer(uuid); boolean save = true; for (ClanPlayer other : getAllClanPlayers()) { + if (other.getName().equals(cp.getName())) { + save = false; break; + } + } + if (save) { + plugin.getStorageManager().insertClanPlayer(cp); importClanPlayer(cp); + } else if (plugin.getSettingsManager().is(DEBUG)) { - plugin.getLogger().log(Level.WARNING, String.format("There already is a ClanPlayer with the name %s", - cp.getName()), new Exception()); + + plugin.getLogger().log(Level.WARNING, + String.format("There already is a ClanPlayer with the name %s", cp.getName()), new Exception()); + } return cp; + } @SuppressWarnings("deprecation") @NotNull public ClanPlayer getCreateClanPlayer(String playerName) { + return getCreateClanPlayer(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** @@ -395,12 +506,16 @@ public final class ClanManager { * @param msg the message */ public void serverAnnounce(String msg) { + if (plugin.getSettingsManager().is(DISABLE_MESSAGES)) { + return; + } plugin.getProxyManager().sendMessage("ALL", ChatColor.DARK_GRAY + "* " + AQUA + msg); Bukkit.getConsoleSender().sendMessage(AQUA + "[" + lang("server.announce") + "] " + ChatColor.WHITE + msg); + } /** @@ -410,14 +525,19 @@ public final class ClanManager { // do not update displayname if in compat mode if (plugin.getSettingsManager().is(CHAT_COMPATIBILITY_MODE)) { + return; + } if (player == null) { + return; + } if (plugin.getSettingsManager().is(DISPLAY_CHAT_TAGS)) { + String prefix = plugin.getPermissionsManager().getPrefix(player); // String suffix = plugin.getPermissionsManager().getSuffix(player); String lastColor = plugin.getSettingsManager().is(COLOR_CODE_FROM_PREFIX_FOR_NAME) @@ -428,45 +548,63 @@ public final class ClanManager { ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); if (cp == null) { + return; + } if (cp.isTagEnabled()) { + Clan clan = cp.getClan(); if (clan != null) { + fullName = clan.getTagLabel(cp.isLeader()) + lastColor + fullName + ChatColor.WHITE; + } player.setDisplayName(fullName); + } else { + player.setDisplayName(lastColor + fullName + ChatColor.WHITE); + } + } + } /** * Process a player and his clan's last seen date */ public void updateLastSeen(Player player) { + ClanPlayer cp = getAnyClanPlayer(player.getUniqueId()); if (cp != null) { + cp.updateLastSeen(); plugin.getStorageManager().updateClanPlayer(cp); Clan clan = cp.getClan(); if (clan != null) { + clan.updateLastUsed(); plugin.getStorageManager().updateClan(clan); + } + } + } @SuppressWarnings("deprecation") public void ban(String playerName) { + ban(Bukkit.getOfflinePlayer(playerName).getUniqueId()); + } /** @@ -475,16 +613,23 @@ public final class ClanManager { * @param uuid the player's uuid */ public void ban(UUID uuid) { + ClanPlayer cp = getClanPlayer(uuid); Clan clan = null; if (cp != null) { + clan = cp.getClan(); + } if (clan != null) { + if (clan.getSize() == 1) { + clan.disband(null, false, false); + } else { + cp.setClan(null); cp.addPastClan(clan.getColorTag() + (cp.isLeader() ? ChatColor.DARK_RED + "*" : "")); cp.setLeader(false); @@ -493,31 +638,41 @@ public final class ClanManager { plugin.getStorageManager().updateClanPlayer(cp); plugin.getStorageManager().updateClan(clan); + } + } plugin.getSettingsManager().addBanned(uuid); + } /** * Get a count of rivable clans */ public int getRivableClanCount() { + int clanCount = 0; for (Clan tm : clans.values()) { + if (!SimpleClans.getInstance().getSettingsManager().isUnrivable(tm.getTag())) { + clanCount++; + } + } return clanCount; + } /** * Returns a formatted string detailing the players armor */ public String getArmorString(PlayerInventory inv) { + String out = ""; ItemStack h = inv.getHelmet(); @@ -525,95 +680,168 @@ public final class ClanManager { Player player = null; InventoryHolder holder = inv.getHolder(); if (holder instanceof Player) { + player = (Player) holder; + } if (h != null) { + if (h.getType().equals(XMaterial.CHAINMAIL_HELMET.parseMaterial())) { + out += ChatColor.WHITE + lang("armor.h", player); + } else if (h.getType().equals(XMaterial.DIAMOND_HELMET.parseMaterial())) { + out += AQUA + lang("armor.h", player); + } else if (h.getType().equals(XMaterial.GOLDEN_HELMET.parseMaterial())) { + out += ChatColor.YELLOW + lang("armor.h", player); + } else if (h.getType().equals(XMaterial.IRON_HELMET.parseMaterial())) { + out += ChatColor.GRAY + lang("armor.h", player); + } else if (h.getType().equals(XMaterial.LEATHER_HELMET.parseMaterial())) { + out += ChatColor.GOLD + lang("armor.h", player); + } else if (h.getType().equals(XMaterial.AIR.parseMaterial())) { + out += ChatColor.BLACK + lang("armor.h", player); + } else { + out += RED + lang("armor.h", player); + } + } + ItemStack c = inv.getChestplate(); if (c != null) { + if (c.getType().equals(XMaterial.CHAINMAIL_CHESTPLATE.parseMaterial())) { + out += ChatColor.WHITE + lang("armor.c", player); + } else if (c.getType().equals(XMaterial.DIAMOND_CHESTPLATE.parseMaterial())) { + out += AQUA + lang("armor.c", player); + } else if (c.getType().equals(XMaterial.GOLDEN_CHESTPLATE.parseMaterial())) { + out += ChatColor.YELLOW + lang("armor.c", player); + } else if (c.getType().equals(XMaterial.IRON_CHESTPLATE.parseMaterial())) { + out += ChatColor.GRAY + lang("armor.c", player); + } else if (c.getType().equals(XMaterial.LEATHER_CHESTPLATE.parseMaterial())) { + out += ChatColor.GOLD + lang("armor.c", player); + } else if (c.getType().equals(XMaterial.AIR.parseMaterial())) { + out += ChatColor.BLACK + lang("armor.c", player); + } else { + out += RED + lang("armor.c", player); + } + } + ItemStack l = inv.getLeggings(); if (l != null) { + if (l.getType().equals(XMaterial.CHAINMAIL_LEGGINGS.parseMaterial())) { + out += ChatColor.WHITE + lang("armor.l", player); + } else if (l.getType().equals(XMaterial.DIAMOND_LEGGINGS.parseMaterial())) { + out += lang("armor.l", player); + } else if (l.getType().equals(XMaterial.GOLDEN_LEGGINGS.parseMaterial())) { + out += lang("armor.l", player); + } else if (l.getType().equals(XMaterial.IRON_LEGGINGS.parseMaterial())) { + out += lang("armor.l", player); + } else if (l.getType().equals(XMaterial.LEATHER_LEGGINGS.parseMaterial())) { + out += lang("armor.l", player); + } else if (l.getType().equals(XMaterial.AIR.parseMaterial())) { + out += lang("armor.l", player); + } else { + out += lang("armor.l", player); + } + } + ItemStack b = inv.getBoots(); if (b != null) { + if (b.getType().equals(XMaterial.CHAINMAIL_BOOTS.parseMaterial())) { + out += ChatColor.WHITE + lang("armor.B", player); + } else if (b.getType().equals(XMaterial.DIAMOND_BOOTS.parseMaterial())) { + out += AQUA + lang("armor.B", player); + } else if (b.getType().equals(XMaterial.GOLDEN_BOOTS.parseMaterial())) { + out += ChatColor.YELLOW + lang("armor.B", player); + } else if (b.getType().equals(XMaterial.IRON_BOOTS.parseMaterial())) { + out += ChatColor.WHITE + lang("armor.B", player); + } else if (b.getType().equals(XMaterial.LEATHER_BOOTS.parseMaterial())) { + out += ChatColor.GOLD + lang("armor.B", player); + } else if (b.getType().equals(XMaterial.AIR.parseMaterial())) { + out += ChatColor.BLACK + lang("armor.B", player); + } else { + out += RED + lang("armor.B", player); + } + } if (out.length() == 0) { + out = lang("none", player); + } return out; + } /** * Returns a formatted string detailing the players weapons */ public String getWeaponString(PlayerInventory inv) { + String headColor = plugin.getSettingsManager().getColored(PAGE_HEADINGS_COLOR); String out = ""; @@ -621,49 +849,63 @@ public final class ClanManager { Player player = null; InventoryHolder holder = inv.getHolder(); if (holder instanceof Player) { + player = (Player) holder; + } int count = getItemCount(inv, XMaterial.DIAMOND_SWORD); if (count > 0) { + String countString = count > 1 ? count + "" : ""; out += AQUA + lang("weapon.S", player) + headColor + countString; + } count = getItemCount(inv, XMaterial.GOLDEN_SWORD); if (count > 0) { + String countString = count > 1 ? count + "" : ""; out += ChatColor.YELLOW + lang("weapon.S", player) + headColor + countString; + } count = getItemCount(inv, XMaterial.IRON_SWORD); if (count > 0) { + String countString = count > 1 ? count + "" : ""; out += ChatColor.WHITE + lang("weapon.S", player) + headColor + countString; + } count = getItemCount(inv, XMaterial.STONE_SWORD); if (count > 0) { + String countString = count > 1 ? count + "" : ""; out += ChatColor.GRAY + lang("weapon.S", player) + headColor + countString; + } count = getItemCount(inv, XMaterial.WOODEN_SWORD); if (count > 0) { + String countString = count > 1 ? count + "" : ""; out += ChatColor.GOLD + lang("weapon.S", player) + headColor + countString; + } count = getItemCount(inv, XMaterial.BOW); if (count > 0) { + String countString = count > 1 ? count + "" : ""; out += ChatColor.GOLD + lang("weapon.B", player) + headColor + countString; + } count = getItemCount(inv, XMaterial.ARROW); @@ -671,45 +913,65 @@ public final class ClanManager { count += getItemCount(inv, XMaterial.TIPPED_ARROW); if (count > 0) { + out += ChatColor.WHITE + lang("weapon.A", player) + headColor + count; + } if (out.length() == 0) { + out = lang("none", player); + } return out; + } private int getItemCount(@NotNull PlayerInventory inv, @NotNull XMaterial material) { + Material parsed = material.parseMaterial(); if (parsed == null) { + return 0; + } return getItemCount(inv.all(parsed)); + } private int getItemCount(HashMap all) { + int count = 0; for (ItemStack is : all.values()) { + count += is.getAmount(); + } return count; + } private double getFoodPoints(PlayerInventory inv, XMaterial material, int points, double saturation) { + Material parsed = material.parseMaterial(); if (parsed == null) { + return 0; + } + return getFoodPoints(inv, parsed, points, saturation); + } private double getFoodPoints(PlayerInventory inv, Material material, int points, double saturation) { + return getItemCount(inv.all(material)) * (points + saturation); + } /** @@ -723,7 +985,9 @@ public final class ClanManager { Player player = null; InventoryHolder holder = inv.getHolder(); if (holder instanceof Player) { + player = (Player) holder; + } double count = getFoodPoints(inv, XMaterial.APPLE, 4, 2.4); @@ -763,369 +1027,540 @@ public final class ClanManager { count += getFoodPoints(inv, XMaterial.COOKED_BEEF, 8, 12.8); if (count == 0) { + return lang("none", player); + } else { + return ((int) count) + "" + ChatColor.GOLD + "p"; + } + } /** * Returns a colored bar based on the length */ public String getBar(double length) { + StringBuilder out = new StringBuilder(); if (length >= 16) { + out.append(ChatColor.GREEN); + } else if (length >= 8) { + out.append(ChatColor.GOLD); + } else { + out.append(RED); + } for (int i = 0; i < length; i++) { + out.append('|'); + } return out.toString(); + } /** * Sort clans by active */ public void sortClansByActive(List clans, boolean asc) { + clans.sort((c1, c2) -> { + int o = 1; if (!asc) { + o = -1; + } return Long.compare(c1.getLastUsed(), c2.getLastUsed()) * o; + }); + } /** * Sort clans by founded date */ public void sortClansByFounded(List clans, boolean asc) { + clans.sort((c1, c2) -> { + int o = 1; if (!asc) { + o = -1; + } return Long.compare(c1.getFounded(), c2.getFounded()) * o; + }); + } /** * Sort clans by kdr */ public void sortClansByKDR(List clans, boolean asc) { + clans.sort((c1, c2) -> { + int o = 1; if (!asc) { + o = -1; + } return Float.compare(c1.getTotalKDR(), c2.getTotalKDR()) * o; + }); + } /** * Sort clans by size */ public void sortClansBySize(List clans, boolean asc) { + clans.sort((c1, c2) -> { + int o = 1; if (!asc) { + o = -1; + } return Integer.compare(c1.getSize(), c2.getSize()) * o; + }); + } /** * Sort clans by name */ public void sortClansByName(List clans, boolean asc) { + clans.sort((c1, c2) -> { + int o = 1; if (!asc) { + o = -1; + } return c1.getName().compareTo(c2.getName()) * o; + }); + } /** * Sort clans by KDR */ public void sortClansByKDR(List clans) { + clans.sort((c1, c2) -> { + Float o1 = c1.getTotalKDR(); Float o2 = c2.getTotalKDR(); return o2.compareTo(o1); + }); + } /** * Sort clans by KDR */ public void sortClansBySize(List clans) { + clans.sort((c1, c2) -> { + Integer o1 = c1.getMembers().size(); Integer o2 = c2.getMembers().size(); return o2.compareTo(o1); + }); + } /** * Sort clan players by KDR */ public void sortClanPlayersByKDR(List cps) { + cps.sort((c1, c2) -> { + Float o1 = c1.getKDR(); Float o2 = c2.getKDR(); return o2.compareTo(o1); + }); + } /** * Sort clan players by last seen days */ public void sortClanPlayersByLastSeen(List cps) { + cps.sort((c1, c2) -> { + Double o1 = c1.getLastSeenDays(); Double o2 = c2.getLastSeenDays(); return o1.compareTo(o2); + }); + } public long getMinutesBeforeRejoin(@NotNull ClanPlayer cp, @NotNull Clan clan) { + SettingsManager settings = plugin.getSettingsManager(); if (settings.is(ENABLE_REJOIN_COOLDOWN)) { + Long resign = cp.getResignTime(clan.getTag()); if (resign != null) { + long timePassed = Instant.ofEpochMilli(resign).until(Instant.now(), ChronoUnit.MINUTES); int cooldown = settings.getInt(REJOIN_COOLDOWN); if (timePassed < cooldown) { + return cooldown - timePassed; + } + } + } + return 0; + } /** * Purchase member fee set */ public boolean purchaseMemberFeeSet(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_MEMBER_FEE_SET)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_MEMBER_FEE_SET_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.MEMBER_FEE_SET); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } return true; + } /** * Purchase clan creation */ public boolean purchaseCreation(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_CREATE)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_CREATION_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.CLAN_CREATION); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } return true; + } /** * Purchase invite */ public boolean purchaseInvite(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_INVITE)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_INVITE_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.CLAN_INVITATION); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } return true; + } /** * Purchase Home Teleport */ public boolean purchaseHomeTeleport(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_HOME_TELEPORT)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_HOME_TELEPORT_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.CLAN_HOME_TELEPORT); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } return true; + } /** * Purchase Home Teleport Set */ public boolean purchaseHomeTeleportSet(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_HOME_TELEPORT_SET)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_HOME_TELEPORT_SET_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.CLAN_HOME_TELEPORT_SET); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } return true; + } /** * Purchase Reset Kdr */ public boolean purchaseResetKdr(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_RESET_KDR)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_RESET_KDR_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.RESET_KDR); - player.spigot().sendMessage(new TextComponent(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price)))); + player.spigot().sendMessage(new TextComponent(RED + MessageFormat + .format(lang("account.has.been.debited", player), CurrencyFormat.format(price)))); + } else { - player.spigot().sendMessage(new TextComponent(RED + MessageFormat.format(lang("not.sufficient.money", player), CurrencyFormat.format(price)))); + + player.spigot().sendMessage(new TextComponent(RED + + MessageFormat.format(lang("not.sufficient.money", player), CurrencyFormat.format(price)))); return false; + } + } return true; + } /** * Purchase Home Regroup */ public boolean purchaseHomeRegroup(Player player) { + ClanPlayer cp = plugin.getClanManager().getClanPlayer(player); if (cp == null) { + return false; + } if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_HOME_REGROUP)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_REGROUP_PRICE); Clan clan = Objects.requireNonNull(cp.getClan(), "Clan cannot be null"); if (!plugin.getSettingsManager().is(ECONOMY_UNIQUE_TAX_ON_REGROUP)) { + price = price * VanishUtils.getNonVanished(player, clan).size(); + } - if (plugin.getSettingsManager().is(ECONOMY_ISSUER_PAYS_REGROUP) && plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getSettingsManager().is(ECONOMY_ISSUER_PAYS_REGROUP) + && plugin.getPermissionsManager().hasEconomy()) + { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.CLAN_REGROUP); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } else { + double money = plugin.getPermissionsManager().playerGetMoney(player); switch (clan.withdraw(new BankOperator(player, money), ClanBalanceUpdateEvent.Cause.COMMAND, price)) { + case SUCCESS: if (plugin.getPermissionsManager().grantPlayer(player, price)) { + player.sendMessage(AQUA + lang("player.clan.withdraw", player, CurrencyFormat.format(price))); clan.addBb(player.getName(), lang("bb.clan.withdraw", CurrencyFormat.format(price))); return true; + } case NOT_ENOUGH_BALANCE: player.sendMessage(lang("clan.bank.not.enough.money", player)); + } + } return false; + } /** * Purchase clan verification */ public boolean purchaseVerification(Player player) { + if (!plugin.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_VERIFY)) { + return true; + } double price = plugin.getSettingsManager().getDouble(ECONOMY_VERIFICATION_PRICE); if (plugin.getPermissionsManager().hasEconomy()) { + if (plugin.getPermissionsManager().playerHasMoney(player, price)) { + plugin.getPermissionsManager().chargePlayer(player, price, Cause.CLAN_VERIFICATION); - player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + player.sendMessage(RED + + MessageFormat.format(lang("account.has.been.debited", player), CurrencyFormat.format(price))); + } else { + player.sendMessage(RED + lang("not.sufficient.money", player, CurrencyFormat.format(price))); return false; + } + } return true; + } /** @@ -1133,32 +1568,45 @@ public final class ClanManager { */ @Deprecated public boolean processGlobalChat(Player player, String msg) { + ClanPlayer cp = plugin.getClanManager().getClanPlayer(player.getUniqueId()); if (cp == null) { + return false; + } String[] split = msg.split(" "); if (split.length == 0) { + return false; + } String command = split[0]; if (command.equals(lang("on", player))) { + cp.setGlobalChat(true); plugin.getStorageManager().updateClanPlayer(cp); ChatBlock.sendMessage(player, AQUA + "You have enabled global chat"); + } else if (command.equals(lang("off", player))) { + cp.setGlobalChat(false); plugin.getStorageManager().updateClanPlayer(cp); ChatBlock.sendMessage(player, AQUA + "You have disabled global chat"); + } else { + return true; + } return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/PermissionsManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/PermissionsManager.java index fc9563f1..097024e2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/PermissionsManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/PermissionsManager.java @@ -41,151 +41,220 @@ public final class PermissionsManager { private final HashMap permAttaches = new HashMap<>(); public PermissionsManager() { + plugin = SimpleClans.getInstance(); try { + Class.forName("net.milkbowl.vault.permission.Permission"); chat = getProvider(Chat.class); economy = getProvider(Economy.class); permission = getProvider(Permission.class); + } catch (ClassNotFoundException e) { + SimpleClans.getInstance().getLogger().info("Vault not found. No economy or extended Permissions support."); + } + } /** * Whether economy plugin exists and is enabled */ public boolean hasEconomy() { + return economy != null && economy.isEnabled(); + } /** * Loads the permissions for each clan from the config */ public void loadPermissions() { + permissions.clear(); for (Clan clan : plugin.getClanManager().getClans()) { - permissions.put(clan.getTag(), SimpleClans.getInstance().getSettingsManager().getConfig(). - getStringList("permissions." + clan.getTag())); + + permissions.put(clan.getTag(), SimpleClans.getInstance().getSettingsManager().getConfig() + .getStringList("permissions." + clan.getTag())); + } + } /** * Saves the permissions for each clan from the config */ public void savePermissions() { + for (Clan clan : plugin.getClanManager().getClans()) { + if (permissions.containsKey(clan.getTag())) { - SimpleClans.getInstance().getSettingsManager().getConfig().set("permissions." + clan.getTag(), getPermissions(clan)); + + SimpleClans.getInstance().getSettingsManager().getConfig().set("permissions." + clan.getTag(), + getPermissions(clan)); + } + } + } /** * Adds all permissions for a clan */ public void updateClanPermissions(Clan clan) { + for (ClanPlayer cp : clan.getMembers()) { + addPlayerPermissions(cp); + } + } /** * Adds permissions for a player */ public void addPlayerPermissions(@Nullable ClanPlayer cp) { + if (cp == null) { + return; + } + Clan clan = cp.getClan(); if (clan == null) { + return; + } + Player player = cp.toPlayer(); if (player != null) { + if (permissions.containsKey(clan.getTag())) { + if (!permAttaches.containsKey(player)) { + permAttaches.put(player, player.addAttachment(SimpleClans.getInstance())); + } - //Adds all permissions from his clan + + // Adds all permissions from his clan for (String perm : getPermissions(clan)) { + permAttaches.get(player).setPermission(perm, true); + } + if (plugin.getSettingsManager().is(PERMISSIONS_AUTO_GROUP_GROUPNAME)) { + permAttaches.get(player).setPermission("group." + clan.getTag(), true); + } + player.recalculatePermissions(); + } + } + } /** * Removes permissions for a clan (when it gets disbanded for example) */ public void removeClanPermissions(Clan clan) { + for (ClanPlayer cp : clan.getMembers()) { + removeClanPlayerPermissions(cp); removeClanPermissions(cp); + } + } /** * Removes permissions for a player (when he gets kicked for example) */ public void removeClanPlayerPermissions(@Nullable ClanPlayer cp) { + if (cp != null && cp.getClan() != null && cp.toPlayer() != null) { + Player player = cp.toPlayer(); if (player != null && permissions.containsKey(cp.getClan().getTag()) && permAttaches.containsKey(player)) { + permAttaches.get(player).remove(); permAttaches.remove(player); + } + } + } /** * Removes permissions linked to a clan from the player */ public void removeClanPermissions(ClanPlayer cp) { + if (!plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS)) { + return; + } if (permission != null && cp.toPlayer() != null) { + permission.playerRemoveGroup(null, cp.toPlayer(), "clan_" + cp.getTag()); permission.playerRemoveGroup(null, cp.toPlayer(), "sc_untrusted"); permission.playerRemoveGroup(null, cp.toPlayer(), "sc_trusted"); permission.playerRemoveGroup(null, cp.toPlayer(), "sc_leader"); + } + } /** * @return the permissions for a clan */ public List getPermissions(Clan clan) { + return permissions.get(clan.getTag()); + } public String format(double value) { + return Objects.requireNonNull(economy, "Can't find economy provider").format(value); + } /** * Charge a player some money * - * @deprecated use {@link PermissionsManager#chargePlayer(OfflinePlayer, double)} instead + * @deprecated use + * {@link PermissionsManager#chargePlayer(OfflinePlayer, double)} + * instead */ @Deprecated public boolean playerChargeMoney(OfflinePlayer player, double money) { + return chargePlayer(player, money); + } /** * Charges the specified amount of money from the player's account. *

- * As the {@link EconomyTransactionEvent.Cause} is not passed, this method won't fire the {@link EconomyTransactionEvent}. - * Use this method when you don't need to track the cause or handle custom transaction events. + * As the {@link EconomyTransactionEvent.Cause} is not passed, this method won't + * fire the {@link EconomyTransactionEvent}. Use this method when you don't need + * to track the cause or handle custom transaction events. *

* * @param player The player whose account will be charged. @@ -193,7 +262,9 @@ public final class PermissionsManager { * @see EconomyTransactionEvent */ public boolean chargePlayer(OfflinePlayer player, double money) { + return chargePlayer(player, money, null); + } /** @@ -206,48 +277,67 @@ public final class PermissionsManager { * @see EconomyTransactionEvent */ public boolean chargePlayer(@NotNull OfflinePlayer player, double money, @Nullable Cause cause) { - EconomyResponse response = Objects.requireNonNull(economy, "Can't find economy provider").withdrawPlayer(player, money); + + EconomyResponse response = Objects.requireNonNull(economy, "Can't find economy provider").withdrawPlayer(player, + money); if (!response.transactionSuccess()) { + return false; + } else if (cause == null) { + return true; + } - EconomyTransactionEvent event = new EconomyTransactionEvent(player, money, cause, EconomyTransactionEvent.TransactionType.WITHDRAW); + EconomyTransactionEvent event = new EconomyTransactionEvent(player, money, cause, + EconomyTransactionEvent.TransactionType.WITHDRAW); getPluginManager().callEvent(event); if (event.isCancelled()) { + economy.depositPlayer(player, money); return false; + } // handle EconomyTransactionEvent#setAmount double difference = event.getAmount() - response.amount; if (difference > 0) { + economy.withdrawPlayer(player, difference); + } + if (difference < 0) { + economy.depositPlayer(player, Math.abs(difference)); + } return true; + } /** * Grants a player some money * - * @deprecated use {@link PermissionsManager#grantPlayer(OfflinePlayer, double)} instead + * @deprecated use {@link PermissionsManager#grantPlayer(OfflinePlayer, double)} + * instead */ @Deprecated public boolean playerGrantMoney(OfflinePlayer player, double money) { + return grantPlayer(player, money); + } /** * Grants the specified amount of money to the player's account. *

- * As the {@link EconomyTransactionEvent.Cause} is not passed, this method won't fire the {@link EconomyTransactionEvent}. - * Use this method when you don't need to track the cause or handle custom transaction events. + * As the {@link EconomyTransactionEvent.Cause} is not passed, this method won't + * fire the {@link EconomyTransactionEvent}. Use this method when you don't need + * to track the cause or handle custom transaction events. *

* * @param player The player to whom the money will be granted. @@ -256,7 +346,9 @@ public final class PermissionsManager { * @see EconomyTransactionEvent */ public boolean grantPlayer(OfflinePlayer player, double money) { + return grantPlayer(player, money, null); + } /** @@ -269,31 +361,46 @@ public final class PermissionsManager { * @see EconomyTransactionEvent */ public boolean grantPlayer(@NotNull OfflinePlayer player, double money, @Nullable Cause cause) { - EconomyResponse response = Objects.requireNonNull(economy, "Can't find economy provider").depositPlayer(player, money); + + EconomyResponse response = Objects.requireNonNull(economy, "Can't find economy provider").depositPlayer(player, + money); if (!response.transactionSuccess()) { + return false; + } else if (cause == null) { + return true; + } - EconomyTransactionEvent event = new EconomyTransactionEvent(player, response.amount, cause, EconomyTransactionEvent.TransactionType.DEPOSIT); + EconomyTransactionEvent event = new EconomyTransactionEvent(player, response.amount, cause, + EconomyTransactionEvent.TransactionType.DEPOSIT); getPluginManager().callEvent(event); if (event.isCancelled()) { + economy.withdrawPlayer(player, money); return false; + } // handle EconomyTransactionEvent#setAmount double difference = event.getAmount() - response.amount; if (difference > 0) { + economy.depositPlayer(player, difference); + } + if (difference < 0) { + economy.withdrawPlayer(player, Math.abs(difference)); + } return true; + } /** @@ -302,7 +409,9 @@ public final class PermissionsManager { * @return whether he has the money */ public boolean playerHasMoney(OfflinePlayer player, double money) { + return economy.has(player, money); + } /** @@ -311,7 +420,9 @@ public final class PermissionsManager { * @return the players money */ public double playerGetMoney(OfflinePlayer player) { + return economy.getBalance(player); + } /** @@ -322,43 +433,62 @@ public final class PermissionsManager { * @return whether he has the permission */ public boolean has(@Nullable Player player, String perm) { + if (player == null) { + SimpleClans.debug("null player"); return false; + } boolean hasPermission; if (permission != null) { + hasPermission = permission.has(player, perm); + } else { + hasPermission = player.hasPermission(perm); + } + SimpleClans.debug(String.format("Permission %s is %s for %s", perm, hasPermission, player.getName())); return hasPermission; + } /** - * Checks if the player has the rank permission or the permission level, and the equivalent Bukkit permission + * Checks if the player has the rank permission or the permission level, and the + * equivalent Bukkit permission * * @param player the player * @param permission the rank permission * @param notify notify the player if they don't have permission - * @deprecated use {@link PermissionsManager#has(Player, RankPermission, boolean)} or {@link PermissionsManager#has(Player, String)} + * @deprecated use + * {@link PermissionsManager#has(Player, RankPermission, boolean)} + * or {@link PermissionsManager#has(Player, String)} */ @Deprecated public boolean has(Player player, RankPermission permission, PermissionLevel level, boolean notify) { + if (player == null || permission == null) { + return false; + } ClanPlayer clanPlayer = plugin.getClanManager().getClanPlayer(player); if (clanPlayer == null) { + return false; + } boolean hasBukkitPermission = has(player, permission.getBukkitPermission()); if (!hasBukkitPermission) { + return false; + } boolean hasLevel = hasLevel(clanPlayer, level); @@ -366,48 +496,72 @@ public final class PermissionsManager { boolean hasRankPermission = false; String rankName = clanPlayer.getRankId(); Clan clan = clanPlayer.getClan(); - //noinspection ConstantConditions + // noinspection ConstantConditions if (clan.hasRank(rankName)) { - //noinspection ConstantConditions + + // noinspection ConstantConditions hasRankPermission = clan.getRank(rankName).getPermissions().contains(permission.toString()); + } else if (!rankName.isEmpty()) { + clanPlayer.setRank(null); + } if (notify && !hasLevel && !hasRankPermission) { - ChatBlock.sendMessage(player, ChatColor.RED + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this", player), - level == PermissionLevel.LEADER ? lang("leader", player) : lang("trusted", player), permission.toString())); + + ChatBlock.sendMessage(player, + ChatColor.RED + + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this", player), + level == PermissionLevel.LEADER ? lang("leader", player) : lang("trusted", player), + permission.toString())); + } return hasLevel || hasRankPermission; + } /** - * Checks if the player has the rank permission or the permission level, and the equivalent Bukkit permission + * Checks if the player has the rank permission or the permission level, and the + * equivalent Bukkit permission * * @param player the player * @param permission the rank permission * @param notify notify the player if they don't have permission */ public boolean has(Player player, RankPermission permission, boolean notify) { + if (player == null || permission == null) { + return false; + } ClanPlayer clanPlayer = plugin.getClanManager().getClanPlayer(player); if (clanPlayer == null) { + if (notify) { + player.sendMessage(ChatColor.RED + lang("not.a.member.of.any.clan", player)); + } + return false; + } boolean hasBukkitPermission = has(player, permission.getBukkitPermission()); if (!hasBukkitPermission) { + if (notify) { + ChatBlock.sendMessage(player, ChatColor.RED + lang("insufficient.permissions", player)); + } + return false; + } boolean hasLevel = hasLevel(clanPlayer, permission.getPermissionLevel()); @@ -415,44 +569,70 @@ public final class PermissionsManager { String rankName = clanPlayer.getRankId(); Clan clan = clanPlayer.getClan(); if (clan != null) { + Rank rank = clan.getRank(rankName); if (rank != null) { + hasRankPermission = rank.getPermissions().contains(permission.toString()); + } + } else if (!rankName.isEmpty()) { + clanPlayer.setRank(null); + } if (notify && !hasLevel && !hasRankPermission) { - ChatBlock.sendMessage(player, ChatColor.RED + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this", player), - permission.getPermissionLevel() == PermissionLevel.LEADER ? lang("leader", player) : lang("trusted", player), permission.toString())); + + ChatBlock.sendMessage(player, + ChatColor.RED + + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this", player), + permission.getPermissionLevel() == PermissionLevel.LEADER ? lang("leader", player) + : lang("trusted", player), + permission.toString())); + } return hasLevel || hasRankPermission; + } private boolean hasLevel(@NotNull ClanPlayer cp, @Nullable PermissionLevel level) { + if (level != null) { + switch (level) { + case LEADER: return cp.isLeader(); case TRUSTED: return cp.isTrusted(); + } + } + return false; + } /** * Gives the player permissions linked to a clan */ public void addClanPermissions(ClanPlayer cp) { + if (!plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS) || cp == null || permission == null) { + return; + } + Player player = cp.toPlayer(); if (player == null) { + return; + } permission.playerRemoveGroup(null, player, "sc_leader"); @@ -460,85 +640,136 @@ public final class PermissionsManager { permission.playerRemoveGroup(null, player, "sc_untrusted"); if (cp.getClan() != null) { + permission.playerAddGroup(null, player, "clan_" + cp.getTag()); if (cp.isLeader()) { + permission.playerAddGroup(null, player, "sc_leader"); return; + } + if (cp.isTrusted()) { + permission.playerAddGroup(null, player, "sc_trusted"); return; + } + permission.playerAddGroup(null, player, "sc_untrusted"); + } + } public String getPrefix(Player p) { + String out = ""; try { + if (chat != null) { + out = chat.getPlayerPrefix(p); + } + } catch (Exception ex) { + // yea vault kinda sucks like that } if (permission != null && chat != null) { + try { + String world = p.getWorld().getName(); String prefix = chat.getPlayerPrefix(world, p); if (prefix == null || prefix.isEmpty()) { + String group = permission.getPrimaryGroup(world, p); prefix = chat.getGroupPrefix(world, group); if (prefix == null) { + prefix = ""; + } + } out = prefix.replace("&", "\u00a7").replace(String.valueOf((char) 194), ""); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } return out; + } public String getSuffix(Player p) { + try { + if (chat != null) { + return chat.getPlayerSuffix(p); + } + } catch (Exception ex) { + // yea vault kinda sucks like that } if (permission != null && chat != null) { + try { + String world = p.getWorld().getName(); String suffix = chat.getPlayerSuffix(world, p); if (suffix == null || suffix.isEmpty()) { + String group = permission.getPrimaryGroup(world, p); suffix = chat.getGroupSuffix(world, group); if (suffix == null) { + suffix = ""; + } + } + return suffix.replace("&", "\u00a7").replace(String.valueOf((char) 194), ""); + } catch (Exception e) { + System.out.println(e.getMessage()); return ""; + } + } + return ""; + } private @Nullable T getProvider(Class clazz) { + RegisteredServiceProvider registration = Bukkit.getServicesManager().getRegistration(clazz); if (registration != null) { + return registration.getProvider(); + } + return null; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java index 014f7a34..ccb4093a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java @@ -38,108 +38,168 @@ public class ProtectionManager { private final SimpleClans plugin; public ProtectionManager() { + plugin = SimpleClans.getInstance(); settingsManager = plugin.getSettingsManager(); clanManager = plugin.getClanManager(); logger = plugin.getLogger(); if (!settingsManager.is(ENABLE_WAR) && !settingsManager.is(LAND_SHARING)) { + return; + } - //running on next tick, so all plugins are already loaded + + // running on next tick, so all plugins are already loaded Bukkit.getScheduler().runTask(plugin, this::registerProviders); clearWars(); + } public void registerListeners() { + landProtection = new LandProtection(plugin); if (!settingsManager.is(ENABLE_WAR) && !settingsManager.is(LAND_SHARING)) { + return; + } + landProtection.registerListeners(); + } /** - * Gets the Player's lands at the given Location, if not found, returns all Player's lands in the World + * Gets the Player's lands at the given Location, if not found, returns all + * Player's lands in the World * * @param player the Player * @param location the Location * @return the lands */ public Set getLands(@NotNull Player player, @NotNull Location location) { + Set lands = getLandsAt(location); lands.removeIf(land -> !land.getOwners().contains(player.getUniqueId())); if (lands.isEmpty()) { + lands = getLandsOf(player, player.getWorld()); + } + return lands; + } @NotNull public Set getLandsAt(@NotNull Location location) { + Set lands = new HashSet<>(); for (ProtectionProvider provider : providers) { + lands.addAll(provider.getLandsAt(location)); + } + return lands; + } public boolean isOwner(@NotNull OfflinePlayer player, @NotNull Location location) { + debug(String.format("isOwner: player %s %s -> %s", player.getName(), player.getUniqueId(), location)); for (Land land : getLandsAt(location)) { + debug(String.format("land -> id %s - owners %s", land.getId(), land.getOwners())); if (land.getOwners().contains(player.getUniqueId())) { + return true; + } + } + return false; + } @NotNull public Set getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) { + Set lands = new HashSet<>(); for (ProtectionProvider provider : providers) { + lands.addAll(provider.getLandsOf(player, world)); + } + return lands; + } public boolean can(@NotNull Action action, @NotNull Location location, @NotNull Player player) { + return can(action, location, player, null); + } - public boolean can(@NotNull Action action, @NotNull Location location, @NotNull Player player, @Nullable Player other) { + public boolean can(@NotNull Action action, @NotNull Location location, @NotNull Player player, + @Nullable Player other) + { + for (Land land : getLandsAt(location)) { + for (UUID owner : land.getOwners()) { + if (owner == null) { + continue; + } + Player involved; if (other != null && player.getUniqueId().equals(owner)) { + involved = other; + } else { + involved = player; + } - if (isWarringAndAllowed(action, owner, involved) || - isSameClanAndAllowed(action, owner, involved, land.getId())) { + + if (isWarringAndAllowed(action, owner, involved) + || isSameClanAndAllowed(action, owner, involved, land.getId())) + { + return true; + } + } + } + return false; + } @SuppressWarnings("UnusedReturnValue") public boolean addWar(@NotNull ClanPlayer requester, Clan requestClan, Clan targetClan) { + War war = new War(requestClan, targetClan); if (wars.containsKey(war)) { + return false; + } WarStartEvent event = new WarStartEvent(war); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return false; + } requestClan.addWarringClan(requester, targetClan); @@ -147,38 +207,61 @@ public class ProtectionManager { wars.put(war, scheduleTask(war, settingsManager.getMinutes(WAR_NORMAL_EXPIRATION_TIME))); return true; + } @Nullable private BukkitTask scheduleTask(@NotNull War war, int expirationTime) { + BukkitTask timeoutTask = null; if (expirationTime > 0) { + timeoutTask = Bukkit.getScheduler().runTaskLater(plugin, new WarTimeoutTask(war), expirationTime); + } + return timeoutTask; + } public void setWarExpirationTime(@NotNull Clan clan, int expirationTime) { + if (expirationTime < 1) { + return; + } + for (Map.Entry entry : wars.entrySet()) { + War war = entry.getKey(); if (!war.getClans().contains(clan)) { + continue; + } + BukkitTask task = entry.getValue(); if (task != null && !task.isCancelled()) { + task.cancel(); + } + entry.setValue(scheduleTask(war, expirationTime)); + } + } public void removeWar(@Nullable War war, @NotNull WarEndEvent.Reason reason) { + if (war == null) { + return; + } + wars.remove(war); Clan clan1 = war.getClans().get(0); Clan clan2 = war.getClans().get(1); @@ -187,104 +270,175 @@ public class ProtectionManager { WarEndEvent event = new WarEndEvent(war, reason); Bukkit.getPluginManager().callEvent(event); + } public @Nullable War getWar(@Nullable Clan clan1, @Nullable Clan clan2) { + if (clan1 == null || clan2 == null) { + return null; + } + for (War war : wars.keySet()) { + List clans = war.getClans(); if (clans.contains(clan1) && clans.contains(clan2)) { + return war; + } + } + return null; + } private void clearWars() { + if (!settingsManager.is(ENABLE_WAR)) { + return; + } + for (Clan clan : clanManager.getClans()) { + for (Clan warringClan : clan.getWarringClans()) { + clan.removeWarringClan(warringClan); + } + } + } private boolean isSameClanAndAllowed(Action action, UUID owner, Player involved, String landId) { + if (!settingsManager.is(LAND_SHARING)) { + return false; + } + ClanPlayer cp = clanManager.getCreateClanPlayer(owner); Clan involvedClan = clanManager.getClanByPlayerUniqueId(involved.getUniqueId()); if (cp.getClan() == null || !cp.getClan().equals(involvedClan)) { + return false; + } + return cp.isAllowed(action, landId); + } private boolean isWarringAndAllowed(@NotNull Action action, @NotNull UUID owner, @NotNull Player involved) { + if (!settingsManager.isActionAllowedInWar(action) || !settingsManager.is(ENABLE_WAR)) { + return false; + } + Clan ownerClan = clanManager.getClanByPlayerUniqueId(owner); Clan involvedClan = clanManager.getClanByPlayerUniqueId(involved.getUniqueId()); if (ownerClan == null || involvedClan == null) { + return false; + } + return ownerClan.isWarring(involvedClan); + } private void registerProviders() { + for (String className : settingsManager.getStringList(LAND_PROTECTION_PROVIDERS)) { + Object instance = null; try { + Class clazz = getProviderClass(className); instance = clazz.getConstructor().newInstance(); + } catch (ClassNotFoundException ex) { + logger.log(Level.WARNING, String.format("Provider %s not found!", className), ex); - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | - IllegalAccessException ex) { + + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException + | IllegalAccessException ex) + { + logger.log(Level.WARNING, String.format("Error instantiating provider %s", className), ex); + } + if (instance instanceof ProtectionProvider) { + registerProvider((ProtectionProvider) instance); + } else if (instance != null) { + logger.warning(String.format("%s is not an instance of ProtectionProvider", className)); + } + } + } public void registerProvider(@NotNull ProtectionProvider provider) { + String requiredPlugin = provider.getRequiredPluginName(); String providerName = provider.getClass().getSimpleName(); if (requiredPlugin != null && Bukkit.getPluginManager().getPlugin(requiredPlugin) == null) { + debug(String.format("Required plugin %s for the provider %s was not found!", requiredPlugin, providerName)); return; + } + try { + provider.setup(); + } catch (LinkageError | Exception throwable) { + logger.log(Level.WARNING, String.format("Error registering provider %s", providerName)); if (settingsManager.is(DEBUG)) { + throwable.printStackTrace(); + } + return; + } + providers.add(provider); landProtection.registerCreateLandEvent(provider, provider.getCreateLandEvent()); logger.info(String.format("Registered %s successfully", providerName)); + } @NotNull private Class getProviderClass(String className) throws ClassNotFoundException { + try { + return Class.forName("net.sacredlabyrinth.phaed.simpleclans.hooks.protection.providers." + className); + } catch (ClassNotFoundException ignored) { + } + return Class.forName(className); + } public enum Action { @@ -296,16 +450,22 @@ public class ProtectionManager { private final War war; private WarTimeoutTask(War war) { + this.war = war; + } @Override public void run() { + removeWar(war, WarEndEvent.Reason.EXPIRATION); Clan clan1 = war.getClans().get(0); Clan clan2 = war.getClans().get(1); clan1.addBb(clan1.getColorTag(), lang("war.expired", clan2.getTag())); clan2.addBb(clan2.getColorTag(), lang("war.expired", clan1.getTag())); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/RequestManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/RequestManager.java index 0bbfdd89..b93bed89 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/RequestManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/RequestManager.java @@ -22,6 +22,7 @@ import static org.bukkit.ChatColor.RED; * @author phaed */ public final class RequestManager { + private final SimpleClans plugin; private final HashMap requests = new HashMap<>(); @@ -29,19 +30,27 @@ public final class RequestManager { * */ public RequestManager() { + plugin = SimpleClans.getInstance(); askerTask(); + } @SuppressWarnings("BooleanMethodIsAlwaysInverted") public boolean hasRequest(String tag) { + return requests.containsKey(tag); + } public void addDemoteRequest(ClanPlayer requester, String demotedName, Clan clan) { + if (requests.containsKey(clan.getTag())) { + return; + } + String msg = MessageFormat.format(lang("asking.for.the.demotion"), requester.getName(), demotedName); ClanPlayer demotedTp = plugin.getClanManager().getAnyClanPlayer(demotedName); @@ -53,45 +62,53 @@ public final class RequestManager { req.vote(requester.getName(), VoteResult.ACCEPT); requests.put(req.getClan().getTag(), req); ask(req); + } /** - * This method asks all leaders about - * some action inside their clan. + * This method asks all leaders about some action inside their + * clan. *

* Example of possible requests: *

*
    - *
  • Disband request can be asked from all leaders
  • - *
  • Rename request can be asked from all leaders
  • - *
  • Promote request can be asked from all leaders
  • + *
  • Disband request can be asked from all leaders
  • + *
  • Rename request can be asked from all leaders
  • + *
  • Promote request can be asked from all leaders
  • *
* *

* Examples of incompatible requests: *

*
    - *
  • Demote request can be asked from all leaders, - * except the demoted one.
  • - *
  • Invite request has to ask someone outside of leaders clan
  • + *
  • Demote request can be asked from all leaders, except the demoted + * one.
  • + *
  • Invite request has to ask someone outside of leaders clan
  • *
* * @param requester the clan player, who sent the request * @param request the type of request, see: {@link ClanRequest} * @param target the target which will be used in request processing - * @param key the language key that would be translated and send the message to all leaders + * @param key the language key that would be translated and send the + * message to all leaders * @param args the language objects, requires in some language strings. * @throws IllegalArgumentException if passed incompatible request */ - public void requestAllLeaders(@NotNull ClanPlayer requester, @NotNull ClanRequest request, - @NotNull String target, @NotNull String key, @Nullable Object... args) { + public void requestAllLeaders(@NotNull ClanPlayer requester, @NotNull ClanRequest request, @NotNull String target, + @NotNull String key, @Nullable Object... args) + { + if (request.equals(ClanRequest.INVITE) || request.equals(ClanRequest.DEMOTE)) { + throw new IllegalArgumentException("Unsupported request: " + request.name()); + } Clan clan = requester.getClan(); if (clan == null || requests.containsKey(clan.getTag())) { + return; + } String msg = lang(key, args); @@ -102,6 +119,7 @@ public final class RequestManager { req.vote(requester.getName(), VoteResult.ACCEPT); ask(req); + } /** @@ -112,25 +130,37 @@ public final class RequestManager { * @param clan the Clan */ public void addInviteRequest(ClanPlayer requester, String invitedName, Clan clan) { + if (requests.containsKey(invitedName.toLowerCase())) { + return; + } + Player player = Bukkit.getPlayer(invitedName); if (player == null) { + return; + } String msg = lang("inviting.you.to.join", player, requester.getName(), clan.getName()); Request req = new Request(ClanRequest.INVITE, null, requester, invitedName, clan, msg); requests.put(invitedName.toLowerCase(), req); ask(req); + } public void addWarStartRequest(ClanPlayer requester, Clan warClan, Clan requestingClan) { + if (requests.containsKey(warClan.getTag())) { + return; + } - String msg = MessageFormat.format(lang("proposing.war"), requestingClan.getName(), ChatUtils.stripColors(warClan.getColorTag())); + + String msg = MessageFormat.format(lang("proposing.war"), requestingClan.getName(), + ChatUtils.stripColors(warClan.getColorTag())); List acceptors = Helper.stripOffLinePlayers(warClan.getLeaders()); acceptors.remove(requester); @@ -138,13 +168,19 @@ public final class RequestManager { Request req = new Request(ClanRequest.START_WAR, acceptors, requester, warClan.getTag(), requestingClan, msg); requests.put(req.getTarget(), req); ask(req); + } public void addWarEndRequest(ClanPlayer requester, Clan warClan, Clan requestingClan) { + if (requests.containsKey(warClan.getTag())) { + return; + } - String msg = MessageFormat.format(lang("proposing.to.end.the.war"), requestingClan.getName(), ChatUtils.stripColors(warClan.getColorTag())); + + String msg = MessageFormat.format(lang("proposing.to.end.the.war"), requestingClan.getName(), + ChatUtils.stripColors(warClan.getColorTag())); List acceptors = Helper.stripOffLinePlayers(warClan.getLeaders()); acceptors.remove(requester); @@ -152,95 +188,139 @@ public final class RequestManager { Request req = new Request(ClanRequest.END_WAR, acceptors, requester, warClan.getTag(), requestingClan, msg); requests.put(req.getTarget(), req); ask(req); + } public void addAllyRequest(ClanPlayer requester, Clan allyClan, Clan requestingClan) { + if (requests.containsKey(allyClan.getTag())) { + return; + } - String msg = MessageFormat.format(lang("proposing.an.alliance"), requestingClan.getName(), ChatUtils.stripColors(allyClan.getColorTag())); + + String msg = MessageFormat.format(lang("proposing.an.alliance"), requestingClan.getName(), + ChatUtils.stripColors(allyClan.getColorTag())); List acceptors = Helper.stripOffLinePlayers(allyClan.getLeaders()); acceptors.remove(requester); - Request req = new Request(ClanRequest.CREATE_ALLY, acceptors, requester, allyClan.getTag(), requestingClan, msg); + Request req = new Request(ClanRequest.CREATE_ALLY, acceptors, requester, allyClan.getTag(), requestingClan, + msg); requests.put(req.getTarget(), req); ask(req); + } public void addRivalryBreakRequest(ClanPlayer requester, Clan rivalClan, Clan requestingClan) { + if (requests.containsKey(rivalClan.getTag())) { + return; + } - String msg = MessageFormat.format(lang("proposing.to.end.the.rivalry"), requestingClan.getName(), ChatUtils.stripColors(rivalClan.getColorTag())); + + String msg = MessageFormat.format(lang("proposing.to.end.the.rivalry"), requestingClan.getName(), + ChatUtils.stripColors(rivalClan.getColorTag())); List acceptors = Helper.stripOffLinePlayers(rivalClan.getLeaders()); acceptors.remove(requester); - Request req = new Request(ClanRequest.BREAK_RIVALRY, acceptors, requester, rivalClan.getTag(), requestingClan, msg); + Request req = new Request(ClanRequest.BREAK_RIVALRY, acceptors, requester, rivalClan.getTag(), requestingClan, + msg); requests.put(req.getTarget(), req); ask(req); + } public void accept(ClanPlayer cp) { + Request req = requests.get(cp.getTag()); if (req != null) { + req.vote(cp.getName(), VoteResult.ACCEPT); processResults(req); + } else { + req = requests.get(cp.getCleanName()); if (req != null) { + processInvite(req, VoteResult.ACCEPT); + } + } + } public void deny(ClanPlayer cp) { + Request req = requests.get(cp.getTag()); if (req != null) { + req.vote(cp.getName(), VoteResult.DENY); processResults(req); + } else { + req = requests.get(cp.getCleanName()); if (req != null) { + processInvite(req, VoteResult.DENY); + } + } + } public void processInvite(Request req, VoteResult vote) { + requests.remove(req.getTarget().toLowerCase()); Clan clan = req.getClan(); Player invited = Bukkit.getPlayerExact(req.getTarget()); if (invited == null) { + return; + } if (vote.equals(VoteResult.ACCEPT)) { + ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(invited.getUniqueId()); - int maxMembers = !clan.isVerified() ? plugin.getSettingsManager().getInt(CLAN_UNVERIFIED_MAX_MEMBERS) : plugin.getSettingsManager().getInt(CLAN_MAX_MEMBERS); + int maxMembers = !clan.isVerified() ? plugin.getSettingsManager().getInt(CLAN_UNVERIFIED_MAX_MEMBERS) + : plugin.getSettingsManager().getInt(CLAN_MAX_MEMBERS); if (maxMembers > 0 && maxMembers > clan.getSize()) { + ChatBlock.sendMessageKey(invited, "accepted.invitation", clan.getName()); clan.addBb(lang("joined.the.clan", invited.getName())); plugin.getClanManager().serverAnnounce(lang("has.joined", invited.getName(), clan.getName())); clan.addPlayerToClan(cp); + } else { + ChatBlock.sendMessageKey(invited, "this.clan.has.reached.the.member.limit"); + } + } else { + ChatBlock.sendMessageKey(invited, "denied.invitation", clan.getName()); clan.leaderAnnounce(RED + lang("membership.invitation", invited.getName())); + } + } - public void processResults(Request req) { + Clan requestClan = req.getClan(); ClanPlayer requester = req.getRequester(); @@ -257,6 +337,7 @@ public final class RequestManager { List denies = req.getDenies(); switch (req.getType()) { + case START_WAR: processStartWar(requester, requestClan, targetClan, accepts, denies); break; @@ -272,139 +353,215 @@ public final class RequestManager { case DEMOTE: case PROMOTE: if (!req.votingFinished() || targetUuid == null) { + return; + } target = requestClan.getTag(); if (req.getType() == ClanRequest.DEMOTE) { + processDemote(req, requestClan, targetUuid, denies); + } if (req.getType() == ClanRequest.PROMOTE) { + processPromote(req, requestClan, targetUuid, denies); + } break; case DISBAND: if (!req.votingFinished()) { + return; + } processDisband(requester, requestClan, denies); break; case RENAME: if (!req.votingFinished()) { + return; + } processRename(req); break; default: return; + } requests.remove(target); SimpleClans.getInstance().getServer().getPluginManager().callEvent(new RequestFinishedEvent(req)); req.cleanVotes(); + } private void processRename(Request request) { + if (request.getDenies().isEmpty()) { + request.getClan().setName(request.getTarget()); + } else { + String deniers = String.join(", ", request.getDenies()); request.getClan().leaderAnnounce(RED + lang("rename.refused", deniers)); + } + } private void processDisband(ClanPlayer requester, Clan requestClan, List denies) { + if (denies.isEmpty()) { + requestClan.disband(requester.toPlayer(), true, false); + } else { + String deniers = String.join(", ", denies); requestClan.leaderAnnounce(RED + lang("clan.deletion", deniers)); + } + } private void processPromote(Request req, Clan requestClan, UUID targetPlayer, List denies) { + String promotedName = req.getTarget(); if (denies.isEmpty()) { + requestClan.addBb(lang("leaders"), lang("promoted.to.leader", promotedName)); requestClan.promote(targetPlayer); + } else { + String deniers = String.join(", ", denies); requestClan.leaderAnnounce(RED + lang("denied.the.promotion", deniers, promotedName)); + } + } private void processDemote(Request req, Clan requestClan, UUID targetPlayer, List denies) { + String demotedName = req.getTarget(); if (denies.isEmpty()) { + requestClan.addBb(lang("leaders"), lang("demoted.back.to.member", demotedName)); requestClan.demote(targetPlayer); + } else { + String deniers = String.join(", ", denies); - requestClan.leaderAnnounce( - RED + lang("denied.demotion", deniers, demotedName)); + requestClan.leaderAnnounce(RED + lang("denied.demotion", deniers, demotedName)); + } + } private void processBreakRivalry(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan, - List accepts, List denies) { + List accepts, List denies) + { + if (targetClan != null && requestClan != null) { + if (!accepts.isEmpty()) { + requestClan.removeRival(targetClan); - targetClan.addBb(requester.getName(), lang("broken.the.rivalry", accepts.get(0), requestClan.getName())); - requestClan.addBb(requester.getName(), lang("broken.the.rivalry.with", requester.getName(), targetClan.getName())); + targetClan.addBb(requester.getName(), + lang("broken.the.rivalry", accepts.get(0), requestClan.getName())); + requestClan.addBb(requester.getName(), + lang("broken.the.rivalry.with", requester.getName(), targetClan.getName())); + } else { - targetClan.addBb(requester.getName(), lang("denied.to.make.peace", denies.get(0), requestClan.getName())); + + targetClan.addBb(requester.getName(), + lang("denied.to.make.peace", denies.get(0), requestClan.getName())); requestClan.addBb(requester.getName(), lang("peace.agreement.denied", targetClan.getName())); + } + } + } private void processCreateAlly(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan, - List accepts, List denies) { + List accepts, List denies) + { + if (targetClan != null && requestClan != null) { + if (!accepts.isEmpty()) { + requestClan.addAlly(targetClan); - targetClan.addBb(requester.getName(), lang("accepted.an.alliance", accepts.get(0), requestClan.getName())); - requestClan.addBb(requester.getName(), lang("created.an.alliance", requester.getName(), targetClan.getName())); + targetClan.addBb(requester.getName(), + lang("accepted.an.alliance", accepts.get(0), requestClan.getName())); + requestClan.addBb(requester.getName(), + lang("created.an.alliance", requester.getName(), targetClan.getName())); + } else { + targetClan.addBb(requester.getName(), lang("denied.an.alliance", denies.get(0), requestClan.getName())); requestClan.addBb(requester.getName(), lang("the.alliance.was.denied", targetClan.getName())); + } + } + } private void processEndWar(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan, List accepts, - List denies) { + List denies) + { + if (requestClan != null && targetClan != null) { + if (!accepts.isEmpty()) { + War war = plugin.getProtectionManager().getWar(requestClan, targetClan); plugin.getProtectionManager().removeWar(war, WarEndEvent.Reason.REQUEST); requestClan.removeWarringClan(targetClan); targetClan.removeWarringClan(requestClan); - targetClan.addBb(requester.getName(), lang("you.are.no.longer.at.war", accepts.get(0), requestClan.getColorTag())); - requestClan.addBb(requester.getName(), lang("you.are.no.longer.at.war", requestClan.getName(), targetClan.getColorTag())); + targetClan.addBb(requester.getName(), + lang("you.are.no.longer.at.war", accepts.get(0), requestClan.getColorTag())); + requestClan.addBb(requester.getName(), + lang("you.are.no.longer.at.war", requestClan.getName(), targetClan.getColorTag())); + } else { + targetClan.addBb(requester.getName(), lang("denied.war.end", denies.get(0), requestClan.getName())); requestClan.addBb(requester.getName(), lang("end.war.denied", targetClan.getName())); + } + } + } private void processStartWar(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan, - List accepts, List denies) { + List accepts, List denies) + { + if (requestClan != null && targetClan != null) { + if (!accepts.isEmpty()) { + plugin.getProtectionManager().addWar(requester, requestClan, targetClan); + } else { - targetClan.addBb(requester.getName(), lang("denied.war.req", denies.get(0), - requestClan.getName())); - requestClan.addBb(requester.getName(), lang("end.war.denied", - targetClan.getName())); + + targetClan.addBb(requester.getName(), lang("denied.war.req", denies.get(0), requestClan.getName())); + requestClan.addBb(requester.getName(), lang("end.war.denied", targetClan.getName())); + } + } + } /** @@ -413,55 +570,79 @@ public final class RequestManager { * @param playerName the Player signing off */ public void endPendingRequest(String playerName) { + for (Request req : new LinkedList<>(requests.values())) { + for (ClanPlayer cp : req.getAcceptors()) { + if (cp.getName().equalsIgnoreCase(playerName)) { + req.getClan().leaderAnnounce(lang("signed.off.request.cancelled", RED + playerName, req.getType())); requests.remove(req.getClan().getTag()); break; + } + } + } } public void removeRequest(@NotNull String keyOrTarget) { + Iterator> iterator = requests.entrySet().iterator(); while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); final String requester = entry.getKey(); final String target = entry.getValue().getTarget(); if (keyOrTarget.equals(requester) || keyOrTarget.equals(target)) { + entry.getValue().cleanVotes(); iterator.remove(); + } + } + } /** * Starts the task that asks for the votes of all requests */ public void askerTask() { + new BukkitRunnable() { @Override public void run() { - for (Iterator> iter = requests.entrySet().iterator(); iter.hasNext(); ) { + + for (Iterator> iter = requests.entrySet().iterator(); iter.hasNext();) { + Request req = iter.next().getValue(); if (req == null) { + continue; + } if (req.reachedRequestLimit()) { + iter.remove(); + } ask(req); req.incrementAskCount(); + } + } + }.runTaskTimerAsynchronously(plugin, 0, plugin.getSettingsManager().getSeconds(REQUEST_FREQUENCY)); + } /** @@ -470,24 +651,39 @@ public final class RequestManager { * @param req the Request */ public void ask(final Request req) { + String message = lang("request.message", req.getClan().getColorTag(), req.getMsg()); ArrayList recipients = new ArrayList<>(); if (req.getType() == ClanRequest.INVITE) { + recipients.add(Bukkit.getPlayerExact(req.getTarget())); + } else { + for (ClanPlayer cp : req.getAcceptors()) { + if (cp.getVote() == null) { + recipients.add(cp.toPlayer()); + } + } + } for (Player recipient : recipients) { + if (recipient != null) { + recipient.spigot().sendMessage(ChatUtils.toBaseComponents(recipient, message)); + } + } Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getPluginManager().callEvent(new RequestEvent(req))); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java index e7117629..9ef85793 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java @@ -32,118 +32,173 @@ public final class SettingsManager { private final File configFile; public SettingsManager(SimpleClans plugin) { + this.plugin = plugin; config = plugin.getConfig(); config.options().copyDefaults(true); configFile = new File(plugin.getDataFolder() + File.separator + "config.yml"); loadAndSave(); warnAboutPluginDependencies(); + } public void set(ConfigField field, T value) { + config.set(field.path, value); + } public int getInt(ConfigField field) { + return config.getInt(field.path, toInt(field.defaultValue)); + } public double getDouble(ConfigField field) { + return config.getDouble(field.path, toDouble(field.defaultValue)); + } public List getStringList(ConfigField field) { + return config.getStringList(field.path); + } public String getString(ConfigField field) { + return config.getString(field.path, String.valueOf(field.defaultValue)); + } public String getColored(ConfigField field) { + String value = getString(field); return (value.length() == 1) ? ChatUtils.getColorByChar(value.charAt(0)) : ChatUtils.parseColors(value); + } public int getMinutes(ConfigField field) { + int value = getInt(field); return (value >= 1) ? value * 20 * 60 : toInt(field.defaultValue) * 20 * 60; + } public int getSeconds(ConfigField field) { + int value = getInt(field); return (value >= 1) ? value * 20 : toInt(field.defaultValue) * 20; + } public double getPercent(ConfigField field) { + double value = getDouble(field); return (getDouble(field) >= 0 || getDouble(field) <= 100) ? value : toDouble(field.defaultValue); + } public boolean is(ConfigField field) { + return config.getBoolean(field.path, (Boolean) field.defaultValue); + } /** * Load the configuration */ public void loadAndSave() { + if (configFile.exists()) { + try { + config.load(configFile); + } catch (IOException | InvalidConfigurationException ex) { + SimpleClans.getInstance().getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + } save(); + } public void save() { + try { + config.save(configFile); + } catch (IOException ex) { + SimpleClans.getInstance().getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + } private void warnAboutPluginDependencies() { + Plugin luckPerms = getPluginManager().getPlugin("LuckPerms"); Plugin discordSrv = getPluginManager().getPlugin("DiscordSRV"); if (luckPerms != null && is(PERMISSIONS_AUTO_GROUP_GROUPNAME)) { + plugin.getLogger().warning("LuckPerms was found and the setting auto-group-groupname is enabled."); - plugin.getLogger().warning("Be careful with that as players will be automatically added in the group" + - " that matches their clan tag."); + plugin.getLogger().warning("Be careful with that as players will be automatically added in the group" + + " that matches their clan tag."); + } if (discordSrv == null && is(DISCORDCHAT_ENABLE)) { + plugin.getLogger().warning("DiscordChat can't be initialized, please, install DiscordSRV."); + } + } public Locale getLanguage() { + String language = getString(LANGUAGE); String[] split = language.split("_"); if (split.length == 2) { + return new Locale(split[0], split[1]); + } return new Locale(language); + } public List getItemList() { + List itemsList = new ArrayList<>(); for (String material : getStringList(ITEM_LIST)) { + Optional x = XMaterial.matchXMaterial(material); if (x.isPresent()) { + itemsList.add(x.get().parseMaterial()); + } else { + plugin.getLogger().warning("Error with Material: " + material); + } + } + return itemsList; + } /** @@ -153,14 +208,20 @@ public final class SettingsManager { * @return whether its disallowed word */ public boolean isDisallowedWord(String word) { + for (String disallowedTag : getStringList(DISALLOWED_TAGS)) { + if (disallowedTag.equalsIgnoreCase(word)) { + return true; + } + } - return word.equalsIgnoreCase(getString(COMMANDS_CLAN)) || word.equalsIgnoreCase(getString(COMMANDS_MORE)) || - word.equalsIgnoreCase(getString(COMMANDS_DENY)) || word.equalsIgnoreCase(getString(COMMANDS_ACCEPT)); + return word.equalsIgnoreCase(getString(COMMANDS_CLAN)) || word.equalsIgnoreCase(getString(COMMANDS_MORE)) + || word.equalsIgnoreCase(getString(COMMANDS_DENY)) || word.equalsIgnoreCase(getString(COMMANDS_ACCEPT)); + } /** @@ -170,15 +231,20 @@ public final class SettingsManager { * @return whether the string contains the color code */ public boolean hasDisallowedColor(String str) { + String loweredString = str.toLowerCase(); - return getStringList(DISALLOWED_TAG_COLORS).stream().map(String::toLowerCase).anyMatch(color -> loweredString.contains("&" + color)); + return getStringList(DISALLOWED_TAG_COLORS).stream().map(String::toLowerCase) + .anyMatch(color -> loweredString.contains("&" + color)); + } /** * @return a comma delimited string with all disallowed colors */ public String getDisallowedColorString() { + return String.join(", ", getStringList(DISALLOWED_TAG_COLORS)); + } /** @@ -188,9 +254,10 @@ public final class SettingsManager { * @return whether the clan is unrivable */ public boolean isUnrivable(String tag) { - return getStringList(UNRIVABLE_CLANS).stream(). - map(String::toLowerCase). - anyMatch(unrivable -> unrivable.equals(tag.toLowerCase())); + + return getStringList(UNRIVABLE_CLANS).stream().map(String::toLowerCase) + .anyMatch(unrivable -> unrivable.equals(tag.toLowerCase())); + } /** @@ -199,14 +266,18 @@ public final class SettingsManager { * @param playerUniqueId the player's name */ public void addBanned(UUID playerUniqueId) { + List bannedPlayers = getStringList(BANNED_PLAYERS); if (isBanned(playerUniqueId)) { + return; + } bannedPlayers.add(playerUniqueId.toString()); set(BANNED_PLAYERS, bannedPlayers); save(); + } /** @@ -216,7 +287,9 @@ public final class SettingsManager { * @return whether player is banned */ public boolean isBanned(UUID playerUniqueId) { + return getStringList(BANNED_PLAYERS).contains(playerUniqueId.toString()); + } /** @@ -225,121 +298,120 @@ public final class SettingsManager { * @param playerUniqueId the player's name */ public void removeBanned(UUID playerUniqueId) { + List bannedPlayers = getStringList(BANNED_PLAYERS); bannedPlayers.remove(playerUniqueId.toString()); set(BANNED_PLAYERS, bannedPlayers); save(); + } public boolean isActionAllowedInWar(@NotNull ProtectionManager.Action action) { + return is(ConfigField.valueOf("WAR_ACTIONS_" + action.name())); + } public List getIgnoredList(@NotNull ProtectionManager.Action action) { + return getStringList(ConfigField.valueOf("WAR_LISTENERS_IGNORED_LIST_" + action.name())); + } @NotNull public RankingType getRankingType() { + try { + return RankingType.valueOf(getString(RANKING_TYPE)); + } catch (IllegalArgumentException ex) { + return RankingType.DENSE; + } + } @SuppressWarnings("unchecked") public @NotNull Collection getStarterRanks() { + List ranks = new ArrayList<>(); List> mapList = config.getMapList("clan.starter-ranks"); for (Map rankMap : mapList) { + Set names = (Set) rankMap.keySet(); for (String name : names) { + Map rank = (Map) rankMap.get(name); String displayName = (String) rank.get("display-name"); List permissions = (List) rank.get("permissions"); ranks.add(new Rank(name, displayName, new HashSet<>(permissions))); + } + } + return ranks; + } public FileConfiguration getConfig() { + return config; + } public enum ConfigField { + /* - ================ - > General Settings - ================ + * ================ > General Settings ================ * */ - ENABLE_GUI("settings.enable-gui", true), - DISABLE_MESSAGES("settings.disable-messages", false), + ENABLE_GUI("settings.enable-gui", true), DISABLE_MESSAGES("settings.disable-messages", false), TAMABLE_MOBS_SHARING("settings.tameable-mobs-sharing", false), TELEPORT_BLOCKS("settings.teleport-blocks", false), TELEPORT_HOME_ON_SPAWN("settings.teleport-home-on-spawn", false), DROP_ITEMS_ON_CLAN_HOME("settings.drop-items-on-clan-home", false), - KEEP_ITEMS_ON_CLAN_HOME("settings.keep-items-on-clan-home", false), - ITEM_LIST("settings.item-list"), - DEBUG("settings.show-debug-info", false), - ENABLE_AUTO_GROUPS("settings.enable-auto-groups", false), + KEEP_ITEMS_ON_CLAN_HOME("settings.keep-items-on-clan-home", false), ITEM_LIST("settings.item-list"), + DEBUG("settings.show-debug-info", false), ENABLE_AUTO_GROUPS("settings.enable-auto-groups", false), CHAT_COMPATIBILITY_MODE("settings.chat-compatibility-mode", true), RIVAL_LIMIT_PERCENT("settings.rival-limit-percent", 50), COLOR_CODE_FROM_PREFIX_FOR_NAME("settings.use-colorcode-from-prefix-for-name", true), DISPLAY_CHAT_TAGS("settings.display-chat-tags", true), - GLOBAL_FRIENDLY_FIRE("settings.global-friendly-fire", false), - UNRIVABLE_CLANS("settings.unrivable-clans"), + GLOBAL_FRIENDLY_FIRE("settings.global-friendly-fire", false), UNRIVABLE_CLANS("settings.unrivable-clans"), SHOW_UNVERIFIED_ON_LIST("settings.show-unverified-on-list", false), - BLACKLISTED_WORLDS("settings.blacklisted-worlds"), - BANNED_PLAYERS("settings.banned-players"), - DISALLOWED_TAGS("settings.disallowed-tags"), - LANGUAGE("settings.language", "en"), + BLACKLISTED_WORLDS("settings.blacklisted-worlds"), BANNED_PLAYERS("settings.banned-players"), + DISALLOWED_TAGS("settings.disallowed-tags"), LANGUAGE("settings.language", "en"), LANGUAGE_SELECTOR("settings.user-language-selector", true), - DISALLOWED_TAG_COLORS("settings.disallowed-tag-colors"), - SERVER_NAME("settings.server-name", "&4SimpleClans"), + DISALLOWED_TAG_COLORS("settings.disallowed-tag-colors"), SERVER_NAME("settings.server-name", "&4SimpleClans"), REQUIRE_VERIFICATION("settings.new-clan-verification-required", true), - ALLOW_REGROUP("settings.allow-regroup-command", true), - ALLOW_RESET_KDR("settings.allow-reset-kdr", false), + ALLOW_REGROUP("settings.allow-regroup-command", true), ALLOW_RESET_KDR("settings.allow-reset-kdr", false), REJOIN_COOLDOWN("settings.rejoin-cooldown", 60), ENABLE_REJOIN_COOLDOWN("settings.rejoin-cooldown-enabled", false), - RANKING_TYPE("settings.ranking-type", "DENSE"), - LIST_DEFAULT_ORDER_BY("settings.list-default-order-by", "kdr"), - LORE_LENGTH("settings.lore-length", 36), - PVP_ONLY_WHILE_IN_WAR("settings.pvp-only-while-at-war", false), + RANKING_TYPE("settings.ranking-type", "DENSE"), LIST_DEFAULT_ORDER_BY("settings.list-default-order-by", "kdr"), + LORE_LENGTH("settings.lore-length", 36), PVP_ONLY_WHILE_IN_WAR("settings.pvp-only-while-at-war", false), PAST_CLANS_LIMIT("settings.past-clans-limit", 10), - USERNAME_REGEX("settings.username-regex", "^\\**[a-zA-Z0-9_$]{1,16}$"), - TAG_REGEX("settings.tag-regex", ""), + USERNAME_REGEX("settings.username-regex", "^\\**[a-zA-Z0-9_$]{1,16}$"), TAG_REGEX("settings.tag-regex", ""), ACCEPT_OTHER_ALPHABETS_LETTERS("settings.accept-other-alphabets-letters-on-tag", false), DATE_TIME_PATTERN("settings.date-time-pattern", "HH:mm - dd/MM/yyyy"), BUNGEE_SERVERS("settings.bungee-servers"), /* - ================ - > Tag Settings - ================ + * ================ > Tag Settings ================ * */ - TAG_DEFAULT_COLOR("tag.default-color", "8"), - TAG_BRACKET_COLOR("tag.bracket.color", "8"), - TAG_BRACKET_LEADER_COLOR("tag.bracket.leader-color", "4"), - TAG_BRACKET_LEFT("tag.bracket.left", ""), - TAG_MAX_LENGTH("tag.max-length", 5), - TAG_MIN_LENGTH("tag.min-length", 2), - TAG_BRACKET_RIGHT("tag.bracket.right", ""), - TAG_SEPARATOR_COLOR("tag.separator.color", "8"), - TAG_SEPARATOR_LEADER_COLOR("tag.separator.leader-color", "4"), - TAG_SEPARATOR_CHAR("tag.separator.char", " ."), + TAG_DEFAULT_COLOR("tag.default-color", "8"), TAG_BRACKET_COLOR("tag.bracket.color", "8"), + TAG_BRACKET_LEADER_COLOR("tag.bracket.leader-color", "4"), TAG_BRACKET_LEFT("tag.bracket.left", ""), + TAG_MAX_LENGTH("tag.max-length", 5), TAG_MIN_LENGTH("tag.min-length", 2), + TAG_BRACKET_RIGHT("tag.bracket.right", ""), TAG_SEPARATOR_COLOR("tag.separator.color", "8"), + TAG_SEPARATOR_LEADER_COLOR("tag.separator.leader-color", "4"), TAG_SEPARATOR_CHAR("tag.separator.char", " ."), @Deprecated TAG_SEPARATOR_char("tag.separator.char", " ."), /* - ================ - > War and Protection Settings - ================ + * ================ > War and Protection Settings ================ * */ - ENABLE_WAR("war-and-protection.war-enabled", false), - LAND_SHARING("war-and-protection.land-sharing", true), + ENABLE_WAR("war-and-protection.war-enabled", false), LAND_SHARING("war-and-protection.land-sharing", true), LAND_PROTECTION_PROVIDERS("war-and-protection.protection-providers"), WAR_LISTENERS_PRIORITY("war-and-protection.listeners.priority", "HIGHEST"), WAR_LISTENERS_IGNORED_LIST_PLACE("war-and-protection.listeners.ignored-list.PLACE"), @@ -359,9 +431,7 @@ public final class SettingsManager { WAR_START_REQUEST_ENABLED("war-and-protection.war-start.request-enabled", true), WAR_MAX_MEMBERS_DIFFERENCE("war-and-protection.war-start.members-online-max-difference", 5), /* - ================ - > KDR Grinding Prevention Settings - ================ + * ================ > KDR Grinding Prevention Settings ================ * */ KDR_ENABLE_MAX_KILLS("kdr-grinding-prevention.enable-max-kills", false), @@ -369,23 +439,15 @@ public final class SettingsManager { KDR_ENABLE_KILL_DELAY("kdr-grinding-prevention.enable-kill-delay", false), KDR_DELAY_BETWEEN_KILLS("kdr-grinding-prevention.delay-between-kills", 5), /* - ================ - > Commands Settings - ================ + * ================ > Commands Settings ================ * */ - COMMANDS_MORE("commands.more", "more"), - COMMANDS_ALLY("commands.ally", "ally"), - COMMANDS_CLAN("commands.clan", "clan"), - COMMANDS_ACCEPT("commands.accept", "accept"), - COMMANDS_DENY("commands.deny", "deny"), - COMMANDS_GLOBAL("commands.global", "global"), - COMMANDS_CLAN_CHAT("commands.clan_chat", "."), - COMMANDS_FORCE_PRIORITY("commands.force-priority", true), + COMMANDS_MORE("commands.more", "more"), COMMANDS_ALLY("commands.ally", "ally"), + COMMANDS_CLAN("commands.clan", "clan"), COMMANDS_ACCEPT("commands.accept", "accept"), + COMMANDS_DENY("commands.deny", "deny"), COMMANDS_GLOBAL("commands.global", "global"), + COMMANDS_CLAN_CHAT("commands.clan_chat", "."), COMMANDS_FORCE_PRIORITY("commands.force-priority", true), /* - ================ - > Economy Settings - ================ + * ================ > Economy Settings ================ * */ ECONOMY_CREATION_PRICE("economy.creation-price", 100.0), @@ -412,145 +474,105 @@ public final class SettingsManager { ECONOMY_MEMBER_FEE_SET_PRICE("economy.member-fee-set-price", 1000.0), ECONOMY_MEMBER_FEE_ENABLED("economy.member-fee-enabled", false), ECONOMY_MEMBER_FEE_LAST_MINUTE_CHANGE_INTERVAL("economy.member-fee-last-minute-change-interval", 8), - ECONOMY_MAX_MEMBER_FEE("economy.max-member-fee", 200.0), - ECONOMY_UPKEEP("economy.upkeep", false), + ECONOMY_MAX_MEMBER_FEE("economy.max-member-fee", 200.0), ECONOMY_UPKEEP("economy.upkeep", false), ECONOMY_UPKEEP_ENABLED("economy.upkeep-enabled", false), ECONOMY_MULTIPLY_UPKEEP_BY_CLAN_SIZE("economy.multiply-upkeep-by-clan-size", false), ECONOMY_UPKEEP_REQUIRES_MEMBER_FEE("economy.charge-upkeep-only-if-member-fee-enabled", true), ECONOMY_BANK_LOG_ENABLED("economy.bank-log.enable", true), /* - ================ - > Kill Weights Settings - ================ + * ================ > Kill Weights Settings ================ * */ - KILL_WEIGHTS_RIVAL("kill-weights.rival", 2.0), - KILL_WEIGHTS_CIVILIAN("kill-weights.civilian", 0.0), - KILL_WEIGHTS_NEUTRAL("kill-weights.neutral", 1.0), - KILL_WEIGHTS_ALLY("kill-weights.ally", -1.0), + KILL_WEIGHTS_RIVAL("kill-weights.rival", 2.0), KILL_WEIGHTS_CIVILIAN("kill-weights.civilian", 0.0), + KILL_WEIGHTS_NEUTRAL("kill-weights.neutral", 1.0), KILL_WEIGHTS_ALLY("kill-weights.ally", -1.0), KILL_WEIGHTS_DENY_SAME_IP_KILLS("kill-weights.deny-same-ip-kills", false), /* - ================ - > Clan Settings - ================ + * ================ > Clan Settings ================ * */ CLAN_TELEPORT_DELAY("clan.homebase-teleport-wait-secs", 10), CLAN_HOMEBASE_CAN_BE_SET_ONLY_ONCE("clan.homebase-can-be-set-only-once", true), CLAN_MIN_SIZE_TO_SET_RIVAL("clan.min-size-to-set-rival", 3), - CLAN_MIN_SIZE_TO_SET_ALLY("clan.min-size-to-set-ally", 3), - CLAN_MAX_LENGTH("clan.max-length", 25), - CLAN_MIN_LENGTH("clan.min-length", 2), - CLAN_MAX_DESCRIPTION_LENGTH("clan.max-description-length", 120), - CLAN_MIN_DESCRIPTION_LENGTH("clan.min-description-length", 10), - CLAN_MAX_MEMBERS("clan.max-members", 25), - CLAN_UNVERIFIED_MAX_MEMBERS("clan.unverified-max-members", 10), - CLAN_MAX_ALLIANCES("clan.max-alliances", -1), + CLAN_MIN_SIZE_TO_SET_ALLY("clan.min-size-to-set-ally", 3), CLAN_MAX_LENGTH("clan.max-length", 25), + CLAN_MIN_LENGTH("clan.min-length", 2), CLAN_MAX_DESCRIPTION_LENGTH("clan.max-description-length", 120), + CLAN_MIN_DESCRIPTION_LENGTH("clan.min-description-length", 10), CLAN_MAX_MEMBERS("clan.max-members", 25), + CLAN_UNVERIFIED_MAX_MEMBERS("clan.unverified-max-members", 10), CLAN_MAX_ALLIANCES("clan.max-alliances", -1), CLAN_CONFIRMATION_FOR_PROMOTE("clan.confirmation-for-promote", false), CLAN_TRUST_MEMBERS_BY_DEFAULT("clan.trust-members-by-default", false), CLAN_CONFIRMATION_FOR_DEMOTE("clan.confirmation-for-demote", false), CLAN_PERCENTAGE_ONLINE_TO_DEMOTE("clan.percentage-online-to-demote", 100.0), - CLAN_FF_ON_BY_DEFAULT("clan.ff-on-by-default", false), - CLAN_MIN_TO_VERIFY("clan.min-to-verify", 1), + CLAN_FF_ON_BY_DEFAULT("clan.ff-on-by-default", false), CLAN_MIN_TO_VERIFY("clan.min-to-verify", 1), CLAN_DEFAULT_RANK("clan.default-rank", "recruit"), /* - ================ - > Tasks Settings - ================ + * ================ > Tasks Settings ================ * */ TASKS_COLLECT_UPKEEP_HOUR("tasks.collect-upkeep.hour", 1), TASKS_COLLECT_UPKEEP_MINUTE("tasks.collect-upkeep.minute", 30), TASKS_COLLECT_UPKEEP_WARNING_HOUR("tasks.collect-upkeep-warning.hour", 12), TASKS_COLLECT_UPKEEP_WARNING_MINUTE("tasks.collect-upkeep-warning.minute", 0), - TASKS_COLLECT_FEE_HOUR("tasks.collect-fee.hour", 1), - TASKS_COLLECT_FEE_MINUTE("tasks.collect-fee.minute", 0), + TASKS_COLLECT_FEE_HOUR("tasks.collect-fee.hour", 1), TASKS_COLLECT_FEE_MINUTE("tasks.collect-fee.minute", 0), /* - ================ - > Page Settings - ================ + * ================ > Page Settings ================ */ - PAGE_LEADER_COLOR("page.leader-color", "4"), - PAGE_UNTRUSTED_COLOR("page.untrusted-color", "8"), - PAGE_TRUSTED_COLOR("page.trusted-color", "f"), - PAGE_CLAN_NAME_COLOR("page.clan-name-color", "b"), - PAGE_SUBTITLE_COLOR("page.subtitle-color", "7"), - PAGE_HEADINGS_COLOR("page.headings-color", "8"), - PAGE_SEPARATOR("page.separator", "-"), - PAGE_SIZE("page.size", 100), - HELP_SIZE("page.help-size", 10), + PAGE_LEADER_COLOR("page.leader-color", "4"), PAGE_UNTRUSTED_COLOR("page.untrusted-color", "8"), + PAGE_TRUSTED_COLOR("page.trusted-color", "f"), PAGE_CLAN_NAME_COLOR("page.clan-name-color", "b"), + PAGE_SUBTITLE_COLOR("page.subtitle-color", "7"), PAGE_HEADINGS_COLOR("page.headings-color", "8"), + PAGE_SEPARATOR("page.separator", "-"), PAGE_SIZE("page.size", 100), HELP_SIZE("page.help-size", 10), /* - ================ - > Clan Chat Settings - ================ + * ================ > Clan Chat Settings ================ * */ - CLANCHAT_ENABLE("clanchat.enable", true), - CLANCHAT_TAG_BASED("clanchat.tag-based-clan-chat", false), + CLANCHAT_ENABLE("clanchat.enable", true), CLANCHAT_TAG_BASED("clanchat.tag-based-clan-chat", false), CLANCHAT_ANNOUNCEMENT_COLOR("clanchat.announcement-color", "e"), CLANCHAT_FORMAT("clanchat.format", "&b[%clan%&b] &4<%nick-color%%player%&4> %rank%: &b%message%"), - CLANCHAT_SPYFORMAT("clanchat.spy-format", "&8[Spy] [&bC&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"), - CLANCHAT_RANK("clanchat.rank", "&f[%rank%&f]"), - CLANCHAT_LEADER_COLOR("clanchat.leader-color", "4"), - CLANCHAT_TRUSTED_COLOR("clanchat.trusted-color", "f"), - CLANCHAT_MEMBER_COLOR("clanchat.member-color", "7"), + CLANCHAT_SPYFORMAT("clanchat.spy-format", + "&8[Spy] [&bC&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"), + CLANCHAT_RANK("clanchat.rank", "&f[%rank%&f]"), CLANCHAT_LEADER_COLOR("clanchat.leader-color", "4"), + CLANCHAT_TRUSTED_COLOR("clanchat.trusted-color", "f"), CLANCHAT_MEMBER_COLOR("clanchat.member-color", "7"), CLANCHAT_BRACKET_COLOR("clanchat.tag-bracket.color", "e"), CLANCHAT_BRACKET_LEFT("clanchat.tag-bracket.left", ""), - CLANCHAT_BRACKET_RIGHT("clanchat.tag-bracket.right", ""), - CLANCHAT_NAME_COLOR("clanchat.name-color", "e"), + CLANCHAT_BRACKET_RIGHT("clanchat.tag-bracket.right", ""), CLANCHAT_NAME_COLOR("clanchat.name-color", "e"), CLANCHAT_PLAYER_BRACKET_LEFT("clanchat.player-bracket.left", ""), CLANCHAT_PLAYER_BRACKET_RIGHT("clanchat.player-bracket.right", ""), CLANCHAT_MESSAGE_COLOR("clanchat.message-color", "b"), CLANCHAT_LISTENER_PRIORITY("clanchat.listener-priority", "LOW"), /* - ================ - > Request Settings - ================ + * ================ > Request Settings ================ * */ - REQUEST_MESSAGE_COLOR("request.message-color", "b"), - REQUEST_FREQUENCY("request.ask-frequency-secs", 60), + REQUEST_MESSAGE_COLOR("request.message-color", "b"), REQUEST_FREQUENCY("request.ask-frequency-secs", 60), REQUEST_MAX("request.max-asks-per-request", 1440), /* - ================ - > BB Settings - ================ + * ================ > BB Settings ================ */ - BB_PREFIX("bb.prefix", "&8* &e"), - BB_SHOW_ON_LOGIN("bb.show-on-login", true), - BB_SIZE("bb.size", 6), + BB_PREFIX("bb.prefix", "&8* &e"), BB_SHOW_ON_LOGIN("bb.show-on-login", true), BB_SIZE("bb.size", 6), BB_LOGIN_SIZE("bb.login-size", 6), /* - ================ - > Ally Chat Settings - ================ + * ================ > Ally Chat Settings ================ */ ALLYCHAT_ENABLE("allychat.enable", true), ALLYCHAT_FORMAT("allychat.format", "&b[Ally Chat] &4<%clan%&4> <%nick-color%%player%&4> %rank%: &b%message%"), - ALLYCHAT_SPYFORMAT("allychat.spy-format", "&8[Spy] [&cA&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"), - ALLYCHAT_RANK("allychat.rank", "&f[%rank%&f]"), - ALLYCHAT_LEADER_COLOR("allychat.leader-color", "4"), - ALLYCHAT_TRUSTED_COLOR("allychat.trusted-color", "f"), - ALLYCHAT_MEMBER_COLOR("allychat.member-color", "7"), + ALLYCHAT_SPYFORMAT("allychat.spy-format", + "&8[Spy] [&cA&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"), + ALLYCHAT_RANK("allychat.rank", "&f[%rank%&f]"), ALLYCHAT_LEADER_COLOR("allychat.leader-color", "4"), + ALLYCHAT_TRUSTED_COLOR("allychat.trusted-color", "f"), ALLYCHAT_MEMBER_COLOR("allychat.member-color", "7"), ALLYCHAT_BRACKET_COLOR("allychat.tag-bracket.color", "8"), ALLYCHAT_BRACKET_lEFT("allychat.tag-bracket.left", ""), ALLYCHAT_BRACKET_RIGHT("allychat.tag-bracket.right", ""), ALLYCHAT_PLAYER_BRACKET_LEFT("allychat.player-bracket.left", ""), ALLYCHAT_PLAYER_BRACKET_RIGHT("allychat.player-bracket.right", ""), - ALLYCHAT_MESSAGE_COLOR("allychat.message-color", "3"), - ALLYCHAT_TAG_COLOR("allychat.tag-color", ""), + ALLYCHAT_MESSAGE_COLOR("allychat.message-color", "3"), ALLYCHAT_TAG_COLOR("allychat.tag-color", ""), /* - ================ - > Discord Chat Settings - ================ + * ================ > Discord Chat Settings ================ */ - DISCORDCHAT_ENABLE("discordchat.enable", false), - DISCORDCHAT_AUTO_CREATION("discordchat.auto-creation", true), + DISCORDCHAT_ENABLE("discordchat.enable", false), DISCORDCHAT_AUTO_CREATION("discordchat.auto-creation", true), DISCORDCHAT_FORMAT_TO("discordchat.discord-format", "%player% » %message%"), - DISCORDCHAT_FORMAT("discordchat.format", "&b[&9D&b] &b[%clan%&b] &4<%nick-color%%player%&4> %rank%: &b%message%"), - DISCORDCHAT_SPYFORMAT("discordchat.spy-format", "&8[Spy] [&9D&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"), - DISCORDCHAT_RANK("discordchat.rank", "[%rank%]"), - DISCORDCHAT_LEADER_ROLE("discordchat.leader-role", "Leader"), + DISCORDCHAT_FORMAT("discordchat.format", + "&b[&9D&b] &b[%clan%&b] &4<%nick-color%%player%&4> %rank%: &b%message%"), + DISCORDCHAT_SPYFORMAT("discordchat.spy-format", + "&8[Spy] [&9D&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"), + DISCORDCHAT_RANK("discordchat.rank", "[%rank%]"), DISCORDCHAT_LEADER_ROLE("discordchat.leader-role", "Leader"), DISCORDCHAT_LEADER_ID("discordchat.leader-id", "0"), DISCORDCHAT_LEADER_COLOR("discordchat.leader-color", "231, 76, 60, 100"), DISCORDCHAT_TEXT_CATEGORY_FORMAT("discordchat.text.category-format", "SC - TextChannels"), @@ -559,35 +581,23 @@ public final class SettingsManager { DISCORDCHAT_TEXT_LIMIT("discordchat.text.clans-limit", 100), DISCORDCHAT_MINIMUM_LINKED_PLAYERS("discordchat.min-linked-players-to-create", 3), /* - ================ - > Purge Settings - ================ + * ================ > Purge Settings ================ */ PURGE_INACTIVE_PLAYER_DAYS("purge.inactive-player-data-days", 30), PURGE_INACTIVE_CLAN_DAYS("purge.inactive-clan-days", 7), PURGE_UNVERIFIED_CLAN_DAYS("purge.unverified-clan-days", 2), /* - ================ - > MySQL Settings - ================ + * ================ > MySQL Settings ================ */ - MYSQL_USERNAME("mysql.username", ""), - MYSQL_HOST("mysql.host", "localhost"), - MYSQL_PORT("mysql.port", 3306), - MYSQL_ENABLE("mysql.enable", false), - MYSQL_PASSWORD("mysql.password", ""), - MYSQL_DATABASE("mysql.database", ""), + MYSQL_USERNAME("mysql.username", ""), MYSQL_HOST("mysql.host", "localhost"), MYSQL_PORT("mysql.port", 3306), + MYSQL_ENABLE("mysql.enable", false), MYSQL_PASSWORD("mysql.password", ""), MYSQL_DATABASE("mysql.database", ""), MYSQL_TABLE_PREFIX("mysql.table_prefix", "sc_"), /* - ================ - > Permissions Settings - ================ + * ================ > Permissions Settings ================ */ PERMISSIONS_AUTO_GROUP_GROUPNAME("permissions.auto-group-groupname", false), /* - ================ - > Performance Settings - ================ + * ================ > Performance Settings ================ */ PERFORMANCE_SAVE_PERIODICALLY("performance.save-periodically", true), PERFORMANCE_SAVE_INTERVAL("performance.save-interval", 10), @@ -601,13 +611,19 @@ public final class SettingsManager { private final Object defaultValue; ConfigField(String path, Object defaultValue) { + this.path = path; this.defaultValue = defaultValue; + } ConfigField(String path) { + this.path = path; defaultValue = null; + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/StorageManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/StorageManager.java index b218311c..d27ca9b7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/StorageManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/StorageManager.java @@ -48,10 +48,12 @@ public final class StorageManager { * */ public StorageManager() { + plugin = SimpleClans.getInstance(); initiateDB(); updateDatabase(); importFromDatabase(); + } /** @@ -61,7 +63,9 @@ public final class StorageManager { * @return the ChatBlock */ public ChatBlock getChatBlock(Player player) { - return chatBlocks.get(player.getName()); + + return chatBlocks.get(player.getName()); + } /** @@ -69,292 +73,331 @@ public final class StorageManager { * */ public void addChatBlock(CommandSender player, ChatBlock cb) { - chatBlocks.put(player.getName(), cb); + + chatBlocks.put(player.getName(), cb); + } /** * Initiates the db */ public void initiateDB() { + SettingsManager settings = plugin.getSettingsManager(); if (settings.is(MYSQL_ENABLE)) { - core = new MySQLCore(settings.getString(MYSQL_HOST), settings.getString(MYSQL_DATABASE), settings.getInt(MYSQL_PORT), settings.getString(MYSQL_USERNAME), settings.getString(MYSQL_PASSWORD)); + + core = new MySQLCore(settings.getString(MYSQL_HOST), settings.getString(MYSQL_DATABASE), + settings.getInt(MYSQL_PORT), settings.getString(MYSQL_USERNAME), + settings.getString(MYSQL_PASSWORD)); if (core.checkConnection()) { + plugin.getLogger().info(lang("mysql.connection.successful")); if (!core.existsTable(getPrefixedTable("clans"))) { + plugin.getLogger().info("Creating table: " + getPrefixedTable("clans")); String query = "CREATE TABLE IF NOT EXISTS `" + getPrefixedTable("clans") + "` (" - + " `id` bigint(20) NOT NULL auto_increment," - + " `verified` tinyint(1) default '0'," - + " `tag` varchar(25) NOT NULL," - + " `color_tag` varchar(255) NOT NULL," - + " `name` varchar(100) NOT NULL," - + " `description` varchar(255)," - + " `friendly_fire` tinyint(1) default '0'," - + " `founded` bigint NOT NULL," - + " `last_used` bigint NOT NULL," - + " `packed_allies` text NOT NULL," - + " `packed_rivals` text NOT NULL," - + " `packed_bb` mediumtext NOT NULL," - + " `cape_url` varchar(255) NOT NULL," - + " `flags` text NOT NULL," - + " `balance` double(64,2)," - + " `fee_enabled` tinyint(1) default '0'," - + " `fee_value` double(64,2)," - + " `ranks` text NOT NULL," - + " `banner` text," - + " PRIMARY KEY (`id`)," - + " UNIQUE KEY `uq_simpleclans_1` (`tag`));"; + + " `id` bigint(20) NOT NULL auto_increment," + " `verified` tinyint(1) default '0'," + + " `tag` varchar(25) NOT NULL," + " `color_tag` varchar(255) NOT NULL," + + " `name` varchar(100) NOT NULL," + " `description` varchar(255)," + + " `friendly_fire` tinyint(1) default '0'," + " `founded` bigint NOT NULL," + + " `last_used` bigint NOT NULL," + " `packed_allies` text NOT NULL," + + " `packed_rivals` text NOT NULL," + " `packed_bb` mediumtext NOT NULL," + + " `cape_url` varchar(255) NOT NULL," + " `flags` text NOT NULL," + + " `balance` double(64,2)," + " `fee_enabled` tinyint(1) default '0'," + + " `fee_value` double(64,2)," + " `ranks` text NOT NULL," + " `banner` text," + + " PRIMARY KEY (`id`)," + " UNIQUE KEY `uq_simpleclans_1` (`tag`));"; core.execute(query); + } if (!core.existsTable(getPrefixedTable("players"))) { + plugin.getLogger().info("Creating table: " + getPrefixedTable("players")); String query = "CREATE TABLE IF NOT EXISTS `" + getPrefixedTable("players") + "` (" - + " `id` bigint(20) NOT NULL auto_increment," - + " `name` varchar(16) NOT NULL," - + " `leader` tinyint(1) default '0'," - + " `tag` varchar(25) NOT NULL," - + " `friendly_fire` tinyint(1) default '0'," - + " `neutral_kills` int(11) default NULL," - + " `rival_kills` int(11) default NULL," - + " `civilian_kills` int(11) default NULL," - + " `ally_kills` int(11) default NULL," - + " `deaths` int(11) default NULL," - + " `last_seen` bigint NOT NULL," - + " `join_date` bigint NOT NULL," - + " `trusted` tinyint(1) default '0'," - + " `flags` text NOT NULL," - + " `packed_past_clans` text," - + " `resign_times` text," - + " `locale` varchar(10)," - + " PRIMARY KEY (`id`)," - + " UNIQUE KEY `uq_sc_players_1` (`name`));"; + + " `id` bigint(20) NOT NULL auto_increment," + " `name` varchar(16) NOT NULL," + + " `leader` tinyint(1) default '0'," + " `tag` varchar(25) NOT NULL," + + " `friendly_fire` tinyint(1) default '0'," + " `neutral_kills` int(11) default NULL," + + " `rival_kills` int(11) default NULL," + " `civilian_kills` int(11) default NULL," + + " `ally_kills` int(11) default NULL," + " `deaths` int(11) default NULL," + + " `last_seen` bigint NOT NULL," + " `join_date` bigint NOT NULL," + + " `trusted` tinyint(1) default '0'," + " `flags` text NOT NULL," + + " `packed_past_clans` text," + " `resign_times` text," + " `locale` varchar(10)," + + " PRIMARY KEY (`id`)," + " UNIQUE KEY `uq_sc_players_1` (`name`));"; core.execute(query); + } if (!core.existsTable(getPrefixedTable("kills"))) { + plugin.getLogger().info("Creating table: " + getPrefixedTable("kills")); String query = "CREATE TABLE IF NOT EXISTS `" + getPrefixedTable("kills") + "` (" - + " `kill_id` bigint(20) NOT NULL auto_increment," - + " `attacker` varchar(16) NOT NULL," - + " `attacker_tag` varchar(16) NOT NULL," - + " `victim` varchar(16) NOT NULL," - + " `victim_tag` varchar(16) NOT NULL," - + " `kill_type` varchar(1) NOT NULL," - + " `created_at` datetime NULL," - + " PRIMARY KEY (`kill_id`));"; + + " `kill_id` bigint(20) NOT NULL auto_increment," + " `attacker` varchar(16) NOT NULL," + + " `attacker_tag` varchar(16) NOT NULL," + " `victim` varchar(16) NOT NULL," + + " `victim_tag` varchar(16) NOT NULL," + " `kill_type` varchar(1) NOT NULL," + + " `created_at` datetime NULL," + " PRIMARY KEY (`kill_id`));"; core.execute(query); + } + } else { - plugin.getServer().getConsoleSender().sendMessage("[SimpleClans] " + ChatColor.RED + lang("mysql.connection.failed")); + + plugin.getServer().getConsoleSender() + .sendMessage("[SimpleClans] " + ChatColor.RED + lang("mysql.connection.failed")); + } + } else { + core = new SQLiteCore(plugin.getDataFolder().getPath()); if (core.checkConnection()) { - plugin.getLogger().info(lang("sqlite.connection.successful")); + plugin.getLogger().info(lang("sqlite.connection.successful")); if (!core.existsTable(getPrefixedTable("clans"))) { + plugin.getLogger().info("Creating table: " + getPrefixedTable("clans")); String query = "CREATE TABLE IF NOT EXISTS `" + getPrefixedTable("clans") + "` (" - + " `id` bigint(20)," - + " `verified` tinyint(1) default '0'," - + " `tag` varchar(25) NOT NULL," - + " `color_tag` varchar(255) NOT NULL," - + " `name` varchar(100) NOT NULL," - + " `description` varchar(255)," - + " `friendly_fire` tinyint(1) default '0'," - + " `founded` bigint NOT NULL," - + " `last_used` bigint NOT NULL," - + " `packed_allies` text NOT NULL," - + " `packed_rivals` text NOT NULL," - + " `packed_bb` mediumtext NOT NULL," - + " `cape_url` varchar(255) NOT NULL," - + " `flags` text NOT NULL," - + " `balance` double(64,2) default 0.0," - + " `fee_enabled` tinyint(1) default '0'," - + " `fee_value` double(64,2)," - + " `ranks` text NOT NULL," - + " `banner` text," - + " PRIMARY KEY (`id`)," - + " UNIQUE (`tag`));"; + + " `id` bigint(20)," + " `verified` tinyint(1) default '0'," + + " `tag` varchar(25) NOT NULL," + " `color_tag` varchar(255) NOT NULL," + + " `name` varchar(100) NOT NULL," + " `description` varchar(255)," + + " `friendly_fire` tinyint(1) default '0'," + " `founded` bigint NOT NULL," + + " `last_used` bigint NOT NULL," + " `packed_allies` text NOT NULL," + + " `packed_rivals` text NOT NULL," + " `packed_bb` mediumtext NOT NULL," + + " `cape_url` varchar(255) NOT NULL," + " `flags` text NOT NULL," + + " `balance` double(64,2) default 0.0," + " `fee_enabled` tinyint(1) default '0'," + + " `fee_value` double(64,2)," + " `ranks` text NOT NULL," + " `banner` text," + + " PRIMARY KEY (`id`)," + " UNIQUE (`tag`));"; core.execute(query); + } if (!core.existsTable(getPrefixedTable("players"))) { + plugin.getLogger().info("Creating table: " + getPrefixedTable("players")); String query = "CREATE TABLE IF NOT EXISTS `" + getPrefixedTable("players") + "` (" - + " `id` bigint(20)," - + " `name` varchar(16) NOT NULL," - + " `leader` tinyint(1) default '0'," - + " `tag` varchar(25) NOT NULL," - + " `friendly_fire` tinyint(1) default '0'," - + " `neutral_kills` int(11) default NULL," - + " `rival_kills` int(11) default NULL," - + " `civilian_kills` int(11) default NULL," - + " `ally_kills` int(11) default NULL," - + " `deaths` int(11) default NULL," - + " `last_seen` bigint NOT NULL," - + " `join_date` bigint NOT NULL," - + " `trusted` tinyint(1) default '0'," - + " `flags` text NOT NULL," - + " `packed_past_clans` text," - + " `resign_times` text," - + " `locale` varchar(10)," - + " PRIMARY KEY (`id`)," - + " UNIQUE (`name`));"; + + " `id` bigint(20)," + " `name` varchar(16) NOT NULL," + + " `leader` tinyint(1) default '0'," + " `tag` varchar(25) NOT NULL," + + " `friendly_fire` tinyint(1) default '0'," + " `neutral_kills` int(11) default NULL," + + " `rival_kills` int(11) default NULL," + " `civilian_kills` int(11) default NULL," + + " `ally_kills` int(11) default NULL," + " `deaths` int(11) default NULL," + + " `last_seen` bigint NOT NULL," + " `join_date` bigint NOT NULL," + + " `trusted` tinyint(1) default '0'," + " `flags` text NOT NULL," + + " `packed_past_clans` text," + " `resign_times` text," + " `locale` varchar(10)," + + " PRIMARY KEY (`id`)," + " UNIQUE (`name`));"; core.execute(query); + } if (!core.existsTable(getPrefixedTable("kills"))) { + plugin.getLogger().info("Creating table: " + getPrefixedTable("kills")); String query = "CREATE TABLE IF NOT EXISTS `" + getPrefixedTable("kills") + "` (" - + " `kill_id` bigint(20)," - + " `attacker` varchar(16) NOT NULL," - + " `attacker_tag` varchar(16) NOT NULL," - + " `victim` varchar(16) NOT NULL," - + " `victim_tag` varchar(16) NOT NULL," - + " `kill_type` varchar(1) NOT NULL," - + " `created_at` datetime NULL," - + " PRIMARY KEY (`kill_id`));"; + + " `kill_id` bigint(20)," + " `attacker` varchar(16) NOT NULL," + + " `attacker_tag` varchar(16) NOT NULL," + " `victim` varchar(16) NOT NULL," + + " `victim_tag` varchar(16) NOT NULL," + " `kill_type` varchar(1) NOT NULL," + + " `created_at` datetime NULL," + " PRIMARY KEY (`kill_id`));"; core.execute(query); + } + } else { - plugin.getServer().getConsoleSender().sendMessage("[SimpleClans] " + ChatColor.RED + lang("sqlite.connection.failed")); + + plugin.getServer().getConsoleSender() + .sendMessage("[SimpleClans] " + ChatColor.RED + lang("sqlite.connection.failed")); + } + } + } /** * Closes DB connection */ public void closeConnection() { + core.close(); + } /** * Import all data from database to memory */ public void importFromDatabase() { + plugin.getClanManager().cleanData(); List clans = retrieveClans(); purgeClans(clans); for (Clan clan : clans) { + plugin.getClanManager().importClan(clan); + } for (Clan clan : clans) { + clan.validateWarring(); + } if (!clans.isEmpty()) { - plugin.getLogger().info(MessageFormat.format(lang("clans"), clans.size())); + + plugin.getLogger().info(MessageFormat.format(lang("clans"), clans.size())); + } List cps = retrieveClanPlayers(); purgeClanPlayers(cps); for (ClanPlayer cp : cps) { + Clan tm = cp.getClan(); if (tm != null) { + tm.importMember(cp); + } + plugin.getClanManager().importClanPlayer(cp); + } if (!cps.isEmpty()) { - plugin.getLogger().info(MessageFormat.format(lang("clan.players"), cps.size())); + + plugin.getLogger().info(MessageFormat.format(lang("clan.players"), cps.size())); + } + } /** - * Import one ClanPlayer data from database to memory - * Used for BungeeCord Reload ClanPlayer and your Clan + * Import one ClanPlayer data from database to memory Used for BungeeCord Reload + * ClanPlayer and your Clan * */ @Deprecated public void importFromDatabaseOnePlayer(Player player) { + plugin.getClanManager().deleteClanPlayerFromMemory(player.getUniqueId()); ClanPlayer cp = retrieveOneClanPlayer(player.getUniqueId()); if (cp != null) { + Clan tm = cp.getClan(); if (tm != null) { + tm.importMember(cp); + } + plugin.getClanManager().importClanPlayer(cp); plugin.getLogger().info("ClanPlayer Reloaded: " + player.getName() + ", UUID: " + player.getUniqueId()); + } + } private void purgeClans(List clans) { + List purge = new ArrayList<>(); for (Clan clan : clans) { + if (clan.isPermanent()) { + continue; + } + if (clan.isVerified()) { + int purgeClan = plugin.getSettingsManager().getInt(PURGE_INACTIVE_CLAN_DAYS); if (clan.getInactiveDays() > purgeClan && purgeClan > 0) { + purge.add(clan); + } + } else { + int purgeUnverified = plugin.getSettingsManager().getInt(PURGE_UNVERIFIED_CLAN_DAYS); if (clan.getInactiveDays() > purgeUnverified && purgeUnverified > 0) { + purge.add(clan); + } + } + } for (Clan clan : purge) { - plugin.getLogger().info(lang("purging.clan", clan.getName())); + + plugin.getLogger().info(lang("purging.clan", clan.getName())); for (ClanPlayer member : clan.getMembers()) { + clan.removePlayerFromClan(member.getUniqueId()); + } + deleteClan(clan); clans.remove(clan); + } + } private void purgeClanPlayers(List cps) { + int purgePlayers = plugin.getSettingsManager().getInt(PURGE_INACTIVE_PLAYER_DAYS); if (purgePlayers < 1) { + return; + } + List purge = new ArrayList<>(); for (ClanPlayer cp : cps) { - //let the clan be purged first + + // let the clan be purged first if (cp.isLeader() && cp.getClan() != null) { + continue; + } + if (cp.getInactiveDays() > purgePlayers) { + purge.add(cp); + } + } for (ClanPlayer cp : purge) { - plugin.getLogger().info(lang("purging.player.data", cp.getName())); + + plugin.getLogger().info(lang("purging.player.data", cp.getName())); deleteClanPlayer(cp); cps.remove(cp); + } + } /** @@ -362,15 +405,20 @@ public final class StorageManager { * */ public List retrieveClans() { + List out = new ArrayList<>(); String query = "SELECT * FROM `" + getPrefixedTable("clans") + "`;"; ResultSet res = core.select(query); if (res != null) { + try { + while (res.next()) { + try { + boolean verified = res.getBoolean("verified"); boolean friendly_fire = res.getBoolean("friendly_fire"); String tag = res.getString("tag"); @@ -390,11 +438,15 @@ public final class StorageManager { ItemStack banner = YAMLSerializer.deserialize(res.getString("banner"), ItemStack.class); if (founded == 0) { + founded = (new Date()).getTime(); + } if (last_used == 0) { + last_used = (new Date()).getTime(); + } Clan clan = new Clan(); @@ -410,7 +462,8 @@ public final class StorageManager { clan.setPackedBb(packed_bb); clan.setFounded(founded); clan.setLastUsed(last_used); - clan.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, balance); + clan.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, + BankLogger.Operation.SET, balance); clan.setMemberFee(feeValue); clan.setMemberFeeEnabled(feeEnabled); clan.setRanks(Helper.ranksFromJson(ranksJson)); @@ -418,33 +471,47 @@ public final class StorageManager { clan.setBanner(banner); out.add(clan); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + plugin.getLogger().severe(String.format("An Error occurred: %s", ex.getErrorCode())); plugin.getLogger().log(Level.SEVERE, null, ex); + } + } return out; + } /** - * Retrieves one Clan from the database - * Used for BungeeCord Reload ClanPlayer and your Clan + * Retrieves one Clan from the database Used for BungeeCord Reload ClanPlayer + * and your Clan */ public @Nullable Clan retrieveOneClan(String tagClan) { + Clan out = null; String query = "SELECT * FROM `" + getPrefixedTable("clans") + "` WHERE `tag` = '" + tagClan + "';"; ResultSet res = core.select(query); if (res != null) { + try { + while (res.next()) { + try { + boolean verified = res.getBoolean("verified"); boolean friendly_fire = res.getBoolean("friendly_fire"); String tag = res.getString("tag"); @@ -464,11 +531,15 @@ public final class StorageManager { ItemStack banner = YAMLSerializer.deserialize(res.getString("banner"), ItemStack.class); if (founded == 0) { + founded = (new Date()).getTime(); + } if (last_used == 0) { + last_used = (new Date()).getTime(); + } Clan clan = new Clan(); @@ -484,7 +555,8 @@ public final class StorageManager { clan.setPackedBb(packed_bb); clan.setFounded(founded); clan.setLastUsed(last_used); - clan.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, balance); + clan.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, + BankLogger.Operation.SET, balance); clan.setMemberFee(feeValue); clan.setMemberFeeEnabled(feeEnabled); clan.setRanks(Helper.ranksFromJson(ranksJson)); @@ -492,17 +564,26 @@ public final class StorageManager { clan.setBanner(banner); out = clan; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + plugin.getLogger().severe(String.format("An Error occurred: %s", ex.getErrorCode())); plugin.getLogger().log(Level.SEVERE, null, ex); + } + } return out; + } /** @@ -510,15 +591,20 @@ public final class StorageManager { * */ public List retrieveClanPlayers() { + List out = new ArrayList<>(); String query = "SELECT * FROM `" + getPrefixedTable("players") + "`;"; ResultSet res = core.select(query); if (res != null) { + try { + while (res.next()) { + try { + String uuid = res.getString("uuid"); String name = res.getString("name"); String tag = res.getString("tag"); @@ -538,13 +624,18 @@ public final class StorageManager { Locale locale = Helper.forLanguageTag(res.getString("locale")); if (last_seen == 0) { + last_seen = (new Date()).getTime(); + } ClanPlayer cp = new ClanPlayer(); if (uuid != null) { + cp.setUniqueId(UUID.fromString(uuid)); + } + cp.setFlags(flags); cp.setName(name); cp.setLeader(leader); @@ -562,41 +653,60 @@ public final class StorageManager { cp.setLocale(locale); if (!tag.isEmpty()) { + Clan clan = plugin.getClanManager().getClan(tag); if (clan != null) { + cp.setClan(clan); + } + } out.add(cp); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + plugin.getLogger().severe(String.format("An Error occurred: %s", ex.getErrorCode())); plugin.getLogger().log(Level.SEVERE, null, ex); + } + } return out; + } /** - * Retrieves one clan player from the database - * Used for BungeeCord Reload ClanPlayer and your Clan + * Retrieves one clan player from the database Used for BungeeCord Reload + * ClanPlayer and your Clan */ public @Nullable ClanPlayer retrieveOneClanPlayer(UUID playerUniqueId) { + ClanPlayer out = null; - String query = "SELECT * FROM `" + getPrefixedTable("players") + "` WHERE `uuid` = '" + playerUniqueId.toString() + "';"; + String query = "SELECT * FROM `" + getPrefixedTable("players") + "` WHERE `uuid` = '" + + playerUniqueId.toString() + "';"; ResultSet res = core.select(query); if (res != null) { + try { + while (res.next()) { + try { + String uuid = res.getString("uuid"); String name = res.getString("name"); String tag = res.getString("tag"); @@ -616,13 +726,18 @@ public final class StorageManager { Locale locale = Helper.forLanguageTag(res.getString("locale")); if (last_seen == 0) { + last_seen = (new Date()).getTime(); + } ClanPlayer cp = new ClanPlayer(); if (uuid != null) { + cp.setUniqueId(UUID.fromString(uuid)); + } + cp.setFlags(flags); cp.setName(name); cp.setLeader(leader); @@ -640,10 +755,12 @@ public final class StorageManager { cp.setLocale(locale); if (!tag.isEmpty()) { + Clan clanDB = retrieveOneClan(tag); Clan clan = plugin.getClanManager().getClan(tag); if (clan != null && clanDB != null) { + Clan clanReSync = SimpleClans.getInstance().getClanManager().getClan(tag); clanReSync.setFlags(clanDB.getFlags()); clanReSync.setVerified(clanDB.isVerified()); @@ -656,28 +773,42 @@ public final class StorageManager { clanReSync.setPackedBb(clanDB.getPackedBb()); clanReSync.setFounded(clanDB.getFounded()); clanReSync.setLastUsed(clanDB.getLastUsed()); - clanReSync.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, clanDB.getBalance()); + clanReSync.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, + BankLogger.Operation.SET, clanDB.getBalance()); cp.setClan(clanReSync); + } else { + plugin.getClanManager().importClan(clanDB); clanDB.validateWarring(); Clan newClan = plugin.getClanManager().getClan(clanDB.getTag()); cp.setClan(newClan); + } + } out = cp; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + plugin.getLogger().severe(String.format("An Error occurred: %s", ex.getErrorCode())); plugin.getLogger().log(Level.SEVERE, null, ex); + } + } return out; + } /** @@ -685,31 +816,25 @@ public final class StorageManager { * */ public void insertClan(Clan clan) { + plugin.getProxyManager().sendUpdate(clan); - String query = "INSERT INTO `" + getPrefixedTable("clans") + "` (`banner`, `ranks`, `description`, `fee_enabled`, `fee_value`, `verified`, `tag`," + - " `color_tag`, `name`, `friendly_fire`, `founded`, `last_used`, `packed_allies`, `packed_rivals`, " + - "`packed_bb`, `cape_url`, `flags`, `balance`) "; - String values = "VALUES ( '" - + Helper.escapeQuotes(YAMLSerializer.serialize(clan.getBanner())) + "','" - + Helper.escapeQuotes(Helper.ranksToJson(clan.getRanks(), clan.getDefaultRank())) + "','" - + Helper.escapeQuotes(clan.getDescription())+ "'," - + (clan.isMemberFeeEnabled() ? 1 : 0) +"," - + Helper.escapeQuotes(String.valueOf(clan.getMemberFee())) + "," - + (clan.isVerified() ? 1 : 0) + ",'" - + Helper.escapeQuotes(clan.getTag()) + "','" - + Helper.escapeQuotes(clan.getColorTag()) + "','" - + Helper.escapeQuotes(clan.getName()) + "'," - + (clan.isFriendlyFire() ? 1 : 0) + ",'" - + clan.getFounded() + "','" - + clan.getLastUsed() + "','" - + Helper.escapeQuotes(clan.getPackedAllies()) + "','" - + Helper.escapeQuotes(clan.getPackedRivals()) + "','" - + Helper.escapeQuotes(clan.getPackedBb()) + "','" - + Helper.escapeQuotes(clan.getCapeUrl()) + "','" - + Helper.escapeQuotes(clan.getFlags()) + "','" - + Helper.escapeQuotes(String.valueOf(clan.getBalance())) + "');"; + String query = "INSERT INTO `" + getPrefixedTable("clans") + + "` (`banner`, `ranks`, `description`, `fee_enabled`, `fee_value`, `verified`, `tag`," + + " `color_tag`, `name`, `friendly_fire`, `founded`, `last_used`, `packed_allies`, `packed_rivals`, " + + "`packed_bb`, `cape_url`, `flags`, `balance`) "; + String values = "VALUES ( '" + Helper.escapeQuotes(YAMLSerializer.serialize(clan.getBanner())) + "','" + + Helper.escapeQuotes(Helper.ranksToJson(clan.getRanks(), clan.getDefaultRank())) + "','" + + Helper.escapeQuotes(clan.getDescription()) + "'," + (clan.isMemberFeeEnabled() ? 1 : 0) + "," + + Helper.escapeQuotes(String.valueOf(clan.getMemberFee())) + "," + (clan.isVerified() ? 1 : 0) + ",'" + + Helper.escapeQuotes(clan.getTag()) + "','" + Helper.escapeQuotes(clan.getColorTag()) + "','" + + Helper.escapeQuotes(clan.getName()) + "'," + (clan.isFriendlyFire() ? 1 : 0) + ",'" + + clan.getFounded() + "','" + clan.getLastUsed() + "','" + Helper.escapeQuotes(clan.getPackedAllies()) + + "','" + Helper.escapeQuotes(clan.getPackedRivals()) + "','" + Helper.escapeQuotes(clan.getPackedBb()) + + "','" + Helper.escapeQuotes(clan.getCapeUrl()) + "','" + Helper.escapeQuotes(clan.getFlags()) + "','" + + Helper.escapeQuotes(String.valueOf(clan.getBalance())) + "');"; core.executeUpdate(query + values); + } /** @@ -718,12 +843,18 @@ public final class StorageManager { */ @Deprecated public void updateClanAsync(final Clan clan) { + new BukkitRunnable() { + @Override public void run() { + updateClan(clan); + } + }.runTaskAsynchronously(plugin); + } /** @@ -732,12 +863,18 @@ public final class StorageManager { * @param cp to update */ public void updatePlayerNameAsync(final @NotNull ClanPlayer cp) { - new BukkitRunnable() { - @Override - public void run() { + + new BukkitRunnable() { + + @Override + public void run() { + updatePlayerName(cp); - } - }.runTaskAsynchronously(plugin); + + } + + }.runTaskAsynchronously(plugin); + } /** @@ -746,8 +883,11 @@ public final class StorageManager { * @param cp to update */ public void updatePlayerName(final @NotNull ClanPlayer cp) { - String query = "UPDATE `" + getPrefixedTable("players") + "` SET `name` = '" + cp.getName() + "' WHERE uuid = '" + cp.getUniqueId() + "';"; + + String query = "UPDATE `" + getPrefixedTable("players") + "` SET `name` = '" + cp.getName() + "' WHERE uuid = '" + + cp.getUniqueId() + "';"; core.executeUpdate(query); + } /** @@ -755,41 +895,59 @@ public final class StorageManager { * */ public void updateClan(Clan clan) { + updateClan(clan, true); + } /** * Update a clan to the database * - * @param clan clan to update + * @param clan clan to update * * @param updateLastUsed should the clan's last used time be updated as well? */ public void updateClan(Clan clan, boolean updateLastUsed) { + if (updateLastUsed) { + clan.updateLastUsed(); + } + plugin.getProxyManager().sendUpdate(clan); if (plugin.getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) { + modifiedClans.add(clan); return; + } + try (PreparedStatement st = prepareUpdateClanStatement(core.getConnection())) { + setValues(st, clan); st.executeUpdate(); + } catch (SQLException ex) { + plugin.getLogger().log(Level.SEVERE, String.format("Error updating Clan %s", clan.getTag()), ex); + } + } private PreparedStatement prepareUpdateClanStatement(Connection connection) throws SQLException { - String sql = "UPDATE `" + getPrefixedTable("clans") + "` SET ranks = ?, banner = ?, description = ?, fee_enabled = ?, fee_value = ?, " + - "verified = ?, tag = ?, color_tag = ?, `name` = ?, friendly_fire = ?, founded = ?, last_used = ?, " + - "packed_allies = ?, packed_rivals = ?, packed_bb = ?, balance = ?, flags = ? WHERE tag = ?;"; + + String sql = "UPDATE `" + getPrefixedTable("clans") + + "` SET ranks = ?, banner = ?, description = ?, fee_enabled = ?, fee_value = ?, " + + "verified = ?, tag = ?, color_tag = ?, `name` = ?, friendly_fire = ?, founded = ?, last_used = ?, " + + "packed_allies = ?, packed_rivals = ?, packed_bb = ?, balance = ?, flags = ? WHERE tag = ?;"; return connection.prepareStatement(sql); + } private void setValues(PreparedStatement statement, Clan clan) throws SQLException { + statement.setString(1, Helper.ranksToJson(clan.getRanks(), clan.getDefaultRank())); statement.setString(2, YAMLSerializer.serialize(clan.getBanner())); statement.setString(3, clan.getDescription()); @@ -808,15 +966,18 @@ public final class StorageManager { statement.setDouble(16, clan.getBalance()); statement.setString(17, clan.getFlags()); statement.setString(18, clan.getTag()); + } /** * Delete a clan from the database */ public void deleteClan(Clan clan) { + plugin.getProxyManager().sendDelete(clan); String query = "DELETE FROM `" + getPrefixedTable("clans") + "` WHERE tag = '" + clan.getTag() + "';"; core.executeUpdate(query); + } /** @@ -824,17 +985,20 @@ public final class StorageManager { * */ public void insertClanPlayer(ClanPlayer cp) { + plugin.getProxyManager().sendUpdate(cp); - String query = "INSERT INTO `" + getPrefixedTable("players") + "` (`uuid`, `name`, `leader`, `tag`, `friendly_fire`, `neutral_kills`, " + - "`rival_kills`, `civilian_kills`, `deaths`, `last_seen`, `join_date`, `packed_past_clans`, `flags`) "; + String query = "INSERT INTO `" + getPrefixedTable("players") + + "` (`uuid`, `name`, `leader`, `tag`, `friendly_fire`, `neutral_kills`, " + + "`rival_kills`, `civilian_kills`, `deaths`, `last_seen`, `join_date`, `packed_past_clans`, `flags`) "; String values = "VALUES ('" + cp.getUniqueId().toString() + "', '" + cp.getName() + "'," + (cp.isLeader() ? 1 : 0) + ",'" + Helper.escapeQuotes(cp.getTag()) + "'," - + (cp.isFriendlyFire() ? 1 : 0) + "," + cp.getNeutralKills() + "," + cp.getRivalKills() - + "," + cp.getCivilianKills() + "," + cp.getDeaths() + ",'" + cp.getLastSeen() + "',' " - + cp.getJoinDate() + "','" + Helper.escapeQuotes(cp.getPackedPastClans()) + "','" - + Helper.escapeQuotes(cp.getFlags()) + "');"; + + (cp.isFriendlyFire() ? 1 : 0) + "," + cp.getNeutralKills() + "," + cp.getRivalKills() + "," + + cp.getCivilianKills() + "," + cp.getDeaths() + ",'" + cp.getLastSeen() + "',' " + cp.getJoinDate() + + "','" + Helper.escapeQuotes(cp.getPackedPastClans()) + "','" + Helper.escapeQuotes(cp.getFlags()) + + "');"; core.executeUpdate(query + values); + } /** @@ -843,12 +1007,18 @@ public final class StorageManager { */ @Deprecated public void updateClanPlayerAsync(final ClanPlayer cp) { - new BukkitRunnable() { - @Override - public void run() { + + new BukkitRunnable() { + + @Override + public void run() { + updateClanPlayer(cp); - } - }.runTaskAsynchronously(plugin); + + } + + }.runTaskAsynchronously(plugin); + } /** @@ -856,28 +1026,41 @@ public final class StorageManager { * */ public void updateClanPlayer(ClanPlayer cp) { + cp.updateLastSeen(); plugin.getProxyManager().sendUpdate(cp); if (plugin.getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) { + modifiedClanPlayers.add(cp); return; + } + try (PreparedStatement st = prepareUpdateClanPlayerStatement(core.getConnection())) { + setValues(st, cp); st.executeUpdate(); + } catch (SQLException ex) { + plugin.getLogger().log(Level.SEVERE, String.format("Error updating ClanPlayer %s", cp.getName()), ex); + } + } private PreparedStatement prepareUpdateClanPlayerStatement(Connection connection) throws SQLException { - String sql = "UPDATE `" + getPrefixedTable("players") + "` SET locale = ?, resign_times = ?, leader = ?, tag = ?, friendly_fire = ?," + - " neutral_kills = ?, ally_kills = ?, rival_kills = ?, civilian_kills = ?, deaths = ?, last_seen = ?," + - " packed_past_clans = ?, trusted = ?, flags = ?, `name` = ? WHERE `uuid` = ?;"; + + String sql = "UPDATE `" + getPrefixedTable("players") + + "` SET locale = ?, resign_times = ?, leader = ?, tag = ?, friendly_fire = ?," + + " neutral_kills = ?, ally_kills = ?, rival_kills = ?, civilian_kills = ?, deaths = ?, last_seen = ?," + + " packed_past_clans = ?, trusted = ?, flags = ?, `name` = ? WHERE `uuid` = ?;"; return connection.prepareStatement(sql); + } private void setValues(PreparedStatement statement, ClanPlayer cp) throws SQLException { + statement.setString(1, Helper.toLanguageTag(cp.getLocale())); statement.setString(2, Helper.resignTimesToJson(cp.getResignTimes())); statement.setInt(3, cp.isLeader() ? 1 : 0); @@ -894,21 +1077,27 @@ public final class StorageManager { statement.setString(14, cp.getFlags()); statement.setString(15, cp.getName()); statement.setString(16, cp.getUniqueId().toString()); + } /** * Delete a clan player from the database */ public void deleteClanPlayer(ClanPlayer cp) { + final Clan clan = cp.getClan(); if (clan != null) { + clan.addBbWithoutSaving(MessageFormat.format(lang("has.been.purged"), cp.getName())); updateClan(clan, false); + } + plugin.getProxyManager().sendDelete(cp); String query = "DELETE FROM `" + getPrefixedTable("players") + "` WHERE uuid = '" + cp.getUniqueId() + "';"; core.executeUpdate(query); deleteKills(cp.getUniqueId()); + } /** @@ -917,24 +1106,33 @@ public final class StorageManager { */ @Deprecated public void insertKill(Player attacker, String attackerTag, Player victim, String victimTag, String type) { - String query = "INSERT INTO `" + getPrefixedTable("kills") + "` ( `attacker_uuid`, `attacker`, `attacker_tag`, `victim_uuid`, `victim`, `victim_tag`, `kill_type`) "; - String values = "VALUES ( '" + attacker.getUniqueId() + "','" + attacker.getName() + "','" + attackerTag + "','" + victim.getUniqueId() + "','" + victim.getName() + "','" + victimTag + "','" + type + "');"; - core.executeUpdate(query + values); + + String query = "INSERT INTO `" + getPrefixedTable("kills") + + "` ( `attacker_uuid`, `attacker`, `attacker_tag`, `victim_uuid`, `victim`, `victim_tag`, `kill_type`) "; + String values = "VALUES ( '" + attacker.getUniqueId() + "','" + attacker.getName() + "','" + attackerTag + "','" + + victim.getUniqueId() + "','" + victim.getName() + "','" + victimTag + "','" + type + "');"; + core.executeUpdate(query + values); + } /** * Insert a kill into the database * * @param attacker the attacker - * @param victim the victim - * @param type the kill type + * @param victim the victim + * @param type the kill type */ - public void insertKill(@NotNull ClanPlayer attacker, @NotNull ClanPlayer victim, @NotNull String type, @NotNull LocalDateTime time) { - String query = "INSERT INTO `sc_kills` ( `attacker_uuid`, `attacker`, `attacker_tag`, `victim_uuid`, " + - "`victim`, `victim_tag`, `kill_type`, `created_at`) "; + public void insertKill(@NotNull ClanPlayer attacker, @NotNull ClanPlayer victim, @NotNull String type, + @NotNull LocalDateTime time) + { + + String query = "INSERT INTO `sc_kills` ( `attacker_uuid`, `attacker`, `attacker_tag`, `victim_uuid`, " + + "`victim`, `victim_tag`, `kill_type`, `created_at`) "; String values = "VALUES ( '" + attacker.getUniqueId() + "','" + attacker.getName() + "','" + attacker.getTag() - + "','" + victim.getUniqueId() + "','" + victim.getName() + "','" + victim.getTag() + "','" + type + "','" + time + "');"; + + "','" + victim.getUniqueId() + "','" + victim.getName() + "','" + victim.getTag() + "','" + type + + "','" + time + "');"; core.executeUpdate(query + values); + } /** @@ -943,8 +1141,10 @@ public final class StorageManager { */ @Deprecated public void deleteKills(String playerName) { + String query = "DELETE FROM `" + getPrefixedTable("kills") + "` WHERE `attacker` = '" + playerName + "'"; core.executeUpdate(query); + } /** @@ -952,12 +1152,16 @@ public final class StorageManager { * */ public void deleteKills(UUID playerUniqueId) { - String query = "DELETE FROM `" + getPrefixedTable("kills") + "` WHERE `attacker_uuid` = '" + playerUniqueId + "'"; + + String query = "DELETE FROM `" + getPrefixedTable("kills") + "` WHERE `attacker_uuid` = '" + playerUniqueId + + "'"; core.executeUpdate(query); + } /** - * Returns a map of victim-{@literal >}count of all kills that specific player did + * Returns a map of victim-{@literal >}count of all kills that specific player + * did * * @param playerName the attacker name * @@ -965,31 +1169,44 @@ public final class StorageManager { * */ public Map getKillsPerPlayer(String playerName) { + HashMap out = new HashMap<>(); - String query = "SELECT victim, count(victim) AS kills FROM `" + getPrefixedTable("kills") + "` WHERE attacker = '" + playerName + "' GROUP BY victim ORDER BY count(victim) DESC;"; + String query = "SELECT victim, count(victim) AS kills FROM `" + getPrefixedTable("kills") + + "` WHERE attacker = '" + playerName + "' GROUP BY victim ORDER BY count(victim) DESC;"; ResultSet res = core.select(query); if (res != null) { + try { + while (res.next()) { + try { + String victim = res.getString("victim"); int kills = res.getInt("kills"); out.put(victim, kills); + } catch (Exception ex) { + plugin.getLogger().info(ex.getMessage()); - } + } + } catch (SQLException ex) { + plugin.getLogger().severe(String.format("An Error occurred: %s", ex.getErrorCode())); plugin.getLogger().log(Level.SEVERE, null, ex); + } + } return out; + } /** @@ -998,60 +1215,86 @@ public final class StorageManager { * @return a map of kills per attacker+victim */ public Map getMostKilled() { + HashMap out = new HashMap<>(); - String query = "SELECT attacker, victim, count(victim) AS kills FROM `" + getPrefixedTable("kills") + "` GROUP BY attacker, victim ORDER BY 3 DESC;"; + String query = "SELECT attacker, victim, count(victim) AS kills FROM `" + getPrefixedTable("kills") + + "` GROUP BY attacker, victim ORDER BY 3 DESC;"; ResultSet res = core.select(query); if (res != null) { + try { + while (res.next()) { + try { + String attacker = res.getString("attacker"); String victim = res.getString("victim"); int kills = res.getInt("kills"); out.put(attacker + " " + victim, kills); + } catch (Exception ex) { + plugin.getLogger().info(ex.getMessage()); - } + } + } catch (SQLException ex) { + plugin.getLogger().severe(String.format("An Error occurred: %s", ex.getErrorCode())); plugin.getLogger().log(Level.SEVERE, null, ex); + } + } return out; + } /** - * Gets, asynchronously, a map of tag-{@literal >}count of all kills and notifies via callback when it's ready + * Gets, asynchronously, a map of tag-{@literal >}count of all kills and + * notifies via callback when it's ready * * @param callback the callback */ public void getMostKilled(DataCallback> callback) { - new BukkitRunnable() { - @Override - public void run() { - callback.onResultReady(getMostKilled()); - } - }.runTaskAsynchronously(plugin); + new BukkitRunnable() { + + @Override + public void run() { + + callback.onResultReady(getMostKilled()); + + } + + }.runTaskAsynchronously(plugin); + } /** - * Gets, asynchronously, a map of victim-{@literal >}count of all kills that specific player did and notifies via callback when it's ready + * Gets, asynchronously, a map of victim-{@literal >}count of all kills that + * specific player did and notifies via callback when it's ready * */ public void getKillsPerPlayer(final String playerName, final DataCallback> callback) { - new BukkitRunnable() { - @Override - public void run() { - callback.onResultReady(getKillsPerPlayer(playerName)); - } - }.runTaskAsynchronously(plugin); + + new BukkitRunnable() { + + @Override + public void run() { + + callback.onResultReady(getKillsPerPlayer(playerName)); + + } + + }.runTaskAsynchronously(plugin); + } /** @@ -1061,11 +1304,13 @@ public final class StorageManager { * */ public interface DataCallback { - /** - * Notifies when the result is ready - * - */ - void onResultReady(T data); + + /** + * Notifies when the result is ready + * + */ + void onResultReady(T data); + } /** @@ -1073,118 +1318,164 @@ public final class StorageManager { * */ private void updateDatabase() { + String query; /* * From 2.2.6.3 to 2.3 */ if (!core.existsColumn(getPrefixedTable("clans"), "balance")) { + query = "ALTER TABLE `" + getPrefixedTable("clans") + "` ADD COLUMN `balance` double(64,2);"; core.execute(query); + } /* * From 2.7.16 to 2.7.17 */ if (!core.existsColumn(getPrefixedTable("clans"), "fee_enabled")) { + query = "ALTER TABLE `" + getPrefixedTable("clans") + "` ADD COLUMN `fee_enabled` tinyint(1) default '0';"; core.execute(query); + } + if (!core.existsColumn(getPrefixedTable("clans"), "fee_value")) { + query = "ALTER TABLE `" + getPrefixedTable("clans") + "` ADD COLUMN `fee_value` double(64,2);"; core.execute(query); + } /* * From 2.7.21 to 2.7.22 */ if (!core.existsColumn(getPrefixedTable("clans"), "description")) { + query = "ALTER TABLE `" + getPrefixedTable("clans") + "` ADD COLUMN `description` varchar(255);"; - core.execute(query); + core.execute(query); + } /* * From 2.7.22 to 2.7.23 */ if (!core.existsColumn(getPrefixedTable("players"), "resign_times")) { + query = "ALTER TABLE `" + getPrefixedTable("players") + "` ADD COLUMN `resign_times` text;"; - core.execute(query); + core.execute(query); + } /* * From 2.8.2 to 2.9 */ if (!core.existsColumn(getPrefixedTable("clans"), "ranks")) { + query = "ALTER TABLE `" + getPrefixedTable("clans") + "` ADD COLUMN `ranks` text;"; - core.execute(query); + core.execute(query); + } // From 2.12.1 to 2.13.0 if (!core.existsColumn(getPrefixedTable("players"), "locale")) { + query = "ALTER TABLE `" + getPrefixedTable("players") + "` ADD COLUMN `locale` varchar(10);"; core.execute(query); + } + if (!core.existsColumn(getPrefixedTable("clans"), "banner")) { + core.execute("ALTER TABLE `" + getPrefixedTable("clans") + "` ADD COLUMN `banner` text;"); + } // From 2.15.1 to 2.15.2 if (!core.existsColumn(getPrefixedTable("players"), "ally_kills")) { - core.execute("ALTER TABLE `" + getPrefixedTable("players") + "` ADD COLUMN `ally_kills` int(11) DEFAULT NULL;"); + + core.execute( + "ALTER TABLE `" + getPrefixedTable("players") + "` ADD COLUMN `ally_kills` int(11) DEFAULT NULL;"); + } if (plugin.getSettingsManager().is(MYSQL_ENABLE)) { + core.execute("ALTER TABLE `" + getPrefixedTable("clans") + "` MODIFY color_tag VARCHAR(255);"); + } /* * Bukkit 1.7.5+ UUID Migration */ if (!core.existsColumn(getPrefixedTable("kills"), "attacker_uuid")) { + query = "ALTER TABLE `" + getPrefixedTable("kills") + "` ADD attacker_uuid VARCHAR( 255 ) DEFAULT NULL;"; core.execute(query); + } + if (!core.existsColumn(getPrefixedTable("kills"), "victim_uuid")) { + query = "ALTER TABLE `" + getPrefixedTable("kills") + "` ADD victim_uuid VARCHAR( 255 ) DEFAULT NULL;"; core.execute(query); + } + boolean useMysql = plugin.getSettingsManager().is(MYSQL_ENABLE); if (!core.existsColumn(getPrefixedTable("players"), "uuid")) { + query = "ALTER TABLE `" + getPrefixedTable("players") + "` ADD uuid VARCHAR( 255 ) DEFAULT NULL;"; core.execute(query); if (useMysql) { + query = "ALTER TABLE `" + getPrefixedTable("players") + "` ADD UNIQUE `uq_player_uuid` (`uuid`);"; core.execute(query); + } updatePlayersToUUID(); if (useMysql) { + query = "ALTER TABLE `" + getPrefixedTable("players") + "` DROP INDEX uq_sc_players_1;"; + } else { + query = "DROP INDEX IF EXISTS uq_sc_players_1;"; + } + core.execute(query); + } if (core.existsColumn(getPrefixedTable("players"), "uuid") && !useMysql) { - query = "CREATE UNIQUE INDEX IF NOT EXISTS `uq_player_uuid` ON `" + getPrefixedTable("players") + "` (`uuid`);"; + + query = "CREATE UNIQUE INDEX IF NOT EXISTS `uq_player_uuid` ON `" + getPrefixedTable("players") + + "` (`uuid`);"; core.execute(query); + } // From 2.19.3 to 2.20.0 if (!core.existsColumn(getPrefixedTable("kills"), "created_at")) { + query = "ALTER TABLE sc_kills ADD `created_at` datetime NULL;"; core.execute(query); + } + } /** * Updates the database to the latest version * */ - private void updatePlayersToUUID() { + private void updatePlayersToUUID() { + logMigrationStart(); List cps = retrieveClanPlayers(); @@ -1192,113 +1483,168 @@ public final class StorageManager { int totalPlayers = cps.size(); for (int i = 0; i < totalPlayers; i++) { + ClanPlayer cp = cps.get(i); try { + UUID uuid = uuidMap.get(cp.getName()); if (uuid != null) { + updatePlayerInDatabase(cp.getName(), uuid); logSuccess(i + 1, totalPlayers, cp.getName(), uuid); + } + } catch (Exception ex) { + logFailure(i + 1, totalPlayers, cp.getName(), ex); + } + } logMigrationEnd(totalPlayers); + } private void updatePlayerInDatabase(String playerName, UUID uuid) { - String[] tables = {"players", "kills", "kills"}; - String[] columns = {"uuid", "attacker_uuid", "victim_uuid"}; - String[] conditions = {"name", "attacker", "victim"}; + + String[] tables = { "players", "kills", "kills" }; + String[] columns = { "uuid", "attacker_uuid", "victim_uuid" }; + String[] conditions = { "name", "attacker", "victim" }; for (int i = 0; i < tables.length; i++) { - String query = String.format("UPDATE `%s` SET %s = '%s' WHERE %s = '%s';", - getPrefixedTable(tables[i]), columns[i], uuid.toString(), conditions[i], playerName); + + String query = String.format("UPDATE `%s` SET %s = '%s' WHERE %s = '%s';", getPrefixedTable(tables[i]), + columns[i], uuid.toString(), conditions[i], playerName); core.executeUpdate(query); + } + } private Map fetchUUIDs(List clanPlayers) { + Map uuidMap = new HashMap<>(); try { + if (SimpleClans.getInstance().getServer().getOnlineMode()) { + uuidMap = UUIDFetcher.fetchUUIDsForClanPlayers(clanPlayers); + } else { - uuidMap = clanPlayers.stream().collect(Collectors.toMap(ClanPlayer::getName, player -> - UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(StandardCharsets.UTF_8)))); + + uuidMap = clanPlayers.stream().collect(Collectors.toMap(ClanPlayer::getName, player -> UUID + .nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(StandardCharsets.UTF_8)))); + } + } catch (InterruptedException | ExecutionException ex) { + plugin.getLogger().log(Level.SEVERE, "Error fetching UUIDs in bulk: " + ex.getMessage(), ex); + } return uuidMap; + } private void logSuccess(int current, int total, String playerName, UUID uuid) { + plugin.getLogger().info(String.format("[%d / %d] Success: %s; UUID: %s", current, total, playerName, uuid)); + } private void logFailure(int current, int total, String playerName, Exception ex) { - plugin.getLogger().log(Level.WARNING, String.format("[%d / %d] Failed [ERROR]: %s; UUID: ???", current, total, playerName), ex); + + plugin.getLogger().log(Level.WARNING, + String.format("[%d / %d] Failed [ERROR]: %s; UUID: ???", current, total, playerName), ex); + } private void logMigrationStart() { + plugin.getLogger().log(Level.WARNING, "Starting Migration to UUID Players!"); plugin.getLogger().log(Level.WARNING, "==================== ATTENTION DON'T STOP BUKKIT! ===================="); plugin.getLogger().log(Level.WARNING, "==================== ATTENTION DON'T STOP BUKKIT! ===================="); plugin.getLogger().log(Level.WARNING, "==================== ATTENTION DON'T STOP BUKKIT! ===================="); + } private void logMigrationEnd(int totalPlayers) { + plugin.getLogger().log(Level.WARNING, "==================== END OF MIGRATION ===================="); plugin.getLogger().log(Level.WARNING, "==================== END OF MIGRATION ===================="); plugin.getLogger().log(Level.WARNING, "==================== END OF MIGRATION ===================="); if (totalPlayers > 0) { + plugin.getLogger().info(MessageFormat.format(lang("clan.players"), totalPlayers)); + } + } private String getPrefixedTable(String name) { + return plugin.getSettingsManager().getString(MYSQL_TABLE_PREFIX) + name; + } - /** - * Saves modified Clans and ClanPlayers to the database + /** + * Saves modified Clans and ClanPlayers to the database + * * @since 2.10.2 * - *

- * author: RoinujNosde - *

- */ - public void saveModified() { + *

+ * author: RoinujNosde + *

+ */ + public void saveModified() { + try (PreparedStatement pst = prepareUpdateClanPlayerStatement(core.getConnection())) { - //removing purged players + + // removing purged players modifiedClanPlayers.retainAll(plugin.getClanManager().getAllClanPlayers()); for (ClanPlayer cp : modifiedClanPlayers) { + setValues(pst, cp); pst.addBatch(); + } + pst.executeBatch(); modifiedClanPlayers.clear(); + } catch (SQLException ex) { + plugin.getLogger().log(Level.SEVERE, "Error saving modified ClanPlayers:", ex); + } + try (PreparedStatement pst = prepareUpdateClanStatement(core.getConnection())) { - //removing disbanded clans + + // removing disbanded clans modifiedClans.retainAll(plugin.getClanManager().getClans()); for (Clan clan : modifiedClans) { + setValues(pst, clan); pst.addBatch(); + } + pst.executeBatch(); modifiedClans.clear(); + } catch (SQLException ex) { + plugin.getLogger().log(Level.SEVERE, "Error saving modified Clans:", ex); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/TeleportManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/TeleportManager.java index 6871c4ca..210d562b 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/TeleportManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/TeleportManager.java @@ -29,12 +29,15 @@ import static org.bukkit.ChatColor.RED; * Class responsible for managing teleports and its queue */ public final class TeleportManager { + private final SimpleClans plugin; private final HashMap waitingPlayers = new HashMap<>(); public TeleportManager() { + plugin = SimpleClans.getInstance(); startCounter(); + } /** @@ -45,180 +48,267 @@ public final class TeleportManager { * @param clanName the Clan name */ public void addPlayer(Player player, Location destination, String clanName) { + PermissionsManager pm = plugin.getPermissionsManager(); int secs = SimpleClans.getInstance().getSettingsManager().getInt(CLAN_TELEPORT_DELAY); if (pm.has(player, "simpleclans.mod.bypass") || pm.has(player, "simpleclans.vip.teleport-delay")) { + secs = 0; + } + waitingPlayers.put(player.getUniqueId().toString(), new TeleportState(player, destination, clanName, secs)); if (secs > 0) { + ChatBlock.sendMessage(player, AQUA + lang("waiting.for.teleport.stand.still.for.0.seconds", player, secs)); + } + } /** - * Teleports all online and non-vanished members of this {@link Clan} to the specified {@link Location} + * Teleports all online and non-vanished members of this {@link Clan} to the + * specified {@link Location} * * @param requester the Player requesting the teleport * @param clan the Clan * @param location the Location */ public void teleport(@NotNull Player requester, @NotNull Clan clan, @NotNull Location location) { + teleport(clan, location, VanishUtils.getNonVanished(requester, clan)); + } /** - * Teleports all online and non-vanished members of this {@link Clan} to the specified {@link Location} + * Teleports all online and non-vanished members of this {@link Clan} to the + * specified {@link Location} * * @param clan the Clan * @param location the Location */ public void teleport(Clan clan, Location location) { + teleport(clan, location, VanishUtils.getNonVanished(null, clan)); + } public void teleportToHome(@NotNull Player player, @NotNull Location destination, @NotNull String clanName) { - PaperLib.teleportAsync(player, getSafe(destination), PlayerTeleportEvent.TeleportCause.COMMAND).thenAccept(result -> { - if (result) { - ChatBlock.sendMessage(player, AQUA + lang("now.at.homebase", player, clanName)); - } else { - plugin.getLogger().log(Level.WARNING, "An error occurred while teleporting a player"); - } - }); + + PaperLib.teleportAsync(player, getSafe(destination), PlayerTeleportEvent.TeleportCause.COMMAND) + .thenAccept(result -> + { + + if (result) { + + ChatBlock.sendMessage(player, AQUA + lang("now.at.homebase", player, clanName)); + + } else { + + plugin.getLogger().log(Level.WARNING, "An error occurred while teleporting a player"); + + } + + }); + } public void teleportToHome(@NotNull Player player, @NotNull Clan clan) { + if (clan.getHomeLocation() == null) { + return; + } + teleportToHome(player, clan.getHomeLocation(), clan.getName()); + } private boolean isSameBlock(Location loc, Location loc2) { - return loc.getBlockX() == loc2.getBlockX() && loc.getBlockY() == loc2.getBlockY() && - loc.getBlockZ() == loc2.getBlockZ(); + + return loc.getBlockX() == loc2.getBlockX() && loc.getBlockY() == loc2.getBlockY() + && loc.getBlockZ() == loc2.getBlockZ(); + } /** - * Converts the specified {@link Location} to a safe one, i.e. where there is no risk of suffocation + * Converts the specified {@link Location} to a safe one, i.e. where there is no + * risk of suffocation * * @param location the Location * @return the safe Location */ public @NotNull Location getSafe(@NotNull Location location) { + int counter = 0; - while (counter < 256) { //max world height + while (counter < 256) { // max world height + counter++; Block bottom = location.getBlock(); Block top = location.add(0, 1, 0).getBlock(); if (!isAir(bottom)) { + continue; + } + if (!isAir(top)) { - location.add(0, 1, 0); //skips checking the same block again + + location.add(0, 1, 0); // skips checking the same block again continue; + } - location.subtract(0, 1, 0); //remove what was added above + + location.subtract(0, 1, 0); // remove what was added above return location; + } - //noinspection ConstantConditions + // noinspection ConstantConditions location.setY(location.getWorld().getHighestBlockYAt(location) + 1); return location; + } private void dropItems(Player player) { + if (plugin.getPermissionsManager().has(player, "simpleclans.mod.keep-items")) { + return; + } + List itemsList = plugin.getSettingsManager().getItemList(); PlayerInventory inv = player.getInventory(); boolean dropOnHome = plugin.getSettingsManager().is(DROP_ITEMS_ON_CLAN_HOME); boolean keepOnHome = plugin.getSettingsManager().is(KEEP_ITEMS_ON_CLAN_HOME); ItemStack[] contents = inv.getContents(); for (ItemStack item : contents) { + if (item == null) { + continue; + } - if ((dropOnHome && itemsList.contains(item.getType())) || - (keepOnHome && !itemsList.contains(item.getType()))) { + + if ((dropOnHome && itemsList.contains(item.getType())) + || (keepOnHome && !itemsList.contains(item.getType()))) + { + player.getWorld().dropItemNaturally(player.getLocation(), item); inv.remove(item); + } + } + } private void startCounter() { + plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> { + waitingPlayers.values().removeIf(ts -> ts.getPlayer() == null); - for (Iterator iter = waitingPlayers.values().iterator(); iter.hasNext(); ) { + for (Iterator iter = waitingPlayers.values().iterator(); iter.hasNext();) { + TeleportState state = iter.next(); Player player = state.getPlayer(); if (state.isProcessing() || player == null) { + continue; + } + state.setProcessing(true); if (!isSameBlock(player.getLocation(), state.getLocation())) { + ChatBlock.sendMessage(player, RED + lang("you.moved.teleport.cancelled", player)); iter.remove(); continue; + } + if (state.isTeleportTime()) { + teleport(state); iter.remove(); + } else { + ChatBlock.sendMessage(player, AQUA + "" + state.getCounter()); + } state.setProcessing(false); + } + }, 0, 20L); + } private void teleport(TeleportState state) { + Player player = state.getPlayer(); if (player == null) { + return; + } + ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(player.getUniqueId()); ClanPlayerTeleportEvent event = new ClanPlayerTeleportEvent(cp, state.getLocation(), state.getDestination()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return; + } + Location loc = state.getDestination(); sendTeleportBlocks(player, loc); dropItems(player); loc.clone().add(.5, .5, .5); teleportToHome(player, loc, state.getClanName()); + } @SuppressWarnings("deprecation") private void sendTeleportBlocks(Player player, Location loc) { + int x = loc.getBlockX(); int z = loc.getBlockZ(); if (plugin.getSettingsManager().is(TELEPORT_BLOCKS)) { - player.sendBlockChange(new Location(loc.getWorld(), x + 1, loc.getBlockY() - 1, z + 1), - Material.GLASS, (byte) 0); - player.sendBlockChange(new Location(loc.getWorld(), x - 1, loc.getBlockY() - 1, z - 1), - Material.GLASS, (byte) 0); - player.sendBlockChange(new Location(loc.getWorld(), x + 1, loc.getBlockY() - 1, z - 1), - Material.GLASS, (byte) 0); - player.sendBlockChange(new Location(loc.getWorld(), x - 1, loc.getBlockY() - 1, z + 1), - Material.GLASS, (byte) 0); + + player.sendBlockChange(new Location(loc.getWorld(), x + 1, loc.getBlockY() - 1, z + 1), Material.GLASS, + (byte) 0); + player.sendBlockChange(new Location(loc.getWorld(), x - 1, loc.getBlockY() - 1, z - 1), Material.GLASS, + (byte) 0); + player.sendBlockChange(new Location(loc.getWorld(), x + 1, loc.getBlockY() - 1, z - 1), Material.GLASS, + (byte) 0); + player.sendBlockChange(new Location(loc.getWorld(), x - 1, loc.getBlockY() - 1, z + 1), Material.GLASS, + (byte) 0); + } + } private void teleport(Clan clan, Location location, List members) { + for (ClanPlayer cp : members) { + Player player = cp.toPlayer(); if (player == null) { + continue; + } + int x = location.getBlockX(); int z = location.getBlockZ(); sendTeleportBlocks(player, location); @@ -227,14 +317,19 @@ public final class TeleportManager { int xx = r.nextInt(2) - 1; int zz = r.nextInt(2) - 1; if (xx == 0 && zz == 0) { + xx = 1; + } + x = x + xx; z = z + zz; plugin.getTeleportManager().addPlayer(player, new Location(location.getWorld(), x + .5, location.getBlockY(), z + .5, location.getYaw(), location.getPitch()), clan.getName()); + } + } /** @@ -245,12 +340,19 @@ public final class TeleportManager { */ @SuppressWarnings("BooleanMethodIsAlwaysInverted") private boolean isAir(@NotNull Block... blocks) { + for (Block b : blocks) { + if (!b.getType().name().contains("AIR")) { + return false; + } + } + return true; + } } \ No newline at end of file diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/BbMigration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/BbMigration.java index 3d787290..fde57609 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/BbMigration.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/BbMigration.java @@ -13,17 +13,26 @@ import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager; public class BbMigration extends ConfigMigration { public BbMigration(SettingsManager settingsManager) { + super(settingsManager); + } @Override public void migrate() { + if (config.contains("bb.accent-color")) { + config.set("bb.accent-color", null); + } if (config.contains("bb.color")) { + config.set("bb.color", null); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ChatFormatMigration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ChatFormatMigration.java index 536695a2..c64aa56b 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ChatFormatMigration.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ChatFormatMigration.java @@ -10,12 +10,17 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class ChatFormatMigration extends ConfigMigration { public ChatFormatMigration(SettingsManager settingsManager) { + super(settingsManager); + } public void migrateClanChat() { + if (config.getString("clanchat.name-color") == null) { + return; + } StringBuilder sb = new StringBuilder(); @@ -48,12 +53,16 @@ public class ChatFormatMigration extends ConfigMigration { config.set("clanchat.player-bracket", null); config.set("clanchat.message-color", null); config.set("clanchat.tag-bracket", null); + } public void migrateAllyChat() { - //Checks if the old format is still in use + + // Checks if the old format is still in use if (config.getString("allychat.tag-color") == null) { + return; + } StringBuilder sb = new StringBuilder(); @@ -88,11 +97,15 @@ public class ChatFormatMigration extends ConfigMigration { config.set("allychat.player-bracket", null); config.set("allychat.message-color", null); config.set("allychat.tag-bracket", null); + } @Override public void migrate() { + migrateClanChat(); migrateAllyChat(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ConfigMigration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ConfigMigration.java index 2b2fadfd..d26b2940 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ConfigMigration.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/ConfigMigration.java @@ -9,10 +9,13 @@ public abstract class ConfigMigration implements Migration { protected final FileConfiguration config; public ConfigMigration(SettingsManager settingsManager) { + this.settings = settingsManager; this.config = settings.getConfig(); migrate(); settings.save(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/LanguageMigration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/LanguageMigration.java index eedcfe77..4c54fd09 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/LanguageMigration.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/LanguageMigration.java @@ -11,124 +11,169 @@ import java.util.List; import java.util.stream.Collectors; /** - * Utility class that migrates old language files (yaml) to the new format (properties) + * Utility class that migrates old language files (yaml) to the new format + * (properties) * * @author RoinujNosde * */ public class LanguageMigration implements Migration { - private final SimpleClans plugin; + private final SimpleClans plugin; - public LanguageMigration(SimpleClans plugin) { - this.plugin = plugin; - } + public LanguageMigration(SimpleClans plugin) { - /** - * Migrates all language files in the plugin's data folder - */ - public void migrate() { - File dataFolder = plugin.getDataFolder(); - if (!dataFolder.exists()) { - return; - } - File[] languageFiles = dataFolder.listFiles(f -> { - return f.getName().startsWith("language") && f.getName().endsWith(".yml"); - }); + this.plugin = plugin; - for (File file : languageFiles) { - convert(file); - backup(file); - file.delete(); - } - } + } - /** - * Copies the file to the backup folder - * - * @param file the file to back up - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - private void backup(File file) { - File backupFolder = new File(plugin.getDataFolder(), "language_backup"); - if (!backupFolder.exists()) { - backupFolder.mkdir(); - } + /** + * Migrates all language files in the plugin's data folder + */ + public void migrate() { - file.renameTo(new File(backupFolder, file.getName())); - } + File dataFolder = plugin.getDataFolder(); + if (!dataFolder.exists()) { - /** - * Converts the yaml file to properties - * - * @param file - */ - private void convert(File file) { - List lines = readLines(file); + return; - if (lines == null || lines.isEmpty()) { - return; - } + } - List convertedLines = convertLines(lines); + File[] languageFiles = dataFolder.listFiles(f -> { - saveFile(file, convertedLines); - } + return f.getName().startsWith("language") && f.getName().endsWith(".yml"); - private void saveFile(File file, List convertedLines) { - String fileName = convertFileName(file); - File converted = new File(file.getParentFile(), fileName); - try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(converted), StandardCharsets.UTF_8))) { - for (String line : convertedLines) { - writer.append(line); - writer.append(System.lineSeparator()); - } + }); - writer.flush(); - } catch (IOException e) { - plugin.getLogger().severe("Error converting language file " + file.getName()); - e.printStackTrace(); - } - } + for (File file : languageFiles) { - @NotNull - private List convertLines(List lines) { - List convertedLines = new ArrayList<>(); - for (String line : lines) { - line = line.replaceFirst(":", "=") - .replaceAll("''''", "''") - .replaceAll("^'", "") - .replaceAll("= \'", "=") - .replaceAll("'$", "") - .replaceAll("^\"", "") - .replaceAll("\"$", "") - .replaceAll("= \"", "="); - convertedLines.add(line); - } - return convertedLines; - } + convert(file); + backup(file); + file.delete(); - @Nullable - private List readLines(File file) { - List lines = null; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { - lines = reader.lines().collect(Collectors.toList()); - } catch (IOException e) { - plugin.getLogger().severe("Error converting language file " + file.getName()); - e.printStackTrace(); - } - return lines; - } + } + + } + + /** + * Copies the file to the backup folder + * + * @param file the file to back up + */ + @SuppressWarnings("ResultOfMethodCallIgnored") + private void backup(File file) { + + File backupFolder = new File(plugin.getDataFolder(), "language_backup"); + if (!backupFolder.exists()) { + + backupFolder.mkdir(); + + } + + file.renameTo(new File(backupFolder, file.getName())); + + } + + /** + * Converts the yaml file to properties + * + * @param file + */ + private void convert(File file) { + + List lines = readLines(file); + + if (lines == null || lines.isEmpty()) { + + return; + + } + + List convertedLines = convertLines(lines); + + saveFile(file, convertedLines); + + } + + private void saveFile(File file, List convertedLines) { + + String fileName = convertFileName(file); + File converted = new File(file.getParentFile(), fileName); + try (Writer writer = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(converted), StandardCharsets.UTF_8))) + { + + for (String line : convertedLines) { + + writer.append(line); + writer.append(System.lineSeparator()); + + } + + writer.flush(); + + } catch (IOException e) { + + plugin.getLogger().severe("Error converting language file " + file.getName()); + e.printStackTrace(); + + } + + } + + @NotNull + private List convertLines(List lines) { + + List convertedLines = new ArrayList<>(); + for (String line : lines) { + + line = line.replaceFirst(":", "=").replaceAll("''''", "''").replaceAll("^'", "").replaceAll("= \'", "=") + .replaceAll("'$", "").replaceAll("^\"", "").replaceAll("\"$", "").replaceAll("= \"", "="); + convertedLines.add(line); + + } + + return convertedLines; + + } + + @Nullable + private List readLines(File file) { + + List lines = null; + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) + { + + lines = reader.lines().collect(Collectors.toList()); + + } catch (IOException e) { + + plugin.getLogger().severe("Error converting language file " + file.getName()); + e.printStackTrace(); + + } + + return lines; + + } + + @NotNull + private String convertFileName(File file) { + + String fileName; + if (file.getName().equals("language.yml")) { + + fileName = "messages_en.properties"; + + } else { + + fileName = file.getName().replace("language", "messages").replace("yml", "properties").replace("-", "_"); + + } + + return fileName; + + } - @NotNull - private String convertFileName(File file) { - String fileName; - if (file.getName().equals("language.yml")) { - fileName = "messages_en.properties"; - } else { - fileName = file.getName().replace("language", "messages") - .replace("yml", "properties").replace("-", "_"); - } - return fileName; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/Migration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/Migration.java index 79c4a0a6..5bacbc58 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/Migration.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/Migration.java @@ -3,4 +3,5 @@ package net.sacredlabyrinth.phaed.simpleclans.migrations; public interface Migration { void migrate(); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/BungeeManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/BungeeManager.java index c7b77c21..65e2f2f4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/BungeeManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/BungeeManager.java @@ -38,8 +38,8 @@ public final class BungeeManager implements ProxyManager, PluginMessageListener private static final String BROADCAST = "Broadcast"; private static final String MESSAGE = "Message"; private static final String VERSION = "v1"; - private static final Pattern SUBCHANNEL_PATTERN = - Pattern.compile("SimpleClans\\|(?\\w+)\\|(?v\\d+)\\|(?.+)"); + private static final Pattern SUBCHANNEL_PATTERN = Pattern + .compile("SimpleClans\\|(?\\w+)\\|(?v\\d+)\\|(?.+)"); private final SimpleClans plugin; private final Gson gson; @@ -48,217 +48,310 @@ public final class BungeeManager implements ProxyManager, PluginMessageListener private final Set unsupportedChannels = new HashSet<>(); public BungeeManager(SimpleClans plugin) { + this.plugin = plugin; gson = new GsonBuilder().registerTypeAdapterFactory(new ClanPlayerTypeAdapterFactory(plugin)) .registerTypeAdapterFactory(new ConfigurationSerializableAdapter()) .registerTypeAdapter(ClanPlayerListAdapter.getType(), new ClanPlayerListAdapter(plugin)) - .registerTypeAdapter(SCMessage.class, new SCMessageAdapter(plugin)).setExclusionStrategies() - .create(); + .registerTypeAdapter(SCMessage.class, new SCMessageAdapter(plugin)).setExclusionStrategies().create(); if (!plugin.getSettingsManager().is(ConfigField.PERFORMANCE_USE_BUNGEECORD)) { + return; + } + Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, "BungeeCord"); Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "BungeeCord", this); Bukkit.getScheduler().runTaskTimer(plugin, this::requestPlayerList, 0, 60 * 20); requestServerName(); + } @SuppressWarnings("UnstableApiUsage") public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] data) { + ByteArrayDataInput dataInput = ByteStreams.newDataInput(data); String subChannel = dataInput.readUTF(); if (unsupportedChannels.contains(subChannel)) { + return; + } SimpleClans.debug("Message received, sub-channel: " + subChannel); try { + String serverName = null; String className = subChannel; String version = null; Matcher matcher = SUBCHANNEL_PATTERN.matcher(subChannel); if (matcher.find()) { + serverName = matcher.group("server"); className = matcher.group("subchannel"); version = matcher.group("version"); + } + Class clazz = Class.forName("net.sacredlabyrinth.phaed.simpleclans.proxy.listeners." + className); MessageListener listener = (MessageListener) clazz.getConstructor(BungeeManager.class).newInstance(this); if (listener.isBungeeSubchannel()) { - listener.accept(dataInput); //uses the original data + + listener.accept(dataInput); // uses the original data return; + } + if (!VERSION.equals(version)) { - plugin.getLogger().severe(String.format("Unsupported channel (%s), expected version: %s", subChannel, VERSION)); + + plugin.getLogger() + .severe(String.format("Unsupported channel (%s), expected version: %s", subChannel, VERSION)); unsupportedChannels.add(subChannel); return; + } + if (serverName != null && !isServerAllowed(serverName)) { + SimpleClans.debug(String.format("Server not allowed: %s", serverName)); return; + } + byte[] messageBytes = new byte[dataInput.readShort()]; dataInput.readFully(messageBytes); final ByteArrayDataInput message = ByteStreams.newDataInput(messageBytes); listener.accept(message); // uses the internal data + } catch (ClassNotFoundException e) { + SimpleClans.debug(String.format("Unknown channel: %s", subChannel)); unsupportedChannels.add(subChannel); + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, String.format("Error processing channel %s", subChannel), ex); + } + } private boolean isServerAllowed(@NotNull String serverName) { + List servers = plugin.getSettingsManager().getStringList(ConfigField.BUNGEE_SERVERS); if (servers.isEmpty()) { + return true; + } return servers.contains(serverName); + } @Override public boolean isOnline(String playerName) { + if (Bukkit.getOnlinePlayers().stream().anyMatch(player -> player.getName().equals(playerName))) { + return true; + } + return onlinePlayers.contains(playerName); + } public void setOnlinePlayers(@NotNull List onlinePlayers) { + this.onlinePlayers.clear(); this.onlinePlayers.addAll(onlinePlayers); + } @Override public String getServerName() { + return serverName; + } public void setServerName(@NotNull String name) { + this.serverName = name; + } @Override public void sendMessage(SCMessage message) { + forwardToOnlineServers(CHAT_CHANNEL, gson.toJson(message)); + } @Override public void sendMessage(@NotNull String target, @NotNull String message) { + if (message.isEmpty()) { + return; + } if ("ALL".equals(target)) { + Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); sendBroadcast(message); return; + } Player player = Bukkit.getPlayerExact(target); if (player != null) { + player.sendMessage(message); return; + } sendPrivateMessage(target, message); + } private void sendBroadcast(@NotNull String message) { + forwardToOnlineServers(BROADCAST, message); + } @Override public void sendDelete(Clan clan) { + forwardToAllServers(DELETE_CLAN_CHANNEL, clan.getTag()); + } @Override public void sendDelete(ClanPlayer cp) { + forwardToAllServers(DELETE_CLANPLAYER_CHANNEL, cp.getUniqueId().toString()); + } @Override public void sendUpdate(Clan clan) { + forwardToAllServers(UPDATE_CLAN_CHANNEL, gson.toJson(clan)); + } @Override public void sendUpdate(ClanPlayer cp) { + forwardToAllServers(UPDATE_CLANPLAYER_CHANNEL, gson.toJson(cp)); + } public SimpleClans getPlugin() { + return plugin; + } public Gson getGson() { + return gson; + } @SuppressWarnings("UnstableApiUsage") private void requestPlayerList() { + if (!isChannelRegistered()) { + return; + } + ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeUTF("PlayerList"); output.writeUTF("ALL"); sendOnBungeeChannel(output); + } private void requestServerName() { + Bukkit.getScheduler().runTaskTimer(plugin, task -> { + if (!serverName.isEmpty()) { + task.cancel(); return; + } + Bukkit.getOnlinePlayers().stream().findFirst().ifPresent(player -> { + @SuppressWarnings("UnstableApiUsage") ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeUTF("GetServer"); player.sendPluginMessage(plugin, "BungeeCord", output.toByteArray()); + }); + }, 0L, 20L); + } private String createSubchannelName(String subchannel) { + return String.format("SimpleClans|%s|%s|%s", subchannel, VERSION, serverName); + } @SuppressWarnings("UnstableApiUsage") private void sendPrivateMessage(@NotNull String playerName, @NotNull String message) { + ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeUTF(playerName); output.writeUTF(message); forwardPluginMessage(MESSAGE, output, false); + } @SuppressWarnings("UnstableApiUsage") private void forwardToAllServers(final String subChannel, final String message) { + ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeUTF(message); forwardPluginMessage(subChannel, output, true); + } @SuppressWarnings("UnstableApiUsage") private void forwardToOnlineServers(final String subChannel, final String message) { + ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeUTF(message); forwardPluginMessage(subChannel, output, false); + } @SuppressWarnings("UnstableApiUsage") private void forwardPluginMessage(final String subChannel, final ByteArrayDataOutput message, final boolean all) { - SimpleClans.debug(String.format("Forwarding message, channel %s, message %s, all %s", subChannel, message, all)); + + SimpleClans + .debug(String.format("Forwarding message, channel %s, message %s, all %s", subChannel, message, all)); if (!isChannelRegistered()) { + return; + } + ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeUTF("Forward"); output.writeUTF(all ? "ALL" : "ONLINE"); @@ -268,18 +361,23 @@ public final class BungeeManager implements ProxyManager, PluginMessageListener output.write(message.toByteArray()); sendOnBungeeChannel(output); + } private void sendOnBungeeChannel(ByteArrayDataOutput output) { - Bukkit.getOnlinePlayers().stream().findAny().ifPresent(player -> - player.sendPluginMessage(plugin, "BungeeCord", output.toByteArray())); + + Bukkit.getOnlinePlayers().stream().findAny() + .ifPresent(player -> player.sendPluginMessage(plugin, "BungeeCord", output.toByteArray())); + } @SuppressWarnings("BooleanMethodIsAlwaysInverted") private boolean isChannelRegistered() { + boolean registered = Bukkit.getMessenger().isOutgoingChannelRegistered(plugin, "BungeeCord"); SimpleClans.debug(String.format("BungeeCord channel registered: %s", registered)); return registered; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/ProxyManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/ProxyManager.java index e8b31cde..6bd631b2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/ProxyManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/ProxyManager.java @@ -21,4 +21,5 @@ public interface ProxyManager { void sendDelete(Clan clan); void sendDelete(ClanPlayer cp); + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerListAdapter.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerListAdapter.java index f3081494..847b4026 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerListAdapter.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerListAdapter.java @@ -15,43 +15,61 @@ import java.util.List; import java.util.UUID; public class ClanPlayerListAdapter extends TypeAdapter> { + private final SimpleClans plugin; public ClanPlayerListAdapter(SimpleClans plugin) { + this.plugin = plugin; + } @Override public void write(JsonWriter out, List value) throws IOException { + out.beginArray(); for (ClanPlayer clanPlayer : value) { + out.beginObject(); out.name("uuid"); out.value(clanPlayer.getUniqueId().toString()); out.endObject(); + } + out.endArray(); + } @Override public List read(JsonReader in) throws IOException { + List list = new ArrayList<>(); in.beginArray(); while (in.peek() == JsonToken.BEGIN_OBJECT) { + in.beginObject(); in.nextName(); UUID uuid = UUID.fromString(in.nextString()); ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(uuid); in.endObject(); if (cp != null) { + list.add(cp); + } + } + in.endArray(); return list; + } public static Type getType() { + return TypeToken.getParameterized(List.class, ClanPlayer.class).getType(); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerTypeAdapterFactory.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerTypeAdapterFactory.java index ca6db862..e5cd62d2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerTypeAdapterFactory.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ClanPlayerTypeAdapterFactory.java @@ -17,27 +17,37 @@ public class ClanPlayerTypeAdapterFactory implements TypeAdapterFactory { private final SimpleClans plugin; public ClanPlayerTypeAdapterFactory(SimpleClans plugin) { + this.plugin = plugin; + } @SuppressWarnings("unchecked") @Override public @Nullable TypeAdapter create(Gson gson, TypeToken type) { + if (type.getType() != ClanPlayer.class) { + return null; + } + final TypeAdapter delegate = (TypeAdapter) gson.getDelegateAdapter(this, type); return (TypeAdapter) new TypeAdapter() { + @Override public void write(JsonWriter out, ClanPlayer value) { + JsonObject object = delegate.toJsonTree(value).getAsJsonObject(); object.addProperty("clan", value.getTag()); gson.toJson(object, out); + } @Override public ClanPlayer read(JsonReader in) { + JsonObject object = gson.fromJson(in, JsonObject.class); String tag = object.get("clan").getAsString(); Clan clan = plugin.getClanManager().getClan(tag); @@ -46,7 +56,11 @@ public class ClanPlayerTypeAdapterFactory implements TypeAdapterFactory { ClanPlayer cp = delegate.fromJsonTree(object); cp.setClan(clan); return cp; + } + }; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ConfigurationSerializableAdapter.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ConfigurationSerializableAdapter.java index 2bbfd4b3..db131d53 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ConfigurationSerializableAdapter.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/ConfigurationSerializableAdapter.java @@ -13,35 +13,54 @@ import org.bukkit.configuration.serialization.ConfigurationSerialization; import java.io.IOException; import java.util.Map; -@SuppressWarnings({"unchecked", "rawtypes"}) +@SuppressWarnings({ "unchecked", "rawtypes" }) public class ConfigurationSerializableAdapter implements TypeAdapterFactory { @Override public TypeAdapter create(Gson gson, TypeToken type) { + if (!ConfigurationSerializable.class.isAssignableFrom(type.getRawType())) { + return null; + } + TypeAdapter adapter = gson.getAdapter(Map.class); return (TypeAdapter) new TypeAdapter() { + @Override public void write(JsonWriter out, ConfigurationSerializable value) throws IOException { + if (value == null) { + out.nullValue(); + } else { + adapter.write(out, value.serialize()); + } + } @Override public ConfigurationSerializable read(JsonReader in) throws IOException { - if (in.peek() == JsonToken.NULL) { //could be replaced with map == null? + + if (in.peek() == JsonToken.NULL) { // could be replaced with map == null? + in.nextNull(); return null; + } + Map map = adapter.read(in); return ConfigurationSerialization.deserializeObject(map, (Class) type.getRawType()); + } + }; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/SCMessageAdapter.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/SCMessageAdapter.java index 00e1147e..cf8e85d4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/SCMessageAdapter.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/adapters/SCMessageAdapter.java @@ -17,11 +17,14 @@ public class SCMessageAdapter extends TypeAdapter { private final SimpleClans plugin; public SCMessageAdapter(SimpleClans plugin) { + this.plugin = plugin; + } @Override public void write(JsonWriter out, SCMessage value) throws IOException { + out.beginObject(); out.name("channel"); out.value(value.getChannel().toString()); @@ -30,10 +33,12 @@ public class SCMessageAdapter extends TypeAdapter { out.name("content"); out.value(value.getContent()); out.endObject(); + } @Override public @Nullable SCMessage read(JsonReader in) throws IOException { + in.beginObject(); in.nextName(); ClanPlayer.Channel channel = ClanPlayer.Channel.valueOf(in.nextString()); @@ -45,8 +50,13 @@ public class SCMessageAdapter extends TypeAdapter { in.endObject(); if (sender == null) { + return null; + } + return new SCMessage(Source.PROXY, channel, sender, content); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Broadcast.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Broadcast.java index 7c44bcf5..85c87d1a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Broadcast.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Broadcast.java @@ -7,17 +7,24 @@ import org.bukkit.Bukkit; public class Broadcast extends MessageListener { public Broadcast(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + String message = data.readUTF(); Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message)); + } @Override public boolean isBungeeSubchannel() { + return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Chat.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Chat.java index 7c07adf3..f5d92969 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Chat.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Chat.java @@ -7,20 +7,30 @@ import net.sacredlabyrinth.phaed.simpleclans.proxy.BungeeManager; public class Chat extends MessageListener { public Chat(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + SCMessage message = getGson().fromJson(data.readUTF(), SCMessage.class); if (message.getSender().getClan() == null) { + return; + } + bungee.getPlugin().getChatManager().processChat(message); + } @Override public boolean isBungeeSubchannel() { + return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClan.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClan.java index 28f49a99..0965cf6d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClan.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClan.java @@ -9,26 +9,38 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.debug; public class DeleteClan extends MessageListener { public DeleteClan(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + String tag = data.readUTF(); getClanManager().removeClan(tag); for (ClanPlayer cp : getClanManager().getAllClanPlayers()) { + if (tag.equals(cp.getTag())) { + cp.setClan(null); cp.setJoinDate(0); cp.setRank(null); cp.setLeader(false); + } + } + debug(String.format("Deleted clan %s", tag)); + } @Override public boolean isBungeeSubchannel() { + return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClanPlayer.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClanPlayer.java index 5a03ce58..1446da8c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClanPlayer.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/DeleteClanPlayer.java @@ -10,18 +10,25 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.debug; public class DeleteClanPlayer extends MessageListener { public DeleteClanPlayer(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + UUID uuid = UUID.fromString(data.readUTF()); getClanManager().deleteClanPlayerFromMemory(uuid); debug(String.format("Deleted cp %s", uuid)); + } @Override public boolean isBungeeSubchannel() { + return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/GetServer.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/GetServer.java index a61860ed..fc35f407 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/GetServer.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/GetServer.java @@ -7,18 +7,25 @@ import net.sacredlabyrinth.phaed.simpleclans.proxy.BungeeManager; public class GetServer extends MessageListener { public GetServer(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + String name = data.readUTF(); bungee.setServerName(name); SimpleClans.debug(String.format("Server name: %s", name)); + } @Override public boolean isBungeeSubchannel() { + return true; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Message.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Message.java index 211c909c..79501d01 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Message.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Message.java @@ -8,22 +8,31 @@ import org.bukkit.entity.Player; public class Message extends MessageListener { public Message(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + String target = data.readUTF(); String message = data.readUTF(); Player player = Bukkit.getPlayerExact(target); if (player != null) { + player.sendMessage(message); + } + } @Override public boolean isBungeeSubchannel() { + return false; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/MessageListener.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/MessageListener.java index 7123056c..c263ec68 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/MessageListener.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/MessageListener.java @@ -10,7 +10,9 @@ public abstract class MessageListener { protected final BungeeManager bungee; public MessageListener(BungeeManager bungee) { + this.bungee = bungee; + } public abstract void accept(ByteArrayDataInput data); @@ -18,11 +20,15 @@ public abstract class MessageListener { public abstract boolean isBungeeSubchannel(); protected ClanManager getClanManager() { + return bungee.getPlugin().getClanManager(); + } protected Gson getGson() { + return bungee.getGson(); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/PlayerList.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/PlayerList.java index 4d863f4b..4a0d6d6a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/PlayerList.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/PlayerList.java @@ -10,19 +10,26 @@ import java.util.List; public class PlayerList extends MessageListener { public PlayerList(BungeeManager bungee) { + super(bungee); + } @Override public void accept(ByteArrayDataInput data) { + data.readUTF(); // target List players = Arrays.asList(data.readUTF().split(", ")); bungee.setOnlinePlayers(players); SimpleClans.debug("Updated player list"); + } @Override public boolean isBungeeSubchannel() { + return true; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Update.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Update.java index f5da3b4e..a33369a1 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Update.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/Update.java @@ -12,7 +12,9 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.debug; public abstract class Update extends MessageListener { public Update(BungeeManager bungee) { + super(bungee); + } protected abstract Class getType(); @@ -23,18 +25,30 @@ public abstract class Update extends MessageListener { @Override public final void accept(ByteArrayDataInput data) { + T t = getGson().fromJson(data.readUTF(), getType()); T current = getCurrent(t); if (current == null) { + insert(t); debug(String.format("Inserted %s", t)); return; + } + try { + ObjectUtils.updateFields(t, current); + } catch (IllegalAccessException e) { - bungee.getPlugin().getLogger().log(Level.SEVERE, String.format("An error happened while updating %s", t), e); + + bungee.getPlugin().getLogger().log(Level.SEVERE, String.format("An error happened while updating %s", t), + e); + } + debug(String.format("Updated %s", t)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClan.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClan.java index b0f88fc9..43abb035 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClan.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClan.java @@ -7,27 +7,37 @@ import org.jetbrains.annotations.Nullable; public class UpdateClan extends Update { public UpdateClan(BungeeManager bungee) { + super(bungee); + } @Override public boolean isBungeeSubchannel() { + return false; + } @Override protected Class getType() { + return Clan.class; + } @Override protected @Nullable Clan getCurrent(Clan clan) { + return getClanManager().getClan(clan.getTag()); + } @Override protected void insert(Clan clan) { + getClanManager().importClan(clan); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClanPlayer.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClanPlayer.java index 75daa37d..9d6bc99e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClanPlayer.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/proxy/listeners/UpdateClanPlayer.java @@ -7,27 +7,37 @@ import org.jetbrains.annotations.Nullable; public class UpdateClanPlayer extends Update { public UpdateClanPlayer(BungeeManager bungee) { + super(bungee); + } @Override public boolean isBungeeSubchannel() { + return false; + } @Override protected Class getType() { + return ClanPlayer.class; + } @Override protected @Nullable ClanPlayer getCurrent(ClanPlayer clanPlayer) { + return getClanManager().getAnyClanPlayer(clanPlayer.getUniqueId()); + } @Override protected void insert(ClanPlayer clanPlayer) { + getClanManager().importClanPlayer(clanPlayer); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/DBCore.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/DBCore.java index 3f829f0e..d14f1a5c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/DBCore.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/DBCore.java @@ -28,7 +28,9 @@ public interface DBCore { * @return whether connection can be established */ default boolean checkConnection() { + return getConnection() != null; + } /** @@ -38,83 +40,128 @@ public interface DBCore { /** * Execute a select statement + * * @param query the query * @return the result set or null if the query failed */ default @Nullable ResultSet select(String query) { + try { + return getConnection().createStatement().executeQuery(query); + } catch (SQLException ex) { + log.log(Level.SEVERE, String.format("Error executing query: %s", query), ex); + } + return null; + } /** * Execute a statement + * * @param query the query * @return true if the statement was executed */ default boolean execute(String query) { + try { + getConnection().createStatement().execute(query); return true; + } catch (SQLException ex) { + log.log(Level.SEVERE, String.format("Error executing query: %s", query), ex); return false; + } + } /** * Check whether a table exists + * * @param table the table * @return true if the table exists */ default boolean existsTable(String table) { + try { + ResultSet tables = getConnection().getMetaData().getTables(null, null, table, null); return tables.next(); + } catch (SQLException ex) { + log.log(Level.SEVERE, String.format("Error checking if table %s exists", table), ex); return false; + } + } /** * Check whether a column exists * - * @param table the table + * @param table the table * @param column the column * @return true if the column exists */ default boolean existsColumn(String table, String column) { + try { + ResultSet col = getConnection().getMetaData().getColumns(null, null, table, column); return col.next(); + } catch (Exception ex) { + log.log(Level.SEVERE, String.format("Error checking if column %s exists in table %s", column, table), ex); return false; + } + } default void executeUpdate(String query) { + final Exception exception = new Exception(); // Stores a reference to the caller's stack trace for async tasks Runnable executeUpdate = () -> { + if (getConnection() != null) { + try { + getConnection().createStatement().executeUpdate(query); + } catch (SQLException ex) { + log.log(Level.SEVERE, String.format("Error executing query: %s", query), ex); if (!Bukkit.isPrimaryThread()) { + log.log(Level.SEVERE, "Caller's stack trace:", exception); + } + } + } + }; if (plugin.getSettingsManager().is(ConfigField.PERFORMANCE_USE_THREADS)) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, executeUpdate); + } else { + executeUpdate.run(); + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/MySQLCore.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/MySQLCore.java index 21c2e75f..be0217c0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/MySQLCore.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/MySQLCore.java @@ -27,6 +27,7 @@ public class MySQLCore implements DBCore { * @param password The password */ public MySQLCore(String host, String database, int port, String username, String password) { + this.database = database; this.port = port; this.host = host; @@ -34,40 +35,69 @@ public class MySQLCore implements DBCore { this.password = password; this.log = SimpleClans.getInstance().getLogger(); initialize(); + } private void initialize() { + try { + Class.forName("com.mysql.jdbc.Driver"); - connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false", username, password); + connection = DriverManager.getConnection( + "jdbc:mysql://" + host + ":" + port + "/" + database + + "?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false", + username, password); + } catch (ClassNotFoundException e) { + log.severe("ClassNotFoundException! " + e.getMessage()); + } catch (SQLException e) { + log.severe("SQLException! " + e.getMessage()); + } + } @Override public Connection getConnection() { + try { + if (connection == null || connection.isClosed() || !connection.isValid(0)) { + initialize(); + } + } catch (SQLException e) { + initialize(); + } + return connection; + } @Override public void close() { + try { + if (connection != null) { + connection.close(); + } + } catch (Exception e) { + log.severe("Failed to close database connection! " + e.getMessage()); + } + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/SQLiteCore.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/SQLiteCore.java index 65aa2c7a..4abd18b3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/SQLiteCore.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/storage/SQLiteCore.java @@ -1,75 +1,101 @@ -package net.sacredlabyrinth.phaed.simpleclans.storage; - -import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.logging.Logger; - -/** - * @author cc_madelg - */ -public class SQLiteCore implements DBCore { - private final Logger log; - private Connection connection; - private final String dbLocation; - private final String dbName; - private File file; - - /** - * @param dbLocation the dbLocation to set - */ - public SQLiteCore(String dbLocation) { - this.dbName = "SimpleClans"; - this.dbLocation = dbLocation; - this.log = SimpleClans.getInstance().getLogger(); - initialize(); - } - - private void initialize() { - if (file == null) { - File dbFolder = new File(dbLocation); - - if (!dbFolder.exists() && !dbFolder.mkdir()) { - log.severe("Failed to create database folder!"); - return; - } - - file = new File(dbFolder.getAbsolutePath() + File.separator + dbName + ".db"); - } - - try { - Class.forName("org.sqlite.JDBC"); - - connection = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath()); - - } catch (SQLException ex) { - log.severe("SQLite exception on initialize " + ex); - } catch (ClassNotFoundException ex) { - log.severe("You need the SQLite library " + ex); - } - } - - @Override - public Connection getConnection() { - if (connection == null) { - initialize(); - } - - return connection; - } - - @Override - public void close() { - try { - if (connection != null) { - connection.close(); - } - } catch (Exception e) { - log.severe("Failed to close database connection! " + e.getMessage()); - } - } - -} +package net.sacredlabyrinth.phaed.simpleclans.storage; + +import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.logging.Logger; + +/** + * @author cc_madelg + */ +public class SQLiteCore implements DBCore { + + private final Logger log; + private Connection connection; + private final String dbLocation; + private final String dbName; + private File file; + + /** + * @param dbLocation the dbLocation to set + */ + public SQLiteCore(String dbLocation) { + + this.dbName = "SimpleClans"; + this.dbLocation = dbLocation; + this.log = SimpleClans.getInstance().getLogger(); + initialize(); + + } + + private void initialize() { + + if (file == null) { + + File dbFolder = new File(dbLocation); + + if (!dbFolder.exists() && !dbFolder.mkdir()) { + + log.severe("Failed to create database folder!"); + return; + + } + + file = new File(dbFolder.getAbsolutePath() + File.separator + dbName + ".db"); + + } + + try { + + Class.forName("org.sqlite.JDBC"); + + connection = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath()); + + } catch (SQLException ex) { + + log.severe("SQLite exception on initialize " + ex); + + } catch (ClassNotFoundException ex) { + + log.severe("You need the SQLite library " + ex); + + } + + } + + @Override + public Connection getConnection() { + + if (connection == null) { + + initialize(); + + } + + return connection; + + } + + @Override + public void close() { + + try { + + if (connection != null) { + + connection.close(); + + } + + } catch (Exception e) { + + log.severe("Failed to close database connection! " + e.getMessage()); + + } + + } + +} diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectFeeTask.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectFeeTask.java index 0543e079..e63e2260 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectFeeTask.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectFeeTask.java @@ -20,50 +20,68 @@ import static org.bukkit.ChatColor.AQUA; * @author roinujnosde */ public class CollectFeeTask extends BukkitRunnable { - private final SimpleClans plugin; - - public CollectFeeTask() { - plugin = SimpleClans.getInstance(); - } - + + private final SimpleClans plugin; + + public CollectFeeTask() { + + plugin = SimpleClans.getInstance(); + + } + /** * Starts the repetitive task */ public void start() { - SettingsManager sm = plugin.getSettingsManager(); - - int hour = sm.getInt(TASKS_COLLECT_FEE_HOUR); - int minute = sm.getInt(TASKS_COLLECT_FEE_MINUTE); + + SettingsManager sm = plugin.getSettingsManager(); + + int hour = sm.getInt(TASKS_COLLECT_FEE_HOUR); + int minute = sm.getInt(TASKS_COLLECT_FEE_MINUTE); long delay = Helper.getDelayTo(hour, minute); - + this.runTaskTimer(plugin, delay * 20, 86400 * 20); + } - + /** * (used internally) */ @Override public void run() { + PermissionsManager pm = plugin.getPermissionsManager(); for (Clan clan : plugin.getClanManager().getClans()) { + final double memberFee = clan.getMemberFee(); if (!clan.isMemberFeeEnabled() || memberFee <= 0) { + continue; + } for (ClanPlayer cp : clan.getFeePayers()) { + OfflinePlayer player = Bukkit.getOfflinePlayer(cp.getUniqueId()); boolean success = pm.chargePlayer(player, memberFee); if (success) { + ChatBlock.sendMessage(cp, AQUA + lang("fee.collected", cp, CurrencyFormat.format(memberFee))); clan.deposit(new BankOperator(cp, pm.playerGetMoney(player)), Cause.MEMBER_FEE, memberFee); plugin.getStorageManager().updateClan(clan); + } else { + clan.removePlayerFromClan(cp.getUniqueId()); clan.addBb(lang("bb.fee.player.kicked", cp.getName())); + } + } - } + + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectUpkeepTask.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectUpkeepTask.java index 00c163ce..cd785db6 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectUpkeepTask.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/CollectUpkeepTask.java @@ -19,23 +19,28 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con * @author roinujnosde */ public class CollectUpkeepTask extends BukkitRunnable { - private final SimpleClans plugin; - private final SettingsManager settingsManager; - - public CollectUpkeepTask() { - plugin = SimpleClans.getInstance(); - settingsManager = plugin.getSettingsManager(); - } + + private final SimpleClans plugin; + private final SettingsManager settingsManager; + + public CollectUpkeepTask() { + + plugin = SimpleClans.getInstance(); + settingsManager = plugin.getSettingsManager(); + + } /** * Starts the repetitive task */ public void start() { - int hour = settingsManager.getInt(TASKS_COLLECT_UPKEEP_HOUR); - int minute = settingsManager.getInt(TASKS_COLLECT_UPKEEP_MINUTE); + + int hour = settingsManager.getInt(TASKS_COLLECT_UPKEEP_HOUR); + int minute = settingsManager.getInt(TASKS_COLLECT_UPKEEP_MINUTE); long delay = Helper.getDelayTo(hour, minute); this.runTaskTimer(plugin, delay * 20, 86400 * 20); + } /** @@ -43,26 +48,44 @@ public class CollectUpkeepTask extends BukkitRunnable { */ @Override public void run() { - if (plugin == null) { - throw new IllegalStateException("Use the start() method!"); - } - plugin.getClanManager().getClans().forEach((clan) -> { - if (settingsManager.is(ECONOMY_UPKEEP_REQUIRES_MEMBER_FEE) && !clan.isMemberFeeEnabled()) { - return; - } - double upkeep = settingsManager.getDouble(ECONOMY_UPKEEP); - if (settingsManager.is(ECONOMY_MULTIPLY_UPKEEP_BY_CLAN_SIZE)) { - upkeep = upkeep * clan.getSize(); + + if (plugin == null) { + + throw new IllegalStateException("Use the start() method!"); + + } + + plugin.getClanManager().getClans().forEach((clan) -> { + + if (settingsManager.is(ECONOMY_UPKEEP_REQUIRES_MEMBER_FEE) && !clan.isMemberFeeEnabled()) { + + return; + } - EconomyResponse response = clan.withdraw(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.UPKEEP, upkeep); + double upkeep = settingsManager.getDouble(ECONOMY_UPKEEP); + if (settingsManager.is(ECONOMY_MULTIPLY_UPKEEP_BY_CLAN_SIZE)) { + + upkeep = upkeep * clan.getSize(); + + } + + EconomyResponse response = clan.withdraw(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.UPKEEP, + upkeep); if (response == EconomyResponse.NOT_ENOUGH_BALANCE) { + clan.disband(null, true, false); + } + if (response == EconomyResponse.SUCCESS) { + clan.addBb(MessageFormat.format(lang("upkeep.collected"), CurrencyFormat.format(upkeep)), false); + } + }); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/PlayerHeadCacheTask.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/PlayerHeadCacheTask.java index 425a2473..9e6c0d3f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/PlayerHeadCacheTask.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/PlayerHeadCacheTask.java @@ -19,19 +19,24 @@ public class PlayerHeadCacheTask extends BukkitRunnable { private final SimpleClans plugin; public PlayerHeadCacheTask(@NotNull SimpleClans plugin) { + this.plugin = plugin; + } /** * Starts the repetitive task */ public void start() { + int hour = 3600; this.runTaskTimerAsynchronously(plugin, 0, (hour + 60) * 20); + } @Override public void run() { + plugin.getLogger().info("Caching player heads..."); long begin = System.currentTimeMillis(); Inventory inventory = Bukkit.createInventory(null, 9); @@ -39,20 +44,31 @@ public class PlayerHeadCacheTask extends BukkitRunnable { players.sort(Comparator.comparing(ClanPlayer::getName)); for (ClanPlayer player : players) { + if (isCancelled()) { + plugin.getLogger().info("Player heads caching task cancelled!"); return; + } + ItemStack itemStack = XMaterial.PLAYER_HEAD.parseItem(); SkullMeta itemMeta = (SkullMeta) Objects.requireNonNull(itemStack).getItemMeta(); if (itemMeta != null) { + itemMeta.setOwningPlayer(Bukkit.getOfflinePlayer(player.getUniqueId())); + } + itemStack.setItemMeta(itemMeta); inventory.setItem(0, itemStack); + } + plugin.getLogger().info(String.format("Finished caching heads! It took %d milliseconds...", System.currentTimeMillis() - begin)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/SaveDataTask.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/SaveDataTask.java index 98bc9b5b..b2516a66 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/SaveDataTask.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/SaveDataTask.java @@ -12,18 +12,24 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con * */ public class SaveDataTask extends BukkitRunnable { - SimpleClans plugin = SimpleClans.getInstance(); + + SimpleClans plugin = SimpleClans.getInstance(); /** * Starts the repetitive task */ - public void start() { - long interval = plugin.getSettingsManager().getMinutes(PERFORMANCE_SAVE_INTERVAL); - runTaskTimerAsynchronously(plugin, interval, interval); - } + public void start() { + + long interval = plugin.getSettingsManager().getMinutes(PERFORMANCE_SAVE_INTERVAL); + runTaskTimerAsynchronously(plugin, interval, interval); + + } + + @Override + public void run() { + + plugin.getStorageManager().saveModified(); + + } - @Override - public void run() { - plugin.getStorageManager().saveModified(); - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/UpkeepWarningTask.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/UpkeepWarningTask.java index d0f453a3..dca94305 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/UpkeepWarningTask.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/tasks/UpkeepWarningTask.java @@ -15,24 +15,29 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con * @author roinujnosde */ public class UpkeepWarningTask extends BukkitRunnable { - private final SimpleClans plugin; - private final SettingsManager sm; - public UpkeepWarningTask() { - plugin = SimpleClans.getInstance(); - sm = plugin.getSettingsManager(); - } - + private final SimpleClans plugin; + private final SettingsManager sm; + + public UpkeepWarningTask() { + + plugin = SimpleClans.getInstance(); + sm = plugin.getSettingsManager(); + + } + /** * Starts the repetitive task * */ public void start() { - int hour = sm.getInt(TASKS_COLLECT_UPKEEP_WARNING_HOUR); - int minute = sm.getInt(TASKS_COLLECT_UPKEEP_WARNING_MINUTE); + + int hour = sm.getInt(TASKS_COLLECT_UPKEEP_WARNING_HOUR); + int minute = sm.getInt(TASKS_COLLECT_UPKEEP_WARNING_MINUTE); long delay = Helper.getDelayTo(hour, minute); - - this.runTaskTimer(plugin, delay * 20, 86400 * 20); + + this.runTaskTimer(plugin, delay * 20, 86400 * 20); + } /** @@ -40,22 +45,37 @@ public class UpkeepWarningTask extends BukkitRunnable { */ @Override public void run() { - if (plugin == null) { - throw new IllegalStateException("Use the start() method!"); - } + + if (plugin == null) { + + throw new IllegalStateException("Use the start() method!"); + + } + plugin.getClanManager().getClans().forEach((clan) -> { - if (sm.is(ECONOMY_UPKEEP_REQUIRES_MEMBER_FEE) && !clan.isMemberFeeEnabled()) { - return; - } + + if (sm.is(ECONOMY_UPKEEP_REQUIRES_MEMBER_FEE) && !clan.isMemberFeeEnabled()) { + + return; + + } + final double balance = clan.getBalance(); double upkeep = sm.getDouble(ECONOMY_UPKEEP); if (sm.is(ECONOMY_MULTIPLY_UPKEEP_BY_CLAN_SIZE)) { + upkeep = upkeep * clan.getSize(); + } + if (balance < upkeep) { + clan.addBb(MessageFormat.format(lang("balance.is.not.enough.for.upkeep"), upkeep), false); + } + }); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/threads/ThreadUpdateSQL.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/threads/ThreadUpdateSQL.java index 0bdf62b0..5797ce45 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/threads/ThreadUpdateSQL.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/threads/ThreadUpdateSQL.java @@ -15,29 +15,36 @@ public class ThreadUpdateSQL extends Thread { String query; String sqlType; - public ThreadUpdateSQL(Connection connection, String query, String sqlType) - { + public ThreadUpdateSQL(Connection connection, String query, String sqlType) { + this.query = query; this.connection = connection; this.sqlType = sqlType; + } @Override - public void run() - { - try - { - if (!connection.isClosed()) { - this.connection.createStatement().executeUpdate(this.query); - } - } - catch (SQLException ex) - { - if (!ex.toString().contains("not return ResultSet")) - { + public void run() { + + try { + + if (!connection.isClosed()) { + + this.connection.createStatement().executeUpdate(this.query); + + } + + } catch (SQLException ex) { + + if (!ex.toString().contains("not return ResultSet")) { + SimpleClans.getInstance().getLogger().severe("[Thread] Error at SQL " + this.sqlType + " Query: " + ex); SimpleClans.getInstance().getLogger().severe("[Thread] Query: " + this.query); + } + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryController.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryController.java index 4990d47c..2048df83 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryController.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryController.java @@ -32,166 +32,226 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con * */ public class InventoryController implements Listener { - private static final Map frames = new HashMap<>(); - @EventHandler(ignoreCancelled = true) - public void onClose(InventoryCloseEvent event) { - HumanEntity entity = event.getPlayer(); - if (!(entity instanceof Player)) { - return; - } + private static final Map frames = new HashMap<>(); - frames.remove(entity.getUniqueId()); - } + @EventHandler(ignoreCancelled = true) + public void onClose(InventoryCloseEvent event) { - @EventHandler(ignoreCancelled = true) - public void onInteract(InventoryClickEvent event) { - HumanEntity entity = event.getWhoClicked(); - if (!(entity instanceof Player)) { - return; - } + HumanEntity entity = event.getPlayer(); + if (!(entity instanceof Player)) { - SCFrame frame = frames.get(entity.getUniqueId()); - if (frame == null) { - return; - } + return; - event.setCancelled(true); + } - if (event.getClickedInventory() == null || event.getClickedInventory().getType() == InventoryType.PLAYER) { - return; - } + frames.remove(entity.getUniqueId()); - SCComponent component = frame.getComponent(event.getSlot()); - if (component == null) { - return; - } + } - ClickType click = event.getClick(); - Runnable listener = component.getListener(click); - if (listener == null) { - return; - } + @EventHandler(ignoreCancelled = true) + public void onInteract(InventoryClickEvent event) { - if (component.isVerifiedOnly(click) && !isClanVerified((Player) entity)) { - InventoryDrawer.open(new WarningFrame(frame, (Player) entity, null)); - return; - } + HumanEntity entity = event.getWhoClicked(); + if (!(entity instanceof Player)) { - Object permission = component.getPermission(click); - if (permission != null) { - if (!hasPermission((Player) entity, permission)) { - InventoryDrawer.open(new WarningFrame(frame, (Player) entity, permission)); - return; - } - } + return; - if (component.isConfirmationRequired(click)) { - listener = () -> InventoryDrawer.open(new ConfirmationFrame(frame, frame.getViewer(), component.getListener(click))); - } + } - Runnable finalListener = listener; - Bukkit.getScheduler().runTask(SimpleClans.getInstance(), () -> { - ItemStack currentItem = event.getCurrentItem(); - if (currentItem == null) return; + SCFrame frame = frames.get(entity.getUniqueId()); + if (frame == null) { - ComponentClickEvent componentClickEvent = new ComponentClickEvent(((Player) entity), frame, component); - Bukkit.getPluginManager().callEvent(componentClickEvent); - if (componentClickEvent.isCancelled()) { - return; - } + return; - ItemMeta itemMeta = currentItem.getItemMeta(); - Objects.requireNonNull(itemMeta).setLore(Collections.singletonList(lang("gui.loading", (Player) entity))); - currentItem.setItemMeta(itemMeta); + } - finalListener.run(); - }); - } + event.setCancelled(true); + if (event.getClickedInventory() == null || event.getClickedInventory().getType() == InventoryType.PLAYER) { - /** - * Checks if the Player's Clan is verified - * @param player the Player - * @return if the Clan is verified - */ - private boolean isClanVerified(@NotNull Player player) { - SimpleClans plugin = SimpleClans.getInstance(); - ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); + return; - return cp != null && cp.getClan() != null && cp.getClan().isVerified(); - } + } - /** - * Checks if the player has the permission - * - * @param player the Player - * @param permission the permission - * @return true if they have permission - * - * @author RoinujNosde - */ - private boolean hasPermission(@NotNull Player player, @NotNull Object permission) { - SimpleClans plugin = SimpleClans.getInstance(); - PermissionsManager pm = plugin.getPermissionsManager(); - if (permission instanceof String) { - String perms = (String) permission; - boolean leaderPerm = perms.contains("simpleclans.leader") && !perms.equalsIgnoreCase("simpleclans.leader.create"); - ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); + SCComponent component = frame.getComponent(event.getSlot()); + if (component == null) { - return pm.has(player, perms) && (!leaderPerm || (cp != null && cp.isLeader())); - } - return pm.has(player, (RankPermission) permission, false); - } + return; - /** - * Registers the frame in the InventoryController - * @param frame the frame - *

- * author: RoinujNosde - */ - public static void register(@NotNull SCFrame frame) { - frames.put(frame.getViewer().getUniqueId(), frame); - } + } - /** - * Checks if the Player is registered - * - * @param player the Player - * @return if they are registered - */ - public static boolean isRegistered(@NotNull Player player) { - return frames.containsKey(player.getUniqueId()); - } + ClickType click = event.getClick(); + Runnable listener = component.getListener(click); + if (listener == null) { - /** - * Runs a subcommand for the Player - * @param player the Player - * @param subcommand the subcommand - * @param update whether to update the inventory instead of closing - *

- * author: RoinujNosde - *

- */ - public static void runSubcommand(@NotNull Player player, @NotNull String subcommand, boolean update, String... args) { - SimpleClans plugin = SimpleClans.getInstance(); - String baseCommand = plugin.getSettingsManager().getString(COMMANDS_CLAN); - String finalCommand = String.format("%s %s ", baseCommand, subcommand) + String.join(" ", args); - new BukkitRunnable() { + return; + + } + + if (component.isVerifiedOnly(click) && !isClanVerified((Player) entity)) { + + InventoryDrawer.open(new WarningFrame(frame, (Player) entity, null)); + return; + + } + + Object permission = component.getPermission(click); + if (permission != null) { + + if (!hasPermission((Player) entity, permission)) { + + InventoryDrawer.open(new WarningFrame(frame, (Player) entity, permission)); + return; + + } + + } + + if (component.isConfirmationRequired(click)) { + + listener = () -> InventoryDrawer + .open(new ConfirmationFrame(frame, frame.getViewer(), component.getListener(click))); + + } + + Runnable finalListener = listener; + Bukkit.getScheduler().runTask(SimpleClans.getInstance(), () -> { + + ItemStack currentItem = event.getCurrentItem(); + if (currentItem == null) + return; + + ComponentClickEvent componentClickEvent = new ComponentClickEvent(((Player) entity), frame, component); + Bukkit.getPluginManager().callEvent(componentClickEvent); + if (componentClickEvent.isCancelled()) { + + return; + + } + + ItemMeta itemMeta = currentItem.getItemMeta(); + Objects.requireNonNull(itemMeta).setLore(Collections.singletonList(lang("gui.loading", (Player) entity))); + currentItem.setItemMeta(itemMeta); + + finalListener.run(); + + }); + + } + + /** + * Checks if the Player's Clan is verified + * + * @param player the Player + * @return if the Clan is verified + */ + private boolean isClanVerified(@NotNull Player player) { + + SimpleClans plugin = SimpleClans.getInstance(); + ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); + + return cp != null && cp.getClan() != null && cp.getClan().isVerified(); + + } + + /** + * Checks if the player has the permission + * + * @param player the Player + * @param permission the permission + * @return true if they have permission + * + * @author RoinujNosde + */ + private boolean hasPermission(@NotNull Player player, @NotNull Object permission) { + + SimpleClans plugin = SimpleClans.getInstance(); + PermissionsManager pm = plugin.getPermissionsManager(); + if (permission instanceof String) { + + String perms = (String) permission; + boolean leaderPerm = perms.contains("simpleclans.leader") + && !perms.equalsIgnoreCase("simpleclans.leader.create"); + ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId()); + + return pm.has(player, perms) && (!leaderPerm || (cp != null && cp.isLeader())); + + } + + return pm.has(player, (RankPermission) permission, false); + + } + + /** + * Registers the frame in the InventoryController + * + * @param frame the frame + *

+ * author: RoinujNosde + */ + public static void register(@NotNull SCFrame frame) { + + frames.put(frame.getViewer().getUniqueId(), frame); + + } + + /** + * Checks if the Player is registered + * + * @param player the Player + * @return if they are registered + */ + public static boolean isRegistered(@NotNull Player player) { + + return frames.containsKey(player.getUniqueId()); + + } + + /** + * Runs a subcommand for the Player + * + * @param player the Player + * @param subcommand the subcommand + * @param update whether to update the inventory instead of closing + *

+ * author: RoinujNosde + *

+ */ + public static void runSubcommand(@NotNull Player player, @NotNull String subcommand, boolean update, + String... args) + { + + SimpleClans plugin = SimpleClans.getInstance(); + String baseCommand = plugin.getSettingsManager().getString(COMMANDS_CLAN); + String finalCommand = String.format("%s %s ", baseCommand, subcommand) + String.join(" ", args); + new BukkitRunnable() { + + @Override + public void run() { + + player.performCommand(finalCommand); + if (!update) { + + player.closeInventory(); + + } else { + + SCFrame currentFrame = frames.get(player.getUniqueId()); + if (currentFrame instanceof ConfirmationFrame) { + + currentFrame = currentFrame.getParent(); + + } + + InventoryDrawer.open(currentFrame); + + } + + } + + }.runTask(plugin); + + } - @Override - public void run() { - player.performCommand(finalCommand); - if (!update) { - player.closeInventory(); - } else { - SCFrame currentFrame = frames.get(player.getUniqueId()); - if (currentFrame instanceof ConfirmationFrame) { - currentFrame = currentFrame.getParent(); - } - InventoryDrawer.open(currentFrame); - } - } - }.runTask(plugin); - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryDrawer.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryDrawer.java index db260aec..0449ab1d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryDrawer.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/InventoryDrawer.java @@ -20,53 +20,76 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; public class InventoryDrawer { + private static final SimpleClans plugin = SimpleClans.getInstance(); private static final ConcurrentHashMap OPENING = new ConcurrentHashMap<>(); private InventoryDrawer() { + } public static void open(@Nullable SCFrame frame) { + if (frame == null) { + return; + } + UUID uuid = frame.getViewer().getUniqueId(); if (frame.equals(OPENING.get(uuid))) { + return; + } - FrameOpenEvent event = new FrameOpenEvent(frame.getViewer(), frame); + FrameOpenEvent event = new FrameOpenEvent(frame.getViewer(), frame); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { + return; - } - OPENING.put(uuid, frame); + + } + + OPENING.put(uuid, frame); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - Inventory inventory = prepareInventory(frame); + + Inventory inventory = prepareInventory(frame); if (!frame.equals(OPENING.get(uuid))) { + return; + } + Bukkit.getScheduler().runTask(plugin, () -> { + frame.getViewer().openInventory(inventory); InventoryController.register(frame); OPENING.remove(uuid); + }); + }); + } @NotNull private static Inventory prepareInventory(@NotNull SCFrame frame) { + Inventory inventory = Bukkit.createInventory(frame.getViewer(), frame.getSize(), frame.getTitle()); long start = System.currentTimeMillis(); setComponents(inventory, frame); if (plugin.getSettingsManager().is(DEBUG)) { - plugin.getLogger().log(Level.INFO, - String.format("It took %s millisecond(s) to load the frame %s for %s", - System.currentTimeMillis() - start, frame.getTitle(), frame.getViewer().getName())); + + plugin.getLogger().log(Level.INFO, String.format("It took %s millisecond(s) to load the frame %s for %s", + System.currentTimeMillis() - start, frame.getTitle(), frame.getViewer().getName())); + } + return inventory; + } /** @@ -75,83 +98,129 @@ public class InventoryDrawer { */ @Deprecated public static void update(@NotNull SCFrame frame) { + open(frame); + } private static void setComponents(@NotNull Inventory inventory, @NotNull SCFrame frame) { + frame.clear(); try { + frame.createComponents(); + } catch (NoSuchFieldError ex) { + runHelpCommand(frame.getViewer()); return; + } Set components = frame.getComponents(); if (components.isEmpty()) { + plugin.getLogger().warning(String.format("Frame %s has no components", frame.getTitle())); return; + } + for (SCComponent c : frame.getComponents()) { + if (c.getSlot() >= frame.getSize()) { + continue; + } + checkLorePermission(frame, c); processLineBreaks(c); inventory.setItem(c.getSlot(), c.getItem()); + } + } private static void processLineBreaks(SCComponent c) { + ItemMeta itemMeta = c.getItemMeta(); if (itemMeta != null) { + List oldLore = itemMeta.getLore(); if (oldLore != null) { + ArrayList newLore = new ArrayList<>(); for (String line : oldLore) { + if (line.isEmpty()) { + continue; + } + WordWrapper wrapper = new WordWrapper(line, plugin.getSettingsManager().getInt(LORE_LENGTH)); newLore.addAll(Arrays.asList(wrapper.wrap())); + } + itemMeta.setLore(newLore); c.setItemMeta(itemMeta); + } + } + } private static void runHelpCommand(@NotNull Player player) { - Bukkit.getScheduler().runTask(plugin, () -> plugin.getServer().getConsoleSender().sendMessage(lang("gui.not.supported"))); + + Bukkit.getScheduler().runTask(plugin, + () -> plugin.getServer().getConsoleSender().sendMessage(lang("gui.not.supported"))); SettingsManager settingsManager = plugin.getSettingsManager(); settingsManager.set(ENABLE_GUI, false); String commandClan = settingsManager.getString(COMMANDS_CLAN); player.performCommand(commandClan); + } private static void checkLorePermission(@NotNull SCFrame frame, @NotNull SCComponent component) { + ItemMeta itemMeta = component.getItemMeta(); if (itemMeta != null) { + List lore = itemMeta.getLore(); if (lore != null) { + Object permission = component.getLorePermission(); if (permission != null) { + if (!hasPermission(frame.getViewer(), permission)) { + lore.clear(); lore.add(lang("gui.lore.no.permission", frame.getViewer())); itemMeta.setLore(lore); component.setItemMeta(itemMeta); + } + } + } + } + } private static boolean hasPermission(@NotNull Player viewer, @NotNull Object permission) { - if (permission instanceof String) { - return plugin.getPermissionsManager().has(viewer, (String) permission); - } - return plugin.getPermissionsManager().has(viewer, (RankPermission) permission, false); - } + + if (permission instanceof String) { + + return plugin.getPermissionsManager().has(viewer, (String) permission); + + } + + return plugin.getPermissionsManager().has(viewer, (RankPermission) permission, false); + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponent.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponent.java index eac39767..47e7b180 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponent.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponent.java @@ -19,74 +19,103 @@ import java.util.Set; */ public abstract class SCComponent { - private final HashMap listeners = new HashMap<>(); - private final HashMap permissions = new HashMap<>(); - private final Set verified = new HashSet<>(); - private final Set confirmationRequired = new HashSet<>(); - private @Nullable Object lorePermission; + private final HashMap listeners = new HashMap<>(); + private final HashMap permissions = new HashMap<>(); + private final Set verified = new HashSet<>(); + private final Set confirmationRequired = new HashSet<>(); + private @Nullable Object lorePermission; - @NotNull - public abstract ItemStack getItem(); + @NotNull + public abstract ItemStack getItem(); - public abstract int getSlot(); + public abstract int getSlot(); - @Nullable - public ItemMeta getItemMeta() { - return getItem().getItemMeta(); - } + @Nullable + public ItemMeta getItemMeta() { - public void setItemMeta(@NotNull ItemMeta itemMeta) { - getItem().setItemMeta(itemMeta); - } + return getItem().getItemMeta(); - public void setVerifiedOnly(@NotNull ClickType clickType) { - verified.add(clickType); - } + } - public boolean isVerifiedOnly(@NotNull ClickType clickType) { - return verified.contains(clickType); - } + public void setItemMeta(@NotNull ItemMeta itemMeta) { - public void setLorePermission(@Nullable RankPermission permission) { - lorePermission = permission; - } + getItem().setItemMeta(itemMeta); - public void setLorePermission(@Nullable String permission) { - lorePermission = permission; - } + } - @Nullable - public Object getLorePermission() { - return lorePermission; - } + public void setVerifiedOnly(@NotNull ClickType clickType) { - public void setPermission(@NotNull ClickType click, @Nullable RankPermission permission) { - permissions.put(click, permission); - } + verified.add(clickType); - public void setPermission(@NotNull ClickType click, @Nullable String permission) { - permissions.put(click, permission); - } + } - @Nullable - public Object getPermission(@NotNull ClickType click) { - return permissions.get(click); - } + public boolean isVerifiedOnly(@NotNull ClickType clickType) { - public void setListener(@NotNull ClickType click, @Nullable Runnable listener) { - listeners.put(click, listener); - } + return verified.contains(clickType); - @Nullable - public Runnable getListener(@NotNull ClickType click) { - return listeners.get(click); - } + } - public void setConfirmationRequired(@NotNull ClickType click) { - confirmationRequired.add(click); - } + public void setLorePermission(@Nullable RankPermission permission) { + + lorePermission = permission; + + } + + public void setLorePermission(@Nullable String permission) { + + lorePermission = permission; + + } + + @Nullable + public Object getLorePermission() { + + return lorePermission; + + } + + public void setPermission(@NotNull ClickType click, @Nullable RankPermission permission) { + + permissions.put(click, permission); + + } + + public void setPermission(@NotNull ClickType click, @Nullable String permission) { + + permissions.put(click, permission); + + } + + @Nullable + public Object getPermission(@NotNull ClickType click) { + + return permissions.get(click); + + } + + public void setListener(@NotNull ClickType click, @Nullable Runnable listener) { + + listeners.put(click, listener); + + } + + @Nullable + public Runnable getListener(@NotNull ClickType click) { + + return listeners.get(click); + + } + + public void setConfirmationRequired(@NotNull ClickType click) { + + confirmationRequired.add(click); + + } + + public boolean isConfirmationRequired(@NotNull ClickType click) { + + return confirmationRequired.contains(click); + + } - public boolean isConfirmationRequired(@NotNull ClickType click) { - return confirmationRequired.contains(click); - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponentImpl.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponentImpl.java index ba0855b7..ee4de8a4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponentImpl.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCComponentImpl.java @@ -13,104 +13,156 @@ import java.util.List; public class SCComponentImpl extends SCComponent { - @NotNull - private ItemStack item; - private int slot; + @NotNull + private ItemStack item; + private int slot; - private SCComponentImpl() { - item = new ItemStack(Material.STONE); - slot = 0; - } + private SCComponentImpl() { - public SCComponentImpl(@Nullable String displayName, @Nullable List lore, @NotNull Material material, - int slot) { - this(displayName, lore, new ItemStack(material), slot); - } + item = new ItemStack(Material.STONE); + slot = 0; - public SCComponentImpl(@Nullable String displayName, @Nullable List lore, @NotNull XMaterial material, - int slot) { - this(displayName, lore, material.parseItem(), slot); - } + } - public SCComponentImpl(@Nullable String displayName, @Nullable List lore, @Nullable ItemStack item, - int slot) { - if (item == null) { - item = new ItemStack(Material.STONE); - } - this.item = item; - ItemMeta itemMeta = item.getItemMeta(); - if (itemMeta != null) { - itemMeta.setDisplayName(displayName); - itemMeta.setLore(lore); - itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); - item.setItemMeta(itemMeta); - } - this.slot = slot; - } - - @Override - public @NotNull ItemStack getItem() { - return item; - } + public SCComponentImpl(@Nullable String displayName, @Nullable List lore, @NotNull Material material, + int slot) + { - @Override - public int getSlot() { - return slot; - } + this(displayName, lore, new ItemStack(material), slot); - public static class Builder { - private final SCComponentImpl component = new SCComponentImpl(); - private @Nullable List lore; + } - public Builder(@NotNull XMaterial material) { - this(material.parseItem()); - } + public SCComponentImpl(@Nullable String displayName, @Nullable List lore, @NotNull XMaterial material, + int slot) + { - public Builder(@NotNull Material material) { - component.item = new ItemStack(material); - } + this(displayName, lore, material.parseItem(), slot); - public Builder(@Nullable ItemStack item) { - if (item == null) { - item = new ItemStack(Material.STONE); - } - component.item = item; - } + } - public Builder withDisplayName(@Nullable String displayName) { - ItemMeta itemMeta = component.getItemMeta(); - if (itemMeta != null) { - itemMeta.setDisplayName(displayName); - component.setItemMeta(itemMeta); - } - return this; - } + public SCComponentImpl(@Nullable String displayName, @Nullable List lore, @Nullable ItemStack item, + int slot) + { - public Builder withLore(@Nullable List lore) { - this.lore = lore; - return this; - } + if (item == null) { - public Builder withLoreLine(@NotNull String line) { - if (lore == null) { - lore = new ArrayList<>(); - } - lore.add(line); - return this; - } + item = new ItemStack(Material.STONE); - public Builder withSlot(int slot) { - component.slot = slot; - return this; - } + } + + this.item = item; + ItemMeta itemMeta = item.getItemMeta(); + if (itemMeta != null) { + + itemMeta.setDisplayName(displayName); + itemMeta.setLore(lore); + itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + item.setItemMeta(itemMeta); + + } + + this.slot = slot; + + } + + @Override + public @NotNull ItemStack getItem() { + + return item; + + } + + @Override + public int getSlot() { + + return slot; + + } + + public static class Builder { + + private final SCComponentImpl component = new SCComponentImpl(); + private @Nullable List lore; + + public Builder(@NotNull XMaterial material) { + + this(material.parseItem()); + + } + + public Builder(@NotNull Material material) { + + component.item = new ItemStack(material); + + } + + public Builder(@Nullable ItemStack item) { + + if (item == null) { + + item = new ItemStack(Material.STONE); + + } + + component.item = item; + + } + + public Builder withDisplayName(@Nullable String displayName) { + + ItemMeta itemMeta = component.getItemMeta(); + if (itemMeta != null) { + + itemMeta.setDisplayName(displayName); + component.setItemMeta(itemMeta); + + } + + return this; + + } + + public Builder withLore(@Nullable List lore) { + + this.lore = lore; + return this; + + } + + public Builder withLoreLine(@NotNull String line) { + + if (lore == null) { + + lore = new ArrayList<>(); + + } + + lore.add(line); + return this; + + } + + public Builder withSlot(int slot) { + + component.slot = slot; + return this; + + } + + public SCComponent build() { + + ItemMeta itemMeta = component.getItemMeta(); + if (itemMeta != null) { + + itemMeta.setLore(lore); + component.setItemMeta(itemMeta); + + } + + return component; + + } + + } - public SCComponent build() { - ItemMeta itemMeta = component.getItemMeta(); - if (itemMeta != null) { - itemMeta.setLore(lore); - component.setItemMeta(itemMeta); - } - return component; - } - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCFrame.java index 754423ea..1faf3067 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/SCFrame.java @@ -14,69 +14,94 @@ import java.util.concurrent.ConcurrentHashMap; */ public abstract class SCFrame { - private final SCFrame parent; - private final Player viewer; - private final Set components = ConcurrentHashMap.newKeySet(); - - public SCFrame(@Nullable SCFrame parent, @NotNull Player viewer) { - this.parent = parent; - this.viewer = viewer; - } + private final SCFrame parent; + private final Player viewer; + private final Set components = ConcurrentHashMap.newKeySet(); - @NotNull - public abstract String getTitle(); + public SCFrame(@Nullable SCFrame parent, @NotNull Player viewer) { - @NotNull - public Player getViewer() { - return viewer; - } + this.parent = parent; + this.viewer = viewer; - @Nullable - public SCFrame getParent() { - return parent; - } + } - public abstract int getSize(); + @NotNull + public abstract String getTitle(); - public abstract void createComponents(); + @NotNull + public Player getViewer() { - @Nullable - public SCComponent getComponent(int slot) { - for (SCComponent c : getComponents()) { - if (c.getSlot() == slot) { - return c; - } - } - return null; - } - - public void add(@NotNull SCComponent c) { - components.add(c); - } - - public void clear() { - components.clear(); - } + return viewer; - @NotNull - public Set getComponents() { - return components; - } + } - @Override - public boolean equals(Object other) { - if (other instanceof SCFrame) { - SCFrame otherFrame = (SCFrame) other; - return getSize() == otherFrame.getSize() && getTitle().equals(otherFrame.getTitle()) - && getComponents().equals(otherFrame.getComponents()); - } + @Nullable + public SCFrame getParent() { - return false; - } + return parent; - @Override - public int hashCode() { - return getTitle().hashCode() + Integer.hashCode(getSize()) + getComponents().hashCode(); - } + } + + public abstract int getSize(); + + public abstract void createComponents(); + + @Nullable + public SCComponent getComponent(int slot) { + + for (SCComponent c : getComponents()) { + + if (c.getSlot() == slot) { + + return c; + + } + + } + + return null; + + } + + public void add(@NotNull SCComponent c) { + + components.add(c); + + } + + public void clear() { + + components.clear(); + + } + + @NotNull + public Set getComponents() { + + return components; + + } + + @Override + public boolean equals(Object other) { + + if (other instanceof SCFrame) { + + SCFrame otherFrame = (SCFrame) other; + return getSize() == otherFrame.getSize() && getTitle().equals(otherFrame.getTitle()) + && getComponents().equals(otherFrame.getComponents()); + + } + + return false; + + } + + @Override + public int hashCode() { + + return getTitle().hashCode() + Integer.hashCode(getSize()) + getComponents().hashCode(); + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddAllyFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddAllyFrame.java index 507577fd..4628d299 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddAllyFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddAllyFrame.java @@ -17,70 +17,94 @@ import java.util.stream.Collectors; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class AddAllyFrame extends SCFrame { - private final List notAllies; - private final Paginator paginator; - public AddAllyFrame(SCFrame parent, Player viewer, Clan subject) { - super(parent, viewer); - SimpleClans plugin = SimpleClans.getInstance(); - notAllies = plugin.getClanManager().getClans().stream() - .filter(c -> !c.equals(subject) && !c.isRival(subject.getTag()) && !c.isAlly(subject.getTag())) - .collect(Collectors.toList()); - paginator = new Paginator(getSize() - 9, notAllies); - } + private final List notAllies; + private final Paginator paginator; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 2, getViewer())); + public AddAllyFrame(SCFrame parent, Player viewer, Clan subject) { - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + super(parent, viewer); + SimpleClans plugin = SimpleClans.getInstance(); + notAllies = plugin.getClanManager().getClans().stream() + .filter(c -> !c.equals(subject) && !c.isRival(subject.getTag()) && !c.isAlly(subject.getTag())) + .collect(Collectors.toList()); + paginator = new Paginator(getSize() - 9, notAllies); - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + } - Clan notRival = notAllies.get(i); - SCComponent c = new SCComponentImpl( - lang("gui.clanlist.clan.title", getViewer(), notRival.getColorTag(), notRival.getName()), - Collections.singletonList(lang("gui.add.ally.clan.lore", getViewer())), XMaterial.CYAN_BANNER, - slot); + @Override + public void createComponents() { - c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "ally add", false, notRival.getTag())); - c.setPermission(ClickType.LEFT, RankPermission.ALLY_ADD); - add(c); - slot++; - } - } + for (int slot = 0; slot < 9; slot++) { - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + } - private void updateFrame() { - InventoryDrawer.open(this); - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - @Override - public @NotNull String getTitle() { - return lang("gui.add.ally.title",getViewer()); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Clan notRival = notAllies.get(i); + SCComponent c = new SCComponentImpl( + lang("gui.clanlist.clan.title", getViewer(), notRival.getColorTag(), notRival.getName()), + Collections.singletonList(lang("gui.add.ally.clan.lore", getViewer())), XMaterial.CYAN_BANNER, + slot); + + c.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "ally add", false, notRival.getTag())); + c.setPermission(ClickType.LEFT, RankPermission.ALLY_ADD); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.add.ally.title", getViewer()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } - @Override - public int getSize() { - return 6 * 9; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddPermissionFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddPermissionFrame.java index 07ee600d..4f939274 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddPermissionFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddPermissionFrame.java @@ -16,72 +16,94 @@ import java.util.Set; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class AddPermissionFrame extends SCFrame { - private final String[] availablePermissions; - private final Paginator paginator; - private final Rank rank; - public AddPermissionFrame(SCFrame parent, Player viewer, Rank rank) { - super(parent, viewer); - this.rank = rank; - Set rankPerms = rank.getPermissions(); - availablePermissions = Arrays.stream(Helper.fromPermissionArray()).filter(p -> !rankPerms.contains(p)) - .toArray(String[]::new); - paginator = new Paginator(getSize() - 9, availablePermissions.length); - } + private final String[] availablePermissions; + private final Paginator paginator; + private final Rank rank; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 2, getViewer())); + public AddPermissionFrame(SCFrame parent, Player viewer, Rank rank) { - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + super(parent, viewer); + this.rank = rank; + Set rankPerms = rank.getPermissions(); + availablePermissions = Arrays.stream(Helper.fromPermissionArray()).filter(p -> !rankPerms.contains(p)) + .toArray(String[]::new); + paginator = new Paginator(getSize() - 9, availablePermissions.length); - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + } - String permission = availablePermissions[i]; + @Override + public void createComponents() { - SCComponent c = new SCComponentImpl( - lang("gui.add.permission.permission.title",getViewer(), permission), - Collections.singletonList(lang("gui.add.permission.permission.lore",getViewer())), - XMaterial.PAPER, slot); - c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "rank permissions add", true, rank.getName(), permission)); - c.setPermission(ClickType.LEFT, "simpleclans.leader.rank.permissions.add"); - add(c); - slot++; - } - } + for (int slot = 0; slot < 9; slot++) { - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + } - private void updateFrame() { - InventoryDrawer.open(this); - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - @Override - public @NotNull String getTitle() { - return lang("gui.add.permission.title",getViewer()); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - @Override - public int getSize() { - return 3 * 9; - } + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + String permission = availablePermissions[i]; + + SCComponent c = new SCComponentImpl(lang("gui.add.permission.permission.title", getViewer(), permission), + Collections.singletonList(lang("gui.add.permission.permission.lore", getViewer())), XMaterial.PAPER, + slot); + c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "rank permissions add", + true, rank.getName(), permission)); + c.setPermission(ClickType.LEFT, "simpleclans.leader.rank.permissions.add"); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.add.permission.title", getViewer()); + + } + + @Override + public int getSize() { + + return 3 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddRivalFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddRivalFrame.java index 7a6a67ca..c4cd136c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddRivalFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AddRivalFrame.java @@ -18,71 +18,94 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class AddRivalFrame extends SCFrame { - private final List notRivals; - private final Paginator paginator; + private final List notRivals; + private final Paginator paginator; - public AddRivalFrame(SCFrame parent, Player viewer, Clan subject) { - super(parent, viewer); - SimpleClans plugin = SimpleClans.getInstance(); - notRivals = plugin.getClanManager().getClans().stream() - .filter(c -> !c.equals(subject) && !c.isRival(subject.getTag()) && !c.isAlly(subject.getTag())) - .collect(Collectors.toList()); - paginator = new Paginator(getSize() - 9, notRivals.size()); - } + public AddRivalFrame(SCFrame parent, Player viewer, Clan subject) { - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 2, getViewer())); + super(parent, viewer); + SimpleClans plugin = SimpleClans.getInstance(); + notRivals = plugin.getClanManager().getClans().stream() + .filter(c -> !c.equals(subject) && !c.isRival(subject.getTag()) && !c.isAlly(subject.getTag())) + .collect(Collectors.toList()); + paginator = new Paginator(getSize() - 9, notRivals.size()); - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + } - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + @Override + public void createComponents() { - Clan notRival = notRivals.get(i); - SCComponent c = new SCComponentImpl( - lang("gui.clanlist.clan.title",getViewer(), notRival.getColorTag(), notRival.getName()), - Collections.singletonList(lang("gui.add.rival.clan.lore", getViewer())), XMaterial.RED_BANNER, - slot); + for (int slot = 0; slot < 9; slot++) { - c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "rival add", false, notRival.getTag())); - c.setConfirmationRequired(ClickType.LEFT); - c.setPermission(ClickType.LEFT, RankPermission.RIVAL_ADD); - add(c); - slot++; - } - } + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + } - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - private void updateFrame() { - InventoryDrawer.open(this); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - @Override - public @NotNull String getTitle() { - return lang("gui.add.rival.title",getViewer()); - } + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Clan notRival = notRivals.get(i); + SCComponent c = new SCComponentImpl( + lang("gui.clanlist.clan.title", getViewer(), notRival.getColorTag(), notRival.getName()), + Collections.singletonList(lang("gui.add.rival.clan.lore", getViewer())), XMaterial.RED_BANNER, + slot); + + c.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "rival add", false, notRival.getTag())); + c.setConfirmationRequired(ClickType.LEFT); + c.setPermission(ClickType.LEFT, RankPermission.RIVAL_ADD); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.add.rival.title", getViewer()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } - @Override - public int getSize() { - return 6 * 9; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AlliesFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AlliesFrame.java index 2ac3f9eb..8d135f08 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AlliesFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/AlliesFrame.java @@ -16,79 +16,100 @@ import java.util.List; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class AlliesFrame extends SCFrame { - private final SimpleClans plugin = SimpleClans.getInstance(); - private final Paginator paginator; - private final List allies; - private final Clan subject; - public AlliesFrame(Player viewer, SCFrame parent, Clan subject) { - super(parent, viewer); - this.subject = subject; - allies = subject.getAllies(); - paginator = new Paginator(getSize() - 9, allies.size()); - } + private final SimpleClans plugin = SimpleClans.getInstance(); + private final Paginator paginator; + private final List allies; + private final Clan subject; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 4 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } + public AlliesFrame(Player viewer, SCFrame parent, Clan subject) { - add(Components.getBackComponent(getParent(), 2, getViewer())); + super(parent, viewer); + this.subject = subject; + allies = subject.getAllies(); + paginator = new Paginator(getSize() - 9, allies.size()); - SCComponent add = new SCComponentImpl(lang("gui.allies.add.title",getViewer()), null, - XMaterial.CYAN_WOOL, 4); - add.setVerifiedOnly(ClickType.LEFT); - add.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AddAllyFrame(this, getViewer(), subject))); - add.setPermission(ClickType.LEFT, RankPermission.ALLY_ADD); - add(add); + } - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + @Override + public void createComponents() { - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + for (int slot = 0; slot < 9; slot++) { - Clan clan = plugin.getClanManager().getClan(allies.get(i)); - if (clan == null) - continue; - SCComponent c = new SCComponentImpl( - lang("gui.clanlist.clan.title",getViewer(), clan.getColorTag(), clan.getName()), - Collections.singletonList(lang("gui.allies.clan.lore",getViewer())), XMaterial.CYAN_BANNER, slot); - c.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), - "ally remove", false, clan.getTag())); - c.setPermission(ClickType.RIGHT, RankPermission.ALLY_REMOVE); - add(c); - slot++; - } - } + if (slot == 2 || slot == 4 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + } - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - private void updateFrame() { - InventoryDrawer.open(this); - } + SCComponent add = new SCComponentImpl(lang("gui.allies.add.title", getViewer()), null, XMaterial.CYAN_WOOL, 4); + add.setVerifiedOnly(ClickType.LEFT); + add.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AddAllyFrame(this, getViewer(), subject))); + add.setPermission(ClickType.LEFT, RankPermission.ALLY_ADD); + add(add); - @Override - public @NotNull String getTitle() { - return lang("gui.allies.title",getViewer()); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - @Override - public int getSize() { - return 6 * 9; - } + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Clan clan = plugin.getClanManager().getClan(allies.get(i)); + if (clan == null) + continue; + SCComponent c = new SCComponentImpl( + lang("gui.clanlist.clan.title", getViewer(), clan.getColorTag(), clan.getName()), + Collections.singletonList(lang("gui.allies.clan.lore", getViewer())), XMaterial.CYAN_BANNER, slot); + c.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "ally remove", false, clan.getTag())); + c.setPermission(ClickType.RIGHT, RankPermission.ALLY_REMOVE); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.allies.title", getViewer()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanDetailsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanDetailsFrame.java index f982228e..28c6d113 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanDetailsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanDetailsFrame.java @@ -24,330 +24,419 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; public class ClanDetailsFrame extends SCFrame { - private final Clan clan; - private final ClanPlayer cp; - private final SimpleClans plugin; - private final SettingsManager settings; - public ClanDetailsFrame(@Nullable SCFrame parent, @NotNull Player viewer, @NotNull Clan clan) { - super(parent, viewer); - this.clan = clan; - plugin = SimpleClans.getInstance(); - settings = plugin.getSettingsManager(); - cp = plugin.getClanManager().getClanPlayer(getViewer()); - } + private final Clan clan; + private final ClanPlayer cp; + private final SimpleClans plugin; + private final SettingsManager settings; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 4) - continue; - add(Components.getPanelComponent(slot)); - } + public ClanDetailsFrame(@Nullable SCFrame parent, @NotNull Player viewer, @NotNull Clan clan) { - add(Components.getBackComponent(getParent(), 4, getViewer())); - add(Components.getClanComponent(this, getViewer(), clan, 13, false)); + super(parent, viewer); + this.clan = clan; + plugin = SimpleClans.getInstance(); + settings = plugin.getSettingsManager(); + cp = plugin.getClanManager().getClanPlayer(getViewer()); - addRoster(); - addCoords(); - addAllies(); - addRivals(); - addHome(); - addRegroup(); - addFf(); - addBank(); - addFee(); - addRank(); - addVerify(); - addResign(); - addDisband(); - addChat(); - } + } - private void addChat() { - Channel cpChannel = cp.getChannel(); - boolean clanEnabled = Channel.CLAN.equals(cpChannel); - boolean allyEnabled = Channel.ALLY.equals(cpChannel); + @Override + public void createComponents() { - SCComponent chat = createChatComponent(clanEnabled, allyEnabled); - chat.setListener(ClickType.LEFT, () -> { - if (clanEnabled) { - cp.setChannel(Channel.NONE); - } else { - cp.setChannel(Channel.CLAN); - } - updateFrame(); - }); - chat.setPermission(ClickType.LEFT, "simpleclans.member.chat"); - chat.setListener(ClickType.RIGHT, () -> { - if (allyEnabled) { - cp.setChannel(Channel.NONE); - } else { - cp.setChannel(Channel.ALLY); - } - updateFrame(); - }); - chat.setPermission(ClickType.RIGHT, RankPermission.ALLY_CHAT); - add(chat); - } + for (int slot = 0; slot < 9; slot++) { - @NotNull - private SCComponent createChatComponent(boolean clanEnabled, boolean allyEnabled) { - String joined = lang("chat.joined", getViewer()); - String notJoined = lang("chat.not.joined", getViewer()); + if (slot == 4) + continue; + add(Components.getPanelComponent(slot)); - String clanStatus = clanEnabled ? joined : notJoined; - String allyStatus = allyEnabled ? joined : notJoined; + } - String chatCommand = settings.is(CLANCHAT_TAG_BASED) ? clan.getTag() : settings.getString(COMMANDS_CLAN_CHAT); - String joinArg = lang("join", getViewer()); - String leaveArg = lang("leave", getViewer()); - return new SCComponentImpl(lang("gui.clandetails.chat.title", getViewer()), - Arrays.asList( - lang("gui.clandetails.chat.clan.chat.lore", getViewer(), chatCommand), - lang("gui.clandetails.chat.clan.join.leave.lore", getViewer(), chatCommand, joinArg, leaveArg), - lang("gui.clandetails.chat.ally.chat.lore", getViewer(), settings.getString(COMMANDS_ALLY)), - lang("gui.clandetails.chat.ally.join.leave.lore", getViewer(), settings.getString(COMMANDS_ALLY), joinArg, leaveArg), - lang("gui.clandetails.chat.clan.status.lore", getViewer(), clanStatus), - lang("gui.clandetails.chat.ally.status.lore", getViewer(), allyStatus), - lang("gui.clandetails.chat.clan.toggle.lore", getViewer()), - lang("gui.clandetails.chat.ally.toggle.lore", getViewer())), - XMaterial.KNOWLEDGE_BOOK, 43); - } + add(Components.getBackComponent(getParent(), 4, getViewer())); + add(Components.getClanComponent(this, getViewer(), clan, 13, false)); - private void addRank() { - SCComponent rank = new SCComponentImpl(lang("gui.clandetails.rank.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.rank.lore", getViewer())), XMaterial.IRON_HELMET, - 37); - rank.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RanksFrame(this, getViewer(), clan, null))); - rank.setPermission(ClickType.LEFT, "simpleclans.leader.rank.list"); - add(rank); - } + addRoster(); + addCoords(); + addAllies(); + addRivals(); + addHome(); + addRegroup(); + addFf(); + addBank(); + addFee(); + addRank(); + addVerify(); + addResign(); + addDisband(); + addChat(); - private void addFee() { - String status = clan.isMemberFeeEnabled() ? lang("fee.enabled", getViewer()) : lang("fee.disabled", getViewer()); - SCComponent fee = new SCComponentImpl(lang("gui.clandetails.fee.title", getViewer()), - Arrays.asList(lang("gui.clandetails.fee.value.lore", getViewer(), clan.getMemberFee()), - lang("gui.clandetails.fee.status.lore", getViewer(), status), - lang("gui.clandetails.fee.toggle.lore", getViewer())), - XMaterial.GOLD_NUGGET, 41); - fee.setVerifiedOnly(ClickType.LEFT); - fee.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "toggle fee", true)); - fee.setPermission(ClickType.LEFT, RankPermission.FEE_ENABLE); - add(fee); - } + } - private void addDisband() { - SCComponent disband = new SCComponentImpl(lang("gui.clandetails.disband.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.disband.lore", getViewer())), XMaterial.BARRIER, - 50); - disband.setListener(ClickType.DROP, () -> InventoryController.runSubcommand(getViewer(), "disband", false)); - disband.setPermission(ClickType.DROP, "simpleclans.leader.disband"); - disband.setConfirmationRequired(ClickType.LEFT); - add(disband); - } + private void addChat() { - private void addResign() { - SCComponent resign = new SCComponentImpl(lang("gui.clandetails.resign.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.resign.lore", getViewer())), XMaterial.IRON_DOOR, 48); - resign.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "resign", false)); - resign.setConfirmationRequired(ClickType.LEFT); - resign.setPermission(ClickType.LEFT, "simpleclans.member.resign"); - add(resign); - } + Channel cpChannel = cp.getChannel(); + boolean clanEnabled = Channel.CLAN.equals(cpChannel); + boolean allyEnabled = Channel.ALLY.equals(cpChannel); - private void addVerify() { - boolean verified = clan.isVerified(); - boolean purchaseVerification = settings.is(REQUIRE_VERIFICATION) && settings.is(ECONOMY_PURCHASE_CLAN_VERIFY); + SCComponent chat = createChatComponent(clanEnabled, allyEnabled); + chat.setListener(ClickType.LEFT, () -> { - XMaterial material = verified ? XMaterial.REDSTONE_TORCH : XMaterial.LEVER; - String title = verified ? lang("gui.clandetails.verified.title", getViewer()) - : lang("gui.clandetails.not.verified.title", getViewer()); - List lore = verified ? null : new ArrayList<>(); - if (!verified) { - if (purchaseVerification) { - lore.add(lang("gui.clandetails.verify.price.lore", getViewer(), CurrencyFormat.format(settings.getDouble(ECONOMY_VERIFICATION_PRICE)))); - } - lore.add(lang("gui.clandetails.not.verified.lore", getViewer())); - } - SCComponent verify = new SCComponentImpl(title, lore, material, 39); - if (!verified) { - verify.setPermission(ClickType.LEFT, "simpleclans.leader.verify"); - verify.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "verify", false)); - } - add(verify); - } + if (clanEnabled) { - private void addBank() { - String withdrawStatus = clan.isAllowWithdraw() ? lang("allowed",getViewer()) : lang("blocked",getViewer()); - String depositStatus = clan.isAllowDeposit() ? lang("allowed", getViewer()) : lang("blocked", getViewer()); - SCComponent bank = new SCComponentImpl(lang("gui.clandetails.bank.title", getViewer()), - Arrays.asList(lang("gui.clandetails.bank.balance.lore", getViewer(), clan.getBalanceFormatted()), - lang("gui.clandetails.bank.withdraw.status.lore", getViewer(), withdrawStatus), - lang("gui.clandetails.bank.deposit.status.lore", getViewer(), depositStatus), - lang("gui.clandetails.bank.withdraw.toggle.lore", getViewer()), - lang("gui.clandetails.bank.deposit.toggle.lore", getViewer())), - XMaterial.GOLD_INGOT, 34); - bank.setLorePermission(RankPermission.BANK_BALANCE); - bank.setVerifiedOnly(ClickType.DROP); - bank.setListener(ClickType.DROP, () -> InventoryController.runSubcommand(getViewer(), "toggle withdraw", true)); - bank.setConfirmationRequired(ClickType.DROP); - bank.setPermission(ClickType.DROP, "simpleclans.leader.withdraw-toggle"); - bank.setVerifiedOnly(ClickType.RIGHT); - bank.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "toggle deposit", true)); - bank.setPermission(ClickType.RIGHT, "simpleclans.leader.deposit-toggle"); + cp.setChannel(Channel.NONE); - add(bank); - } + } else { - private void addFf() { - String personalFf = cp.isFriendlyFire() ? lang("allowed",getViewer()) : lang("auto",getViewer()); - String clanFf = clan.isFriendlyFire() ? lang("allowed", getViewer()) : lang("blocked", getViewer()); - SCComponent ff = new SCComponentImpl(lang("gui.clandetails.ff.title", getViewer()), - Arrays.asList(lang("gui.clandetails.ff.personal.lore", getViewer(), personalFf), - lang("gui.clandetails.ff.clan.lore", getViewer(), clanFf), - lang("gui.clandetails.ff.personal.toggle.lore", getViewer()), - lang("gui.clandetails.ff.clan.toggle.lore", getViewer())), - XMaterial.GOLDEN_SWORD, 32); + cp.setChannel(Channel.CLAN); - ff.setListener(ClickType.LEFT, this::togglePersonalFf); - ff.setPermission(ClickType.LEFT, "simpleclans.member.ff"); - ff.setListener(ClickType.RIGHT, this::toggleClanFf); - ff.setPermission(ClickType.RIGHT, RankPermission.FRIENDLYFIRE); - add(ff); - } + } - private void toggleClanFf() { - String arg; - if (clan.isFriendlyFire()) { - arg = "block"; - } else { - arg = "allow"; - } - InventoryController.runSubcommand(getViewer(), "clanff", true, arg); - } + updateFrame(); - private void togglePersonalFf() { - String arg; - if (cp.isFriendlyFire()) { - arg = "auto"; - } else { - arg = "allow"; - } - InventoryController.runSubcommand(getViewer(), "ff", true, arg); - } + }); + chat.setPermission(ClickType.LEFT, "simpleclans.member.chat"); + chat.setListener(ClickType.RIGHT, () -> { - private void addRegroup() { - double price = 0; - if (settings.is(ECONOMY_PURCHASE_HOME_REGROUP)) { - price = settings.getDouble(ECONOMY_REGROUP_PRICE); - if (!settings.is(ECONOMY_UNIQUE_TAX_ON_REGROUP)) { - price = price * VanishUtils.getNonVanished(getViewer(), clan).size(); - } - } + if (allyEnabled) { - List lore = new ArrayList<>(); - if (price != 0) lore.add(lang("gui.clandetails.regroup.lore.price", getViewer(), CurrencyFormat.format(price))); - lore.add(lang("gui.clandetails.regroup.lore.home", getViewer())); - lore.add(lang("gui.clandetails.regroup.lore.me", getViewer())); + cp.setChannel(Channel.NONE); - SCComponent regroup = new SCComponentImpl(lang("gui.clandetails.regroup.title", getViewer()), lore, - XMaterial.BEACON, 30); - regroup.setVerifiedOnly(ClickType.LEFT); - regroup.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "regroup home", false)); - regroup.setConfirmationRequired(ClickType.LEFT); - regroup.setPermission(ClickType.LEFT, RankPermission.REGROUP_HOME); - regroup.setVerifiedOnly(ClickType.RIGHT); - regroup.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "regroup me", false)); - regroup.setConfirmationRequired(ClickType.RIGHT); - regroup.setPermission(ClickType.RIGHT, RankPermission.REGROUP_ME); - add(regroup); - } + } else { - private void addHome() { - double homePrice = settings.is(ECONOMY_PURCHASE_HOME_TELEPORT) ? settings.getDouble(ECONOMY_HOME_TELEPORT_PRICE) : 0; - double setPrice = settings.is(ECONOMY_PURCHASE_HOME_TELEPORT_SET) ? settings.getDouble(ECONOMY_HOME_TELEPORT_SET_PRICE) : 0; + cp.setChannel(Channel.ALLY); - List lore = new ArrayList<>(); - if (homePrice != 0) lore.add(lang("gui.clandetails.home.lore.teleport.price", getViewer(), CurrencyFormat.format(homePrice))); - lore.add(lang("gui.clandetails.home.lore.teleport", getViewer())); - if (setPrice != 0) lore.add(lang("gui.clandetails.home.lore.set.price", getViewer(), CurrencyFormat.format(setPrice))); - lore.add(lang("gui.clandetails.home.lore.set", getViewer())); - lore.add(lang("gui.clandetails.home.lore.clear", getViewer())); + } - SCComponent home = new SCComponentImpl(lang("gui.clandetails.home.title", getViewer()), lore, - Objects.requireNonNull(XMaterial.MAGENTA_BED.parseMaterial()), 28); - home.setVerifiedOnly(ClickType.LEFT); - home.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "home", false)); - home.setPermission(ClickType.LEFT, RankPermission.HOME_TP); - home.setVerifiedOnly(ClickType.RIGHT); - home.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "home set", false)); - home.setPermission(ClickType.RIGHT, RankPermission.HOME_SET); - home.setConfirmationRequired(ClickType.RIGHT); - home.setVerifiedOnly(ClickType.DROP); - home.setListener(ClickType.DROP, () -> InventoryController.runSubcommand(getViewer(), "home clear", false)); - home.setPermission(ClickType.DROP, RankPermission.HOME_SET); - home.setConfirmationRequired(ClickType.DROP); - add(home); - } + updateFrame(); - private void addRoster() { - SCComponent roster = new SCComponentImpl(lang("gui.clandetails.roster.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.roster.lore", getViewer())), XMaterial.PLAYER_HEAD, - 19); - List members = clan.getMembers(); - if (members.size() != 0) { - OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer( - members.get((int) (Math.random() * members.size())).getUniqueId()); - Components.setOwningPlayer(roster.getItem(), offlinePlayer); - } - roster.setVerifiedOnly(ClickType.LEFT); - roster.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RosterFrame(getViewer(), this, clan))); - roster.setPermission(ClickType.LEFT, "simpleclans.member.roster"); - add(roster); - } + }); + chat.setPermission(ClickType.RIGHT, RankPermission.ALLY_CHAT); + add(chat); - private void addCoords() { - SCComponent coords = new SCComponentImpl(lang("gui.clandetails.coords.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.coords.lore", getViewer())), XMaterial.COMPASS, - 21); - coords.setVerifiedOnly(ClickType.LEFT); - coords.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new CoordsFrame(getViewer(), this, clan))); - coords.setPermission(ClickType.LEFT, RankPermission.COORDS); - add(coords); - } + } - private void addAllies() { - SCComponent allies = new SCComponentImpl(lang("gui.clandetails.allies.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.allies.lore", getViewer())), XMaterial.CYAN_BANNER, - 23); - allies.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AlliesFrame(getViewer(), this, clan))); - allies.setPermission(ClickType.LEFT, "simpleclans.anyone.alliances"); - add(allies); - } + @NotNull + private SCComponent createChatComponent(boolean clanEnabled, boolean allyEnabled) { - private void addRivals() { - SCComponent rivals = new SCComponentImpl(lang("gui.clandetails.rivals.title", getViewer()), - Collections.singletonList(lang("gui.clandetails.rivals.lore", getViewer())), XMaterial.RED_BANNER, - 25); - rivals.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RivalsFrame(getViewer(), this, clan))); - rivals.setPermission(ClickType.LEFT, "simpleclans.anyone.rivalries"); - add(rivals); - } + String joined = lang("chat.joined", getViewer()); + String notJoined = lang("chat.not.joined", getViewer()); - private void updateFrame() { - InventoryDrawer.open(this); - } + String clanStatus = clanEnabled ? joined : notJoined; + String allyStatus = allyEnabled ? joined : notJoined; - @Override - public @NotNull String getTitle() { - return lang("gui.clandetails.title",getViewer(), ChatUtils.stripColors(clan.getColorTag()), - clan.getName()); - } + String chatCommand = settings.is(CLANCHAT_TAG_BASED) ? clan.getTag() : settings.getString(COMMANDS_CLAN_CHAT); + String joinArg = lang("join", getViewer()); + String leaveArg = lang("leave", getViewer()); + return new SCComponentImpl(lang("gui.clandetails.chat.title", getViewer()), + Arrays.asList(lang("gui.clandetails.chat.clan.chat.lore", getViewer(), chatCommand), + lang("gui.clandetails.chat.clan.join.leave.lore", getViewer(), chatCommand, joinArg, leaveArg), + lang("gui.clandetails.chat.ally.chat.lore", getViewer(), settings.getString(COMMANDS_ALLY)), + lang("gui.clandetails.chat.ally.join.leave.lore", getViewer(), + settings.getString(COMMANDS_ALLY), joinArg, leaveArg), + lang("gui.clandetails.chat.clan.status.lore", getViewer(), clanStatus), + lang("gui.clandetails.chat.ally.status.lore", getViewer(), allyStatus), + lang("gui.clandetails.chat.clan.toggle.lore", getViewer()), + lang("gui.clandetails.chat.ally.toggle.lore", getViewer())), + XMaterial.KNOWLEDGE_BOOK, 43); - @Override - public int getSize() { - return 6 * 9; - } + } + + private void addRank() { + + SCComponent rank = new SCComponentImpl(lang("gui.clandetails.rank.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.rank.lore", getViewer())), XMaterial.IRON_HELMET, 37); + rank.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RanksFrame(this, getViewer(), clan, null))); + rank.setPermission(ClickType.LEFT, "simpleclans.leader.rank.list"); + add(rank); + + } + + private void addFee() { + + String status = clan.isMemberFeeEnabled() ? lang("fee.enabled", getViewer()) + : lang("fee.disabled", getViewer()); + SCComponent fee = new SCComponentImpl(lang("gui.clandetails.fee.title", getViewer()), + Arrays.asList(lang("gui.clandetails.fee.value.lore", getViewer(), clan.getMemberFee()), + lang("gui.clandetails.fee.status.lore", getViewer(), status), + lang("gui.clandetails.fee.toggle.lore", getViewer())), + XMaterial.GOLD_NUGGET, 41); + fee.setVerifiedOnly(ClickType.LEFT); + fee.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "toggle fee", true)); + fee.setPermission(ClickType.LEFT, RankPermission.FEE_ENABLE); + add(fee); + + } + + private void addDisband() { + + SCComponent disband = new SCComponentImpl(lang("gui.clandetails.disband.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.disband.lore", getViewer())), XMaterial.BARRIER, 50); + disband.setListener(ClickType.DROP, () -> InventoryController.runSubcommand(getViewer(), "disband", false)); + disband.setPermission(ClickType.DROP, "simpleclans.leader.disband"); + disband.setConfirmationRequired(ClickType.LEFT); + add(disband); + + } + + private void addResign() { + + SCComponent resign = new SCComponentImpl(lang("gui.clandetails.resign.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.resign.lore", getViewer())), XMaterial.IRON_DOOR, 48); + resign.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "resign", false)); + resign.setConfirmationRequired(ClickType.LEFT); + resign.setPermission(ClickType.LEFT, "simpleclans.member.resign"); + add(resign); + + } + + private void addVerify() { + + boolean verified = clan.isVerified(); + boolean purchaseVerification = settings.is(REQUIRE_VERIFICATION) && settings.is(ECONOMY_PURCHASE_CLAN_VERIFY); + + XMaterial material = verified ? XMaterial.REDSTONE_TORCH : XMaterial.LEVER; + String title = verified ? lang("gui.clandetails.verified.title", getViewer()) + : lang("gui.clandetails.not.verified.title", getViewer()); + List lore = verified ? null : new ArrayList<>(); + if (!verified) { + + if (purchaseVerification) { + + lore.add(lang("gui.clandetails.verify.price.lore", getViewer(), + CurrencyFormat.format(settings.getDouble(ECONOMY_VERIFICATION_PRICE)))); + + } + + lore.add(lang("gui.clandetails.not.verified.lore", getViewer())); + + } + + SCComponent verify = new SCComponentImpl(title, lore, material, 39); + if (!verified) { + + verify.setPermission(ClickType.LEFT, "simpleclans.leader.verify"); + verify.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "verify", false)); + + } + + add(verify); + + } + + private void addBank() { + + String withdrawStatus = clan.isAllowWithdraw() ? lang("allowed", getViewer()) : lang("blocked", getViewer()); + String depositStatus = clan.isAllowDeposit() ? lang("allowed", getViewer()) : lang("blocked", getViewer()); + SCComponent bank = new SCComponentImpl(lang("gui.clandetails.bank.title", getViewer()), + Arrays.asList(lang("gui.clandetails.bank.balance.lore", getViewer(), clan.getBalanceFormatted()), + lang("gui.clandetails.bank.withdraw.status.lore", getViewer(), withdrawStatus), + lang("gui.clandetails.bank.deposit.status.lore", getViewer(), depositStatus), + lang("gui.clandetails.bank.withdraw.toggle.lore", getViewer()), + lang("gui.clandetails.bank.deposit.toggle.lore", getViewer())), + XMaterial.GOLD_INGOT, 34); + bank.setLorePermission(RankPermission.BANK_BALANCE); + bank.setVerifiedOnly(ClickType.DROP); + bank.setListener(ClickType.DROP, () -> InventoryController.runSubcommand(getViewer(), "toggle withdraw", true)); + bank.setConfirmationRequired(ClickType.DROP); + bank.setPermission(ClickType.DROP, "simpleclans.leader.withdraw-toggle"); + bank.setVerifiedOnly(ClickType.RIGHT); + bank.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "toggle deposit", true)); + bank.setPermission(ClickType.RIGHT, "simpleclans.leader.deposit-toggle"); + + add(bank); + + } + + private void addFf() { + + String personalFf = cp.isFriendlyFire() ? lang("allowed", getViewer()) : lang("auto", getViewer()); + String clanFf = clan.isFriendlyFire() ? lang("allowed", getViewer()) : lang("blocked", getViewer()); + SCComponent ff = new SCComponentImpl(lang("gui.clandetails.ff.title", getViewer()), + Arrays.asList(lang("gui.clandetails.ff.personal.lore", getViewer(), personalFf), + lang("gui.clandetails.ff.clan.lore", getViewer(), clanFf), + lang("gui.clandetails.ff.personal.toggle.lore", getViewer()), + lang("gui.clandetails.ff.clan.toggle.lore", getViewer())), + XMaterial.GOLDEN_SWORD, 32); + + ff.setListener(ClickType.LEFT, this::togglePersonalFf); + ff.setPermission(ClickType.LEFT, "simpleclans.member.ff"); + ff.setListener(ClickType.RIGHT, this::toggleClanFf); + ff.setPermission(ClickType.RIGHT, RankPermission.FRIENDLYFIRE); + add(ff); + + } + + private void toggleClanFf() { + + String arg; + if (clan.isFriendlyFire()) { + + arg = "block"; + + } else { + + arg = "allow"; + + } + + InventoryController.runSubcommand(getViewer(), "clanff", true, arg); + + } + + private void togglePersonalFf() { + + String arg; + if (cp.isFriendlyFire()) { + + arg = "auto"; + + } else { + + arg = "allow"; + + } + + InventoryController.runSubcommand(getViewer(), "ff", true, arg); + + } + + private void addRegroup() { + + double price = 0; + if (settings.is(ECONOMY_PURCHASE_HOME_REGROUP)) { + + price = settings.getDouble(ECONOMY_REGROUP_PRICE); + if (!settings.is(ECONOMY_UNIQUE_TAX_ON_REGROUP)) { + + price = price * VanishUtils.getNonVanished(getViewer(), clan).size(); + + } + + } + + List lore = new ArrayList<>(); + if (price != 0) + lore.add(lang("gui.clandetails.regroup.lore.price", getViewer(), CurrencyFormat.format(price))); + lore.add(lang("gui.clandetails.regroup.lore.home", getViewer())); + lore.add(lang("gui.clandetails.regroup.lore.me", getViewer())); + + SCComponent regroup = new SCComponentImpl(lang("gui.clandetails.regroup.title", getViewer()), lore, + XMaterial.BEACON, 30); + regroup.setVerifiedOnly(ClickType.LEFT); + regroup.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "regroup home", false)); + regroup.setConfirmationRequired(ClickType.LEFT); + regroup.setPermission(ClickType.LEFT, RankPermission.REGROUP_HOME); + regroup.setVerifiedOnly(ClickType.RIGHT); + regroup.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "regroup me", false)); + regroup.setConfirmationRequired(ClickType.RIGHT); + regroup.setPermission(ClickType.RIGHT, RankPermission.REGROUP_ME); + add(regroup); + + } + + private void addHome() { + + double homePrice = settings.is(ECONOMY_PURCHASE_HOME_TELEPORT) ? settings.getDouble(ECONOMY_HOME_TELEPORT_PRICE) + : 0; + double setPrice = settings.is(ECONOMY_PURCHASE_HOME_TELEPORT_SET) + ? settings.getDouble(ECONOMY_HOME_TELEPORT_SET_PRICE) + : 0; + + List lore = new ArrayList<>(); + if (homePrice != 0) + lore.add(lang("gui.clandetails.home.lore.teleport.price", getViewer(), CurrencyFormat.format(homePrice))); + lore.add(lang("gui.clandetails.home.lore.teleport", getViewer())); + if (setPrice != 0) + lore.add(lang("gui.clandetails.home.lore.set.price", getViewer(), CurrencyFormat.format(setPrice))); + lore.add(lang("gui.clandetails.home.lore.set", getViewer())); + lore.add(lang("gui.clandetails.home.lore.clear", getViewer())); + + SCComponent home = new SCComponentImpl(lang("gui.clandetails.home.title", getViewer()), lore, + Objects.requireNonNull(XMaterial.MAGENTA_BED.parseMaterial()), 28); + home.setVerifiedOnly(ClickType.LEFT); + home.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "home", false)); + home.setPermission(ClickType.LEFT, RankPermission.HOME_TP); + home.setVerifiedOnly(ClickType.RIGHT); + home.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "home set", false)); + home.setPermission(ClickType.RIGHT, RankPermission.HOME_SET); + home.setConfirmationRequired(ClickType.RIGHT); + home.setVerifiedOnly(ClickType.DROP); + home.setListener(ClickType.DROP, () -> InventoryController.runSubcommand(getViewer(), "home clear", false)); + home.setPermission(ClickType.DROP, RankPermission.HOME_SET); + home.setConfirmationRequired(ClickType.DROP); + add(home); + + } + + private void addRoster() { + + SCComponent roster = new SCComponentImpl(lang("gui.clandetails.roster.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.roster.lore", getViewer())), XMaterial.PLAYER_HEAD, 19); + List members = clan.getMembers(); + if (members.size() != 0) { + + OfflinePlayer offlinePlayer = Bukkit + .getOfflinePlayer(members.get((int) (Math.random() * members.size())).getUniqueId()); + Components.setOwningPlayer(roster.getItem(), offlinePlayer); + + } + + roster.setVerifiedOnly(ClickType.LEFT); + roster.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RosterFrame(getViewer(), this, clan))); + roster.setPermission(ClickType.LEFT, "simpleclans.member.roster"); + add(roster); + + } + + private void addCoords() { + + SCComponent coords = new SCComponentImpl(lang("gui.clandetails.coords.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.coords.lore", getViewer())), XMaterial.COMPASS, 21); + coords.setVerifiedOnly(ClickType.LEFT); + coords.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new CoordsFrame(getViewer(), this, clan))); + coords.setPermission(ClickType.LEFT, RankPermission.COORDS); + add(coords); + + } + + private void addAllies() { + + SCComponent allies = new SCComponentImpl(lang("gui.clandetails.allies.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.allies.lore", getViewer())), XMaterial.CYAN_BANNER, 23); + allies.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AlliesFrame(getViewer(), this, clan))); + allies.setPermission(ClickType.LEFT, "simpleclans.anyone.alliances"); + add(allies); + + } + + private void addRivals() { + + SCComponent rivals = new SCComponentImpl(lang("gui.clandetails.rivals.title", getViewer()), + Collections.singletonList(lang("gui.clandetails.rivals.lore", getViewer())), XMaterial.RED_BANNER, 25); + rivals.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RivalsFrame(getViewer(), this, clan))); + rivals.setPermission(ClickType.LEFT, "simpleclans.anyone.rivalries"); + add(rivals); + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.clandetails.title", getViewer(), ChatUtils.stripColors(clan.getColorTag()), clan.getName()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanListFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanListFrame.java index 6fdd13a2..b1f5d9b8 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanListFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ClanListFrame.java @@ -24,76 +24,101 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.SHOW_UNVERIFIED_ON_LIST; public class ClanListFrame extends SCFrame { - private final List clans; - private final Paginator paginator; - private final RankingNumberResolver rankingResolver; - public ClanListFrame(SCFrame parent, Player viewer) { - super(parent, viewer); - SimpleClans plugin = SimpleClans.getInstance(); - SettingsManager sm = plugin.getSettingsManager(); - clans = plugin.getClanManager().getClans().stream() - .filter(clan -> clan.isVerified() || sm.is(SHOW_UNVERIFIED_ON_LIST)).collect(Collectors.toList()); - paginator = new Paginator(getSize() - 9, clans); - plugin.getClanManager().sortClansByKDR(clans); + private final List clans; + private final Paginator paginator; + private final RankingNumberResolver rankingResolver; - rankingResolver = new RankingNumberResolver<>(clans, c -> KDRFormat.toBigDecimal(c.getTotalKDR()), false, - sm.getRankingType()); - } + public ClanListFrame(SCFrame parent, Player viewer) { - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 2, getViewer())); + super(parent, viewer); + SimpleClans plugin = SimpleClans.getInstance(); + SettingsManager sm = plugin.getSettingsManager(); + clans = plugin.getClanManager().getClans().stream() + .filter(clan -> clan.isVerified() || sm.is(SHOW_UNVERIFIED_ON_LIST)).collect(Collectors.toList()); + paginator = new Paginator(getSize() - 9, clans); + plugin.getClanManager().sortClansByKDR(clans); - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + rankingResolver = new RankingNumberResolver<>(clans, c -> KDRFormat.toBigDecimal(c.getTotalKDR()), false, + sm.getRankingType()); - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - Clan clan = clans.get(i); - ItemStack banner = clan.getBanner() != null ? clan.getBanner() : XMaterial.BLACK_BANNER.parseItem(); - SCComponent c = new SCComponentImpl( - lang("gui.clanlist.clan.title", getViewer(), clan.getColorTag(), clan.getName()), - Arrays.asList(lang("gui.clanlist.clan.lore.position", getViewer(), - rankingResolver.getRankingNumber(clan)), - lang("gui.clanlist.clan.lore.kdr", getViewer(), KDRFormat.format(clan.getTotalKDR())), - lang("gui.clanlist.clan.lore.members", getViewer(), clan.getMembers().size())), - banner, slot); - c.setLorePermission("simpleclans.anyone.list"); - add(c); - slot++; - } - } + } - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + @Override + public void createComponents() { - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + for (int slot = 0; slot < 9; slot++) { - private void updateFrame() { - InventoryDrawer.open(this); - } + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - @Override - public @NotNull String getTitle() { - return lang("gui.clanlist.title",getViewer(), clans.size()); - } + } - @Override - public int getSize() { - return 6 * 9; - } + add(Components.getBackComponent(getParent(), 2, getViewer())); + + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Clan clan = clans.get(i); + ItemStack banner = clan.getBanner() != null ? clan.getBanner() : XMaterial.BLACK_BANNER.parseItem(); + SCComponent c = new SCComponentImpl( + lang("gui.clanlist.clan.title", getViewer(), clan.getColorTag(), clan.getName()), + Arrays.asList( + lang("gui.clanlist.clan.lore.position", getViewer(), + rankingResolver.getRankingNumber(clan)), + lang("gui.clanlist.clan.lore.kdr", getViewer(), KDRFormat.format(clan.getTotalKDR())), + lang("gui.clanlist.clan.lore.members", getViewer(), clan.getMembers().size())), + banner, slot); + c.setLorePermission("simpleclans.anyone.list"); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.clanlist.title", getViewer(), clans.size()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/Components.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/Components.java index 635a4e57..5f826a1e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/Components.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/Components.java @@ -27,178 +27,275 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class Components { private Components() { + } public static SCComponent getPlayerComponent(SCFrame frame, Player viewer, OfflinePlayer subject, int slot, - boolean openDetails) { + boolean openDetails) + { + ClanPlayer cp = SimpleClans.getInstance().getClanManager().getCreateClanPlayer(subject.getUniqueId()); return getPlayerComponent(frame, viewer, cp, slot, openDetails); + } public static SCComponent getPlayerComponent(SCFrame frame, Player viewer, ClanPlayer cp, int slot, - boolean openDetails) { + boolean openDetails) + { + SimpleClans pl = SimpleClans.getInstance(); String status = getPlayerStatus(viewer, cp); - SCComponent c = new SCComponentImpl(lang("gui.playerdetails.player.title", viewer, cp.getName()), - Arrays.asList( - cp.getClan() == null ? lang("gui.playerdetails.player.lore.noclan", viewer) - : lang("gui.playerdetails.player.lore.clan", viewer, cp.getClan().getColorTag(), + SCComponent c = new SCComponentImpl(lang("gui.playerdetails.player.title", viewer, cp.getName()), Arrays.asList( + cp.getClan() == null ? lang("gui.playerdetails.player.lore.noclan", viewer) + : lang("gui.playerdetails.player.lore.clan", viewer, cp.getClan().getColorTag(), cp.getClan().getName()), - lang("gui.playerdetails.player.lore.rank", viewer, - ChatUtils.parseColors(cp.getRankDisplayName())), - lang("gui.playerdetails.player.lore.status", viewer, status), - lang("gui.playerdetails.player.lore.kdr", viewer, - new DecimalFormat("#.#").format(cp.getKDR())), - lang("gui.playerdetails.player.lore.kill.totals", viewer, cp.getRivalKills(), - cp.getNeutralKills(), cp.getCivilianKills()), - lang("gui.playerdetails.player.lore.deaths", viewer, cp.getDeaths()), - lang("gui.playerdetails.player.lore.join.date", viewer, cp.getJoinDateString()), - lang("gui.playerdetails.player.lore.last.seen", viewer, cp.getLastSeenString(viewer)), - lang("gui.playerdetails.player.lore.past.clans", viewer, cp.getPastClansString( - lang("gui.playerdetails.player.lore.past.clans.separator", viewer))), - lang("gui.playerdetails.player.lore.inactive", viewer, cp.getInactiveDays(), - pl.getSettingsManager().getInt(PURGE_INACTIVE_PLAYER_DAYS))), + lang("gui.playerdetails.player.lore.rank", viewer, ChatUtils.parseColors(cp.getRankDisplayName())), + lang("gui.playerdetails.player.lore.status", viewer, status), + lang("gui.playerdetails.player.lore.kdr", viewer, new DecimalFormat("#.#").format(cp.getKDR())), + lang("gui.playerdetails.player.lore.kill.totals", viewer, cp.getRivalKills(), cp.getNeutralKills(), + cp.getCivilianKills()), + lang("gui.playerdetails.player.lore.deaths", viewer, cp.getDeaths()), + lang("gui.playerdetails.player.lore.join.date", viewer, cp.getJoinDateString()), + lang("gui.playerdetails.player.lore.last.seen", viewer, cp.getLastSeenString(viewer)), + lang("gui.playerdetails.player.lore.past.clans", viewer, + cp.getPastClansString(lang("gui.playerdetails.player.lore.past.clans.separator", viewer))), + lang("gui.playerdetails.player.lore.inactive", viewer, cp.getInactiveDays(), + pl.getSettingsManager().getInt(PURGE_INACTIVE_PLAYER_DAYS))), XMaterial.PLAYER_HEAD, slot); OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(cp.getUniqueId()); setOwningPlayer(c.getItem(), offlinePlayer); if (viewer.getUniqueId().equals(cp.getUniqueId())) { + c.setLorePermission("simpleclans.member.lookup"); + } else { + c.setLorePermission("simpleclans.anyone.lookup"); + } + if (openDetails) { + c.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new PlayerDetailsFrame(viewer, frame, offlinePlayer))); + } + return c; + } @NotNull private static String getPlayerStatus(Player viewer, ClanPlayer cp) { + if (cp.getClan() == null) { + return lang("free.agent", viewer); + } + if (cp.isLeader()) { + return lang("leader", viewer); + } + if (cp.isTrusted()) { + return lang("trusted", viewer); + } + if (!cp.getRankId().isEmpty()) { + return lang("in.rank", viewer); + } + return lang("untrusted", viewer); + } - public static SCComponent getClanComponent(@NotNull SCFrame frame, @NotNull Player viewer, - @Nullable Clan clan, int slot, boolean openDetails) { + public static SCComponent getClanComponent(@NotNull SCFrame frame, @NotNull Player viewer, @Nullable Clan clan, + int slot, boolean openDetails) + { + SimpleClans pl = SimpleClans.getInstance(); String name; List lore; if (clan != null) { + name = lang("gui.clandetails.clan.title", viewer, clan.getColorTag(), clan.getName()); lore = Arrays.asList( lang("gui.clandetails.clan.lore.description", viewer, - clan.getDescription() != null && !clan.getDescription().isEmpty() ? clan.getDescription() : lang("no.description", viewer)), + clan.getDescription() != null && !clan.getDescription().isEmpty() ? clan.getDescription() + : lang("no.description", viewer)), lang("gui.clandetails.clan.lore.status", viewer, Helper.getFormattedClanStatus(clan, viewer)), lang("gui.clandetails.clan.lore.leaders", viewer, clan.getLeadersString("", ", ")), - lang("gui.clandetails.clan.lore.online.members", viewer, VanishUtils.getNonVanished(viewer, clan).size(), clan.getMembers().size()), + lang("gui.clandetails.clan.lore.online.members", viewer, + VanishUtils.getNonVanished(viewer, clan).size(), clan.getMembers().size()), lang("gui.clandetails.clan.lore.kdr", viewer, KDRFormat.format(clan.getTotalKDR())), - lang("gui.clandetails.clan.lore.kill.totals", viewer, clan.getTotalRival(), clan.getTotalNeutral(), clan.getTotalCivilian()), + lang("gui.clandetails.clan.lore.kill.totals", viewer, clan.getTotalRival(), clan.getTotalNeutral(), + clan.getTotalCivilian()), lang("gui.clandetails.clan.lore.deaths", viewer, clan.getTotalDeaths()), - lang("gui.clandetails.clan.lore.fee", viewer, clan.isMemberFeeEnabled() - ? lang("fee.enabled", viewer) : lang("fee.disabled", viewer), clan.getMemberFee()), - lang("gui.clandetails.clan.lore.allies", viewer, clan.getAllies().isEmpty() ? lang("none", viewer) : clan.getAllyString(lang("gui.clandetails.clan.lore.allies.separator", viewer), viewer)), - lang("gui.clandetails.clan.lore.rivals", viewer, clan.getRivals().isEmpty() ? lang("none", viewer) : clan.getRivalString(lang("gui.clandetails.clan.lore.rivals.separator", viewer), viewer)), + lang("gui.clandetails.clan.lore.fee", viewer, + clan.isMemberFeeEnabled() ? lang("fee.enabled", viewer) : lang("fee.disabled", viewer), + clan.getMemberFee()), + lang("gui.clandetails.clan.lore.allies", viewer, + clan.getAllies().isEmpty() ? lang("none", viewer) + : clan.getAllyString(lang("gui.clandetails.clan.lore.allies.separator", viewer), + viewer)), + lang("gui.clandetails.clan.lore.rivals", viewer, + clan.getRivals().isEmpty() ? lang("none", viewer) + : clan.getRivalString(lang("gui.clandetails.clan.lore.rivals.separator", viewer), + viewer)), lang("gui.clandetails.clan.lore.founded", viewer, clan.getFoundedString()), - lang("gui.clandetails.clan.lore.inactive", viewer, clan.getInactiveDays(), Helper.formatMaxInactiveDays(clan.getMaxInactiveDays()))); + lang("gui.clandetails.clan.lore.inactive", viewer, clan.getInactiveDays(), + Helper.formatMaxInactiveDays(clan.getMaxInactiveDays()))); + } else { + name = lang("gui.clandetails.free.agent.title", viewer); - double price = pl.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_CREATE) ? pl.getSettingsManager().getDouble(ECONOMY_CREATION_PRICE) : 0; + double price = pl.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_CREATE) + ? pl.getSettingsManager().getDouble(ECONOMY_CREATION_PRICE) + : 0; lore = new ArrayList<>(); if (price != 0) { - lore.add(lang("gui.clandetails.free.agent.create.clan.price.lore", frame.getViewer(), CurrencyFormat.format(price))); + + lore.add(lang("gui.clandetails.free.agent.create.clan.price.lore", frame.getViewer(), + CurrencyFormat.format(price))); + } + lore.add(lang("gui.clandetails.free.agent.create.clan.lore", frame.getViewer())); + } ItemStack item; if (clan != null && clan.getBanner() != null) { + item = clan.getBanner(); + } else { + item = XMaterial.GREEN_BANNER.parseItem(); + } + SCComponent c = new SCComponentImpl.Builder(item).withLore(lore).withDisplayName(name).withSlot(slot).build(); if (openDetails && clan != null) { + c.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new ClanDetailsFrame(frame, viewer, clan))); + } + if (clan == null) { + c.setPermission(ClickType.LEFT, "simpleclans.leader.create"); c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(viewer, "create", false)); + } if (clan != null && clan.isMember(viewer)) { + c.setLorePermission("simpleclans.member.profile"); + } else { + c.setLorePermission("simpleclans.anyone.profile"); + } return c; + } public static SCComponent getBackComponent(@Nullable SCFrame parent, int slot, Player viewer) { - SCComponent back = new SCComponentImpl(lang("gui.back.title", viewer), null, - XMaterial.ARROW, slot); + + SCComponent back = new SCComponentImpl(lang("gui.back.title", viewer), null, XMaterial.ARROW, slot); back.setListener(ClickType.LEFT, () -> InventoryDrawer.open(parent)); return back; + } public static SCComponent getPanelComponent(int slot) { + return new SCComponentImpl(" ", null, XMaterial.GRAY_STAINED_GLASS_PANE, slot); + } - public static @NotNull SCComponent getPreviousPageComponent(int slot, @Nullable Runnable listener, @NotNull Paginator paginator, @NotNull Player viewer) { + public static @NotNull SCComponent getPreviousPageComponent(int slot, @Nullable Runnable listener, + @NotNull Paginator paginator, @NotNull Player viewer) + { + if (!paginator.hasPreviousPage()) { + return getPanelComponent(slot); + } - SCComponent c = new SCComponentImpl(lang("gui.previous.page.title", viewer), null, - XMaterial.STONE_BUTTON, slot); + + SCComponent c = new SCComponentImpl(lang("gui.previous.page.title", viewer), null, XMaterial.STONE_BUTTON, + slot); setOneTimeUseListener(c, listener); return c; + } - public static @NotNull SCComponent getNextPageComponent(int slot, @Nullable Runnable listener, @NotNull Paginator paginator, @NotNull Player viewer) { + public static @NotNull SCComponent getNextPageComponent(int slot, @Nullable Runnable listener, + @NotNull Paginator paginator, @NotNull Player viewer) + { + if (!paginator.hasNextPage()) { + return getPanelComponent(slot); + } - SCComponent c = new SCComponentImpl(lang("gui.next.page.title", viewer), null, - XMaterial.STONE_BUTTON, slot); + + SCComponent c = new SCComponentImpl(lang("gui.next.page.title", viewer), null, XMaterial.STONE_BUTTON, slot); setOneTimeUseListener(c, listener); return c; + } private static void setOneTimeUseListener(SCComponent c, @Nullable Runnable listener) { + c.setListener(ClickType.LEFT, () -> { + if (listener != null) { + listener.run(); + } + c.setListener(ClickType.LEFT, null); + }); + } @SuppressWarnings("deprecation") public static void setOwningPlayer(@NotNull ItemStack item, @NotNull OfflinePlayer player) { + SkullMeta itemMeta = (SkullMeta) item.getItemMeta(); if (itemMeta == null || player.getName() == null) { + return; + } + try { + itemMeta.setOwningPlayer(player); + } catch (NoSuchMethodError e) { + itemMeta.setOwner(player.getName()); + } item.setItemMeta(itemMeta); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ConfirmationFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ConfirmationFrame.java index d4cb229c..50ad32cf 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ConfirmationFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/ConfirmationFrame.java @@ -17,22 +17,29 @@ public class ConfirmationFrame extends SCFrame { private final Runnable listener; public ConfirmationFrame(@Nullable SCFrame parent, @NotNull Player viewer, @Nullable Runnable listener) { + super(parent, viewer); this.listener = listener; + } @Override public @NotNull String getTitle() { + return lang("gui.confirmation.title", getViewer()); + } @Override public int getSize() { + return 3 * 9; + } @Override public void createComponents() { + SCComponent confirm = new SCComponentImpl.Builder(XMaterial.LIME_WOOL.parseItem()) .withDisplayName(lang("gui.confirmation.confirm", getViewer())).withSlot(12).build(); confirm.setListener(ClickType.LEFT, listener); @@ -42,5 +49,7 @@ public class ConfirmationFrame extends SCFrame { .withDisplayName(lang("gui.confirmation.return", getViewer())).withSlot(14).build(); returnC.setListener(ClickType.LEFT, () -> InventoryDrawer.open(getParent())); add(returnC); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/CoordsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/CoordsFrame.java index c1949009..951d2b19 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/CoordsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/CoordsFrame.java @@ -25,75 +25,99 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class CoordsFrame extends SCFrame { - private final List allMembers; - private final Paginator paginator; + private final List allMembers; + private final Paginator paginator; - public CoordsFrame(Player viewer, SCFrame parent, Clan subject) { - super(parent, viewer); - allMembers = VanishUtils.getNonVanished(getViewer(), subject); - allMembers.sort((cp1, cp2) -> Boolean.compare(cp1.isLeader(), cp2.isLeader())); + public CoordsFrame(Player viewer, SCFrame parent, Clan subject) { - paginator = new Paginator(getSize() - 9, allMembers); - } + super(parent, viewer); + allMembers = VanishUtils.getNonVanished(getViewer(), subject); + allMembers.sort((cp1, cp2) -> Boolean.compare(cp1.isLeader(), cp2.isLeader())); - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } + paginator = new Paginator(getSize() - 9, allMembers); - add(Components.getBackComponent(getParent(), 2, getViewer())); + } - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - ClanPlayer cp = allMembers.get(i); - Location cpLoc = Objects.requireNonNull(cp.toPlayer()).getLocation(); - int distance = (int) Math.ceil(cpLoc.toVector().distance(getViewer().getLocation().toVector())); + @Override + public void createComponents() { - SCComponent c = new SCComponentImpl(lang("gui.playerdetails.player.title",getViewer(), cp.getName()), - Arrays.asList(lang("gui.coords.player.lore.distance",getViewer(), distance), - lang("gui.coords.player.lore.coords",getViewer(), cpLoc.getBlockX(), - cpLoc.getBlockY(), cpLoc.getBlockZ()), - lang("gui.coords.player.lore.world",getViewer(), Objects.requireNonNull(cpLoc.getWorld()).getName())), - XMaterial.PLAYER_HEAD, slot); - OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(cp.getUniqueId()); - Components.setOwningPlayer(c.getItem(), offlinePlayer); - c.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new PlayerDetailsFrame(getViewer(), this, offlinePlayer))); - c.setLorePermission(RankPermission.COORDS); - add(c); - slot++; - - } - } + for (int slot = 0; slot < 9; slot++) { - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + } - private void updateFrame() { - InventoryDrawer.open(this); - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - @Override - @NotNull - public String getTitle() { - return lang("gui.coords.title",getViewer()); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + ClanPlayer cp = allMembers.get(i); + Location cpLoc = Objects.requireNonNull(cp.toPlayer()).getLocation(); + int distance = (int) Math.ceil(cpLoc.toVector().distance(getViewer().getLocation().toVector())); + + SCComponent c = new SCComponentImpl(lang("gui.playerdetails.player.title", getViewer(), cp.getName()), + Arrays.asList(lang("gui.coords.player.lore.distance", getViewer(), distance), + lang("gui.coords.player.lore.coords", getViewer(), cpLoc.getBlockX(), cpLoc.getBlockY(), + cpLoc.getBlockZ()), + lang("gui.coords.player.lore.world", getViewer(), + Objects.requireNonNull(cpLoc.getWorld()).getName())), + XMaterial.PLAYER_HEAD, slot); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(cp.getUniqueId()); + Components.setOwningPlayer(c.getItem(), offlinePlayer); + c.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new PlayerDetailsFrame(getViewer(), this, offlinePlayer))); + c.setLorePermission(RankPermission.COORDS); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + @NotNull + public String getTitle() { + + return lang("gui.coords.title", getViewer()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } - @Override - public int getSize() { - return 6 * 9; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/InviteFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/InviteFrame.java index ee7aa3c2..fa3f13ad 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/InviteFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/InviteFrame.java @@ -23,85 +23,115 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class InviteFrame extends SCFrame { - private final Paginator paginator; - private final SimpleClans plugin; - private final List players; + private final Paginator paginator; + private final SimpleClans plugin; + private final List players; - public InviteFrame(SCFrame parent, Player viewer) { - super(parent, viewer); - this.plugin = SimpleClans.getInstance(); - ClanManager cm = plugin.getClanManager(); - players = plugin.getServer().getOnlinePlayers().stream().filter(p -> cm.getClanPlayer(p) == null) - .collect(Collectors.toList()); - paginator = new Paginator(getSize() - 9, players.size()); + public InviteFrame(SCFrame parent, Player viewer) { - } + super(parent, viewer); + this.plugin = SimpleClans.getInstance(); + ClanManager cm = plugin.getClanManager(); + players = plugin.getServer().getOnlinePlayers().stream().filter(p -> cm.getClanPlayer(p) == null) + .collect(Collectors.toList()); + paginator = new Paginator(getSize() - 9, players.size()); - @Override - public void createComponents() { - addHeader(); + } - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + @Override + public void createComponents() { - Player player = players.get(i); - SCComponent c = createPlayerComponent(player, slot); - add(c); - slot++; - } - } + addHeader(); - @NotNull - private SCComponent createPlayerComponent(@NotNull Player player, int slot) { - double price = plugin.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_INVITE) ? plugin.getSettingsManager().getDouble(ECONOMY_INVITE_PRICE) : 0; - List lore = new ArrayList<>(); - if (price != 0) lore.add(lang("gui.invite.player.price.lore", getViewer(), CurrencyFormat.format(price))); - lore.add(lang("gui.invite.player.lore", getViewer())); + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - SCComponent c = new SCComponentImpl( - lang("gui.invite.player.title", getViewer(), player.getName()), lore, XMaterial.PLAYER_HEAD, slot); - OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUniqueId()); - Components.setOwningPlayer(c.getItem(), offlinePlayer); - c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "invite", false, player.getName())); - c.setPermission(ClickType.LEFT, RankPermission.INVITE); - return c; - } + Player player = players.get(i); + SCComponent c = createPlayerComponent(player, slot); + add(c); + slot++; - public void addHeader() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 2, getViewer())); + } - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - } + } - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + @NotNull + private SCComponent createPlayerComponent(@NotNull Player player, int slot) { - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + double price = plugin.getSettingsManager().is(ECONOMY_PURCHASE_CLAN_INVITE) + ? plugin.getSettingsManager().getDouble(ECONOMY_INVITE_PRICE) + : 0; + List lore = new ArrayList<>(); + if (price != 0) + lore.add(lang("gui.invite.player.price.lore", getViewer(), CurrencyFormat.format(price))); + lore.add(lang("gui.invite.player.lore", getViewer())); - private void updateFrame() { - InventoryDrawer.open(this); - } + SCComponent c = new SCComponentImpl(lang("gui.invite.player.title", getViewer(), player.getName()), lore, + XMaterial.PLAYER_HEAD, slot); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(player.getUniqueId()); + Components.setOwningPlayer(c.getItem(), offlinePlayer); + c.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "invite", false, player.getName())); + c.setPermission(ClickType.LEFT, RankPermission.INVITE); + return c; + + } + + public void addHeader() { + + for (int slot = 0; slot < 9; slot++) { + + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); + + } + + add(Components.getBackComponent(getParent(), 2, getViewer())); + + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.invite.title", getViewer()); + + } + + @Override + public int getSize() { + + return 3 * 9; + + } - @Override - public @NotNull String getTitle() { - return lang("gui.invite.title",getViewer()); - } - - @Override - public int getSize() { - return 3 * 9; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LanguageSelectorFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LanguageSelectorFrame.java index 5a8d591a..89620076 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LanguageSelectorFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LanguageSelectorFrame.java @@ -28,100 +28,147 @@ public class LanguageSelectorFrame extends SCFrame { private final List languages; public LanguageSelectorFrame(@Nullable SCFrame parent, @NotNull Player viewer) { + super(parent, viewer); plugin = SimpleClans.getInstance(); clanPlayer = plugin.getClanManager().getCreateClanPlayer(viewer.getUniqueId()); languages = LanguageResource.getAvailableLocales(); paginator = new Paginator(getSize() - 9, languages); + } @Override public @NotNull String getTitle() { + Locale locale = clanPlayer.getLocale(); if (locale == null) { + locale = plugin.getSettingsManager().getLanguage(); + } + return lang("gui.languageselector.title", getViewer(), locale.toLanguageTag()); + } @Override public int getSize() { + return 3 * 9; + } @Override public void createComponents() { + addHeader(); int slot = 9; for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + Locale locale = languages.get(i); addLanguage(slot, locale); slot++; + } + } private void addLanguage(int slot, Locale locale) { + SCComponent c = new SCComponentImpl.Builder(XMaterial.PAPER) - .withDisplayName(lang("gui.languageselector.language.title", getViewer(), locale.toLanguageTag().replace("-", "_"))) - .withSlot(slot).withLore( - Arrays.asList(lang("gui.languageselector.language.lore.left.click", getViewer()), - lang("gui.languageselector.language.lore.translation.status", getViewer(), - LanguageResource.getTranslationStatus(locale)), - !locale.equals(Locale.ENGLISH) ? - lang("gui.languageselector.language.lore.right.click", getViewer()) : "")) + .withDisplayName(lang("gui.languageselector.language.title", getViewer(), + locale.toLanguageTag().replace("-", "_"))) + .withSlot(slot) + .withLore(Arrays.asList(lang("gui.languageselector.language.lore.left.click", getViewer()), + lang("gui.languageselector.language.lore.translation.status", getViewer(), + LanguageResource.getTranslationStatus(locale)), + !locale.equals(Locale.ENGLISH) + ? lang("gui.languageselector.language.lore.right.click", getViewer()) + : "")) .build(); c.setListener(ClickType.LEFT, () -> { + clanPlayer.setLocale(locale); plugin.getStorageManager().updateClanPlayer(clanPlayer); InventoryDrawer.open(this); + }); if (!locale.equals(Locale.ENGLISH)) { + c.setListener(ClickType.RIGHT, () -> { + getViewer().sendMessage(lang("click.to.help.translating", getViewer(), getCrowdinLink(locale))); getViewer().closeInventory(); + }); + } + add(c); + } private String getCrowdinLink(@NotNull Locale locale) { + String base = "https://crowdin.com/project/simpleclans/"; - //only known exception + // only known exception if (locale.equals(new Locale("uk", "UA"))) { + return base + "uk"; + } + if (locale.getLanguage().equalsIgnoreCase(locale.getCountry())) { + return base + locale.getLanguage(); + } return base + locale.toLanguageTag(); + } public void addHeader() { + for (int slot = 0; slot < 9; slot++) { + if (slot == 2 || slot == 6 || slot == 7) continue; add(Components.getPanelComponent(slot)); + } + add(Components.getBackComponent(getParent(), 2, getViewer())); add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + } private void previousPage() { + if (paginator.previousPage()) { + updateFrame(); + } + } private void nextPage() { + if (paginator.nextPage()) { + updateFrame(); + } + } private void updateFrame() { + InventoryDrawer.open(this); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LeaderboardFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LeaderboardFrame.java index 263e5070..eea08212 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LeaderboardFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/LeaderboardFrame.java @@ -29,6 +29,7 @@ public class LeaderboardFrame extends SCFrame { private final RankingNumberResolver rankingResolver; public LeaderboardFrame(Player viewer, SCFrame parent) { + super(parent, viewer); SimpleClans plugin = SimpleClans.getInstance(); @@ -37,15 +38,20 @@ public class LeaderboardFrame extends SCFrame { rankingResolver = new RankingNumberResolver<>(clanPlayers, c -> KDRFormat.toBigDecimal(c.getKDR()), false, plugin.getSettingsManager().getRankingType()); paginator = new Paginator(getSize() - 9, this.clanPlayers); + } @Override public void createComponents() { + for (int slot = 0; slot < 9; slot++) { + if (slot == 2 || slot == 6 || slot == 7) continue; add(Components.getPanelComponent(slot)); + } + add(Components.getBackComponent(getParent(), 2, getViewer())); add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); @@ -53,16 +59,18 @@ public class LeaderboardFrame extends SCFrame { int slot = 9; for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + ClanPlayer cp = clanPlayers.get(i); SCComponent c = new SCComponentImpl( - lang("gui.leaderboard.player.title", getViewer(), - rankingResolver.getRankingNumber(cp), cp.getName()), + lang("gui.leaderboard.player.title", getViewer(), rankingResolver.getRankingNumber(cp), + cp.getName()), Arrays.asList( cp.getClan() == null ? lang("gui.playerdetails.player.lore.noclan", getViewer()) : lang("gui.playerdetails.player.lore.clan", getViewer(), - cp.getClan().getColorTag(), cp.getClan().getName()), + cp.getClan().getColorTag(), cp.getClan().getName()), lang("gui.playerdetails.player.lore.kdr", getViewer(), KDRFormat.format(cp.getKDR())), - lang("gui.playerdetails.player.lore.last.seen", getViewer(), cp.getLastSeenString(getViewer()))), + lang("gui.playerdetails.player.lore.last.seen", getViewer(), + cp.getLastSeenString(getViewer()))), XMaterial.PLAYER_HEAD, slot); OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(cp.getUniqueId()); Components.setOwningPlayer(c.getItem(), offlinePlayer); @@ -71,33 +79,49 @@ public class LeaderboardFrame extends SCFrame { c.setLorePermission("simpleclans.anyone.leaderboard"); add(c); slot++; + } + } private void previousPage() { + if (paginator.previousPage()) { + updateFrame(); + } + } private void nextPage() { + if (paginator.nextPage()) { + updateFrame(); + } + } private void updateFrame() { + InventoryDrawer.open(this); + } @Override public @NotNull String getTitle() { + return lang("gui.leaderboard.title", getViewer(), clanPlayers.size()); + } @Override public int getSize() { + return 6 * 9; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/MainFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/MainFrame.java index 0bc86f45..02a467ee 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/MainFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/MainFrame.java @@ -18,106 +18,141 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class MainFrame extends SCFrame { - private final SimpleClans plugin = SimpleClans.getInstance(); + private final SimpleClans plugin = SimpleClans.getInstance(); - public MainFrame(Player viewer) { - super(null, viewer); - } + public MainFrame(Player viewer) { - @Override - public void createComponents() { - add(Components.getPlayerComponent(this, getViewer(), getViewer(), 0, false)); - add(Components.getClanComponent(this, getViewer(), - plugin.getClanManager().getCreateClanPlayer(getViewer().getUniqueId()).getClan(), 1, true)); - addLeaderboard(); - addClanList(); - addResetKdr(); - addStaff(); - addLanguageSelector(); - addOtherCommands(); - } + super(null, viewer); - private void addOtherCommands() { - SCComponent otherCommands = new SCComponentImpl(lang("gui.main.other.commands.title",getViewer()), - Collections.singletonList(lang("gui.main.other.commands.lore",getViewer())), XMaterial.BOOK, 8); - otherCommands.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "help", false)); - add(otherCommands); - } + } - private void addStaff() { - if (plugin.getPermissionsManager().has(getViewer(), "simpleclans.mod.staffgui")) { - SCComponent staff = new SCComponentImpl.Builder(XMaterial.COMMAND_BLOCK).withSlot(6).withDisplayName( - lang("gui.main.staff.title", getViewer())).withLore(Collections.singletonList(lang("gui.main.staff.lore", getViewer()))).build(); - staff.setPermission(ClickType.LEFT, "simpleclans.mod.staffgui"); - staff.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new StaffFrame(this, getViewer()))); - add(staff); - } - } + @Override + public void createComponents() { - private void addLeaderboard() { - SCComponent leaderboard = new SCComponentImpl(lang("gui.main.leaderboard.title",getViewer()), - Collections.singletonList(lang("gui.main.leaderboard.lore",getViewer())), XMaterial.PAINTING, 3); - leaderboard.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new LeaderboardFrame(getViewer(), this))); - leaderboard.setPermission(ClickType.LEFT, "simpleclans.anyone.leaderboard"); - add(leaderboard); - } + add(Components.getPlayerComponent(this, getViewer(), getViewer(), 0, false)); + add(Components.getClanComponent(this, getViewer(), + plugin.getClanManager().getCreateClanPlayer(getViewer().getUniqueId()).getClan(), 1, true)); + addLeaderboard(); + addClanList(); + addResetKdr(); + addStaff(); + addLanguageSelector(); + addOtherCommands(); - private void addClanList() { - SCComponent clanList = new SCComponentImpl(lang("gui.main.clan.list.title", getViewer()), - Collections.singletonList(lang("gui.main.clan.list.lore", getViewer())), XMaterial.PURPLE_BANNER, - 4); - clanList.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new ClanListFrame(this, getViewer()))); - clanList.setPermission(ClickType.LEFT, "simpleclans.anyone.list"); - add(clanList); - } + } - private void addLanguageSelector() { - if (plugin.getSettingsManager().is(LANGUAGE_SELECTOR)) { - SCComponent language = new SCComponentImpl.Builder(XMaterial.MAP) - .withDisplayName(lang("gui.main.languageselector.title", getViewer())) - .withSlot(7).withLore(Arrays.asList(lang("gui.main.languageselector.lore.left.click", getViewer()) - , lang("gui.main.languageselector.lore.right.click", getViewer()))).build(); - language.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new LanguageSelectorFrame(this, getViewer()))); - language.setListener(ClickType.RIGHT, () -> { - getViewer().sendMessage(lang("click.to.help.translating", getViewer(), - "https://crowdin.com/project/simpleclans")); - getViewer().closeInventory(); - }); - add(language); - } - } + private void addOtherCommands() { - public void addResetKdr() { - if (!plugin.getPermissionsManager().has(getViewer(), "simpleclans.vip.resetkdr")) { - return; - } + SCComponent otherCommands = new SCComponentImpl(lang("gui.main.other.commands.title", getViewer()), + Collections.singletonList(lang("gui.main.other.commands.lore", getViewer())), XMaterial.BOOK, 8); + otherCommands.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "help", false)); + add(otherCommands); - List resetKdrLore; - if (plugin.getSettingsManager().is(ECONOMY_PURCHASE_RESET_KDR)) { - double price = plugin.getSettingsManager().getDouble(ECONOMY_RESET_KDR_PRICE); - resetKdrLore = Arrays.asList( - lang("gui.main.reset.kdr.lore.price", getViewer(), CurrencyFormat.format(price)), - lang("gui.main.reset.kdr.lore", getViewer())); - } else { - resetKdrLore = Collections.singletonList(lang("gui.main.reset.kdr.lore", getViewer())); - } - SCComponent resetKdr = new SCComponentImpl(lang("gui.main.reset.kdr.title", getViewer()), - resetKdrLore, XMaterial.ANVIL, 5); - resetKdr.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "resetkdr", false)); - resetKdr.setConfirmationRequired(ClickType.LEFT); - resetKdr.setPermission(ClickType.LEFT, "simpleclans.vip.resetkdr"); + } - add(resetKdr); - } + private void addStaff() { - @Override - public @NotNull String getTitle() { - return lang("gui.main.title", getViewer(), plugin.getSettingsManager().getColored(SERVER_NAME)); - } + if (plugin.getPermissionsManager().has(getViewer(), "simpleclans.mod.staffgui")) { - @Override - public int getSize() { - return 3 * 9; - } + SCComponent staff = new SCComponentImpl.Builder(XMaterial.COMMAND_BLOCK).withSlot(6) + .withDisplayName(lang("gui.main.staff.title", getViewer())) + .withLore(Collections.singletonList(lang("gui.main.staff.lore", getViewer()))).build(); + staff.setPermission(ClickType.LEFT, "simpleclans.mod.staffgui"); + staff.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new StaffFrame(this, getViewer()))); + add(staff); + + } + + } + + private void addLeaderboard() { + + SCComponent leaderboard = new SCComponentImpl(lang("gui.main.leaderboard.title", getViewer()), + Collections.singletonList(lang("gui.main.leaderboard.lore", getViewer())), XMaterial.PAINTING, 3); + leaderboard.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new LeaderboardFrame(getViewer(), this))); + leaderboard.setPermission(ClickType.LEFT, "simpleclans.anyone.leaderboard"); + add(leaderboard); + + } + + private void addClanList() { + + SCComponent clanList = new SCComponentImpl(lang("gui.main.clan.list.title", getViewer()), + Collections.singletonList(lang("gui.main.clan.list.lore", getViewer())), XMaterial.PURPLE_BANNER, 4); + clanList.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new ClanListFrame(this, getViewer()))); + clanList.setPermission(ClickType.LEFT, "simpleclans.anyone.list"); + add(clanList); + + } + + private void addLanguageSelector() { + + if (plugin.getSettingsManager().is(LANGUAGE_SELECTOR)) { + + SCComponent language = new SCComponentImpl.Builder(XMaterial.MAP) + .withDisplayName(lang("gui.main.languageselector.title", getViewer())).withSlot(7) + .withLore(Arrays.asList(lang("gui.main.languageselector.lore.left.click", getViewer()), + lang("gui.main.languageselector.lore.right.click", getViewer()))) + .build(); + language.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new LanguageSelectorFrame(this, getViewer()))); + language.setListener(ClickType.RIGHT, () -> { + + getViewer().sendMessage( + lang("click.to.help.translating", getViewer(), "https://crowdin.com/project/simpleclans")); + getViewer().closeInventory(); + + }); + add(language); + + } + + } + + public void addResetKdr() { + + if (!plugin.getPermissionsManager().has(getViewer(), "simpleclans.vip.resetkdr")) { + + return; + + } + + List resetKdrLore; + if (plugin.getSettingsManager().is(ECONOMY_PURCHASE_RESET_KDR)) { + + double price = plugin.getSettingsManager().getDouble(ECONOMY_RESET_KDR_PRICE); + resetKdrLore = Arrays.asList( + lang("gui.main.reset.kdr.lore.price", getViewer(), CurrencyFormat.format(price)), + lang("gui.main.reset.kdr.lore", getViewer())); + + } else { + + resetKdrLore = Collections.singletonList(lang("gui.main.reset.kdr.lore", getViewer())); + + } + + SCComponent resetKdr = new SCComponentImpl(lang("gui.main.reset.kdr.title", getViewer()), resetKdrLore, + XMaterial.ANVIL, 5); + resetKdr.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "resetkdr", false)); + resetKdr.setConfirmationRequired(ClickType.LEFT); + resetKdr.setPermission(ClickType.LEFT, "simpleclans.vip.resetkdr"); + + add(resetKdr); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.main.title", getViewer(), plugin.getSettingsManager().getColored(SERVER_NAME)); + + } + + @Override + public int getSize() { + + return 3 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PermissionsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PermissionsFrame.java index f7ff1cf0..c8f70cf7 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PermissionsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PermissionsFrame.java @@ -13,75 +13,98 @@ import java.util.Collections; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class PermissionsFrame extends SCFrame { - private final Rank rank; - private final Paginator paginator; - private final String[] permissions; - public PermissionsFrame(SCFrame parent, Player viewer, Rank rank) { - super(parent, viewer); - this.rank = rank; - permissions = rank.getPermissions().toArray(new String[0]); - paginator = new Paginator(getSize() - 9, permissions.length); - } + private final Rank rank; + private final Paginator paginator; + private final String[] permissions; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 4 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } + public PermissionsFrame(SCFrame parent, Player viewer, Rank rank) { - add(Components.getBackComponent(getParent(), 2, getViewer())); + super(parent, viewer); + this.rank = rank; + permissions = rank.getPermissions().toArray(new String[0]); + paginator = new Paginator(getSize() - 9, permissions.length); - SCComponent add = new SCComponentImpl(lang("gui.permissions.add.title",getViewer()), null, XMaterial.WHITE_WOOL, - 4); - add.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AddPermissionFrame(this, getViewer(), rank))); - add.setPermission(ClickType.LEFT, "simpleclans.leader.rank.permissions.add"); - add(add); + } - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + @Override + public void createComponents() { - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + for (int slot = 0; slot < 9; slot++) { - String permission = permissions[i]; + if (slot == 2 || slot == 4 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - SCComponent c = new SCComponentImpl(lang("gui.permissions.permission.title",getViewer(), permission), - Collections.singletonList(lang("gui.permissions.permission.lore",getViewer())), XMaterial.PAPER, slot); - c.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), - "rank permissions remove", true, rank.getName(), permission)); - c.setPermission(ClickType.RIGHT, "simpleclans.leader.rank.permissions.remove"); - add(c); - slot++; - } - } + } - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + SCComponent add = new SCComponentImpl(lang("gui.permissions.add.title", getViewer()), null, + XMaterial.WHITE_WOOL, 4); + add.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AddPermissionFrame(this, getViewer(), rank))); + add.setPermission(ClickType.LEFT, "simpleclans.leader.rank.permissions.add"); + add(add); - private void updateFrame() { - InventoryDrawer.open(this); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - @Override - public @NotNull String getTitle() { - return lang("gui.permissions.title",getViewer(), rank.getName()); - } + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - @Override - public int getSize() { - return 3 * 9; - } + String permission = permissions[i]; + + SCComponent c = new SCComponentImpl(lang("gui.permissions.permission.title", getViewer(), permission), + Collections.singletonList(lang("gui.permissions.permission.lore", getViewer())), XMaterial.PAPER, + slot); + c.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), + "rank permissions remove", true, rank.getName(), permission)); + c.setPermission(ClickType.RIGHT, "simpleclans.leader.rank.permissions.remove"); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.permissions.title", getViewer(), rank.getName()); + + } + + @Override + public int getSize() { + + return 3 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PlayerDetailsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PlayerDetailsFrame.java index 1a2c4bb1..81892ce2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PlayerDetailsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/PlayerDetailsFrame.java @@ -20,113 +20,140 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con public class PlayerDetailsFrame extends SCFrame { - private final SimpleClans plugin = SimpleClans.getInstance(); - private final OfflinePlayer subject; - private final String subjectName; - private final Clan clan; + private final SimpleClans plugin = SimpleClans.getInstance(); + private final OfflinePlayer subject; + private final String subjectName; + private final Clan clan; - public PlayerDetailsFrame(Player viewer, SCFrame parent, OfflinePlayer subject) { - super(parent, viewer); - this.subject = subject; - ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(subject.getUniqueId()); - subjectName = cp.getName(); - clan = cp.getClan(); - } + public PlayerDetailsFrame(Player viewer, SCFrame parent, OfflinePlayer subject) { - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 4) - continue; - add(Components.getPanelComponent(slot)); - } + super(parent, viewer); + this.subject = subject; + ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(subject.getUniqueId()); + subjectName = cp.getName(); + clan = cp.getClan(); - add(Components.getBackComponent(getParent(), 4, getViewer())); - add(Components.getPlayerComponent(this, getViewer(), subject, 13, false)); + } - if (!isSameClan()) { - return; - } + @Override + public void createComponents() { - addKick(); - addPromoteDemote(); - addAssignUnassign(); - addTrustUntrust(); - } + for (int slot = 0; slot < 9; slot++) { - private void addKick() { - SCComponent kick = new SCComponentImpl(lang("gui.playerdetails.kick.title",getViewer()), null, XMaterial.RED_WOOL, - 28); - kick.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "kick", true, subjectName)); - kick.setConfirmationRequired(ClickType.LEFT); - kick.setPermission(ClickType.LEFT, RankPermission.KICK); - add(kick); - } + if (slot == 4) + continue; + add(Components.getPanelComponent(slot)); - private void addPromoteDemote() { - SettingsManager settings = plugin.getSettingsManager(); - SCComponent promoteDemote = new SCComponentImpl(lang("gui.playerdetails.promote.demote.title",getViewer()), - Arrays.asList(lang("gui.playerdetails.promote.lore.left.click",getViewer()), - lang("gui.playerdetails.demote.lore.right.click",getViewer())), - XMaterial.GUNPOWDER, 30); - promoteDemote.setConfirmationRequired(ClickType.LEFT); - promoteDemote.setListener(ClickType.LEFT, - () -> InventoryController.runSubcommand(getViewer(), "promote", !settings.is(CLAN_CONFIRMATION_FOR_PROMOTE), subjectName)); - promoteDemote.setPermission(ClickType.LEFT, "simpleclans.leader.promote"); - promoteDemote.setListener(ClickType.RIGHT, - () -> InventoryController.runSubcommand(getViewer(), "demote", !settings.is(CLAN_CONFIRMATION_FOR_DEMOTE), subjectName)); - promoteDemote.setConfirmationRequired(ClickType.RIGHT); - add(promoteDemote); - promoteDemote.setPermission(ClickType.RIGHT, "simpleclans.leader.demote"); - } + } - private void addAssignUnassign() { - SCComponentImpl assignUnassign = new SCComponentImpl(lang("gui.playerdetails.assign.unassign.title",getViewer()), - Arrays.asList(lang("gui.playerdetails.assign.lore.left.click",getViewer()), - lang("gui.playerdetails.unassign.lore.right.click",getViewer())), - XMaterial.FEATHER, 32); - assignUnassign.setConfirmationRequired(ClickType.RIGHT); - assignUnassign.setListener(ClickType.RIGHT, - () -> InventoryController.runSubcommand(getViewer(), "rank unassign", true, subjectName)); - assignUnassign.setPermission(ClickType.RIGHT, "simpleclans.leader.rank.unassign"); - assignUnassign.setListener(ClickType.LEFT, - () -> InventoryDrawer.open(new RanksFrame(this, getViewer(), clan, subject))); - add(assignUnassign); - assignUnassign.setPermission(ClickType.LEFT, "simpleclans.leader.rank.assign"); - } + add(Components.getBackComponent(getParent(), 4, getViewer())); + add(Components.getPlayerComponent(this, getViewer(), subject, 13, false)); - private void addTrustUntrust() { - SCComponent trustUntrust = new SCComponentImpl(lang("gui.playerdetails.trust.untrust.title",getViewer()), - Arrays.asList(lang("gui.playerdetails.trust.lore.left.click",getViewer()), - lang("gui.playerdetails.untrust.lore.right.click",getViewer())), - XMaterial.CYAN_DYE, 34); - trustUntrust.setConfirmationRequired(ClickType.LEFT); - trustUntrust.setListener(ClickType.LEFT, - () -> InventoryController.runSubcommand(getViewer(), "trust", true, subjectName)); - trustUntrust.setPermission(ClickType.LEFT, "simpleclans.leader.settrust"); - trustUntrust.setListener(ClickType.RIGHT, - () -> InventoryController.runSubcommand(getViewer(), "untrust", true, subjectName)); - trustUntrust.setPermission(ClickType.RIGHT, "simpleclans.leader.settrust"); - trustUntrust.setConfirmationRequired(ClickType.RIGHT); - add(trustUntrust); - } + if (!isSameClan()) { - @Override - public @NotNull String getTitle() { - return lang("gui.playerdetails.title",getViewer(), subjectName); - } + return; - @Override - public int getSize() { - int size = 3; - if (isSameClan()) { - size = 6; - } - return size * 9; - } + } - private boolean isSameClan() { - return clan != null && clan.isMember(subject.getUniqueId()); - } + addKick(); + addPromoteDemote(); + addAssignUnassign(); + addTrustUntrust(); + + } + + private void addKick() { + + SCComponent kick = new SCComponentImpl(lang("gui.playerdetails.kick.title", getViewer()), null, + XMaterial.RED_WOOL, 28); + kick.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "kick", true, subjectName)); + kick.setConfirmationRequired(ClickType.LEFT); + kick.setPermission(ClickType.LEFT, RankPermission.KICK); + add(kick); + + } + + private void addPromoteDemote() { + + SettingsManager settings = plugin.getSettingsManager(); + SCComponent promoteDemote = new SCComponentImpl(lang("gui.playerdetails.promote.demote.title", getViewer()), + Arrays.asList(lang("gui.playerdetails.promote.lore.left.click", getViewer()), + lang("gui.playerdetails.demote.lore.right.click", getViewer())), + XMaterial.GUNPOWDER, 30); + promoteDemote.setConfirmationRequired(ClickType.LEFT); + promoteDemote.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "promote", + !settings.is(CLAN_CONFIRMATION_FOR_PROMOTE), subjectName)); + promoteDemote.setPermission(ClickType.LEFT, "simpleclans.leader.promote"); + promoteDemote.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), "demote", + !settings.is(CLAN_CONFIRMATION_FOR_DEMOTE), subjectName)); + promoteDemote.setConfirmationRequired(ClickType.RIGHT); + add(promoteDemote); + promoteDemote.setPermission(ClickType.RIGHT, "simpleclans.leader.demote"); + + } + + private void addAssignUnassign() { + + SCComponentImpl assignUnassign = new SCComponentImpl( + lang("gui.playerdetails.assign.unassign.title", getViewer()), + Arrays.asList(lang("gui.playerdetails.assign.lore.left.click", getViewer()), + lang("gui.playerdetails.unassign.lore.right.click", getViewer())), + XMaterial.FEATHER, 32); + assignUnassign.setConfirmationRequired(ClickType.RIGHT); + assignUnassign.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "rank unassign", true, subjectName)); + assignUnassign.setPermission(ClickType.RIGHT, "simpleclans.leader.rank.unassign"); + assignUnassign.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new RanksFrame(this, getViewer(), clan, subject))); + add(assignUnassign); + assignUnassign.setPermission(ClickType.LEFT, "simpleclans.leader.rank.assign"); + + } + + private void addTrustUntrust() { + + SCComponent trustUntrust = new SCComponentImpl(lang("gui.playerdetails.trust.untrust.title", getViewer()), + Arrays.asList(lang("gui.playerdetails.trust.lore.left.click", getViewer()), + lang("gui.playerdetails.untrust.lore.right.click", getViewer())), + XMaterial.CYAN_DYE, 34); + trustUntrust.setConfirmationRequired(ClickType.LEFT); + trustUntrust.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "trust", true, subjectName)); + trustUntrust.setPermission(ClickType.LEFT, "simpleclans.leader.settrust"); + trustUntrust.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "untrust", true, subjectName)); + trustUntrust.setPermission(ClickType.RIGHT, "simpleclans.leader.settrust"); + trustUntrust.setConfirmationRequired(ClickType.RIGHT); + add(trustUntrust); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.playerdetails.title", getViewer(), subjectName); + + } + + @Override + public int getSize() { + + int size = 3; + if (isSameClan()) { + + size = 6; + + } + + return size * 9; + + } + + private boolean isSameClan() { + + return clan != null && clan.isMember(subject.getUniqueId()); + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RanksFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RanksFrame.java index d2169318..76665f64 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RanksFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RanksFrame.java @@ -22,104 +22,141 @@ import java.util.List; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class RanksFrame extends SCFrame { - private final Paginator paginator; - private final OfflinePlayer toEdit; - private final List ranks; - public RanksFrame(SCFrame parent, Player viewer, Clan subject, @Nullable OfflinePlayer toEdit) { - super(parent, viewer); - this.toEdit = toEdit; - ranks = subject != null ? subject.getRanks() : new ArrayList<>(); - paginator = new Paginator(getSize() - 9, ranks); - } + private final Paginator paginator; + private final OfflinePlayer toEdit; + private final List ranks; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 4 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - - add(Components.getBackComponent(getParent(), 2, getViewer())); + public RanksFrame(SCFrame parent, Player viewer, Clan subject, @Nullable OfflinePlayer toEdit) { - SCComponent create = new SCComponentImpl(lang("gui.ranks.create.title",getViewer()), - Collections.singletonList(lang("gui.ranks.create.lore",getViewer())), XMaterial.WHITE_WOOL, 4); - create.setVerifiedOnly(ClickType.LEFT); - create.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "rank create", false)); - create.setPermission(ClickType.LEFT, "simpleclans.leader.rank.create"); - add(create); + super(parent, viewer); + this.toEdit = toEdit; + ranks = subject != null ? subject.getRanks() : new ArrayList<>(); + paginator = new Paginator(getSize() - 9, ranks); - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + } - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - Rank rank = ranks.get(i); - List lore; - if (toEdit == null) { - lore = Arrays.asList( - lang("gui.ranks.rank.displayname.lore",getViewer(), - ChatUtils.parseColors(rank.getDisplayName())), - lang("gui.ranks.rank.edit.permissions.lore",getViewer()), - lang("gui.ranks.rank.remove.lore",getViewer())); - } else { - lore = Arrays.asList( - lang("gui.ranks.rank.displayname.lore",getViewer(), - ChatUtils.parseColors(rank.getDisplayName())), - lang("gui.ranks.rank.assign.lore",getViewer(), toEdit.getName())); - } - SCComponent c = new SCComponentImpl(lang("gui.ranks.rank.title",getViewer(), rank.getName()), lore, - XMaterial.FILLED_MAP, slot); - if (toEdit != null) { - c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "rank assign", true, toEdit.getName(), rank.getName())); - c.setConfirmationRequired(ClickType.LEFT); - c.setPermission(ClickType.LEFT, "simpleclans.leader.rank.assign"); - } else { - c.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new PermissionsFrame(this, getViewer(), rank))); - c.setPermission(ClickType.LEFT, "simpleclans.leader.rank.permissions.list"); - c.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), - "rank delete", true, rank.getName())); - c.setConfirmationRequired(ClickType.RIGHT); - c.setPermission(ClickType.RIGHT, "simpleclans.leader.rank.delete"); - } - c.setVerifiedOnly(ClickType.LEFT); - c.setVerifiedOnly(ClickType.RIGHT); - add(c); - slot++; - } - } + @Override + public void createComponents() { - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + for (int slot = 0; slot < 9; slot++) { - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + if (slot == 2 || slot == 4 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void updateFrame() { - InventoryDrawer.open(this); - } + } - @Override - public @NotNull String getTitle() { - if (toEdit != null) { - ClanManager clanManager = SimpleClans.getInstance().getClanManager(); - String rank = clanManager.getCreateClanPlayer(toEdit.getUniqueId()).getRankId(); - return lang("gui.ranks.title.set.rank",getViewer(), rank); - } - return lang("gui.ranks.title",getViewer()); - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - @Override - public int getSize() { - return 3 * 9; - } + SCComponent create = new SCComponentImpl(lang("gui.ranks.create.title", getViewer()), + Collections.singletonList(lang("gui.ranks.create.lore", getViewer())), XMaterial.WHITE_WOOL, 4); + create.setVerifiedOnly(ClickType.LEFT); + create.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "rank create", false)); + create.setPermission(ClickType.LEFT, "simpleclans.leader.rank.create"); + add(create); + + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Rank rank = ranks.get(i); + List lore; + if (toEdit == null) { + + lore = Arrays.asList( + lang("gui.ranks.rank.displayname.lore", getViewer(), + ChatUtils.parseColors(rank.getDisplayName())), + lang("gui.ranks.rank.edit.permissions.lore", getViewer()), + lang("gui.ranks.rank.remove.lore", getViewer())); + + } else { + + lore = Arrays.asList( + lang("gui.ranks.rank.displayname.lore", getViewer(), + ChatUtils.parseColors(rank.getDisplayName())), + lang("gui.ranks.rank.assign.lore", getViewer(), toEdit.getName())); + + } + + SCComponent c = new SCComponentImpl(lang("gui.ranks.rank.title", getViewer(), rank.getName()), lore, + XMaterial.FILLED_MAP, slot); + if (toEdit != null) { + + c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "rank assign", true, + toEdit.getName(), rank.getName())); + c.setConfirmationRequired(ClickType.LEFT); + c.setPermission(ClickType.LEFT, "simpleclans.leader.rank.assign"); + + } else { + + c.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new PermissionsFrame(this, getViewer(), rank))); + c.setPermission(ClickType.LEFT, "simpleclans.leader.rank.permissions.list"); + c.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "rank delete", true, rank.getName())); + c.setConfirmationRequired(ClickType.RIGHT); + c.setPermission(ClickType.RIGHT, "simpleclans.leader.rank.delete"); + + } + + c.setVerifiedOnly(ClickType.LEFT); + c.setVerifiedOnly(ClickType.RIGHT); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + if (toEdit != null) { + + ClanManager clanManager = SimpleClans.getInstance().getClanManager(); + String rank = clanManager.getCreateClanPlayer(toEdit.getUniqueId()).getRankId(); + return lang("gui.ranks.title.set.rank", getViewer(), rank); + + } + + return lang("gui.ranks.title", getViewer()); + + } + + @Override + public int getSize() { + + return 3 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RivalsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RivalsFrame.java index 8b1ea5b2..9dea644a 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RivalsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RivalsFrame.java @@ -16,78 +16,100 @@ import java.util.List; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class RivalsFrame extends SCFrame { - private final SimpleClans plugin = SimpleClans.getInstance(); - private final Paginator paginator; - private final Clan subject; - private final List rivals; - public RivalsFrame(Player viewer, SCFrame parent, Clan subject) { - super(parent, viewer); - this.subject = subject; - rivals = subject.getRivals(); - paginator = new Paginator(getSize() - 9, rivals); - } + private final SimpleClans plugin = SimpleClans.getInstance(); + private final Paginator paginator; + private final Clan subject; + private final List rivals; - @Override - public void createComponents() { + public RivalsFrame(Player viewer, SCFrame parent, Clan subject) { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 4 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } + super(parent, viewer); + this.subject = subject; + rivals = subject.getRivals(); + paginator = new Paginator(getSize() - 9, rivals); - add(Components.getBackComponent(getParent(), 2, getViewer())); + } - SCComponent add = new SCComponentImpl(lang("gui.rivals.add.title",getViewer()), null, XMaterial.RED_WOOL, 4); - add.setVerifiedOnly(ClickType.LEFT); - add.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AddRivalFrame(this, getViewer(), subject))); - add.setPermission(ClickType.LEFT, RankPermission.RIVAL_ADD); - add(add); + @Override + public void createComponents() { - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + for (int slot = 0; slot < 9; slot++) { - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + if (slot == 2 || slot == 4 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - Clan clan = plugin.getClanManager().getClan(rivals.get(i)); - if (clan == null) - continue; - SCComponent c = new SCComponentImpl( - lang("gui.clanlist.clan.title",getViewer(), clan.getColorTag(), clan.getName()), - Collections.singletonList(lang("gui.rivals.clan.lore",getViewer())), XMaterial.RED_BANNER, slot ); - c.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), - "rival remove", false, clan.getTag())); - c.setPermission(ClickType.RIGHT, RankPermission.RIVAL_REMOVE); - add(c); - slot++; - } - } + } - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + SCComponent add = new SCComponentImpl(lang("gui.rivals.add.title", getViewer()), null, XMaterial.RED_WOOL, 4); + add.setVerifiedOnly(ClickType.LEFT); + add.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new AddRivalFrame(this, getViewer(), subject))); + add.setPermission(ClickType.LEFT, RankPermission.RIVAL_ADD); + add(add); - private void updateFrame() { - InventoryDrawer.open(this); - } + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); - @Override - public @NotNull String getTitle() { - return lang("gui.rivals.title",getViewer()); - } + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Clan clan = plugin.getClanManager().getClan(rivals.get(i)); + if (clan == null) + continue; + SCComponent c = new SCComponentImpl( + lang("gui.clanlist.clan.title", getViewer(), clan.getColorTag(), clan.getName()), + Collections.singletonList(lang("gui.rivals.clan.lore", getViewer())), XMaterial.RED_BANNER, slot); + c.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "rival remove", false, clan.getTag())); + c.setPermission(ClickType.RIGHT, RankPermission.RIVAL_REMOVE); + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.rivals.title", getViewer()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } - @Override - public int getSize() { - return 6 * 9; - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RosterFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RosterFrame.java index a356836b..7708689e 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RosterFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/RosterFrame.java @@ -23,86 +23,116 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class RosterFrame extends SCFrame { - private final Clan subject; - private final boolean staff; - private final List allMembers; - private final Paginator paginator; + private final Clan subject; + private final boolean staff; + private final List allMembers; + private final Paginator paginator; - public RosterFrame(Player viewer, SCFrame parent, Clan subject) { - this(viewer, parent, subject, false); - } + public RosterFrame(Player viewer, SCFrame parent, Clan subject) { - public RosterFrame(Player viewer, SCFrame parent, Clan subject, boolean staff) { - super(parent, viewer); - this.subject = subject; - this.staff = staff; + this(viewer, parent, subject, false); - allMembers = subject.getLeaders(); - allMembers.addAll(subject.getNonLeaders()); - paginator = new Paginator(getSize() - 9, allMembers.size()); - } + } - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 4 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } + public RosterFrame(Player viewer, SCFrame parent, Clan subject, boolean staff) { - add(Components.getBackComponent(getParent(), 2, getViewer())); + super(parent, viewer); + this.subject = subject; + this.staff = staff; - if (!staff) { - SCComponent invite = new SCComponentImpl(lang("gui.roster.invite.title", getViewer()), - Collections.singletonList(lang("gui.roster.invite.lore", getViewer())), XMaterial.LIME_WOOL, 4); - invite.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new InviteFrame(this, getViewer()))); - invite.setPermission(ClickType.LEFT, RankPermission.INVITE); - add(invite); - } else { - add(Components.getPanelComponent(4)); - } + allMembers = subject.getLeaders(); + allMembers.addAll(subject.getNonLeaders()); + paginator = new Paginator(getSize() - 9, allMembers.size()); - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + } - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - ClanPlayer cp = allMembers.get(i); - SCComponent playerComponent = Components.getPlayerComponent(this, getViewer(), cp, slot, - true); - if (staff) { - playerComponent.setListener(ClickType.LEFT, () -> InventoryDrawer.open( - new PlayerDetailsFrame(getViewer(), this, Bukkit.getOfflinePlayer(cp.getUniqueId())))); - } - add(playerComponent); - slot++; - } - } + @Override + public void createComponents() { - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + for (int slot = 0; slot < 9; slot++) { - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + if (slot == 2 || slot == 4 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); - private void updateFrame() { - InventoryDrawer.open(this); - } + } - @Override - public @NotNull String getTitle() { - return lang("gui.roster.title", getViewer(), ChatUtils.stripColors(subject.getColorTag())); - } + add(Components.getBackComponent(getParent(), 2, getViewer())); - @Override - public int getSize() { - return 6 * 9; - } + if (!staff) { + + SCComponent invite = new SCComponentImpl(lang("gui.roster.invite.title", getViewer()), + Collections.singletonList(lang("gui.roster.invite.lore", getViewer())), XMaterial.LIME_WOOL, 4); + invite.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new InviteFrame(this, getViewer()))); + invite.setPermission(ClickType.LEFT, RankPermission.INVITE); + add(invite); + + } else { + + add(Components.getPanelComponent(4)); + + } + + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + ClanPlayer cp = allMembers.get(i); + SCComponent playerComponent = Components.getPlayerComponent(this, getViewer(), cp, slot, true); + if (staff) { + + playerComponent.setListener(ClickType.LEFT, () -> InventoryDrawer + .open(new PlayerDetailsFrame(getViewer(), this, Bukkit.getOfflinePlayer(cp.getUniqueId())))); + + } + + add(playerComponent); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.roster.title", getViewer(), ChatUtils.stripColors(subject.getColorTag())); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/WarningFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/WarningFrame.java index e930b287..23f90ad3 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/WarningFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/WarningFrame.java @@ -18,64 +18,92 @@ import java.util.List; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class WarningFrame extends SCFrame { - private final SimpleClans plugin = SimpleClans.getInstance(); - private final Object permission; - public WarningFrame(@NotNull SCFrame parent, @NotNull Player viewer, @Nullable Object permission) { - super(parent, viewer); - this.permission = permission; - } + private final SimpleClans plugin = SimpleClans.getInstance(); + private final Object permission; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 4) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 4, getViewer())); + public WarningFrame(@NotNull SCFrame parent, @NotNull Player viewer, @Nullable Object permission) { - int slot = 22; - if (permission != null) { - addNoPermissionComponent(permission, slot); - } else { - addNotVerifiedComponent(slot); - } - } + super(parent, viewer); + this.permission = permission; - private void addNotVerifiedComponent(int slot) { - SCComponent verified = new SCComponentImpl(lang("gui.warning.not.verified.title", getViewer()), - Collections.singletonList(lang("gui.warning.not.verified.lore", getViewer())), XMaterial.LEVER, slot); - add(verified); - } + } - private void addNoPermissionComponent(Object permission, int slot) { - List lore; - if (permission instanceof String) { - lore = Collections.singletonList(lang("gui.warning.no.permission.plugin.lore",getViewer())); - ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(getViewer().getUniqueId()); - if (((String) permission).contains("simpleclans.leader") && !cp.isLeader()) { - lore = Collections.singletonList(lang("gui.warning.no.permission.leader.lore",getViewer())); - } - } else { - RankPermission p = (RankPermission) permission; - String level = p.getPermissionLevel() == PermissionLevel.LEADER ? lang("leader",getViewer()) - : lang("trusted",getViewer()); - lore = Collections.singletonList(lang("gui.warning.no.permission.rank.lore",getViewer(), level, p.toString())); - } - SCComponent perm = new SCComponentImpl(lang("gui.warning.no.permission.title",getViewer()), lore, - XMaterial.BARRIER, slot); - add(perm); - } + @Override + public void createComponents() { - @Override - public @NotNull String getTitle() { - return lang("gui.warning.title",getViewer()); - } + for (int slot = 0; slot < 9; slot++) { - @Override - public int getSize() { - return 6 * 9; - } + if (slot == 4) + continue; + add(Components.getPanelComponent(slot)); + + } + + add(Components.getBackComponent(getParent(), 4, getViewer())); + + int slot = 22; + if (permission != null) { + + addNoPermissionComponent(permission, slot); + + } else { + + addNotVerifiedComponent(slot); + + } + + } + + private void addNotVerifiedComponent(int slot) { + + SCComponent verified = new SCComponentImpl(lang("gui.warning.not.verified.title", getViewer()), + Collections.singletonList(lang("gui.warning.not.verified.lore", getViewer())), XMaterial.LEVER, slot); + add(verified); + + } + + private void addNoPermissionComponent(Object permission, int slot) { + + List lore; + if (permission instanceof String) { + + lore = Collections.singletonList(lang("gui.warning.no.permission.plugin.lore", getViewer())); + ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(getViewer().getUniqueId()); + if (((String) permission).contains("simpleclans.leader") && !cp.isLeader()) { + + lore = Collections.singletonList(lang("gui.warning.no.permission.leader.lore", getViewer())); + + } + + } else { + + RankPermission p = (RankPermission) permission; + String level = p.getPermissionLevel() == PermissionLevel.LEADER ? lang("leader", getViewer()) + : lang("trusted", getViewer()); + lore = Collections + .singletonList(lang("gui.warning.no.permission.rank.lore", getViewer(), level, p.toString())); + + } + + SCComponent perm = new SCComponentImpl(lang("gui.warning.no.permission.title", getViewer()), lore, + XMaterial.BARRIER, slot); + add(perm); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.warning.title", getViewer()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanDetailsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanDetailsFrame.java index 49890c3e..067a1664 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanDetailsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanDetailsFrame.java @@ -22,19 +22,25 @@ import java.util.Objects; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class ClanDetailsFrame extends SCFrame { + private final Clan clan; public ClanDetailsFrame(@Nullable SCFrame parent, @NotNull Player viewer, @NotNull Clan clan) { + super(parent, viewer); this.clan = clan; + } @Override public void createComponents() { + for (int slot = 0; slot < 9; slot++) { + if (slot == 4) continue; add(Components.getPanelComponent(slot)); + } add(Components.getBackComponent(getParent(), 4, getViewer())); @@ -45,20 +51,24 @@ public class ClanDetailsFrame extends SCFrame { addBank(); addVerify(); addDisband(); + } private void addDisband() { + SCComponent disband = new SCComponentImpl(lang("gui.clandetails.disband.title", getViewer()), - Collections.singletonList(lang("gui.staffclandetails.disband.lore", getViewer())), - XMaterial.BARRIER, 34); - disband.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "mod disband", false, clan.getTag())); + Collections.singletonList(lang("gui.staffclandetails.disband.lore", getViewer())), XMaterial.BARRIER, + 34); + disband.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "mod disband", false, clan.getTag())); disband.setConfirmationRequired(ClickType.LEFT); disband.setPermission(ClickType.LEFT, "simpleclans.mod.disband"); add(disband); + } private void addVerify() { + boolean verified = clan.isVerified(); XMaterial material = verified ? XMaterial.REDSTONE_TORCH : XMaterial.LEVER; @@ -66,67 +76,87 @@ public class ClanDetailsFrame extends SCFrame { : lang("gui.clandetails.not.verified.title", getViewer()); List lore = verified ? null : new ArrayList<>(); if (!verified) { + lore.add(lang("gui.staffclandetails.not.verified.lore", getViewer())); + } + SCComponent verify = new SCComponentImpl(title, lore, material, 32); if (!verified) { + verify.setPermission(ClickType.LEFT, "simpleclans.mod.verify"); verify.setConfirmationRequired(ClickType.LEFT); - verify.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "mod verify", false, clan.getTag())); + verify.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "mod verify", false, clan.getTag())); + } + add(verify); + } private void addHome() { + List lore = new ArrayList<>(); lore.add(lang("gui.staffclandetails.home.lore.teleport", getViewer())); lore.add(lang("gui.staffclandetails.home.lore.set", getViewer())); SCComponent home = new SCComponentImpl(lang("gui.clandetails.home.title", getViewer()), lore, Objects.requireNonNull(XMaterial.MAGENTA_BED.parseMaterial()), 30); - home.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "mod home tp", false, clan.getTag())); + home.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "mod home tp", false, clan.getTag())); home.setPermission(ClickType.LEFT, "simpleclans.mod.hometp"); - home.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), - "mod home set", false, clan.getTag())); + home.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "mod home set", false, clan.getTag())); home.setPermission(ClickType.RIGHT, "simpleclans.mod.home"); home.setConfirmationRequired(ClickType.RIGHT); add(home); + } private void addRoster() { + SCComponent roster = new SCComponentImpl(lang("gui.clandetails.roster.title", getViewer()), - Collections.singletonList(lang("gui.staffclandetails.roster.lore", getViewer())), - XMaterial.PLAYER_HEAD, 28); + Collections.singletonList(lang("gui.staffclandetails.roster.lore", getViewer())), XMaterial.PLAYER_HEAD, + 28); List members = clan.getMembers(); if (members.size() != 0) { - OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer( - members.get((int) (Math.random() * members.size())).getUniqueId()); + + OfflinePlayer offlinePlayer = Bukkit + .getOfflinePlayer(members.get((int) (Math.random() * members.size())).getUniqueId()); Components.setOwningPlayer(roster.getItem(), offlinePlayer); + } roster.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new RosterFrame(getViewer(), this, clan, true))); add(roster); + } private void addBank() { - List lore = Collections.singletonList(lang("gui.clandetails.bank.balance.lore", getViewer(), clan.getBalanceFormatted())); - SCComponent bank = new SCComponentImpl(lang("gui.clandetails.bank.title", getViewer()), lore, XMaterial.GOLD_INGOT, 40); + List lore = Collections + .singletonList(lang("gui.clandetails.bank.balance.lore", getViewer(), clan.getBalanceFormatted())); + + SCComponent bank = new SCComponentImpl(lang("gui.clandetails.bank.title", getViewer()), lore, + XMaterial.GOLD_INGOT, 40); add(bank); + } @Override public @NotNull String getTitle() { - return lang("gui.clandetails.title", getViewer(), ChatUtils.stripColors(clan.getColorTag()), - clan.getName()); + + return lang("gui.clandetails.title", getViewer(), ChatUtils.stripColors(clan.getColorTag()), clan.getName()); + } @Override public int getSize() { + return 6 * 9; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanListFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanListFrame.java index f4ab6929..7860178f 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanListFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/ClanListFrame.java @@ -20,89 +20,132 @@ import java.util.stream.Collectors; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; public class ClanListFrame extends SCFrame { - private final Type type; - private final @Nullable OfflinePlayer toPlace; - private List clans; - private final Paginator paginator; - public ClanListFrame(@Nullable SCFrame parent, @NotNull Player viewer, @NotNull Type type, @Nullable OfflinePlayer toPlace) { - super(parent, viewer); - this.type = type; - this.toPlace = toPlace; - SimpleClans plugin = SimpleClans.getInstance(); - clans = plugin.getClanManager().getClans(); - if (type == Type.UNVERIFIED) { - clans = clans.stream().filter(c -> !c.isVerified()).collect(Collectors.toList()); - } - paginator = new Paginator(getSize() - 9, clans); - plugin.getClanManager().sortClansByName(clans, true); - } + private final Type type; + private final @Nullable OfflinePlayer toPlace; + private List clans; + private final Paginator paginator; - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 2 || slot == 6 || slot == 7) - continue; - add(Components.getPanelComponent(slot)); - } - add(Components.getBackComponent(getParent(), 2, getViewer())); + public ClanListFrame(@Nullable SCFrame parent, @NotNull Player viewer, @NotNull Type type, + @Nullable OfflinePlayer toPlace) + { - add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); - add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + super(parent, viewer); + this.type = type; + this.toPlace = toPlace; + SimpleClans plugin = SimpleClans.getInstance(); + clans = plugin.getClanManager().getClans(); + if (type == Type.UNVERIFIED) { - int slot = 9; - for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { - Clan clan = clans.get(i); - SCComponent c = Components.getClanComponent(this, getViewer(), clan, slot, false); - if (type != Type.PLACE) { - c.setListener(ClickType.LEFT, () -> - InventoryDrawer.open(new ClanDetailsFrame(this, getViewer(), clan))); - } else { - if (toPlace != null) { - c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "mod place", false, toPlace.getName(), clan.getTag())); - c.setConfirmationRequired(ClickType.LEFT); - c.setPermission(ClickType.LEFT, "simpleclans.mod.place"); - } - } - add(c); - slot++; - } - } + clans = clans.stream().filter(c -> !c.isVerified()).collect(Collectors.toList()); - private void previousPage() { - if (paginator.previousPage()) { - updateFrame(); - } - } + } - private void nextPage() { - if (paginator.nextPage()) { - updateFrame(); - } - } + paginator = new Paginator(getSize() - 9, clans); + plugin.getClanManager().sortClansByName(clans, true); - private void updateFrame() { - InventoryDrawer.open(this); - } + } - @Override - public @NotNull String getTitle() { - if (type == Type.PLACE && toPlace != null) { - return lang("gui.staff.clanlist.toplace.title", getViewer(), toPlace.getName()); - } - if (type == Type.UNVERIFIED) { - return lang("gui.staff.clanlist.unverified.title", getViewer(), clans.size()); - } - return lang("gui.clanlist.title", getViewer(), clans.size()); - } + @Override + public void createComponents() { - @Override - public int getSize() { - return 6 * 9; - } + for (int slot = 0; slot < 9; slot++) { + + if (slot == 2 || slot == 6 || slot == 7) + continue; + add(Components.getPanelComponent(slot)); + + } + + add(Components.getBackComponent(getParent(), 2, getViewer())); + + add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); + add(Components.getNextPageComponent(7, this::nextPage, paginator, getViewer())); + + int slot = 9; + for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + + Clan clan = clans.get(i); + SCComponent c = Components.getClanComponent(this, getViewer(), clan, slot, false); + if (type != Type.PLACE) { + + c.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new ClanDetailsFrame(this, getViewer(), clan))); + + } else { + + if (toPlace != null) { + + c.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "mod place", + false, toPlace.getName(), clan.getTag())); + c.setConfirmationRequired(ClickType.LEFT); + c.setPermission(ClickType.LEFT, "simpleclans.mod.place"); + + } + + } + + add(c); + slot++; + + } + + } + + private void previousPage() { + + if (paginator.previousPage()) { + + updateFrame(); + + } + + } + + private void nextPage() { + + if (paginator.nextPage()) { + + updateFrame(); + + } + + } + + private void updateFrame() { + + InventoryDrawer.open(this); + + } + + @Override + public @NotNull String getTitle() { + + if (type == Type.PLACE && toPlace != null) { + + return lang("gui.staff.clanlist.toplace.title", getViewer(), toPlace.getName()); + + } + + if (type == Type.UNVERIFIED) { + + return lang("gui.staff.clanlist.unverified.title", getViewer(), clans.size()); + + } + + return lang("gui.clanlist.title", getViewer(), clans.size()); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } + + public enum Type { + ALL, UNVERIFIED, PLACE + } - public enum Type { - ALL, UNVERIFIED, PLACE - } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerDetailsFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerDetailsFrame.java index 81d60266..be4fa5a5 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerDetailsFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerDetailsFrame.java @@ -16,105 +16,126 @@ import static net.sacredlabyrinth.phaed.simpleclans.ui.frames.staff.ClanListFram public class PlayerDetailsFrame extends SCFrame { - private final OfflinePlayer subject; - private final String subjectName; + private final OfflinePlayer subject; + private final String subjectName; - public PlayerDetailsFrame(@NotNull Player viewer, SCFrame parent, @NotNull OfflinePlayer subject) { - super(parent, viewer); - this.subject = subject; - subjectName = SimpleClans.getInstance().getClanManager().getCreateClanPlayer(subject.getUniqueId()).getName(); - } + public PlayerDetailsFrame(@NotNull Player viewer, SCFrame parent, @NotNull OfflinePlayer subject) { - @Override - public void createComponents() { - for (int slot = 0; slot < 9; slot++) { - if (slot == 4) - continue; - add(Components.getPanelComponent(slot)); - } + super(parent, viewer); + this.subject = subject; + subjectName = SimpleClans.getInstance().getClanManager().getCreateClanPlayer(subject.getUniqueId()).getName(); - add(Components.getBackComponent(getParent(), 4, getViewer())); - add(Components.getPlayerComponent(this, getViewer(), subject, 13, false)); + } - addBanUnban(); - addPlace(); - addResetKDR(); - addPurge(); - addPromoteDemote(); - } + @Override + public void createComponents() { - private void addPromoteDemote() { - SCComponent promoteDemote = new SCComponentImpl(lang("gui.playerdetails.promote.demote.title",getViewer()), - Arrays.asList(lang("gui.playerdetails.promote.lore.left.click", getViewer()), - lang("gui.playerdetails.demote.lore.right.click", getViewer())), - XMaterial.GUNPOWDER, 28); - promoteDemote.setConfirmationRequired(ClickType.LEFT); - promoteDemote.setListener(ClickType.LEFT, - () -> InventoryController.runSubcommand(getViewer(), "admin promote", true, subjectName)); - promoteDemote.setPermission(ClickType.LEFT, "simpleclans.admin.promote"); - promoteDemote.setListener(ClickType.RIGHT, - () -> InventoryController.runSubcommand(getViewer(), "admin demote", true, subjectName)); - promoteDemote.setConfirmationRequired(ClickType.RIGHT); - add(promoteDemote); - promoteDemote.setPermission(ClickType.RIGHT, "simpleclans.admin.demote"); - } + for (int slot = 0; slot < 9; slot++) { - private void addPurge() { - SCComponent purge = new SCComponentImpl.Builder(XMaterial.LAVA_BUCKET).withSlot(34).withDisplayName( - lang("gui.playerdetails.purge.title", getViewer())).withLoreLine( - lang("gui.playerdetails.purge.lore", getViewer())).build(); - purge.setConfirmationRequired(ClickType.LEFT); - purge.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "admin purge", false, subjectName)); - purge.setPermission(ClickType.LEFT, "simpleclans.admin.purge"); - add(purge); - } + if (slot == 4) + continue; + add(Components.getPanelComponent(slot)); - private void addResetKDR() { - SCComponent resetKdr = new SCComponentImpl.Builder(XMaterial.ANVIL) - .withSlot(30).withDisplayName(lang("gui.main.reset.kdr.title", getViewer())) - .withLoreLine(lang("gui.playerdetails.resetkdr.lore", getViewer())).build(); - resetKdr.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "admin resetkdr", false, subjectName)); - resetKdr.setConfirmationRequired(ClickType.LEFT); - resetKdr.setPermission(ClickType.LEFT, "simpleclans.admin.resetkdr"); - add(resetKdr); - } + } - private void addPlace() { - SCComponent place = new SCComponentImpl.Builder(XMaterial.MINECART).withSlot(32) - .withDisplayName(lang("gui.playerdetails.place.title", getViewer())) - .withLoreLine(lang("gui.playerdetails.place.lore", getViewer())).build(); - place.setPermission(ClickType.LEFT, "simpleclans.mod.place"); - place.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new ClanListFrame(this, getViewer(), - Type.PLACE, subject))); - add(place); - } + add(Components.getBackComponent(getParent(), 4, getViewer())); + add(Components.getPlayerComponent(this, getViewer(), subject, 13, false)); - private void addBanUnban() { - SCComponent banUnban = new SCComponentImpl.Builder(XMaterial.BARRIER).withSlot(40) - .withDisplayName(lang("gui.playerdetails.ban.unban.title", getViewer())) - .withLore(Arrays.asList(lang("gui.playerdetails.ban.left.click", getViewer()), - lang("gui.playerdetails.unban.right.click", getViewer()))).build(); - banUnban.setConfirmationRequired(ClickType.LEFT); - banUnban.setConfirmationRequired(ClickType.RIGHT); - banUnban.setPermission(ClickType.LEFT, "simpleclans.mod.ban"); - banUnban.setPermission(ClickType.RIGHT, "simpleclans.mod.ban"); - banUnban.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), - "mod ban", false, subjectName)); - banUnban.setListener(ClickType.RIGHT, () -> InventoryController.runSubcommand(getViewer(), - "mod unban", false, subjectName)); - add(banUnban); - } + addBanUnban(); + addPlace(); + addResetKDR(); + addPurge(); + addPromoteDemote(); - @Override - public @NotNull String getTitle() { - return lang("gui.playerdetails.title", getViewer(), subjectName); - } + } - @Override - public int getSize() { - return 6 * 9; - } + private void addPromoteDemote() { + + SCComponent promoteDemote = new SCComponentImpl(lang("gui.playerdetails.promote.demote.title", getViewer()), + Arrays.asList(lang("gui.playerdetails.promote.lore.left.click", getViewer()), + lang("gui.playerdetails.demote.lore.right.click", getViewer())), + XMaterial.GUNPOWDER, 28); + promoteDemote.setConfirmationRequired(ClickType.LEFT); + promoteDemote.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "admin promote", true, subjectName)); + promoteDemote.setPermission(ClickType.LEFT, "simpleclans.admin.promote"); + promoteDemote.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "admin demote", true, subjectName)); + promoteDemote.setConfirmationRequired(ClickType.RIGHT); + add(promoteDemote); + promoteDemote.setPermission(ClickType.RIGHT, "simpleclans.admin.demote"); + + } + + private void addPurge() { + + SCComponent purge = new SCComponentImpl.Builder(XMaterial.LAVA_BUCKET).withSlot(34) + .withDisplayName(lang("gui.playerdetails.purge.title", getViewer())) + .withLoreLine(lang("gui.playerdetails.purge.lore", getViewer())).build(); + purge.setConfirmationRequired(ClickType.LEFT); + purge.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "admin purge", false, subjectName)); + purge.setPermission(ClickType.LEFT, "simpleclans.admin.purge"); + add(purge); + + } + + private void addResetKDR() { + + SCComponent resetKdr = new SCComponentImpl.Builder(XMaterial.ANVIL).withSlot(30) + .withDisplayName(lang("gui.main.reset.kdr.title", getViewer())) + .withLoreLine(lang("gui.playerdetails.resetkdr.lore", getViewer())).build(); + resetKdr.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "admin resetkdr", false, subjectName)); + resetKdr.setConfirmationRequired(ClickType.LEFT); + resetKdr.setPermission(ClickType.LEFT, "simpleclans.admin.resetkdr"); + add(resetKdr); + + } + + private void addPlace() { + + SCComponent place = new SCComponentImpl.Builder(XMaterial.MINECART).withSlot(32) + .withDisplayName(lang("gui.playerdetails.place.title", getViewer())) + .withLoreLine(lang("gui.playerdetails.place.lore", getViewer())).build(); + place.setPermission(ClickType.LEFT, "simpleclans.mod.place"); + place.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new ClanListFrame(this, getViewer(), Type.PLACE, subject))); + add(place); + + } + + private void addBanUnban() { + + SCComponent banUnban = new SCComponentImpl.Builder(XMaterial.BARRIER).withSlot(40) + .withDisplayName(lang("gui.playerdetails.ban.unban.title", getViewer())) + .withLore(Arrays.asList(lang("gui.playerdetails.ban.left.click", getViewer()), + lang("gui.playerdetails.unban.right.click", getViewer()))) + .build(); + banUnban.setConfirmationRequired(ClickType.LEFT); + banUnban.setConfirmationRequired(ClickType.RIGHT); + banUnban.setPermission(ClickType.LEFT, "simpleclans.mod.ban"); + banUnban.setPermission(ClickType.RIGHT, "simpleclans.mod.ban"); + banUnban.setListener(ClickType.LEFT, + () -> InventoryController.runSubcommand(getViewer(), "mod ban", false, subjectName)); + banUnban.setListener(ClickType.RIGHT, + () -> InventoryController.runSubcommand(getViewer(), "mod unban", false, subjectName)); + add(banUnban); + + } + + @Override + public @NotNull String getTitle() { + + return lang("gui.playerdetails.title", getViewer(), subjectName); + + } + + @Override + public int getSize() { + + return 6 * 9; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerListFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerListFrame.java index 636fea9f..fa94ebe2 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerListFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/PlayerListFrame.java @@ -28,18 +28,24 @@ public class PlayerListFrame extends SCFrame { private List players; public PlayerListFrame(@NotNull Player viewer, @Nullable SCFrame parent, boolean onlineOnly) { + super(parent, viewer); this.onlineOnly = onlineOnly; loadPlayers(); + } @Override public void createComponents() { + for (int slot = 0; slot < 9; slot++) { + if (slot == 2 || slot == 6 || slot == 7) continue; add(Components.getPanelComponent(slot)); + } + add(Components.getBackComponent(getParent(), 2, getViewer())); add(Components.getPreviousPageComponent(6, this::previousPage, paginator, getViewer())); @@ -47,54 +53,78 @@ public class PlayerListFrame extends SCFrame { int slot = 9; for (int i = paginator.getMinIndex(); paginator.isValidIndex(i); i++) { + OfflinePlayer player = players.get(i); SCComponent c = Components.getPlayerComponent(this, getViewer(), player, slot, false); - c.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new PlayerDetailsFrame(getViewer(), this, player))); + c.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new PlayerDetailsFrame(getViewer(), this, player))); add(c); slot++; + } + } private void loadPlayers() { + if (onlineOnly) { + players = new ArrayList<>(Bukkit.getOnlinePlayers()); + } else { - players = Stream.concat( - SimpleClans.getInstance().getClanManager().getAllClanPlayers().stream(). - map(cp -> Bukkit.getOfflinePlayer(cp.getUniqueId())), - Bukkit.getOnlinePlayers().stream()) + + players = Stream + .concat(SimpleClans.getInstance().getClanManager().getAllClanPlayers().stream() + .map(cp -> Bukkit.getOfflinePlayer(cp.getUniqueId())), Bukkit.getOnlinePlayers().stream()) .distinct().collect(Collectors.toList()); + } + players = players.stream().filter(p -> p.getName() != null).collect(Collectors.toList()); players.sort(Comparator.comparing(OfflinePlayer::getName)); paginator = new Paginator(getSize() - 9, players.size()); + } private void previousPage() { + if (paginator.previousPage()) { + updateFrame(); + } + } private void nextPage() { + if (paginator.nextPage()) { + updateFrame(); + } + } private void updateFrame() { + InventoryDrawer.open(this); + } @Override public @NotNull String getTitle() { + return lang("gui.player.list.title", getViewer()); + } @Override public int getSize() { + return 6 * 9; + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/StaffFrame.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/StaffFrame.java index 82facdfd..4ddff288 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/StaffFrame.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/ui/frames/staff/StaffFrame.java @@ -17,25 +17,34 @@ import static net.sacredlabyrinth.phaed.simpleclans.ui.frames.staff.ClanListFram public class StaffFrame extends SCFrame { public StaffFrame(@Nullable SCFrame parent, @NotNull Player viewer) { + super(parent, viewer); + } @Override public @NotNull String getTitle() { + return lang("gui.staff.title", getViewer()); + } @Override public int getSize() { + return 3 * 9; + } @Override public void createComponents() { + for (int slot = 0; slot < 9; slot++) { + if (slot == 4) continue; add(Components.getPanelComponent(slot)); + } add(Components.getBackComponent(getParent(), 4, getViewer())); @@ -43,21 +52,25 @@ public class StaffFrame extends SCFrame { addPlayers(); addGlobalFf(); addReload(); + } private void addClans() { + SCComponent clanList = new SCComponentImpl.Builder(XMaterial.PURPLE_BANNER) .withDisplayName(lang("gui.main.clan.list.title", getViewer())).withSlot(9) .withLoreLine(lang("gui.staff.clan.list.lore.left.click", getViewer())) .withLoreLine(lang("gui.staff.clan.list.lore.right.click", getViewer())).build(); - clanList.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new ClanListFrame(this, getViewer(), - Type.ALL, null))); - clanList.setListener(ClickType.RIGHT, () -> InventoryDrawer.open(new ClanListFrame(this, getViewer(), - Type.UNVERIFIED, null))); + clanList.setListener(ClickType.LEFT, + () -> InventoryDrawer.open(new ClanListFrame(this, getViewer(), Type.ALL, null))); + clanList.setListener(ClickType.RIGHT, + () -> InventoryDrawer.open(new ClanListFrame(this, getViewer(), Type.UNVERIFIED, null))); add(clanList); + } private void addPlayers() { + SCComponent players = new SCComponentImpl.Builder(XMaterial.WHITE_BANNER) .withDisplayName(lang("gui.staff.player.list.title", getViewer())).withSlot(10) .withLoreLine(lang("gui.staff.player.list.lore.left.click", getViewer())) @@ -65,20 +78,23 @@ public class StaffFrame extends SCFrame { players.setListener(ClickType.LEFT, () -> InventoryDrawer.open(new PlayerListFrame(getViewer(), this, false))); players.setListener(ClickType.RIGHT, () -> InventoryDrawer.open(new PlayerListFrame(getViewer(), this, true))); add(players); + } private void addReload() { + SCComponent reload = new SCComponentImpl.Builder(XMaterial.SPAWNER) .withDisplayName(lang("gui.staff.reload.title", getViewer())).withSlot(17) .withLoreLine(lang("gui.staff.reload.lore", getViewer())).build(); reload.setPermission(ClickType.LEFT, "simpleclans.admin.reload"); reload.setConfirmationRequired(ClickType.LEFT); - reload.setListener(ClickType.LEFT, () -> - InventoryController.runSubcommand(getViewer(), "admin reload", false)); + reload.setListener(ClickType.LEFT, () -> InventoryController.runSubcommand(getViewer(), "admin reload", false)); add(reload); + } private void addGlobalFf() { + SettingsManager sm = SimpleClans.getInstance().getSettingsManager(); boolean globalffAllowed = sm.is(GLOBAL_FRIENDLY_FIRE); String status = globalffAllowed ? lang("allowed", getViewer()) : lang("auto", getViewer()); @@ -88,14 +104,23 @@ public class StaffFrame extends SCFrame { .withLoreLine(lang("gui.staff.global.ff.lore.toggle", getViewer())).build(); globalFf.setPermission(ClickType.LEFT, "simpleclans.mod.globalff"); globalFf.setListener(ClickType.LEFT, () -> { + String arg; if (globalffAllowed) { + arg = "auto"; + } else { + arg = "allow"; + } + InventoryController.runSubcommand(getViewer(), "mod globalff", true, arg); + }); add(globalFf); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtils.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtils.java index 55dea9bc..ee50cd92 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtils.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtils.java @@ -23,98 +23,145 @@ public class ChatUtils { private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("(%([A-Za-z]+)%)"); private static final Pattern HEX_COLOR_PATTERN = Pattern.compile("&#([0-9A-Fa-f]{6})"); private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("[&§][0-9a-fA-Fk-orK-OR]"); - private static final Pattern HEX_STRIP_COLOR_PATTERN = Pattern.compile("([&§]#[0-9A-Fa-f]{6})|([&§][0-9a-fA-Fk-orK-OR])|([&§]x([&§][a-fA-F0-9]){6})"); + private static final Pattern HEX_STRIP_COLOR_PATTERN = Pattern + .compile("([&§]#[0-9A-Fa-f]{6})|([&§][0-9a-fA-Fk-orK-OR])|([&§]x([&§][a-fA-F0-9]){6})"); static { + try { + ChatColor.class.getDeclaredMethod("of", String.class); HEX_COLOR_SUPPORT = true; + } catch (NoSuchMethodException e) { + HEX_COLOR_SUPPORT = false; + } + } private ChatUtils() { + } public static String getColorByChar(char character) { + ChatColor color = ChatColor.getByChar(character); return color != null ? color.toString() : Character.toString(character); + } public static String parseColors(@NotNull String text) { + // Special thanks to the Spigot community! // https://www.spigotmc.org/threads/hex-color-code-translate.449748/#post-3867795 if (HEX_COLOR_SUPPORT) { + Matcher matcher = HEX_COLOR_PATTERN.matcher(text); StringBuffer buffer = new StringBuffer(); while (matcher.find()) { + matcher.appendReplacement(buffer, ChatColor.of("#" + matcher.group(1)).toString()); + } + text = matcher.appendTail(buffer).toString(); + } + return ChatColor.translateAlternateColorCodes('&', text); + } public static String stripColors(String text) { + Pattern pattern = HEX_COLOR_SUPPORT ? HEX_STRIP_COLOR_PATTERN : STRIP_COLOR_PATTERN; Matcher matcher = pattern.matcher(text); StringBuffer buffer = new StringBuffer(); while (matcher.find()) { + matcher.appendReplacement(buffer, ""); + } + return matcher.appendTail(buffer).toString(); + } public static String getLastColorCode(String msg) { + if (msg.length() < 2) { + return ""; + } String one = msg.substring(msg.length() - 2, msg.length() - 1); String two = msg.substring(msg.length() - 1); if (one.equals("§")) { + return one + two; + } if (one.equals("&")) { + return getColorByChar(two.charAt(0)); + } return ""; + } public static BaseComponent[] toBaseComponents(@Nullable CommandSender receiver, @NotNull String text) { + ComponentBuilder builder = new ComponentBuilder(""); ArrayList placeholders = new ArrayList<>(); Matcher matcher = PLACEHOLDER_PATTERN.matcher(text); while (matcher.find()) { + placeholders.add(matcher.group(0)); + } + String[] split = PLACEHOLDER_PATTERN.split(text); for (int i = 0; i < split.length; i++) { + builder.append(split[i]); if (i >= placeholders.size()) { + continue; + } + appendPlaceholder(receiver, builder, placeholders.get(i)); + } return builder.create(); + } @SuppressWarnings("deprecation") - private static void appendPlaceholder(@Nullable CommandSender receiver, ComponentBuilder builder, String placeholder) { + private static void appendPlaceholder(@Nullable CommandSender receiver, ComponentBuilder builder, + String placeholder) + { + Matcher matcher = PLACEHOLDER_PATTERN.matcher(placeholder); if (!matcher.find()) { + return; + } + placeholder = matcher.group(2); builder.retain(FormatRetention.FORMATTING).append(lang("clickable." + placeholder, receiver)) - .event(new ClickEvent(RUN_COMMAND, "/" + placeholder)) - .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText( - (lang("hover.click.to." + placeholder, receiver))))); + .event(new ClickEvent(RUN_COMMAND, "/" + placeholder)).event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + TextComponent.fromLegacyText((lang("hover.click.to." + placeholder, receiver))))); + } /** @@ -125,42 +172,64 @@ public class ChatUtils { */ @NotNull public static String getLastColors(@NotNull String input) { + StringBuilder result = new StringBuilder(); int length = input.length(); for (int index = length - 1; index > -1; index--) { + boolean found = false; String color = String.valueOf(input.charAt(index)); if (ChatColor.ALL_CODES.contains(color)) { + if (index - 1 >= 0) { + char section = input.charAt(index - 1); if (section == COLOR_CHAR) { + index--; result.insert(0, section + color); found = true; + } + } + } + if (!found && result.length() != 0) { + break; + } + } return result.toString(); + } public static void applyLastColorToFollowingLines(@NotNull List lines) { + if (lines.get(0).isEmpty() || lines.get(0).charAt(0) != COLOR_CHAR) { + lines.set(0, ChatColor.WHITE + lines.get(0)); + } + for (int i = 1; i < lines.size(); i++) { + final String pLine = lines.get(i - 1); final String subLine = lines.get(i); if (subLine.isEmpty() || subLine.charAt(0) != COLOR_CHAR) { + lines.set(i, getLastColors(pLine) + subLine); + } + } + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/CurrencyFormat.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/CurrencyFormat.java index a53cc59f..b5a791d0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/CurrencyFormat.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/CurrencyFormat.java @@ -11,11 +11,16 @@ public class CurrencyFormat { private static final NumberFormat fallbackFormat = NumberFormat.getCurrencyInstance(); public static String format(double value) { + PermissionsManager permissionsManager = plugin.getPermissionsManager(); if (permissionsManager.hasEconomy()) { + return permissionsManager.format(value); + } + return fallbackFormat.format(value); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/DateFormat.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/DateFormat.java index 819c5b7a..585db891 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/DateFormat.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/DateFormat.java @@ -13,17 +13,25 @@ public class DateFormat { private static SimpleDateFormat format; static { + String pattern = plugin.getSettingsManager().getString(DATE_TIME_PATTERN); try { + format = new SimpleDateFormat(pattern); + } catch (IllegalArgumentException ex) { + plugin.getLogger().warning(String.format("%s is not a valid pattern!", (pattern))); format = new SimpleDateFormat("HH:mm - dd/MM/yyyy"); + } + } public static String formatDateTime(long date) { + return format.format(new Date(date)); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/KDRFormat.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/KDRFormat.java index 3286c1d0..d067cb53 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/KDRFormat.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/KDRFormat.java @@ -10,30 +10,46 @@ import java.text.ParseException; * @author RoinujNosde */ public class KDRFormat { + private static final DecimalFormat FORMATTER = new DecimalFormat("#.##"); static { + FORMATTER.setParseBigDecimal(true); + } - private KDRFormat() {} + private KDRFormat() { + + } @NotNull public static String format(float kdr) { + return FORMATTER.format(kdr); + } @NotNull public static BigDecimal parse(String kdr) { + try { + return (BigDecimal) FORMATTER.parse(kdr); + } catch (ParseException e) { + return new BigDecimal("-1"); + } + } @NotNull public static BigDecimal toBigDecimal(float kdr) { + return parse(format(kdr)); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtils.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtils.java index f3b3a723..ce072752 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtils.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtils.java @@ -8,46 +8,70 @@ import java.util.Map; public final class ObjectUtils { private ObjectUtils() { + } public static void updateFields(Object origin, Object destination) throws IllegalAccessException { + if (origin.getClass() != destination.getClass()) { + throw new IllegalArgumentException("origin and destination must be of the same type"); + } + Field[] fields = origin.getClass().getDeclaredFields(); for (Field field : fields) { + field.setAccessible(true); if (Modifier.isFinal(field.getModifiers())) { + copyValues(field, field.get(origin), field.get(destination)); continue; + } + field.set(destination, field.get(origin)); + } + } private static boolean isPrimitive(Field field) { + Class type = field.getType(); return type.isPrimitive() || Number.class.isAssignableFrom(type) || type == String.class; + } - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) private static void copyValues(Field field, Object originValue, Object destValue) { + if (isPrimitive(field)) { + return; + } + if (originValue instanceof Collection) { + Collection destColl = (Collection) destValue; destColl.clear(); destColl.addAll((Collection) originValue); return; + } + if (originValue instanceof Map) { + Map destMap = (Map) destValue; destMap.clear(); destMap.putAll((Map) originValue); return; + } + throw new UnsupportedOperationException(String.format("unknown field type: %s", originValue.getClass())); + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/Paginator.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/Paginator.java index 1202c085..0cc20872 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/Paginator.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/Paginator.java @@ -10,132 +10,179 @@ import java.util.Collection; * */ public class Paginator { - - private int currentPage; - private final int sizePerPage; - private int totalElements; - private Collection collection; - public Paginator(int sizePerPage, int totalElements) { - if (sizePerPage < 1) { - throw new IllegalArgumentException("sizePerPage cannot be less than 1"); - } - if (totalElements < 0) { - throw new IllegalArgumentException("totalElements cannot be less than 0"); - } - this.sizePerPage = sizePerPage; - this.totalElements = totalElements; - } + private int currentPage; + private final int sizePerPage; + private int totalElements; + private Collection collection; - public Paginator(int sizePerPage, @NotNull Collection collection) { - if (sizePerPage < 1) { - throw new IllegalArgumentException("sizePerPage cannot be less than 1"); - } - this.sizePerPage = sizePerPage; - this.collection = collection; - } - - /** - * author: RoinujNosde - * @return the total elements - */ - public int getTotalElements() { - if (collection != null) { - return collection.size(); - } - return totalElements; - } - - /** - * author: RoinujNosde - * @return the size per page - * - */ - public int getSizePerPage() { - return sizePerPage; - } - - /** - * author: RoinujNosde - * @return the minimal index based on the current page - * - */ - public int getMinIndex() { - return getCurrentPage() * getSizePerPage(); - } - - /** - * author: RoinujNosde - * @return the max index based on the current page - * - */ - public int getMaxIndex() { - return (getCurrentPage() + 1) * getSizePerPage(); - } - - /** - * author: RoinujNosde - * - * @return the current page, starting at 0 - */ - public int getCurrentPage() { - return currentPage; - } - - /** - * Increases the page number if there are elements to display - * - *

- * author: RoinujNosde - *

- */ - public boolean nextPage() { - if (!hasNextPage()) { - return false; - } - currentPage++; - return true; - } + public Paginator(int sizePerPage, int totalElements) { - /** - * @return if there is a next page - */ - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public boolean hasNextPage() { - return !((sizePerPage * (currentPage + 1)) > getTotalElements()); - } + if (sizePerPage < 1) { - /** - * Decreases the page number if current {@literal >} 0 - *

- * author: RoinujNosde - *

- */ - public boolean previousPage() { - if (hasPreviousPage()) { - currentPage--; - return true; - } - return false; - } + throw new IllegalArgumentException("sizePerPage cannot be less than 1"); - /** - * @return if there is a previous page - */ - public boolean hasPreviousPage() { - return currentPage > 0; - } + } + + if (totalElements < 0) { + + throw new IllegalArgumentException("totalElements cannot be less than 0"); + + } + + this.sizePerPage = sizePerPage; + this.totalElements = totalElements; - /** - * - * @param index the index - * @return if this index will not cause any IndexOutOfBoundsException - * - *

- * author: RoinujNosde - *

- */ - public boolean isValidIndex(int index) { - return index >= getMinIndex() && index < getMaxIndex() && index < getTotalElements(); } + + public Paginator(int sizePerPage, @NotNull Collection collection) { + + if (sizePerPage < 1) { + + throw new IllegalArgumentException("sizePerPage cannot be less than 1"); + + } + + this.sizePerPage = sizePerPage; + this.collection = collection; + + } + + /** + * author: RoinujNosde + * + * @return the total elements + */ + public int getTotalElements() { + + if (collection != null) { + + return collection.size(); + + } + + return totalElements; + + } + + /** + * author: RoinujNosde + * + * @return the size per page + * + */ + public int getSizePerPage() { + + return sizePerPage; + + } + + /** + * author: RoinujNosde + * + * @return the minimal index based on the current page + * + */ + public int getMinIndex() { + + return getCurrentPage() * getSizePerPage(); + + } + + /** + * author: RoinujNosde + * + * @return the max index based on the current page + * + */ + public int getMaxIndex() { + + return (getCurrentPage() + 1) * getSizePerPage(); + + } + + /** + * author: RoinujNosde + * + * @return the current page, starting at 0 + */ + public int getCurrentPage() { + + return currentPage; + + } + + /** + * Increases the page number if there are elements to display + * + *

+ * author: RoinujNosde + *

+ */ + public boolean nextPage() { + + if (!hasNextPage()) { + + return false; + + } + + currentPage++; + return true; + + } + + /** + * @return if there is a next page + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public boolean hasNextPage() { + + return !((sizePerPage * (currentPage + 1)) > getTotalElements()); + + } + + /** + * Decreases the page number if current {@literal >} 0 + *

+ * author: RoinujNosde + *

+ */ + public boolean previousPage() { + + if (hasPreviousPage()) { + + currentPage--; + return true; + + } + + return false; + + } + + /** + * @return if there is a previous page + */ + public boolean hasPreviousPage() { + + return currentPage > 0; + + } + + /** + * + * @param index the index + * @return if this index will not cause any IndexOutOfBoundsException + * + *

+ * author: RoinujNosde + *

+ */ + public boolean isValidIndex(int index) { + + return index >= getMinIndex() && index < getMaxIndex() && index < getTotalElements(); + + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/RankingNumberResolver.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/RankingNumberResolver.java index 4192f521..03bc12d5 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/RankingNumberResolver.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/RankingNumberResolver.java @@ -23,42 +23,62 @@ public class RankingNumberResolver> { private final Map positions = new HashMap<>(); public RankingNumberResolver(@NotNull List elements, @NotNull Function orderBy, boolean asc, - @NotNull RankingType type) { + @NotNull RankingType type) + { + this.elements = elements; this.orderBy = orderBy; this.type = type; this.asc = asc; loadPositions(); + } private void loadPositions() { + Comparator comparator = Comparator.comparing(orderBy); elements.sort(asc ? comparator : comparator.reversed()); if (type == RankingType.DENSE) { + E previous = null; int position = 1; for (E e : elements) { + if (previous == null) { + positions.put(e, position); previous = e; continue; + } + if (comparator.compare(previous, e) != 0) { + position++; + } + previous = e; positions.put(e, position); + } + } + } public int getRankingNumber(@NotNull E element) { + if (type == RankingType.DENSE) { + return positions.getOrDefault(element, -1); + } + int indexOf = elements.indexOf(element); return indexOf == -1 ? -1 : indexOf + 1; + } public enum RankingType { @@ -71,4 +91,5 @@ public class RankingNumberResolver> { */ ORDINAL } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/TagValidator.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/TagValidator.java index 7fbd6ec6..5b82dc6c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/TagValidator.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/TagValidator.java @@ -14,6 +14,7 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; public class TagValidator { + private final SettingsManager settings; private final PermissionsManager permissions; @Nullable @@ -22,13 +23,17 @@ public class TagValidator { private String error; public TagValidator(@NotNull SettingsManager settings, @NotNull PermissionsManager permissions) { + this.settings = settings; this.permissions = permissions; String regex = settings.getString(TAG_REGEX); if (!regex.isEmpty()) { + tagRegex = Pattern.compile(regex); + } + } /** @@ -39,55 +44,92 @@ public class TagValidator { * @return error message if any */ public Optional validate(@NotNull Player player, @NotNull String tag) { + error = null; String cleanTag = Helper.cleanTag(tag); if (tag.length() > 255 && settings.is(MYSQL_ENABLE)) { + return Optional.of(lang("your.clan.color.tag.cannot.be.longer.than.characters", player, 255)); + } if (!permissions.has(player, "simpleclans.mod.bypass")) { + if (settings.isDisallowedWord(cleanTag)) { + error = lang("that.tag.name.is.disallowed", player); + } + if (!permissions.has(player, "simpleclans.leader.coloredtag") && tag.contains("&")) { + error = lang("your.tag.cannot.contain.color.codes", player); + } + int minLength = settings.getInt(TAG_MIN_LENGTH); if (cleanTag.length() < minLength) { + error = lang("your.clan.tag.must.be.longer.than.characters", player, minLength); + } + int maxLength = settings.getInt(TAG_MAX_LENGTH); if (cleanTag.length() > maxLength) { + error = lang("your.clan.tag.cannot.be.longer.than.characters", player, maxLength); + } + if (settings.hasDisallowedColor(tag)) { - error = lang("your.tag.cannot.contain.the.following.colors", player, settings.getDisallowedColorString()); + + error = lang("your.tag.cannot.contain.the.following.colors", player, + settings.getDisallowedColorString()); + } + } if (tagRegex == null) { + checkAlphabet(player, cleanTag); + } else if (!tagRegex.matcher(cleanTag).matches()) { + error = lang("your.tag.doesnt.meet.the.requirements", player); + } return Optional.ofNullable(error); + } private void checkAlphabet(@NotNull Player player, @NotNull String cleanTag) { + String alphabetError = lang("your.clan.tag.can.only.contain.letters.numbers.and.color.codes", player); if (settings.is(ACCEPT_OTHER_ALPHABETS_LETTERS)) { + for (char c : cleanTag.toCharArray()) { + if (!Character.isLetterOrDigit(c) || Character.isSpaceChar(c)) { + error = alphabetError; return; + } + } + return; + } if (!cleanTag.matches("[0-9a-zA-Z]*")) { + error = alphabetError; + } + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateChecker.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateChecker.java index 14878732..d5433108 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateChecker.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateChecker.java @@ -21,65 +21,88 @@ import java.util.logging.Level; */ public class UpdateChecker { - private final SimpleClans plugin; - private static final String LATEST_VERSION_URL = "https://api.spiget.org/v2/resources/71242/versions/latest"; - private final String version; - private final String userAgent; + private final SimpleClans plugin; + private static final String LATEST_VERSION_URL = "https://api.spiget.org/v2/resources/71242/versions/latest"; + private final String version; + private final String userAgent; - public UpdateChecker(SimpleClans plugin) { - this.plugin = plugin; - version = plugin.getDescription().getVersion().split("-")[0]; //removing trailing hash - userAgent = "SimpleClans/" + version; - } + public UpdateChecker(SimpleClans plugin) { - /** - * Checks if the version installed is up-to-date - * - */ - public void check() { - new BukkitRunnable() { + this.plugin = plugin; + version = plugin.getDescription().getVersion().split("-")[0]; // removing trailing hash + userAgent = "SimpleClans/" + version; - @Override - public void run() { - try { - URL url = new URL(LATEST_VERSION_URL); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.addRequestProperty("User-Agent", userAgent); - InputStreamReader reader = new InputStreamReader(connection.getInputStream()); - - JsonElement parse = JsonParser.parseReader(reader); - if (parse.isJsonObject()) { - String latestVersion = parse.getAsJsonObject().get("name").getAsString(); + } - if (compareVersions(version, latestVersion) < 0) { - plugin.getLogger().info(String.format("You're running an outdated version (%s).", version)); - plugin.getLogger().info(String.format("The latest version is %s. Download it at:", latestVersion)); - plugin.getLogger().info("https://www.spigotmc.org/resources/simpleclans.71242/"); - } - - } - - reader.close(); - } catch (MalformedURLException ignored) { - } catch (IOException | JsonParseException ex) { - plugin.getLogger().log(Level.WARNING, "Error checking the plugin version..."); - } - } - }.runTaskAsynchronously(plugin); - } + /** + * Checks if the version installed is up-to-date + * + */ + public void check() { - public static int compareVersions(@NotNull String a, @NotNull String b) { - String[] aSplit = a.split("\\."); - String[] bSplit = b.split("\\."); - int length = Math.max(aSplit.length, bSplit.length); - for (int i = 0; i < length; i++) { - int aPart = aSplit.length > i ? Integer.parseInt(aSplit[i]) : 0; - int bPart = bSplit.length > i ? Integer.parseInt(bSplit[i]) : 0; - if (aPart != bPart) { - return Integer.compare(aPart, bPart); - } - } - return 0; - } + new BukkitRunnable() { + + @Override + public void run() { + + try { + + URL url = new URL(LATEST_VERSION_URL); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.addRequestProperty("User-Agent", userAgent); + InputStreamReader reader = new InputStreamReader(connection.getInputStream()); + + JsonElement parse = JsonParser.parseReader(reader); + if (parse.isJsonObject()) { + + String latestVersion = parse.getAsJsonObject().get("name").getAsString(); + + if (compareVersions(version, latestVersion) < 0) { + + plugin.getLogger().info(String.format("You're running an outdated version (%s).", version)); + plugin.getLogger() + .info(String.format("The latest version is %s. Download it at:", latestVersion)); + plugin.getLogger().info("https://www.spigotmc.org/resources/simpleclans.71242/"); + + } + + } + + reader.close(); + + } catch (MalformedURLException ignored) { + + } catch (IOException | JsonParseException ex) { + + plugin.getLogger().log(Level.WARNING, "Error checking the plugin version..."); + + } + + } + + }.runTaskAsynchronously(plugin); + + } + + public static int compareVersions(@NotNull String a, @NotNull String b) { + + String[] aSplit = a.split("\\."); + String[] bSplit = b.split("\\."); + int length = Math.max(aSplit.length, bSplit.length); + for (int i = 0; i < length; i++) { + + int aPart = aSplit.length > i ? Integer.parseInt(aSplit[i]) : 0; + int bPart = bSplit.length > i ? Integer.parseInt(bSplit[i]) : 0; + if (aPart != bPart) { + + return Integer.compare(aPart, bPart); + + } + + } + + return 0; + + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/VanishUtils.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/VanishUtils.java index c98a43a9..7a233b1c 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/VanishUtils.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/VanishUtils.java @@ -13,59 +13,95 @@ import java.util.List; public class VanishUtils { - private VanishUtils() {} + private VanishUtils() { + + } public static @NotNull List getNonVanished(@Nullable CommandSender viewer, @NotNull Clan clan) { + return getNonVanished(viewer, clan.getMembers()); + } public static @NotNull List getNonVanished(@Nullable CommandSender viewer, - @NotNull List clanPlayers) { + @NotNull List clanPlayers) + { + ArrayList nonVanished = new ArrayList<>(); for (ClanPlayer cp : clanPlayers) { + if (!isVanished(viewer, cp)) { + nonVanished.add(cp); + } + } + return nonVanished; + } public static boolean isVanished(@Nullable CommandSender viewer, @NotNull ClanPlayer cp) { + if (isVanished(cp)) { + return true; + } + Player player = cp.toPlayer(); if (viewer instanceof Player && player != null) { + return !((Player) viewer).canSee(player); + } return false; + } public static boolean isVanished(@Nullable CommandSender viewer, @NotNull Player player) { + if (viewer instanceof Player) { + return !((Player) viewer).canSee(player); + } + return checkMetadata(player); + } public static boolean isVanished(@NotNull ClanPlayer cp) { + if (!isOnline(cp)) { + return true; + } Player player = cp.toPlayer(); return player != null && checkMetadata(player); + } private static boolean checkMetadata(Player player) { + if (player.hasMetadata("vanished") && !player.getMetadata("vanished").isEmpty()) { + return player.getMetadata("vanished").get(0).asBoolean(); + } + return false; + } public static boolean isOnline(@NotNull ClanPlayer player) { + return SimpleClans.getInstance().getProxyManager().isOnline(player.getName()); + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapper.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapper.java index 432055d3..96e84f36 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapper.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapper.java @@ -21,130 +21,203 @@ public class WordWrapper { int lineColorChars = 0; public WordWrapper(@NotNull String rawString, int lineLength) { + this.rawString = rawString; this.lineLength = lineLength > 0 ? lineLength : 319; rawChars = (rawString + ' ').toCharArray(); // add a trailing space to trigger pagination + } @NotNull public String[] wrap() { + // A string shorter than the lineWidth is a single line if (rawString.length() <= lineLength && !rawString.contains("\n")) { - return new String[]{rawString}; + + return new String[] { rawString }; + } for (int i = 0; i < rawChars.length; i++) { + char c = rawChars[i]; // skip chat color modifiers if (c == COLOR_CHAR) { + processChatColorModifiers(rawChars[i + 1]); i++; // Eat the next character as we have already processed it continue; + } + if (c == ' ' || c == '\n') { + processSpace(); processLineBreak(c); + } else { + word.append(c); + } + } + addLastLine(); - // Iterate over the wrapped lines, applying the last color from one line to the beginning of the next + // Iterate over the wrapped lines, applying the last color from one line to the + // beginning of the next applyLastColorToFollowingLines(lines); return lines.toArray(new String[0]); + } private void addLastLine() { + if (line.length() > 0) { // Only add the last line if there is anything to add + lines.add(line.toString()); + } + } private void processLineBreak(char c) { + if (c == '\n') { // Newline forces the line to flush + lines.add(line.toString()); line = new StringBuilder(); + } + } private void processSpace() { - if (line.length() == 0 && word.length() - lineColorChars > lineLength) { // special case: extremely long word begins a line + + if (line.length() == 0 && word.length() - lineColorChars > lineLength) { // special case: extremely long word + // begins a line + lines.addAll(split(word.toString(), lineLength)); - } else if (line.length() + 1 + word.length() - lineColorChars == lineLength) { // Line exactly the correct length...newline + + } else if (line.length() + 1 + word.length() - lineColorChars == lineLength) { // Line exactly the correct + // length...newline + processLineCorrectLength(); + } else if (line.length() + 1 + word.length() - lineColorChars > lineLength) { // Line too long...break the line + processLineTooLong(); + } else { + appendWord(); + } + word = new StringBuilder(); + } private void appendWord() { + if (line.length() > 0) { + line.append(' '); + } + line.append(word); + } private void processLineTooLong() { + for (String partialWord : split(word.toString(), lineLength)) { + if (line.length() > 0) { + lines.add(line.toString()); + } + line = new StringBuilder(partialWord); + } + lineColorChars = 0; + } private void processLineCorrectLength() { + appendWord(); lines.add(line.toString()); line = new StringBuilder(); lineColorChars = 0; + } private void processChatColorModifiers(char rawChar) { + word.append(COLOR_CHAR); word.append(rawChar); lineColorChars += 2; + } /** - * Breaks a String, using the passed length and respecting color codes, into a List of Strings + * Breaks a String, using the passed length and respecting color codes, into a + * List of Strings * * @param input the input * @return the split input */ @NotNull public static List split(@NotNull String input, int length) { + List split = new ArrayList<>(); int nonColorCount = 0; for (int i = 0; i < input.length(); i++) { + if (nonColorCount == length) { + split.add(input.substring(0, i)); input = input.substring(i); nonColorCount = 0; i = 0; + } + char c = input.charAt(i); if (c == COLOR_CHAR) { + if (i + 1 < input.length()) { + String s = String.valueOf(input.charAt(i + 1)); if (ChatColor.ALL_CODES.contains(s)) { + i++; continue; + } + } + } + nonColorCount++; + } + if (!input.isEmpty()) { + split.add(input); + } + return split; + } - } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/YAMLSerializer.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/YAMLSerializer.java index 34863273..be394fe0 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/YAMLSerializer.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/utils/YAMLSerializer.java @@ -16,33 +16,47 @@ public class YAMLSerializer { private static final Logger LOGGER = SimpleClans.getInstance().getLogger(); private YAMLSerializer() { + } public static @Nullable String serialize(@Nullable ConfigurationSerializable cs) { + String serialized = null; if (cs != null) { + YamlConfiguration config = new YamlConfiguration(); config.set("cs", cs); serialized = config.saveToString(); + } return serialized; + } @SuppressWarnings("unchecked") public static @Nullable T deserialize(@Nullable String cs, - @NotNull Class clazz) { + @NotNull Class clazz) + { + YamlConfiguration config = new YamlConfiguration(); if (cs != null) { + try { + config.loadFromString(cs); return (T) config.get("cs"); + } catch (Exception e) { - LOGGER.warning(String.format( - "Error deserializing %s... Content: %s", clazz, cs)); + + LOGGER.warning(String.format("Error deserializing %s... Content: %s", clazz, cs)); + } + } return null; + } + } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcher.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcher.java index 87fbb12a..73de1348 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcher.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcher.java @@ -23,35 +23,44 @@ import static java.util.Collections.singletonList; /** * @author evilmidget38 (previous author) * @see Bukkit Thread - * @see Github Gist + * @see Github + * Gist */ public final class UUIDFetcher { + private static final String PROFILE_URL = "https://api.minetools.eu/uuid/"; private static final String FALLBACK_PROFILE_URL = "https://api.mojang.com/users/profiles/minecraft/"; private static final int BATCH_SIZE = 100; private static final Gson gson = new Gson(); private UUIDFetcher() { + // Private constructor to prevent instantiation } /** - * Fetches UUIDs for a list of ClanPlayer objects. - * This method extracts the names from the ClanPlayer objects and fetches their corresponding UUIDs. + * Fetches UUIDs for a list of ClanPlayer objects. This method extracts the + * names from the ClanPlayer objects and fetches their corresponding UUIDs. * * @param clanPlayers A list of ClanPlayer objects for which to fetch UUIDs - * @return A Map where the keys are player names and the values are their corresponding UUIDs + * @return A Map where the keys are player names and the values are their + * corresponding UUIDs * @throws InterruptedException If the operation is interrupted while waiting * @throws ExecutionException If the computation threw an exception */ - public static Map fetchUUIDsForClanPlayers(List clanPlayers) throws InterruptedException, ExecutionException { + public static Map fetchUUIDsForClanPlayers(List clanPlayers) + throws InterruptedException, ExecutionException + { + List names = clanPlayers.stream().map(ClanPlayer::getName).collect(Collectors.toList()); return fetchUUIDsConcurrently(names); + } /** - * Fetches the UUID for a single player name. - * This method is a convenience wrapper around the batch UUID fetching process. + * Fetches the UUID for a single player name. This method is a convenience + * wrapper around the batch UUID fetching process. * * @param name The name of the player whose UUID is to be fetched * @return The UUID of the specified player, or null if not found @@ -59,19 +68,26 @@ public final class UUIDFetcher { * @throws ExecutionException If the computation threw an exception */ public static @Nullable UUID getUUIDOf(@NotNull String name) throws InterruptedException, ExecutionException { + return fetchUUIDsConcurrently(singletonList(name)).get(name); + } // Fetch UUIDs in batches with concurrency - private static Map fetchUUIDsConcurrently(List names) throws InterruptedException, ExecutionException { + private static Map fetchUUIDsConcurrently(List names) + throws InterruptedException, ExecutionException + { + Map resultMap = new ConcurrentHashMap<>(); - ExecutorService executorService = Executors.newFixedThreadPool(10); // Thread pool for parallel execution + ExecutorService executorService = Executors.newFixedThreadPool(10); // Thread pool for parallel execution List>> tasks = new ArrayList<>(); // Split the list of names into batches and create tasks for (int i = 0; i < names.size(); i += BATCH_SIZE) { + List batch = names.subList(i, Math.min(i + BATCH_SIZE, names.size())); tasks.add(createTask(batch)); + } // Execute all tasks in parallel @@ -79,20 +95,26 @@ public final class UUIDFetcher { // Collect results from all batches for (Future> future : futures) { - resultMap.putAll(future.get()); // Merge each batch result into the final result map + + resultMap.putAll(future.get()); // Merge each batch result into the final result map + } // Shutdown the executor service executorService.shutdownNow(); if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) { + SimpleClans.getInstance().getLogger().warning("Executor did not terminate in time."); + } return resultMap; + } // Create connection for each name private static HttpURLConnection createConnection(@NotNull URL url) throws IOException { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); @@ -101,71 +123,106 @@ public final class UUIDFetcher { connection.setDoInput(true); return connection; + } // Get UUID by name private static @NotNull UUID getUUID(@NotNull String id) { - return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32)); + + return UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + + id.substring(16, 20) + "-" + id.substring(20, 32)); + } // Handle single batch of names private static Map fetchUUIDsForBatch(List batch) { + Map uuidMap = new HashMap<>(); for (String name : batch) { + uuidMap.computeIfAbsent(name, k -> { + try { + return tryFetchUUIDWithFallback(k); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } return uuidMap; + } private static @Nullable UUID tryFetchUUIDWithFallback(@NotNull String name) throws IOException { + try { + // Try the primary URL return fetchUUID(URI.create(PROFILE_URL + name).toURL()); + } catch (IOException e) { + // If the primary URL fails, attempt the fallback URL - SimpleClans.debug(String.format("Failed to fetch %s UUID by MineTools API. Trying to use Mojang API instead...", name)); + SimpleClans.debug(String + .format("Failed to fetch %s UUID by MineTools API. Trying to use Mojang API instead...", name)); return fetchUUID(URI.create(FALLBACK_PROFILE_URL + name).toURL()); + } + } private static @Nullable UUID fetchUUID(@NotNull URL url) throws IOException { + HttpURLConnection connection = createConnection(url); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_NOT_FOUND) { + return null; - } - if (responseCode != HttpURLConnection.HTTP_OK) { - throw new IOException(String.format("Unexpected response code: %d. Response: %s", - responseCode, connection.getResponseMessage())); + } - JsonObject response = gson.fromJson(new InputStreamReader(connection.getInputStream(), UTF_8), JsonObject.class); + if (responseCode != HttpURLConnection.HTTP_OK) { + + throw new IOException(String.format("Unexpected response code: %d. Response: %s", responseCode, + connection.getResponseMessage())); + + } + + JsonObject response = gson.fromJson(new InputStreamReader(connection.getInputStream(), UTF_8), + JsonObject.class); if (!response.has("id")) { + return null; + } JsonElement id = response.get("id"); JsonElement status = response.get("status"); - if (id.isJsonNull() || - (response.has("status") && status.getAsString().equals("ERR"))) { + if (id.isJsonNull() || (response.has("status") && status.getAsString().equals("ERR"))) { + throw new IOException(String.format("Invalid UUID: %s", id)); + } return getUUID(id.getAsString()); + } // Callable task for batch processing private static Callable> createTask(List batch) { + return () -> fetchUUIDsForBatch(batch); + } + } \ No newline at end of file diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDMigration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDMigration.java index 805c43e1..941682a4 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDMigration.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDMigration.java @@ -14,33 +14,52 @@ import java.util.UUID; */ public class UUIDMigration { - private UUIDMigration() {} - + private UUIDMigration() { + + } + public static boolean canReturnUUID() { + try { + Bukkit.class.getDeclaredMethod("getPlayer", UUID.class); return true; + } catch (NoSuchMethodException e) { + return false; + } + } @Deprecated public static UUID getForcedPlayerUUID(String playerName) { + Player player = Bukkit.getPlayerExact(playerName); if (player != null) { - return player.getUniqueId(); + + return player.getUniqueId(); + } else { - for (ClanPlayer cp : SimpleClans.getInstance().getClanManager().getAllClanPlayers()) { - if (cp.getName().equalsIgnoreCase(playerName)) { - return cp.getUniqueId(); - } - } + + for (ClanPlayer cp : SimpleClans.getInstance().getClanManager().getAllClanPlayers()) { + + if (cp.getName().equalsIgnoreCase(playerName)) { + + return cp.getUniqueId(); + + } + + } + @SuppressWarnings("deprecation") OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName); return offlinePlayer.getUniqueId(); + } + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 855afe68..305c586d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: SimpleClans main: net.sacredlabyrinth.phaed.simpleclans.SimpleClans -version: '${project.version}-${git.commit.id.describe-short}' +version: '${version}' softdepend: - Vault - PlaceholderAPI @@ -356,4 +356,4 @@ permissions: simpleclans.leader.rank.permissions.add: true simpleclans.leader.rank.permissions.remove: true simpleclans.leader.rank.permissions.list: true - simpleclans.leader.discord.create: true \ No newline at end of file + simpleclans.leader.discord.create: true diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/hooks/DiscordHookTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/hooks/DiscordHookTest.java index 156078db..1b6f1a8e 100644 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/hooks/DiscordHookTest.java +++ b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/hooks/DiscordHookTest.java @@ -12,6 +12,7 @@ public class DiscordHookTest { @Test @DisplayName("Checks if colors from configuration can be transformed to java.awt.Color") public void leaderColorTest() throws IllegalArgumentException { + Color expectedColor = new Color(231, 76, 60, 100); String[] colors = "231, 76, 60, 100".replaceAll("\\s", "").split(","); @@ -22,5 +23,7 @@ public class DiscordHookTest { Color actualColor = new Color(red, green, blue, alpha); assertEquals(expectedColor, actualColor); + } + } diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/language/ResourceControlTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/language/ResourceControlTest.java index 8345225d..d6a1f473 100644 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/language/ResourceControlTest.java +++ b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/language/ResourceControlTest.java @@ -10,6 +10,7 @@ public class ResourceControlTest { @Test public void getFallbackLocaleAcf() { + LanguageResource.ResourceControl resourceControl = new LanguageResource.ResourceControl(Locale.ENGLISH, true); String acfBaseName = "acf"; Locale locale = resourceControl.getFallbackLocale(acfBaseName, Locale.ENGLISH); @@ -25,12 +26,13 @@ public class ResourceControlTest { locale = resourceControl.getFallbackLocale(acfBaseName, ptBR); assertEquals(Locale.ENGLISH, locale); + } @Test public void getFallbackLocale() { - LanguageResource.ResourceControl resourceControl = new LanguageResource.ResourceControl(Locale.ENGLISH, - true); + + LanguageResource.ResourceControl resourceControl = new LanguageResource.ResourceControl(Locale.ENGLISH, true); String pluginBaseName = "messages"; Locale locale = resourceControl.getFallbackLocale(pluginBaseName, Locale.ENGLISH); assertEquals(Locale.ROOT, locale); @@ -55,5 +57,7 @@ public class ResourceControlTest { locale = resourceControl.getFallbackLocale(pluginBaseName, Locale.ENGLISH); assertEquals(ptBR, locale); + } + } \ No newline at end of file diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtilsTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtilsTest.java deleted file mode 100644 index 6d72184e..00000000 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/ChatUtilsTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.sacredlabyrinth.phaed.simpleclans.utils; - - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class ChatUtilsTest { - - @Test - public void getLastColors() { - String lastColors = ChatUtils.getLastColors("§aa mensagem§x termina com §4vermelho"); - assertEquals("§4", lastColors); - - lastColors = ChatUtils.getLastColors("§aa mensagem§x termina com §a§4vermelho"); - assertEquals("§a§4", lastColors); - - lastColors = ChatUtils.getLastColors("§aa mensagem§x termina com §a§4ver§fmel§§§§§§§§§§ho"); - assertEquals("§f", lastColors); - - lastColors = ChatUtils.getLastColors("§aa mensagem§x termina com"); - assertEquals("§x", lastColors); - - lastColors = ChatUtils.getLastColors("§aa mensagem§ ax termina com"); - assertEquals("§a", lastColors); - } - - @Test - public void parseColors() { - assertEquals("Hello", ChatUtils.parseColors("Hello")); - assertEquals("§aHello §x§a§a§a§a§a§aWorld", ChatUtils.parseColors("&aHello &#aaaaaaWorld")); - } - - @Test - public void stripColors() { - assertEquals("Hello", ChatUtils.stripColors("Hello")); - assertEquals("&xHello", ChatUtils.stripColors("&xHello")); - assertEquals("Hello", ChatUtils.stripColors("��Hello")); - assertEquals("&aHello", ChatUtils.stripColors("�&�aHello")); - - } -} diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtilsTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtilsTest.java deleted file mode 100644 index 9d566203..00000000 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/ObjectUtilsTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.sacredlabyrinth.phaed.simpleclans.utils; - -import net.sacredlabyrinth.phaed.simpleclans.Clan; -import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class ObjectUtilsTest { - - private ClanPlayer cpOrigin; - private ClanPlayer cpDest; - private Clan clanOrigin; - private Clan clanDest; - - @BeforeEach - public void setup() { - cpOrigin = new ClanPlayer(); - cpOrigin.setName("Test"); - cpDest = new ClanPlayer(); - clanOrigin = new Clan(); - clanDest = new Clan(); - } - - @Test - public void updateFields() throws IllegalAccessException { - ObjectUtils.updateFields(cpOrigin, cpDest); - assertEquals("Test", cpDest.getName()); - - clanOrigin.setMemberFee(0.222); - ObjectUtils.updateFields(clanOrigin, clanDest); - assertEquals(0.222, clanDest.getMemberFee(), 0); - } - - @Test - public void updateFieldsDifferentType() { - assertThrows(IllegalArgumentException.class, () -> ObjectUtils.updateFields(clanOrigin, cpOrigin)); - } -} diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateCheckerTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateCheckerTest.java deleted file mode 100644 index a3cfc0f1..00000000 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/UpdateCheckerTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.sacredlabyrinth.phaed.simpleclans.utils; - - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class UpdateCheckerTest { - - @Test - public void compareVersions() { - assertEquals(UpdateChecker.compareVersions("0.0", "0"), 0); - assertTrue(UpdateChecker.compareVersions("0.1", "0") > 0); - assertTrue(UpdateChecker.compareVersions("1", "1.1.1") < 0); - assertTrue(UpdateChecker.compareVersions("1.1", "1") > 0); - assertTrue(UpdateChecker.compareVersions("1", "0") > 0); - assertEquals(UpdateChecker.compareVersions("1.0.0", "1"), 0); - assertEquals(UpdateChecker.compareVersions("1.0", "1"), 0); - assertEquals(UpdateChecker.compareVersions("1.0.0", "1.0"), 0); - assertEquals(UpdateChecker.compareVersions("1.0.0", "1.0.0"), 0); - } -} \ No newline at end of file diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapperTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapperTest.java deleted file mode 100644 index 1d6940ad..00000000 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/utils/WordWrapperTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.sacredlabyrinth.phaed.simpleclans.utils; - - -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -public class WordWrapperTest { - - @Test - public void wrap() { - String[] wrap = new WordWrapper("a§aa", 2).wrap(); - assertArrayEquals(new String[]{"§fa§aa"}, wrap); - wrap = new WordWrapper("a§aa a§aa", 2).wrap(); - assertArrayEquals(new String[]{"§fa§aa", "§aa§aa"}, wrap); - } - - @Test - public void split() { - String s = "§x§f§f§f§f§f§f"; - List split = WordWrapper.split(s, 1); - assertEquals(1, split.size()); - assertLinesMatch(Collections.singletonList("§x§f§f§f§f§f§f"), split); - s = "§x§f§f§f§f§f§faa"; - split = WordWrapper.split(s, 1); - assertEquals(2, split.size()); - assertLinesMatch(Arrays.asList("§x§f§f§f§f§f§fa", "a"), split); - s = "§x§fa§tfa§fa§f§f§faa"; - split = WordWrapper.split(s, 3); - assertEquals(3, split.size()); - assertLinesMatch(Arrays.asList("§x§fa§t", "fa§fa", "§f§f§faa"), split); - } -} \ No newline at end of file diff --git a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcherTest.java b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcherTest.java index 7bbd51d3..1b3ec4bf 100644 --- a/src/test/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcherTest.java +++ b/src/test/java/net/sacredlabyrinth/phaed/simpleclans/uuid/UUIDFetcherTest.java @@ -13,13 +13,18 @@ public class UUIDFetcherTest { @BeforeEach public void setup() { + ghostUUID = UUID.fromString("bfe9a44f-e44d-453b-8219-74eb186c3932"); + } @Test public void getUUIDOf() throws Exception { + assertEquals(ghostUUID, UUIDFetcher.getUUIDOf("GhostTheWolf"), "Assert fetching UUID from right name"); assertNull(UUIDFetcher.getUUIDOf("AnyNameLongerThan16Chars"), "Assert fetching UUID from wrong name"); + } + } \ No newline at end of file