Merge PR #2 into Gradle-based QuickShop-OG

This commit is contained in:
NotAlexNoyle committed 2026-03-26 11:50:42 -04:00
1 parent 70a1b69a9e
commit 9736254016
349 files changed
+18569 -5693

No files matched your search

+3 -12
View File
@@ -1,16 +1,7 @@
# Created by .ignore support plugin (hsz.mobi)
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
### Gradle template
.gradle/
build/
### Java template
# Compiled class file
-19
View File
@@ -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.9/apache-maven-3.9.9-bin.zip
+16 -91
View File
@@ -1,104 +1,29 @@
# QuickShop-Reremake
# QuickShop-OG
**Credit to nfish2021 for their command changes. Licensed under GPLv3.
QuickShop-OG is a GPLv3-only shop plugin fork focused on keeping a non-AGPL QuickShop codebase available.
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/e33e2fafe3ac4d4eb9048d154bbd874e)](https://www.codacy.com/gh/PotatoCraft-Studio/QuickShop-Reremake/dashboard?utm_source=github.com&utm_medium=referral&utm_content=PotatoCraft-Studio/QuickShop-Reremake&utm_campaign=Badge_Grade)
[![CodeFactor](https://www.codefactor.io/repository/github/potatocraft-studio/quickshop-reremake/badge)](https://www.codefactor.io/repository/github/potatocraft-studio/quickshop-reremake)
![BuildStatus](https://ci.codemc.io/job/PotatoCraft-Studio/job/QuickShop-Reremake/21/badge/icon)
![TestsPassed](https://img.shields.io/jenkins/tests?compact_message&jobUrl=https://ci.codemc.io/job/PotatoCraft-Studio/job/QuickShop-Reremake)
![Contributors](https://img.shields.io/github/contributors/potatocraft-studio/QuickShop-Reremake)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FPotatoCraft-Studio%2FQuickShop-Reremake.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FPotatoCraft-Studio%2FQuickShop-Reremake?ref=badge_shield)
---
This repository is named `QuickShop-OG-Alt`, but the project, plugin, and built jar are `QuickShop-OG`.
![Java](https://img.shields.io/badge/java-version%208%2B%20(currently%20is%208--16)-orange)
![MC](https://img.shields.io/badge/minecraft-java%20edition%201.15%2B-blueviolet)
![Ver](https://img.shields.io/spiget/version/62575?label=version)
![Downloads](https://img.shields.io/spiget/downloads/62575?label=downloads)
![Rating](https://img.shields.io/spiget/rating/62575?label=rating)
---
## Goals
QuickShop is a **FREE** shop plugin that allows players to easily sell/buy any items from a chest without any commands. In fact,
none of the commands that QuickShop provides are ever needed by a player. QuickShop-Reremake is a **FREE** fork of QuickShop
NotLikeMe with more features, bug fixes and other improvements.
QuickShop-Reremake is made by PotatoCraft Studio
from [KaiKikuchi's QuickShop upstream repository](https://github.com/KaiKikuchi/QuickShop).
- Keep the codebase GPLv3-only
- Maintain a QuickShop-OG identity instead of QuickShop-Reremake branding
- Target Purpur `1.19.4` as the primary server runtime
- Preserve broad client compatibility in mixed-version setups such as `1.8` through `1.21.11`
## Support
## Build
| <a href="https://discord.gg/bfefw2E"/> <img src="/.github/icons/Discord.svg" width="100" height="100" />| <a href="https://github.com/PotatoCraft-Studio/QuickShop-Reremake/issues"><img src="/.github/icons/Github.png" width="100" height="100" />|
| :---: | :---: |
| [**Discord**](https://discord.gg/bfefw2E) | [**Github Issues**](https://github.com/PotatoCraft-Studio/QuickShop-Reremake/issues) |
Use Java 17 and Maven:
## Features
- Easy to use
- Toggleable Display Item on top of the chest
- NBT Data, Enchantment, Tool Damage, Potion, and Mob Egg support
- Unlimited chest support
- Blacklist support & bypass permissions
- Shops that buy and sell items at the same time (Using double chests)
- Customisable permission checks
- UUID support
- Better shop protection [Reremake]
- Item display name i18n [Reremake]
- Enchantment display name i18n [Reremake]
- A cool item preview [Reremake]
- World/region protection plugins support [Reremake]
- ProtocolLib based Virtual DisplayItem support [Reremake]
- Powerful API [Reremake]
- Optimized performance [Reremake]
## Downloads
| <a href="https://www.spigotmc.org/resources/62575/"><img src="/.github/icons/Spigot.png" width="100" height="90" /></a> | <a href="https://dev.bukkit.org/projects/quickshop-reremake"><img src="/.github/icons/Bukkit.png" width="100" height="100" /></a></a> | <a href="https://www.mcbbs.net/thread-1426607-1-1.html"><img src="/.github/icons/MCBBS.png" width="100" height="100" /></a> | <a href="https://ci.codemc.io/job/PotatoCraft-Studio/job/QuickShop-Reremake-SNAPSHOT/"><img src="/.github/icons/Jenkins.svg" width="85" height="100" /></a>
| :---: | :---: | :---: | :---: |
| **Spigot** | **BukkitDev** | **MCBBS** | **Jenkins** |
## Contribute
If you're a developer, you can contribute to the QuickShop code! Just make a fork and install the Lombok plugin,
then make a pull request when you're done! Please try to
follow [Google Java Style](https://google.github.io/styleguide/javaguide.html). Also do not increase the plugin version
number. Thank you very much!
To compile the QuickShop and debug it by yourself, please follow these steps:
0. Make sure you're using Java16 JDK in your PATH.
1. Compile main-project without signature by using debug profile: `mvn install -Pdebug`
2. Start your server with extra flag to skip the QuickShop signature
checks: `-Dorg.maxgamer.quickshop.util.envcheck.skip.SIGNATURE_VERIFY`
## Maven
```XML
<repository>
<id>quickshop-repo</id>
<url>https://repo.codemc.io/repository/maven-public/</url>
</repository>
<dependency>
<groupId>org.maxgamer</groupId>
<artifactId>QuickShop</artifactId>
<version>{VERSION}</version>
<scope>provided</scope>
</dependency>
```bash
./mvnw -Pdebug package
```
## Bstats
## Runtime Notes
[![BigImage](https://bstats.org/signatures/bukkit/QuickShop-Reremake.svg)](https://bstats.org/plugin/bukkit/QuickShop-Reremake/3320)
- `plugin.yml` keeps Folia support enabled because the codebase already contains region-scheduler handling
- Actual mixed-version client support depends on the proxy or protocol translation stack used by the server
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FPotatoCraft-Studio%2FQuickShop-Reremake.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FPotatoCraft-Studio%2FQuickShop-Reremake?ref=badge_large)
## Developer API
```java
Plugin plugin = Bukkit.getPluginManager().getPlugin("QuickShop");
if(plugin != null){
QuickShopAPI api = (QuickShopAPI)plugin;
api.xxxx;
}
```
This project is licensed under GPLv3.
+205
View File
@@ -0,0 +1,205 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.tasks.Jar
plugins {
id("java")
id("java-library")
id("com.diffplug.spotless") version "8.1.0"
id("com.gradleup.shadow") version "8.3.9"
id("checkstyle")
eclipse
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain { languageVersion.set(JavaLanguageVersion.of(17)) }
}
group = "org.maxgamer"
version = "5.1.2.5-SNAPSHOT"
val apiVersion = "1.19"
repositories {
mavenCentral()
gradlePluginPortal()
mavenLocal()
maven(url = "https://repo.purpurmc.org/snapshots")
maven(url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
maven(url = "https://repo.dmulloy2.net/repository/public/")
maven(url = "https://repo.codemc.io/repository/maven-public/")
maven(url = "https://oss.sonatype.org/content/groups/public/")
maven(url = "https://repo.md-5.net/content/repositories/snapshots/")
maven(url = "https://repo.md-5.net/content/repositories/releases/")
maven(url = "https://repo.extendedclip.com/content/repositories/placeholderapi/")
maven(url = "https://ci.ender.zone/plugin/repository/everything/")
maven(url = "https://jitpack.io")
maven(url = "https://mvn.intellectualsites.com/content/groups/public/")
maven(url = "https://repo.onarandombox.com/content/groups/public")
maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/")
maven(url = "https://repo.papermc.io/repository/maven-public/")
maven(url = "https://repo.bg-software.com/repository/api/")
maven(url = "https://maven.enginehub.org/repo/")
maven(url = "https://repo.songoda.com/repository/public/")
maven(url = "https://repo.craftaro.com/repository/public/")
maven(url = "https://repo.minebench.de/")
}
dependencies {
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
compileOnly("com.griefcraft.lwc:LWCX:2.2.7")
compileOnly("com.github.TechFortress:GriefPrevention:16.18.1")
compileOnly("com.github.dmulloy2:ProtocolLib:5.0.0")
implementation("com.dumptruckman.minecraft:JsonConfiguration:1.1")
compileOnly("com.github.MilkBowl:VaultAPI:1.7.1")
compileOnly("com.github.true-og.OpenInv:openinvapi:a85e8ebc28")
compileOnly("fr.neatmonster:nocheatplus:3.17-SNAPSHOT")
compileOnly(files("lib/Clearlag-3.2.2.jar"))
compileOnly("me.clip:placeholderapi:2.11.6")
compileOnly("com.github.angeschossen:LandsAPI:6.35.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.87.0")
testImplementation("org.xerial:sqlite-jdbc:3.40.1.0")
testImplementation("mysql:mysql-connector-java:8.0.33")
implementation("org.apache.commons:commons-compress:1.22")
implementation("org.apache.commons:commons-lang3:3.12.0")
compileOnly(files("lib/SpartanAPI-9.1.jar"))
compileOnly("com.github.TownyAdvanced:Towny:0.97.0.5")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.9")
compileOnly("com.plotsquared:PlotSquared-Core:6.11.1") { isTransitive = false }
compileOnly(files("lib/Residence5.0.1.0.jar"))
compileOnly("com.massivecraft:Factions:1.6.9.5-U0.6.0")
compileOnly(files("lib/BlocksHub-3.2.1.jar"))
implementation("com.rollbar:rollbar-java:1.10.0")
implementation("com.github.PotatoCraft-Studio:MineDown:1.7.1-modified")
compileOnly(files("lib/GemsEconomy-4.9.2.jar"))
compileOnly(files("lib/TNE-0.1.1.17-PRE-2.jar"))
compileOnly("com.songoda:skyblock:2.3.30")
compileOnly("com.songoda:SongodaCore:2.6.18")
implementation("commons-codec:commons-codec:1.15")
implementation("org.slf4j:slf4j-nop:1.7.32")
implementation("io.papermc:paperlib:1.0.7")
compileOnly("com.bgsoftware:SuperiorSkyblockAPI:1.11.1")
implementation("me.lucko:helper:5.6.13")
implementation("me.lucko:helper-profiles:1.2.0")
compileOnly("com.github.alex9849:advanced-region-market:3.5.4")
compileOnly(files("lib/IridiumSkyblock-3.2.3.jar"))
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation("commons-io:commons-io:2.11.0")
implementation("org.maxgamer.storage:simplixstorage:3.2.3.3")
compileOnly("de.tr7zw:item-nbt-api-plugin:2.12.0")
compileOnly("net.tnemc:Reserve:0.1.5.4")
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.30")
testCompileOnly("org.projectlombok:lombok:1.18.30")
testAnnotationProcessor("org.projectlombok:lombok:1.18.30")
compileOnly("org.jetbrains:annotations:24.0.1")
testCompileOnly("org.jetbrains:annotations:24.0.1")
}
tasks.named<ProcessResources>("processResources") {
val props = mapOf("version" to project.version.toString(), "apiVersion" to apiVersion)
inputs.properties(props)
filesMatching("plugin.yml") { expand(props) }
from("crowdin/lang") { into("crowdin/lang") }
from("LICENSE") { into("/") }
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.withType<Test>().configureEach { useJUnitPlatform() }
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters")
options.compilerArgs.add("-Xlint:deprecation")
options.encoding = "UTF-8"
options.isFork = true
}
spotless {
java {
eclipse().configFile("config/formatter/eclipse-java-formatter.xml")
leadingTabsToSpaces()
removeUnusedImports()
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) }
target("build.gradle.kts", "settings.gradle.kts", "eclipse.gradle.kts")
}
}
checkstyle {
toolVersion = "10.18.1"
configFile = file("config/checkstyle/checkstyle.xml")
isIgnoreFailures = true
isShowViolations = true
}
tasks.named("compileJava") { dependsOn("spotlessApply") }
tasks.named("spotlessCheck") { dependsOn("spotlessApply") }
tasks.named<Jar>("jar") { archiveClassifier.set("part") }
tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
minimize()
relocate("com.google.errorprone", "org.maxgamer.quickshop.shade.com.google.errorprone")
relocate("org.checkerframework", "org.maxgamer.quickshop.shade.org.checkerframework")
relocate("org.apache.commons.lang3", "org.maxgamer.quickshop.shade.org.apache.commons.lang3")
relocate("org.objectweb.asm", "org.maxgamer.quickshop.shade.org.objectweb.asm")
relocate("org.slf4j", "org.maxgamer.quickshop.shade.org.slf4j")
relocate("net.minidev.json", "org.maxgamer.quickshop.shade.net.minidev.json.minidev.json")
relocate("com.fasterxml.jackson.core", "org.maxgamer.quickshop.shade.com.fasterxml.jackson.jackson.core")
relocate("me.lucko", "org.maxgamer.quickshop.shade.me.lucko")
relocate("com.rollbar", "org.maxgamer.quickshop.shade.com.rollbar")
relocate(
"com.dumptruckman.bukkit.configuration",
"org.maxgamer.quickshop.shade.com.dumptruckman.bukkit.configuration",
)
relocate("org.apache.commons.compress", "org.maxgamer.quickshop.shade.org.apache.commons.compress")
relocate("org.apache.commons.codec", "org.maxgamer.quickshop.shade.org.apache.commons.codec")
relocate("me.lucko.helper", "org.maxgamer.quickshop.shade.me.lucko.helper")
relocate("com.github.SparklingComet", "org.maxgamer.quickshop.shade.com.github.SparklingComet")
relocate("de.themoep", "org.maxgamer.quickshop.shade.de.themoep")
relocate("io.papermc.lib", "org.maxgamer.quickshop.shade.io.papermc.lib")
relocate("com.github.ben-manes.caffeine", "org.maxgamer.quickshop.shade.com.github.ben-manes.caffeine")
relocate("org.enginehub.squirrelid", "org.maxgamer.quickshop.shade.org.enginehub.squirrelid")
relocate("kotlin", "org.maxgamer.quickshop.shade.org.kotlin")
relocate("javax.annotation", "org.maxgamer.quickshop.shade.org.javax.annotation")
relocate("com.flowpowered.math", "org.maxgamer.quickshop.shade.com.flowpowered.math")
relocate("okio", "org.maxgamer.quickshop.shade.okio")
relocate("okhttp3", "org.maxgamer.quickshop.shade.okhttp3")
relocate("net.kyori.minecraft", "org.maxgamer.quickshop.shade.net.kyori.minecraft")
relocate("net.minidev.asm", "org.maxgamer.quickshop.shade.net.minidev.asm")
relocate("com.squareup", "org.maxgamer.quickshop.shade.org.com.squareup")
relocate("de.leonhard.storage", "org.maxgamer.quickshop.shade.de.leonhard.storage")
exclude("META-INF/*.SF")
exclude("META-INF/*.DSA")
exclude("META-INF/*.RSA")
exclude("META-INF/*.kotlin_module")
exclude("META-INF/*.txt")
exclude("META-INF/proguard/*")
exclude("META-INF/services/*")
exclude("META-INF/versions/9/*")
exclude("*License*")
exclude("*LICENSE*")
}
tasks.named("build") { dependsOn("spotlessApply", "shadowJar") }
apply(from = "eclipse.gradle.kts")
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="TreeWalker">
<module name="FinalLocalVariable"/>
<module name="AvoidStarImport"/>
<module name="Indentation">
<property name="severity" value="ignore"/>
</module>
</module>
<module name="RegexpSingleline">
<property name="format" value="\borg\.junit\.jupiter\.api\.Assertions\.fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="ignoreCase" value="true"/>
<property name="severity" value="warning"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="(?&lt;!\w)fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="severity" value="warning"/>
</module>
</module>
+404
View File
@@ -0,0 +1,404 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="23">
<profile kind="CodeFormatterProfile" name="TrueOG Network Formatting" version="23">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
</profile>
</profiles>
+155
View File
@@ -0,0 +1,155 @@
/* This is free and unencumbered software released into the public domain */
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
import org.gradle.api.tasks.bundling.Jar
import org.gradle.plugins.ide.eclipse.model.EclipseModel
val sourcePluginProjects =
configurations
.getByName("compileClasspath")
.allDependencies
.filterIsInstance<ProjectDependency>()
.map { it.path }
.filter { it.startsWith(":libs:") }
.distinct()
val sourcePluginProjectNames = sourcePluginProjects.map { it.substringAfterLast(":") }.toSet()
sourcePluginProjects.forEach { evaluationDependsOn(it) }
val ideLibs: Configuration by
configurations.creating {
isCanBeResolved = true
isCanBeConsumed = false
}
configure<EclipseModel> {
project { name = "${rootProject.name}-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<TaskProvider<Copy>>()
sourcePluginProjects.forEach { path ->
val sub = project(path)
val archiveTaskName = if ("shadowJar" in sub.tasks.names) "shadowJar" else "jar"
val archiveTask = sub.tasks.named<Jar>(archiveTaskName)
val copyTask =
tasks.register<Copy>("ideCopy${sub.name.replaceFirstChar(Char::titlecase)}") {
dependsOn(archiveTask)
from(archiveTask.flatMap { it.archiveFile })
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 or unresolved :libs: project refs.
val toRemove = mutableListOf<org.w3c.dom.Node>()
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 ?: ""
val isIdeLibEntry = kind == "lib" && (p == dirPath || p.startsWith("$dirPath/"))
val sourceProjectPath = p.removePrefix("/")
val isHalfImportedSourceModule = kind == "src" && p.startsWith("/libs:")
val isSourcePluginModule = kind == "src" && sourceProjectPath in sourcePluginProjectNames
if (isIdeLibEntry || isHalfImportedSourceModule || isSourcePluginModule) {
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<EclipseModel>()
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()
+7
View File
@@ -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
Vendored Executable
+251
View File
@@ -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" "$@"
Vendored
+94
View File
@@ -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
Vendored
-259
View File
@@ -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-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -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 "$@"
Vendored
-149
View File
@@ -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-<version>,maven-mvnd-<version>-<platform>}/<hash>
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"
-865
View File
@@ -1,865 +0,0 @@
<!--
~ This file is a part of project QuickShop, the name is pom.xml
~ Copyright (C) PotatoCraft Studio and contributors
~
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the
~ Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
~ for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
~
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.maxgamer</groupId>
<artifactId>QuickShop</artifactId>
<properties>
<pluginver>5.1.2.5</pluginver>
<package>org.maxgamer.quickshop</package>
<developer>Ghost-chu</developer>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<version>${mvn.build.ver}</version>
<licenses>
<license>
<name>GPL v3 License</name>
<url>https://www.gnu.org/licenses/</url>
<distribution>repo</distribution>
</license>
</licenses>
<issueManagement>
<url>https://github.com/${developer}/${name}/issues</url>
<system>GitHub Issues</system>
</issueManagement>
<distributionManagement>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.io/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>codemc-snapshots</id>
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<profiles>
<profile>
<id>debug</id>
<properties>
<mvn.build.ver>${pluginver}-SNAPSHOT</mvn.build.ver>
<!-- Disable signature in local env, deploy phrase never will running in local env -->
<mvn.sign.phrase>deploy</mvn.sign.phrase>
</properties>
</profile>
<profile>
<id>master</id>
<properties>
<mvn.build.ver>${pluginver}-SNAPSHOT</mvn.build.ver>
<mvn.sign.phrase>install</mvn.sign.phrase>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>release</id>
<properties>
<mvn.build.ver>${pluginver}</mvn.build.ver>
<mvn.sign.phrase>install</mvn.sign.phrase>
</properties>
</profile>
</profiles>
<scm>
<url>https://github.com/${developer}/${project.version}</url>
<connection>scm:git:git://github.com/${developer}/${project.version}.git</connection>
<developerConnection>scm:git:git@github.com:${developer}/${project.version}.git</developerConnection>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>17</source>
<target>17</target>
<release>17</release>
<encoding>UTF-8</encoding>
<!--Use this comments args when compiler is NullPointerException-->
<!--<forceJavacCompilerUse>true</forceJavacCompilerUse>-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<finalName>QuickShop</finalName>
<minimizeJar>true</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<createSourcesJar>false</createSourcesJar>
<createTestSourcesJar>false</createTestSourcesJar>
<relocations>
<relocation>
<pattern>com.google.errorprone.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.google.errorprone.</shadedPattern>
</relocation>
<relocation>
<pattern>org.checkerframework.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.checkerframework.</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.lang3.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.apache.commons.lang3.</shadedPattern>
</relocation>
<relocation>
<pattern>org.objectweb.asm.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.objectweb.asm.</shadedPattern>
</relocation>
<relocation>
<pattern>org.slf4j.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.slf4j.slf4j.</shadedPattern>
</relocation>
<relocation>
<pattern>net.minidev.json.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.net.minidev.json.minidev.json.</shadedPattern>
</relocation>
<relocation>
<pattern>com.fasterxml.jackson.core.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.fasterxml.jackson.jackson.core.
</shadedPattern>
</relocation>
<relocation>
<pattern>me.lucko.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.me.lucko.</shadedPattern>
</relocation>
<relocation>
<pattern>com.rollbar.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.rollbar.</shadedPattern>
</relocation>
<relocation>
<pattern>com.dumptruckman.bukkit.configuration.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.dumptruckman.bukkit.configuration.
</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.compress.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.apache.commons.compress.</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.codec.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.apache.commons.codec.</shadedPattern>
</relocation>
<relocation>
<pattern>me.lucko.helper.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.me.lucko.helper.</shadedPattern>
</relocation>
<relocation>
<pattern>org.slf4j.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.slf4j.</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.SparklingComet.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.github.SparklingComet.</shadedPattern>
</relocation>
<relocation>
<pattern>de.themoep.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.de.themoep.</shadedPattern>
</relocation>
<relocation>
<pattern>io.papermc.lib.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.io.papermc.lib.</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.ben-manes.caffeine.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.github.ben-manes.caffeine.</shadedPattern>
</relocation>
<relocation>
<pattern>org.enginehub.squirrelid.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.enginehub.squirrelid.</shadedPattern>
</relocation>
<relocation>
<pattern>kotlin.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.kotlin.</shadedPattern>
</relocation>
<relocation>
<pattern>javax.annotation.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.javax.annotation.</shadedPattern>
</relocation>
<relocation>
<pattern>com.flowpowered.math.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.com.flowpowered.math.</shadedPattern>
</relocation>
<relocation>
<pattern>okio.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.okio.</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp3.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.okhttp3.</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.minecraft.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.net.kyori.minecraft.</shadedPattern>
</relocation>
<relocation>
<pattern>net.minidev.asm.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.net.minidev.asm.</shadedPattern>
</relocation>
<relocation>
<pattern>com.squareup.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.org.com.squareup.</shadedPattern>
</relocation>
<relocation>
<pattern>de.leonhard.storage.</pattern>
<shadedPattern>org.maxgamer.quickshop.shade.de.leonhard.storage.</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.maxgamer.quickshop.javaw.bootstrap.Bootstrap</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.kotlin_module</exclude>
<exclude>META-INF/*.txt</exclude>
<exclude>META-INF/proguard/*</exclude>
<exclude>META-INF/services/*</exclude>
<exclude>META-INF/versions/9/*</exclude>
<exclude>*License*</exclude>
<exclude>*LICENSE*</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<encoding>UTF-8</encoding>
<excludePackageNames>org.maxgamer.quickshop.nonquickshopstuff.*</excludePackageNames>
<!--<aggregate>true</aggregate>
<charmvnset>UTF-8</charmvnset>
<docencoding>UTF-8</docencoding>-->
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<failOnError>false</failOnError>
<additionalJOption>-Xdoclint:none</additionalJOption>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>src/main/resources/bin</exclude>
<exclude>src/main/resources/lang</exclude>
</excludes>
</resource>
<resource>
<targetPath>bin</targetPath>
<filtering>false</filtering>
<directory>src/main/resources/bin</directory>
</resource>
<resource>
<targetPath>lang</targetPath>
<filtering>false</filtering>
<directory>src/main/resources/lang</directory>
</resource>
<resource>
<targetPath>crowdin/lang</targetPath>
<filtering>false</filtering>
<directory>crowdin/lang</directory>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<!--Disable for 503
<repository>
<id>sk89q-repo</id>
<url>https://maven.sk89q.com/repo/</url>
</repository>-->
<repository>
<id>dmulloy2-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
<repository>
<id>CodeMC</id>
<url>https://repo.codemc.io/repository/maven-public/</url>
</repository>
<repository>
<id>Sonatype-public</id>
<name>SnakeYAML repository</name>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>md_5-snapshots</id>
<url>https://repo.md-5.net/content/repositories/snapshots/</url>
</repository>
<repository>
<id>md_5-releases</id>
<url>https://repo.md-5.net/content/repositories/releases/</url>
</repository>
<repository>
<id>EnderZone</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<!-- JsonConfiguration -->
<repository>
<id>onarandombox</id>
<url>https://repo.onarandombox.com/content/groups/public</url>
</repository>
<!-- for development builds -->
<repository>
<id>sonatype-oss</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>bg-repo</id>
<url>https://repo.bg-software.com/repository/api/</url>
</repository>
<repository>
<id>enginehub-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<!-- IridiumSkyblock -->
<!-- Temporary disable for downed website
<repository>
<id>IridiumDevelopment</id>
<url>https://nexus.iridiumdevelopment.net/repository/maven-releases/</url>
</repository>-->
<!--
<repository>
<id>Sparky</id>
<url>https://nexus.sparky.ac/repository/Sparky/</url>
</repository>-->
<repository>
<id>songoda</id>
<url>https://repo.craftaro.com/repository/public/</url>
</repository>
<!--MineDown -->
<repository>
<id>minebench-repo</id>
<url>https://repo.minebench.de/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>http://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.22</version>
</dependency>
<dependency>
<groupId>com.griefcraft.lwc</groupId>
<artifactId>LWCX</artifactId>
<version>2.2.7</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.TechFortress</groupId>
<artifactId>GriefPrevention</artifactId>
<version>16.18.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>com.sk89q</groupId>
<artifactId>worldguard</artifactId>
</exclusion>
<exclusion>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
<!--JsonConfiguration Dependency Start-->
<dependency>
<groupId>com.dumptruckman.minecraft</groupId>
<artifactId>JsonConfiguration</artifactId>
<version>1.1</version>
</dependency>
<!--JsonConfiguration Dependency End-->
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
<exclusion>
<artifactId>bukkit</artifactId>
<groupId>org.bukkit</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>net.tnemc</groupId>-->
<!-- <artifactId>Reserve</artifactId>-->
<!-- <version>0.1.3.0</version>-->
<!-- <scope>provided</scope>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>com.github</groupId>-->
<!-- <artifactId>TNELib</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.true-og.OpenInv</groupId>
<artifactId>openinvapi</artifactId>
<version>a85e8ebc28</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>fr.neatmonster</groupId>
<artifactId>nocheatplus</artifactId>
<version>3.17-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.minebuilders</groupId>
<artifactId>clearlag</artifactId>
<version>3.2.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Clearlag-3.2.2.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.clerezza.ext/org.json.simple -->
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.angeschossen</groupId>
<artifactId>LandsAPI</artifactId>
<version>6.35.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<!-- Documentation of MockBukkit: https://github.com/MockBukkit/MockBukkit -->
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.20</artifactId>
<version>3.87.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>spigot-api</artifactId>
<groupId>org.spigotmc</groupId>
</exclusion>
<exclusion>
<artifactId>annotations</artifactId>
<groupId>org.jetbrains</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Database lib for testing-->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.40.1.0</version>
<scope>test</scope>
</dependency>
<!-- Database lib for testing-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>me.vagdedes.spartan</groupId>
<artifactId>SpartanAPI</artifactId>
<version>9.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/SpartanAPI-9.1.jar</systemPath>
</dependency>
<!--New towny version, As we support 1.13+, so we choose 0.96.2.0 according their README-->
<dependency>
<groupId>com.github.TownyAdvanced</groupId>
<artifactId>Towny</artifactId>
<version>0.97.0.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.9</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>annotations</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>truecommons-logging</artifactId>
<groupId>net.java.truecommons</groupId>
</exclusion>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>bstats-bukkit</artifactId>
<groupId>org.bstats</groupId>
</exclusion>
<exclusion>
<artifactId>bukkit</artifactId>
<groupId>org.bukkit</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>spigot-api</artifactId>
<groupId>org.spigotmc</groupId>
</exclusion>
<exclusion>
<artifactId>httpclient</artifactId>
<groupId>org.apache.httpcomponents</groupId>
</exclusion>
<exclusion>
<artifactId>truevfs-comp-zip</artifactId>
<groupId>net.java.truevfs</groupId>
</exclusion>
<exclusion>
<artifactId>truevfs-comp-tardriver</artifactId>
<groupId>net.java.truevfs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Core</artifactId>
<version>6.11.1</version>
<scope>provided</scope>
<!--We just need the core jar-->
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.bekvon.bukkit.residence</groupId>
<artifactId>Residence</artifactId>
<version>5.0.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Residence5.0.1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>
<artifactId>Factions</artifactId>
<version>1.6.9.5-U0.6.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.primesoft.blockshub</groupId>
<artifactId>BlocksHub</artifactId>
<version>3.2.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/BlocksHub-3.2.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.rollbar</groupId>
<version>1.10.0</version>
<artifactId>rollbar-java</artifactId>
</dependency>
<dependency>
<groupId>com.github.PotatoCraft-Studio</groupId>
<artifactId>MineDown</artifactId>
<version>1.7.1-modified</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.xanium</groupId>
<artifactId>GemsEconomy</artifactId>
<scope>system</scope>
<version>4.9.3-GCRemake-1.6</version>
<systemPath>${project.basedir}/lib/GemsEconomy-4.9.2.jar</systemPath>
</dependency>
<dependency>
<groupId>tne.tne</groupId>
<artifactId>TheNewEconomy</artifactId>
<scope>system</scope>
<version>0.1.1.17-PRE-2</version>
<systemPath>${project.basedir}/lib/TNE-0.1.1.17-PRE-2.jar</systemPath>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>skyblock</artifactId>
<version>2.3.30</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>MVdWPlaceholderAPI</artifactId>
<groupId>be.maximvdw</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.songoda</groupId>
<artifactId>SongodaCore</artifactId>
<version>2.6.18</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.32</version>
<scope>compile</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.simplix-softworks</groupId>-->
<!-- <artifactId>SimplixStorage</artifactId>-->
<!-- <version>3.1.9</version>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.bgsoftware</groupId>
<artifactId>SuperiorSkyblockAPI</artifactId>
<version>1.11.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.lucko</groupId>
<artifactId>helper</artifactId>
<version>5.6.13</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.lucko</groupId>
<artifactId>helper-profiles</artifactId>
<version>1.2.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.github.alex9849.arm-shopbridge</groupId>-->
<!-- <artifactId>armshopbridge</artifactId>-->
<!-- <version>1.2.5</version>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>com.github.alex9849</groupId>
<artifactId>advanced-region-market</artifactId>
<version>3.5.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.iridium</groupId>
<artifactId>IridiumSkyblock</artifactId>
<version>3.2.3</version>
<systemPath>${project.basedir}/lib/IridiumSkyblock-3.2.3.jar</systemPath>
<scope>system</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.maxgamer.storage</groupId>
<artifactId>simplixstorage</artifactId>
<version>3.2.3.3</version>
</dependency>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api-plugin</artifactId>
<version>2.12.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.tnemc</groupId>
<artifactId>Reserve</artifactId>
<version>0.1.5.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
+1
View File
@@ -0,0 +1 @@
rootProject.name = "QuickShop-OG"
@@ -29,7 +29,8 @@ import java.util.Arrays;
import java.util.logging.Logger;
/**
* BootError class contains print errors on /qs command when plugin failed launched.
* BootError class contains print errors on /qs command when plugin failed
* launched.
*
* @author Ghost_chu
*/
@@ -40,29 +41,42 @@ public class BootError {
private final String[] errors;
public BootError(@NotNull Logger logger, @NotNull String... errors) {
this.errors = errors;
for (String err : errors) {
logger.severe(err);
}
}
/**
* Print the errors. ##################################################### QuickShop is disabled,
* Please fix errors and restart ..........................
* Print the errors. #####################################################
* QuickShop is disabled, Please fix errors and restart
* ..........................
* #################################################### This one.
*
* @param sender The sender you want output the errors.
*/
public void printErrors(CommandSender sender) { //Do not use any method that not in CraftBukkit
public void printErrors(CommandSender sender) { // Do not use any method that not in CraftBukkit
sender.sendMessage(ChatColor.RED + "#####################################################");
sender.sendMessage(ChatColor.RED + " QuickShop is disabled, Please fix any errors and restart");
for (String issue : errors) {
sender.sendMessage(ChatColor.WHITE + "- " + ChatColor.YELLOW + issue);
}
sender.sendMessage(ChatColor.RED + "#####################################################");
}
public String[] getErrors() {
return Arrays.copyOf(errors, errors.length);
}
}
@@ -29,12 +29,14 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
/**
* BuildInfo is utilities to help read BUILDINFO file that generated by CodeMC Jenkins.
* BuildInfo is utilities to help read BUILDINFO file that generated by CodeMC
* Jenkins.
*
* @author Ghost_chu
*/
@Data
public class BuildInfo {
private final int buildId;
private final String buildTag;
private final String buildUrl;
@@ -50,7 +52,9 @@ public class BuildInfo {
private static final String UNKNOWN = "Unknown";
public BuildInfo(@Nullable InputStream inputStream) {
if (inputStream == null) {
buildId = 0;
buildTag = UNKNOWN;
buildUrl = UNKNOWN;
@@ -62,8 +66,11 @@ public class BuildInfo {
pomBuildNumber = UNKNOWN;
jobUrl = null;
return;
}
YamlConfiguration buildInfo = YamlConfiguration.loadConfiguration(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
YamlConfiguration buildInfo = YamlConfiguration
.loadConfiguration(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
buildId = buildInfo.getInt("build-id", 0);
buildTag = buildInfo.getString("build-tag", "Unknown");
buildUrl = buildInfo.getString("build-url", "Unknown");
@@ -75,8 +82,13 @@ public class BuildInfo {
jobName = buildInfo.getString("job-name", "Unknown");
pomBuildNumber = buildInfo.getString("pom-buildnumber", "1");
try {
inputStream.close();
} catch (IOException ignored) {
}
}
}
@@ -32,10 +32,10 @@ public class BuiltInSolution {
* @return The error reason.
*/
public static BootError databaseError() {
return new BootError(QuickShop.getInstance().getLogger(),
"Error connecting to the database!",
"Please make sure your database service is running.",
"and check the configuration in your config.yml");
return new BootError(QuickShop.getInstance().getLogger(), "Error connecting to the database!",
"Please make sure your database service is running.", "and check the configuration in your config.yml");
}
/**
@@ -44,26 +44,32 @@ public class BuiltInSolution {
* @return The error reason.
*/
public static BootError econError() {
// Check if Vault is installed
if (QuickShop.getInstance().getServer().getPluginManager().getPlugin("Vault") == null) {
// Vault is not installed
return new BootError(QuickShop.getInstance().getLogger(),
"Vault is not installed or loaded!",
return new BootError(QuickShop.getInstance().getLogger(), "Vault is not installed or loaded!",
"Please make sure Vault is installed.");
}
// Vault is installed
if (QuickShop.getInstance().getServer().getPluginManager().getPlugin("CMI") != null) {
// Found possible incompatible plugin
return new BootError(QuickShop.getInstance().getLogger(),
"No Economy plugin detected! Please make sure that you have a compatible economy",
"plugin installed that is hooked into Vault and loads before QuickShop.",
ChatColor.YELLOW + "Incompatibility detected: CMI Installed",
"The use of the CMI Edition of Vault might fix this.");
}
return new BootError(QuickShop.getInstance().getLogger(),
"No Economy plugin detected! Please make sure that you have a",
"compatible economy plugin installed to get Vault working.");
}
}
+45 -12
View File
@@ -31,27 +31,28 @@ import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
/**
* Cache is a utilities to quick access shops on large network with Caffeine Cache Library
* Cache is a utilities to quick access shops on large network with Caffeine
* Cache Library
*
* @author Ghost_chu
*/
public class Cache {
private final QuickShop plugin;
private final com.google.common.cache.Cache<Location, BoxedShop> accessCaching = CacheBuilder
.newBuilder()
.initialCapacity(5000)
.expireAfterAccess(120, TimeUnit.MINUTES)
.recordStats()
.build();
private final com.google.common.cache.Cache<Location, BoxedShop> accessCaching = CacheBuilder.newBuilder()
.initialCapacity(5000).expireAfterAccess(120, TimeUnit.MINUTES).recordStats().build();
public Cache(QuickShop plugin) {
this.plugin = plugin;
}
public @NotNull CacheStats getStats() {
return accessCaching.stats();
}
return accessCaching.stats();
}
/**
* Gets shop from plugin caching
@@ -62,21 +63,32 @@ public class Cache {
*/
@Nullable
public Shop find(@NotNull Location location, boolean attached) {
BoxedShop boxedShop = accessCaching.getIfPresent(location);
//Cache is invalid, generated a new one
// Cache is invalid, generated a new one
if (boxedShop == null || !boxedShop.isValid()) {
Shop shop;
if (attached) {
shop = ((SimpleShopManager) plugin.getShopManager()).findShopIncludeAttached(location, false);
} else {
shop = plugin.getShopManager().getShop(location);
}
setCache(location, shop);
return shop;
} else {
//Cache is valid
// Cache is valid
return boxedShop.getShop();
}
}
/**
@@ -86,39 +98,60 @@ public class Cache {
* @param shop null for invalidate and Shop object for update
*/
public void setCache(@NotNull Location location, @Nullable Shop shop) {
accessCaching.put(location, new BoxedShop(shop));
}
public void invalidate(@NotNull Location location) {
accessCaching.invalidate(location);
}
private static class BoxedShop {
@Nullable
private final WeakReference<Shop> shopWeakRef;
public BoxedShop(Shop shop) {
if (shop != null) {
this.shopWeakRef = new WeakReference<>(shop);
} else {
shopWeakRef = null;
}
}
@Nullable
public Shop getShop() {
return shopWeakRef == null ? null : shopWeakRef.get();
}
public boolean isValid() {
if (shopWeakRef != null) {
Shop shop = shopWeakRef.get();
if (shop != null) {
return shop.isValid();
}
}
return false;
}
}
}
+277 -46
View File
@@ -48,8 +48,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@@ -59,9 +57,10 @@ import java.util.zip.GZIPOutputStream;
/**
* bStats collects some data for plugin authors.
*
* <p>Check out https://bStats.org/ to learn more about bStats!
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*/
@SuppressWarnings({"WeakerAccess"})
@SuppressWarnings({ "WeakerAccess" })
public class Metrics {
// The version of this bStats class
@@ -83,24 +82,33 @@ public class Metrics {
private static String serverUUID;
static {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null
|| !"false".equals(System.getProperty("bstats.relocatecheck"))) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick"
|| !"false".equals(System.getProperty("bstats.relocatecheck")))
{
// Maven's Relocate is clever and changes strings, too. So we have to use this
// little "trick"
// ... :D
final String defaultPackage =
new String(
new byte[]{
'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'
});
final String examplePackage =
new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
final String defaultPackage = new String(
new byte[]
{ 'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't' });
final String examplePackage = new String(
new byte[]
{ 'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e' });
// We want to make sure nobody just copy & pastes the example and use the wrong
// package names
if (Metrics.class.getPackage().getName().equals(defaultPackage)
|| Metrics.class.getPackage().getName().equals(examplePackage)) {
|| Metrics.class.getPackage().getName().equals(examplePackage))
{
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
// The plugin
@@ -121,13 +129,18 @@ public class Metrics {
* Class constructor.
*
* @param plugin The plugin which stats should be submitted.
* @param pluginId The id of the plugin. It can be found at <a
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
* @param pluginId The id of the plugin. It can be found at
* <a href="https://bstats.org/what-is-my-plugin-id">What is my
* plugin id?</a>
*/
public Metrics(Plugin plugin, int pluginId) {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
this.plugin = plugin;
this.pluginId = pluginId;
@@ -151,18 +164,20 @@ public class Metrics {
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config
.options()
.header(
config.options().header(
"bStats collects some data for plugin authors like how many servers are using their plugins.\n"
+ "To honor their work, you should not disable it.\n"
+ "This has nearly no effect on the server performance!\n"
+ "Check out https://bStats.org/ to learn more :)")
.copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) {
}
}
// Load the data
@@ -173,23 +188,34 @@ public class Metrics {
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
if (enabled) {
boolean found = false;
// Search for all other bStats Metrics classes to see if we are the first one
for (Class<?> service : plugin.getServer().getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first
break;
} catch (NoSuchFieldException ignored) {
}
}
// Register our service
plugin.getServer().getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
if (!found) {
// We are the first!
startSubmitting();
}
}
}
/**
@@ -201,15 +227,25 @@ public class Metrics {
* @throws IOException If the request failed.
*/
private static void sendData(Plugin plugin, JsonObject data) throws IllegalAccessException, IOException {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
if (plugin.getServer().isPrimaryThread()) {
throw new IllegalAccessException("This method must not be called from the main thread!");
}
if (logSentData) {
plugin.getLogger().info("Sending data to bStats: " + data);
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
// Compress the data to save bandwidth
@@ -221,28 +257,37 @@ public class Metrics {
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty(
"Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
// Send data
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
try (BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)))
{
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (logResponseStatusText) {
plugin.getLogger().info("Sent data to bStats and received response: " + builder);
}
}
/**
@@ -253,110 +298,163 @@ public class Metrics {
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
// This ThreadFactory enforces the naming convention for our Threads
private final ThreadFactory threadFactory = task -> new Thread(task, "bStats-Metrics");
// Executor service for requests
// We use an executor service because the Bukkit scheduler is affected by server lags
//private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, threadFactory);
// We use an executor service because the Bukkit scheduler is affected by server
// lags
// private final ScheduledExecutorService scheduler =
// Executors.newScheduledThreadPool(1, threadFactory);
/**
* Starts the Scheduler which submits our data every 30 minutes.
*/
private void startSubmitting() {
final Consumer<ScheduledTask> submitTask = task -> {
if (!plugin.isEnabled()) { // Plugin was disabled
task.cancel();
return;
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
// Nevertheless we want our code to run in the Bukkit main thread, so we have to
// use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the
// stats collection is sync ;)
// global region is the closest thing we have to a main thread
plugin.getServer().getGlobalRegionScheduler().run(plugin, t -> submitData());
};
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay.
// WARNING: You must not modify and part of this Metrics class, including the submit delay or frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven
// distribution of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into
// the initial and second delay.
// WARNING: You must not modify and part of this Metrics class, including the
// submit delay or frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just
// don't do it!
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
AsyncScheduler scheduler = plugin.getServer().getAsyncScheduler();
scheduler.runDelayed(plugin, submitTask, initialDelay, TimeUnit.MILLISECONDS);
scheduler.runAtFixedRate(plugin, submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
}
/**
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JsonObject data = getServerData();
JsonArray pluginData = new JsonArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Class<?> service : plugin.getServer().getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
for (RegisteredServiceProvider<?> provider :
plugin.getServer().getServicesManager().getRegistrations(service)) {
for (RegisteredServiceProvider<?> provider : plugin.getServer().getServicesManager()
.getRegistrations(service))
{
try {
Object plugin =
provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
if (plugin instanceof JsonObject) {
pluginData.add((JsonObject) plugin);
} else { // old bstats version compatibility
try {
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
jsonStringGetter.setAccessible(true);
String jsonString = (String) jsonStringGetter.invoke(plugin);
JsonObject object = JsonUtil.readObject(jsonString).getAsJsonObject();
pluginData.add(object);
}
} catch (ClassNotFoundException e) {
// minecraft version 1.14+
if (logFailedRequests) {
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
}
}
}
} catch (NullPointerException
| NoSuchMethodException
| IllegalAccessException
| InvocationTargetException ignored) {
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException ignored)
{
}
}
} catch (NoSuchFieldException ignored) {
}
}
data.add("plugins", pluginData);
// Create a new thread for the connection to the bStats server
plugin.getServer().getAsyncScheduler().runNow(plugin, task -> {
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
}
}
});
}
/**
@@ -365,20 +463,26 @@ public class Metrics {
* @return The server specific data.
*/
private JsonObject getServerData() {
// Minecraft specific data
int playerAmount;
try {
// Around MC 1.8 the return type was changed to a collection from an array,
// This fixes java.lang.NoSuchMethodError:
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
playerAmount =
onlinePlayersMethod.getReturnType().equals(Collection.class)
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(plugin.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(plugin.getServer())).length;
} catch (Exception e) {
playerAmount = plugin.getServer().getOnlinePlayers().size(); // Just use the new method if the Reflection failed
playerAmount = plugin.getServer().getOnlinePlayers().size(); // Just use the new method if the Reflection
// failed
}
int onlineMode = plugin.getServer().getOnlineMode() ? 1 : 0;
String bukkitVersion = plugin.getServer().getVersion();
String bukkitName = plugin.getServer().getName();
@@ -406,6 +510,7 @@ public class Metrics {
data.addProperty("coreCount", coreCount);
return data;
}
/**
@@ -414,7 +519,9 @@ public class Metrics {
* @return Whether bStats is enabled or not.
*/
public boolean isEnabled() {
return enabled;
}
/**
@@ -423,10 +530,15 @@ public class Metrics {
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
if (chart == null) {
throw new IllegalArgumentException("Chart cannot be null!");
}
charts.add(chart);
}
/**
@@ -435,6 +547,7 @@ public class Metrics {
* @return The plugin specific data.
*/
public JsonObject getPluginData() {
JsonObject data = new JsonObject();
String pluginName = "QuickShop-" + QuickShop.getFork();
@@ -445,16 +558,23 @@ public class Metrics {
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
JsonArray customCharts = new JsonArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JsonObject chart = customChart.getRequestJsonObject();
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.add("customCharts", customCharts);
return data;
}
/**
@@ -471,30 +591,48 @@ public class Metrics {
* @param chartId The id of the chart.
*/
CustomChart(String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JsonObject getRequestJsonObject() {
JsonObject chart = new JsonObject();
chart.addProperty("chartId", chartId);
try {
JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.add("data", data);
} catch (Exception t) {
if (logFailedRequests) {
QuickShop.getInstance().getLogger()
.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
QuickShop.getInstance().getLogger().log(Level.WARNING,
"Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return chart;
}
protected abstract JsonObject getChartData() throws Exception;
@@ -515,20 +653,27 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.addProperty("value", value);
return data;
}
}
@@ -547,33 +692,49 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
@@ -592,38 +753,56 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObject value = new JsonObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.add(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
@@ -642,20 +821,27 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.addProperty("value", value);
return data;
}
}
@@ -674,33 +860,49 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
@@ -719,26 +921,36 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JsonArray categoryValues = new JsonArray();
categoryValues.add(new JsonPrimitive(entry.getValue()));
values.add(entry.getKey(), categoryValues);
}
data.add("values", values);
return data;
}
}
@@ -757,37 +969,56 @@ public class Metrics {
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue; // Skip this invalid
}
allSkipped = false;
JsonArray categoryValues = new JsonArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(new JsonPrimitive(categoryValue));
}
values.add(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
File diff suppressed because it is too large. Load diff
@@ -29,49 +29,80 @@ import org.maxgamer.quickshop.database.AbstractDatabaseCore;
import org.maxgamer.quickshop.localization.game.game.GameLanguage;
/**
* ServiceInjector used for "Replaceable Modules" features that allow 3rd party QuickShop addon
* replace some modules used in QuickShop internal by register as service.
* ServiceInjector used for "Replaceable Modules" features that allow 3rd party
* QuickShop addon replace some modules used in QuickShop internal by register
* as service.
*
* @author Ghost_chu
*/
public class ServiceInjector {
public static @NotNull AbstractEconomy getEconomy(@NotNull AbstractEconomy def) {
@Nullable RegisteredServiceProvider<? extends AbstractEconomy> registeredServiceProvider =
Bukkit.getServicesManager().getRegistration(AbstractEconomy.class);
@Nullable
RegisteredServiceProvider<? extends AbstractEconomy> registeredServiceProvider = Bukkit.getServicesManager()
.getRegistration(AbstractEconomy.class);
if (registeredServiceProvider == null) {
return def;
} else {
return registeredServiceProvider.getProvider();
}
}
public static @NotNull ItemMatcher getItemMatcher(@NotNull ItemMatcher def) {
@Nullable RegisteredServiceProvider<? extends ItemMatcher> registeredServiceProvider =
Bukkit.getServicesManager().getRegistration(ItemMatcher.class);
@Nullable
RegisteredServiceProvider<? extends ItemMatcher> registeredServiceProvider = Bukkit.getServicesManager()
.getRegistration(ItemMatcher.class);
if (registeredServiceProvider == null) {
return def;
} else {
return registeredServiceProvider.getProvider();
}
}
public static @Nullable GameLanguage getGameLanguage() {
@Nullable RegisteredServiceProvider<? extends GameLanguage> registeredServiceProvider =
Bukkit.getServicesManager().getRegistration(GameLanguage.class);
@Nullable
RegisteredServiceProvider<? extends GameLanguage> registeredServiceProvider = Bukkit.getServicesManager()
.getRegistration(GameLanguage.class);
if (registeredServiceProvider == null) {
return null;
} else {
return registeredServiceProvider.getProvider();
}
}
public static @NotNull AbstractDatabaseCore getDatabaseCore(@NotNull AbstractDatabaseCore def) {
@Nullable RegisteredServiceProvider<? extends AbstractDatabaseCore> registeredServiceProvider =
Bukkit.getServicesManager().getRegistration(AbstractDatabaseCore.class);
@Nullable
RegisteredServiceProvider<? extends AbstractDatabaseCore> registeredServiceProvider = Bukkit
.getServicesManager().getRegistration(AbstractDatabaseCore.class);
if (registeredServiceProvider == null) {
return def;
} else {
return registeredServiceProvider.getProvider();
}
}
}
@@ -33,6 +33,7 @@ import java.util.Map;
* The unique entry point to allow you to access most features of QuickShop
*/
public interface QuickShopAPI {
/**
* Getting Compatibility Manager (usually used for anti-cheat)
*
@@ -62,8 +63,7 @@ public interface QuickShopAPI {
boolean isDisplayEnabled();
/**
* Getting shop limit system status
* false if limit system is disabled
* Getting shop limit system status false if limit system is disabled
*
* @return Limit enabled
*/
@@ -84,7 +84,8 @@ public interface QuickShopAPI {
DatabaseHelper getDatabaseHelper();
/**
* Getting text manager that allow addon to create a user language locale based message
* Getting text manager that allow addon to create a user language locale based
* message
*
* @return The text maanger
*/
@@ -105,7 +106,8 @@ public interface QuickShopAPI {
boolean isPriceChangeRequiresFee();
/**
* Getting command manager that allow addon direct access QuickShop sub-command system
* Getting command manager that allow addon direct access QuickShop sub-command
* system
*
* @return The command manager
*/
@@ -3,13 +3,19 @@ package org.maxgamer.quickshop.api.chat;
import net.md_5.bungee.api.chat.BaseComponent;
public class ComponentPackage {
private final BaseComponent[] components;
public ComponentPackage(BaseComponent... components) {
this.components = components;
}
public BaseComponent[] getComponents() {
return components;
}
}
@@ -32,6 +32,7 @@ import java.util.Map;
* QuickChat is a system to allow us to process complex messages
*/
public interface QuickChat {
/**
* Send plain text to specified receiver
*
@@ -55,10 +56,7 @@ public interface QuickChat {
* @param text The text will sent
* @param itemStack The ItemStack will append to text in message
*/
void sendItemHologramChat(
@NotNull Player player,
@NotNull String text,
@NotNull ItemStack itemStack);
void sendItemHologramChat(@NotNull Player player, @NotNull String text, @NotNull ItemStack itemStack);
/**
* Generate the chat component with preview item hover event
@@ -69,7 +67,9 @@ public interface QuickChat {
* @param message The message with hover event
* @return The component
*/
@NotNull QuickComponent getItemHologramChat(@NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull Player player, @NotNull String message);
@NotNull
QuickComponent getItemHologramChat(@NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull Player player,
@NotNull String message);
/**
* Create chat with hover-item to specified receiver
@@ -79,16 +79,19 @@ public interface QuickChat {
* @param itemStack The ItemStack will append to text in message
* @return The QuickComponent created by this method
*/
@NotNull QuickComponent getItemTextComponent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull String text);
@NotNull
QuickComponent getItemTextComponent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull String text);
/**
* Send click-run-command chat to specified receiver
*
* @param receiver The PLAYER will receive this message
* @param message The text will sent
* @param textToCommandMapping The hover text associated with command, will be applied to placeholder (like {0} {1} {2}...)
* @param textToCommandMapping The hover text associated with command, will be
* applied to placeholder (like {0} {1} {2}...)
*/
void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message, Map.Entry<String, String>... textToCommandMapping);
void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message,
Map.Entry<String, String>... textToCommandMapping);
/**
* Send click-run-command chat to specified receiver
@@ -98,7 +101,8 @@ public interface QuickChat {
* @param hoverText The hover text will show when hover on chat
* @param command The command when click to be run
*/
void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText, @NotNull String command);
void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText,
@NotNull String command);
/**
* Send click-suggest-command chat to specified receiver
@@ -108,6 +112,7 @@ public interface QuickChat {
* @param command The command when click to be suggested
* @param hoverText The text while player hover on the text
*/
void sendSuggestedChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText, @NotNull String command);
void sendSuggestedChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText,
@NotNull String command);
}
@@ -25,12 +25,14 @@ import org.jetbrains.annotations.NotNull;
* Pack the MineDown
*/
public interface QuickComponent {
/**
* Gets QuickComponent object (BungeeChatComponent or AdventureChatComponent)
*
* @return The component
*/
@NotNull Object get();
@NotNull
Object get();
/**
* Sets QuickComponent object (BungeeChatComponent or AdventureChatComponent)
@@ -38,4 +40,5 @@ public interface QuickComponent {
* @param component The component
*/
void set(@NotNull Object component);
}
@@ -36,12 +36,14 @@ import java.util.function.Supplier;
@Data
@Builder
public class CommandContainer {
@NotNull
private CommandHandler<?> executor;
private boolean hidden; // Hide from help, tabcomplete
/*
E.g you can use the command when having quickshop.removeall.self or quickshop.removeall.others permission
* E.g you can use the command when having quickshop.removeall.self or
* quickshop.removeall.others permission
*/
@Singular
private List<String> selectivePermissions;
@@ -52,44 +54,71 @@ public class CommandContainer {
@Nullable
private String description; // Will show in the /qs help
private boolean disabled; //Set command is disabled or not.
private boolean disabled; // Set command is disabled or not.
@Nullable
private Supplier<Boolean> disabledSupplier; //Set command is disabled or not.
private Supplier<Boolean> disabledSupplier; // Set command is disabled or not.
@Nullable
private String disablePlaceholder; //Set the text shown if command disabled
private String disablePlaceholder; // Set the text shown if command disabled
@Nullable
private Function<@Nullable CommandSender, @NotNull String> disableCallback; //Set the callback that should return a text to shown
private Function<@Nullable CommandSender, @NotNull String> disableCallback; // Set the callback that should return a
// text to shown
private Class<?> executorType;
@NotNull
public Class<?> getExecutorType() {
if (executorType == null) {
bakeExecutorType();
}
return executorType;
}
public void bakeExecutorType() {
for (Method declaredMethod : getExecutor().getClass().getMethods()) {
if ("onCommand".equals(declaredMethod.getName()) || "onTabComplete".equals(declaredMethod.getName())) {
if (declaredMethod.getParameterCount() != 3 || declaredMethod.isSynthetic() || declaredMethod.isBridge()) {
if (declaredMethod.getParameterCount() != 3 || declaredMethod.isSynthetic()
|| declaredMethod.isBridge())
{
continue;
}
executorType = declaredMethod.getParameterTypes()[0];
return;
}
}
executorType = Object.class;
}
public final @NotNull String getDisableText(@NotNull CommandSender sender) {
if (this.getDisableCallback() != null) {
return this.getDisableCallback().apply(sender);
} else if (StringUtils.isNotEmpty(this.getDisablePlaceholder())) {
return this.getDisablePlaceholder();
} else {
return QuickShop.getInstance().text().of(sender, "command.feature-not-enabled").forLocale();
}
}
}
@@ -29,13 +29,16 @@ import java.util.List;
/**
* The command handler that processing sub commands under QS main command
*
* @param <T> The required sender class you want, must is the sub type of CommandSender
* @param <T> The required sender class you want, must is the sub type of
* CommandSender
*/
public interface CommandHandler<T extends CommandSender> {
/**
* Calling while command executed by specified sender
*
* @param sender The command sender but will automatically convert to specified instance
* @param sender The command sender but will automatically convert to
* specified instance
* @param commandLabel The command prefix (/qs = qs, /shop = shop)
* @param cmdArg The arguments (/qs create stone will receive stone)
*/
@@ -44,13 +47,17 @@ public interface CommandHandler<T extends CommandSender> {
/**
* Calling while sender trying to tab-complete
*
* @param sender The command sender but will automatically convert to specified instance
* @param sender The command sender but will automatically convert to
* specified instance
* @param commandLabel The command prefix (/qs = qs, /shop = shop)
* @param cmdArg The arguments (/qs create stone [TAB] will receive stone)
* @return Candidate list
*/
@Nullable
default List<String> onTabComplete(@NotNull T sender, @NotNull String commandLabel, @NotNull String[] cmdArg) {
return Collections.emptyList();
}
}
@@ -27,12 +27,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* The manager that managing all sub-commands that registered
* Also performing permission checks in there.
* The manager that managing all sub-commands that registered Also performing
* permission checks in there.
*/
public interface CommandManager {
/**
* This is a interface to allow addons to register the subcommand into quickshop command manager.
* This is a interface to allow addons to register the subcommand into quickshop
* command manager.
*
* @param container The command container to register
* @throws IllegalStateException Will throw the error if register conflict.
@@ -40,7 +42,8 @@ public interface CommandManager {
void registerCmd(@NotNull CommandContainer container);
/**
* This is a interface to allow addons to unregister the registered/butil-in subcommand from command manager.
* This is a interface to allow addons to unregister the registered/butil-in
* subcommand from command manager.
*
* @param container The command container to unregister
*/
@@ -51,17 +54,14 @@ public interface CommandManager {
*
* @return All registered commands.
*/
@NotNull List<CommandContainer> getRegisteredCommands();
@NotNull
List<CommandContainer> getRegisteredCommands();
boolean onCommand(
@NotNull CommandSender sender,
@NotNull Command command,
@NotNull String commandLabel,
boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String commandLabel,
@NotNull String[] cmdArg);
@Nullable List<String> onTabComplete(
@NotNull CommandSender sender,
@NotNull Command command,
@NotNull String commandLabel,
@Nullable
List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String commandLabel,
@NotNull String[] cmdArg);
}
@@ -35,9 +35,12 @@ public interface CommandProcesser extends CommandHandler<CommandSender> {
@Override
@Nullable
default List<String> onTabComplete(
@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) {
default List<String> onTabComplete(@NotNull CommandSender sender, @NotNull String commandLabel,
@NotNull String[] cmdArg)
{
return Collections.emptyList();
}
}
@@ -25,12 +25,18 @@ import org.maxgamer.quickshop.QuickShop;
import org.maxgamer.quickshop.util.holder.QuickShopInstanceHolder;
public abstract class AbstractQSCompatibilityModule extends QuickShopInstanceHolder implements CompatibilityModule {
public AbstractQSCompatibilityModule(QuickShop plugin) {
super(plugin);
}
@Override
public @NotNull Plugin getPlugin() {
return plugin;
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
* Manager that managing all registered compatibility for anti-cheat modules
*/
public interface CompatibilityManager {
/**
* Check a module registered
*
@@ -35,10 +36,12 @@ public interface CompatibilityManager {
boolean isRegistered(String moduleName);
/**
* Switch the compatibility mode on or off, set false to disable all we known incompatiable plugin
* listener, set true to enable back all disabled plugin liseners. WIP
* Switch the compatibility mode on or off, set false to disable all we known
* incompatiable plugin listener, set true to enable back all disabled plugin
* liseners. WIP
*
* @param status true=turn on closed listeners, false=turn off all turned on listeners.
* @param status true=turn on closed listeners, false=turn off all turned on
* listeners.
* @param player The player to check the listeners
*/
void toggleProtectionListeners(boolean status, @NotNull Player player);
@@ -68,4 +71,5 @@ public interface CompatibilityManager {
* @param module Compatibility module
*/
void unregister(@NotNull CompatibilityModule module);
}
@@ -24,12 +24,14 @@ import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
public interface CompatibilityModule {
/**
* Gets the CompatibilityModule provider name
*
* @return Provider name
*/
@NotNull String getName();
@NotNull
String getName();
/***
* Call on registering module
@@ -50,13 +52,16 @@ public interface CompatibilityModule {
*
* @return Provider Plugin instance
*/
@NotNull Plugin getPlugin();
@NotNull
Plugin getPlugin();
/**
* Calls CompatibilityModule to toggle the detection status for player between on and off
* Calls CompatibilityModule to toggle the detection status for player between
* on and off
*
* @param player The player
* @param status On or Off
*/
void toggle(@NotNull Player player, boolean status);
}
@@ -30,6 +30,7 @@ import java.util.UUID;
import java.util.function.Consumer;
public interface DatabaseHelper {
/**
* Creates a column with specific name and data type
*
@@ -48,7 +49,8 @@ public interface DatabaseHelper {
void cleanMessage(long weekAgo);
/**
* Purge and clean all saved transaction message in data that should send to specific player
* Purge and clean all saved transaction message in data that should send to
* specific player
*
* @param player The player
*/
@@ -113,7 +115,6 @@ public interface DatabaseHelper {
*/
void saveOfflineTransactionMessage(@NotNull UUID player, @NotNull String message, long time);
/**
* Upgrade legacy name based data record to uniqueId based record
*
@@ -126,8 +127,7 @@ public interface DatabaseHelper {
void updateOwner2UUID(@NotNull String ownerUUID, int x, int y, int z, @NotNull String worldName);
/**
* Update external cache data
* (Used for Web UI or other something like that)
* Update external cache data (Used for Web UI or other something like that)
*
* @param shop The shop
* @param space The shop remaining space
@@ -152,9 +152,9 @@ public interface DatabaseHelper {
* @param disableDisplay Shop display disabled status
* @param taxAccount Shop specific tax account
*/
void updateShop(@NotNull String owner, @NotNull ItemStack item, int unlimited, int shopType,
double price, int x, int y, int z, @NotNull String world, @NotNull String extra,
@Nullable String currency, boolean disableDisplay, @Nullable String taxAccount);
void updateShop(@NotNull String owner, @NotNull ItemStack item, int unlimited, int shopType, double price, int x,
int y, int z, @NotNull String world, @NotNull String extra, @Nullable String currency,
boolean disableDisplay, @Nullable String taxAccount);
/**
* Insert a history record into logs table
@@ -23,8 +23,10 @@ import java.sql.ResultSet;
import java.sql.SQLException;
public interface WarpedResultSet extends AutoCloseable {
@Override
void close() throws SQLException;
ResultSet getResultSet();
}
@@ -35,6 +35,7 @@ import java.util.UUID;
public abstract class AbstractEconomy implements EconomyCore, Reloadable {
public AbstractEconomy() {
}
/**
@@ -43,15 +44,17 @@ public abstract class AbstractEconomy implements EconomyCore, Reloadable {
* @return Economy type that QuickShop now using
*/
public static EconomyType getNowUsing() {
return EconomyType.fromID(QuickShop.getInstance().getConfig().getInt("economy-type"));
}
@Override
public abstract String toString();
/**
* Transfer specific amount of currency from A to B
* (Developer: This is low layer of Economy System, use EconomyTransaction if possible)
* Transfer specific amount of currency from A to B (Developer: This is low
* layer of Economy System, use EconomyTransaction if possible)
*
* @param from The player who is paying money
* @param to The player who is receiving money
@@ -61,26 +64,44 @@ public abstract class AbstractEconomy implements EconomyCore, Reloadable {
* @return successed
*/
@Override
public boolean transfer(@NotNull UUID from, @NotNull UUID to, double amount, @NotNull World world, @Nullable String currency) {
public boolean transfer(@NotNull UUID from, @NotNull UUID to, double amount, @NotNull World world,
@Nullable String currency)
{
if (!isValid()) {
return false;
}
if (this.getBalance(from, world, currency) >= amount) {
if (this.withdraw(from, amount, world, currency)) {
if (this.deposit(to, amount, world, currency)) {
this.deposit(from, amount, world, currency);
return false;
}
return true;
}
return false;
}
return false;
}
@Override
public @NotNull String getName() {
return "BuiltIn-Economy Processor";
}
/**
@@ -90,6 +111,9 @@ public abstract class AbstractEconomy implements EconomyCore, Reloadable {
*/
@Override
public ReloadResult reloadModule() {
return ReloadResult.builder().status(ReloadStatus.SUCCESS).build();
}
}
@@ -31,6 +31,7 @@ import java.util.UUID;
* @author netherfoam Represents an economy.
*/
public interface EconomyCore {
/**
* Deposits a given amount of money from thin air to the given username.
*
@@ -54,7 +55,8 @@ public interface EconomyCore {
boolean deposit(@NotNull OfflinePlayer trader, double amount, @NotNull World world, @Nullable String currency);
/**
* Formats the given number... E.g. 50.5 becomes $50.5 Dollars, or 50 Dollars 5 Cents
* Formats the given number... E.g. 50.5 becomes $50.5 Dollars, or 50 Dollars 5
* Cents
*
* @param balance The given number
* @param currency The currency name
@@ -91,12 +93,15 @@ public interface EconomyCore {
* @param amount The amount to transfer
* @param currency The currency name
* @param world The transaction world
* @return true if success (Payer had enough cash, receiver was able to receive the funds)
* @return true if success (Payer had enough cash, receiver was able to receive
* the funds)
*/
boolean transfer(@NotNull UUID from, @NotNull UUID to, double amount, @NotNull World world, @Nullable String currency);
boolean transfer(@NotNull UUID from, @NotNull UUID to, double amount, @NotNull World world,
@Nullable String currency);
/**
* Withdraws a given amount of money from the given username and turns it to thin air.
* Withdraws a given amount of money from the given username and turns it to
* thin air.
*
* @param name The exact (case insensitive) username to take money from
* @param amount The amount to take from them
@@ -107,7 +112,8 @@ public interface EconomyCore {
boolean withdraw(@NotNull UUID name, double amount, @NotNull World world, @Nullable String currency);
/**
* Withdraws a given amount of money from the given username and turns it to thin air.
* Withdraws a given amount of money from the given username and turns it to
* thin air.
*
* @param trader The player to take money from
* @param amount The amount to take from them
@@ -135,12 +141,12 @@ public interface EconomyCore {
/**
* Gets the economy processor last error message
*
* @return Error message or null if never happens
*/
@Nullable
String getLastError();
/**
* Checks that this economy is valid. Returns false if it is not valid.
*
@@ -153,13 +159,15 @@ public interface EconomyCore {
*
* @return Impl name
*/
@NotNull String getName();
@NotNull
String getName();
/**
* Getting Economy impl owned by
*
* @return Owned by
*/
@NotNull Plugin getPlugin();
@NotNull
Plugin getPlugin();
}
@@ -38,6 +38,7 @@ import java.util.UUID;
@Getter
public class EconomyTransaction {
@Nullable
private final UUID from;
@Nullable
@@ -60,12 +61,11 @@ public class EconomyTransaction {
@JsonUtil.Hidden
private final QuickShop plugin = QuickShop.getInstance();
@Getter
private TransactionSteps steps; //For rollback
private TransactionSteps steps; // For rollback
@Nullable
@Getter
private String lastError = null;
/**
* Create a transaction
*
@@ -79,7 +79,11 @@ public class EconomyTransaction {
*/
@Builder
public EconomyTransaction(@Nullable UUID from, @Nullable UUID to, double amount, double taxModifier, @Nullable Trader taxAccount, EconomyCore core, boolean allowLoan, @NotNull World world, @Nullable String currency) {
public EconomyTransaction(@Nullable UUID from, @Nullable UUID to, double amount, double taxModifier,
@Nullable Trader taxAccount, EconomyCore core, boolean allowLoan, @NotNull World world,
@Nullable String currency)
{
this.from = from;
this.to = to;
this.core = core == null ? QuickShop.getInstance().getEconomy() : core;
@@ -90,47 +94,75 @@ public class EconomyTransaction {
this.world = world;
this.currency = currency;
if (Double.doubleToLongBits(taxModifier) != Double.doubleToLongBits(0.0d)) { //Calc total money and apply tax
if (Double.doubleToLongBits(taxModifier) != Double.doubleToLongBits(0.0d)) { // Calc total money and apply tax
this.actualAmount = CalculateUtil.multiply(CalculateUtil.subtract(1, taxModifier), amount);
} else {
this.actualAmount = amount;
}
this.tax = CalculateUtil.subtract(amount, actualAmount); //Calc total tax
this.tax = CalculateUtil.subtract(amount, actualAmount); // Calc total tax
if (from == null && to == null) {
lastError = "From and To cannot be null in same time.";
throw new IllegalArgumentException("From and To cannot be null in same time.");
}
//For passing Test
//noinspection ConstantConditions
// For passing Test
// noinspection ConstantConditions
if (QuickShop.getInstance() != null) {
this.tryingFixBalanceInsufficient = QuickShop.getInstance().getConfig().getBoolean("trying-fix-banlance-insuffient");
this.tryingFixBalanceInsufficient = QuickShop.getInstance().getConfig()
.getBoolean("trying-fix-banlance-insuffient");
} else {
this.tryingFixBalanceInsufficient = false;
}
if (tryingFixBalanceInsufficient) {
//Fetch some stupid plugin caching
// Fetch some stupid plugin caching
if (from != null) {
this.core.getBalance(from, world, currency);
}
if (to != null) {
this.core.getBalance(to, world, currency);
}
}
}
/**
* Commit the transaction by the Fail-Safe way
* Automatic rollback when commit failed
* Commit the transaction by the Fail-Safe way Automatic rollback when commit
* failed
*
* @return The transaction success.
*/
public boolean failSafeCommit() {
Util.debugLog("Transaction begin: FailSafe Commit --> " + from + " => " + to + "; Amount: " + amount + ", EconomyCore: " + core.getName());
Util.debugLog("Transaction begin: FailSafe Commit --> " + from + " => " + to + "; Amount: " + amount
+ ", EconomyCore: " + core.getName());
boolean result = commit();
if (!result) {
rollback(true);
}
return result;
}
/**
@@ -139,20 +171,33 @@ public class EconomyTransaction {
* @return The transaction success.
*/
public boolean commit() {
return this.commit(new TransactionCallback() {
@Override
public void onSuccess(@NotNull EconomyTransaction economyTransaction) {
if (tryingFixBalanceInsufficient) {
//Fetch some stupid plugin caching
// Fetch some stupid plugin caching
if (from != null) {
core.getBalance(from, world, currency);
}
if (to != null) {
core.getBalance(to, world, currency);
}
}
}
});
}
/**
@@ -162,95 +207,129 @@ public class EconomyTransaction {
* @return The transaction success.
*/
public boolean commit(@NotNull TransactionCallback callback) {
Util.debugLog("Transaction begin: Regular Commit --> " + from + " => " + to + "; Amount: " + amount + " Total(include tax): " + actualAmount + " Tax: " + tax + ", EconomyCore: " + core.getName());
Util.debugLog("Transaction begin: Regular Commit --> " + from + " => " + to + "; Amount: " + amount
+ " Total(include tax): " + actualAmount + " Tax: " + tax + ", EconomyCore: " + core.getName());
steps = TransactionSteps.CHECK;
if (!callback.onCommit(this)) {
this.lastError = "Plugin cancelled this transaction.";
return false;
}
if (from != null && core.getBalance(from, world, currency) < amount && !allowLoan) {
this.lastError = "From hadn't enough money";
callback.onFailed(this);
return false;
}
steps = TransactionSteps.WITHDRAW;
if (from != null && !core.withdraw(from, amount, world, currency)) {
this.lastError = "Failed to withdraw " + amount + " from player " + from + " account. LastError: " + core.getLastError();
this.lastError = "Failed to withdraw " + amount + " from player " + from + " account. LastError: "
+ core.getLastError();
callback.onFailed(this);
return false;
}
steps = TransactionSteps.DEPOSIT;
if (to != null && !core.deposit(to, actualAmount, world, currency)) {
this.lastError = "Failed to deposit " + actualAmount + " to player " + to + " account. LastError: " + core.getLastError();
this.lastError = "Failed to deposit " + actualAmount + " to player " + to + " account. LastError: "
+ core.getLastError();
callback.onFailed(this);
return false;
}
steps = TransactionSteps.TAX;
if (tax > 0 && taxer != null && !core.deposit(taxer, tax, world, currency)) {
this.lastError = "Failed to deposit tax account: " + tax + ". LastError: " + core.getLastError();
callback.onTaxFailed(this);
//Tax never should failed.
// Tax never should failed.
}
steps = TransactionSteps.DONE;
callback.onSuccess(this);
return true;
}
/**
* Rolling back the transaction
*
* @param continueWhenFailed Continue when some parts of the rollback fails.
* @return A list contains all steps executed. If "continueWhenFailed" is false, it only contains all success steps before hit the error. Else all.
* @return A list contains all steps executed. If "continueWhenFailed" is false,
* it only contains all success steps before hit the error. Else all.
*/
@SuppressWarnings("UnusedReturnValue")
@NotNull
public List<RollbackSteps> rollback(boolean continueWhenFailed) {
List<RollbackSteps> rollbackSteps = new ArrayList<>(3);
if (steps == TransactionSteps.CHECK) {
return rollbackSteps; //We did nothing, just checks balance
return rollbackSteps; // We did nothing, just checks balance
}
if (steps == TransactionSteps.WITHDRAW) {
return rollbackSteps; //We did nothing, because the trade failed so no anybody money changes.
return rollbackSteps; // We did nothing, because the trade failed so no anybody money changes.
}
if (steps == TransactionSteps.DEPOSIT || steps == TransactionSteps.TAX) {
if (from != null && !core.deposit(from, amount, world, currency)) { //Rollback withdraw
if (from != null && !core.deposit(from, amount, world, currency)) { // Rollback withdraw
if (!continueWhenFailed) {
rollbackSteps.add(RollbackSteps.ROLLBACK_WITHDRAW);
return rollbackSteps;
}
}
}
if (steps == TransactionSteps.TAX) {
if (to != null && !core.withdraw(to, actualAmount, world, currency)) { //Rollback deposit
if (to != null && !core.withdraw(to, actualAmount, world, currency)) { // Rollback deposit
if (!continueWhenFailed) {
rollbackSteps.add(RollbackSteps.ROLLBACK_DEPOSIT);
return rollbackSteps;
}
}
}
rollbackSteps.add(RollbackSteps.ROLLBACK_DONE);
return rollbackSteps;
}
private enum RollbackSteps {
ROLLBACK_WITHDRAW,
ROLLBACK_DEPOSIT,
ROLLBACK_TAX,
ROLLBACK_DONE
ROLLBACK_WITHDRAW, ROLLBACK_DEPOSIT, ROLLBACK_TAX, ROLLBACK_DONE
}
public enum TransactionSteps {
WAIT,
CHECK,
WITHDRAW,
DEPOSIT,
TAX,
DONE
WAIT, CHECK, WITHDRAW, DEPOSIT, TAX, DONE
}
public interface TransactionCallback {
/**
* Calling while Transaction commit
*
@@ -258,7 +337,9 @@ public class EconomyTransaction {
* @return Does commit event has been cancelled
*/
default boolean onCommit(@NotNull EconomyTransaction economyTransaction) {
return !Util.fireCancellableEvent(new EconomyCommitEvent(economyTransaction));
}
/**
@@ -267,32 +348,51 @@ public class EconomyTransaction {
* @param economyTransaction Transaction
*/
default void onSuccess(@NotNull EconomyTransaction economyTransaction) {
Util.debugLog("Transaction succeed.");
QuickShop.getInstance().logEvent(new EconomyTransactionLog(true, economyTransaction.getFrom(), economyTransaction.getTo(), economyTransaction.getCurrency(), economyTransaction.getTax(), economyTransaction.getTaxer() == null ? Util.getNilUniqueId() : economyTransaction.getTaxer().getUniqueId(), economyTransaction.getAmount(), economyTransaction.getLastError()));
QuickShop.getInstance()
.logEvent(new EconomyTransactionLog(true, economyTransaction.getFrom(), economyTransaction.getTo(),
economyTransaction.getCurrency(), economyTransaction.getTax(),
economyTransaction.getTaxer() == null ? Util.getNilUniqueId()
: economyTransaction.getTaxer().getUniqueId(),
economyTransaction.getAmount(), economyTransaction.getLastError()));
}
/**
* Calling while Transaction commit failed
* Use EconomyTransaction#getLastError() to getting reason
* Use EconomyTransaction#getSteps() to getting the fail step
* Calling while Transaction commit failed Use EconomyTransaction#getLastError()
* to getting reason Use EconomyTransaction#getSteps() to getting the fail step
*
* @param economyTransaction Transaction
*/
default void onFailed(@NotNull EconomyTransaction economyTransaction) {
Util.debugLog("Transaction failed: " + economyTransaction.getLastError() + ".");
QuickShop.getInstance().logEvent(new EconomyTransactionLog(false, economyTransaction.getFrom(), economyTransaction.getTo(), economyTransaction.getCurrency(), economyTransaction.getTax(), economyTransaction.getTaxer() == null ? Util.getNilUniqueId() : economyTransaction.getTaxer().getUniqueId(), economyTransaction.getAmount(), economyTransaction.getLastError()));
QuickShop.getInstance()
.logEvent(new EconomyTransactionLog(false, economyTransaction.getFrom(), economyTransaction.getTo(),
economyTransaction.getCurrency(), economyTransaction.getTax(),
economyTransaction.getTaxer() == null ? Util.getNilUniqueId()
: economyTransaction.getTaxer().getUniqueId(),
economyTransaction.getAmount(), economyTransaction.getLastError()));
}
/**
* Calling while Tax processing failed
* Use EconomyTransaction#getLastError() to getting reason
* Use EconomyTransaction#getSteps() to getting the fail step
* Calling while Tax processing failed Use EconomyTransaction#getLastError() to
* getting reason Use EconomyTransaction#getSteps() to getting the fail step
*
* @param economyTransaction Transaction
*/
default void onTaxFailed(@NotNull EconomyTransaction economyTransaction) {
Util.debugLog("Tax Transaction failed: " + economyTransaction.getLastError() + ".");
QuickShop.getInstance().logEvent(new EconomyTransactionLog(false, economyTransaction.getFrom(), economyTransaction.getTo(), economyTransaction.getCurrency(), economyTransaction.getTax(), economyTransaction.getTaxer() == null ? Util.getNilUniqueId() : economyTransaction.getTaxer().getUniqueId(), economyTransaction.getAmount(), economyTransaction.getLastError()));
QuickShop.getInstance()
.logEvent(new EconomyTransactionLog(false, economyTransaction.getFrom(), economyTransaction.getTo(),
economyTransaction.getCurrency(), economyTransaction.getTax(),
economyTransaction.getTaxer() == null ? Util.getNilUniqueId()
: economyTransaction.getTaxer().getUniqueId(),
economyTransaction.getAmount(), economyTransaction.getLastError()));
}
}
@@ -22,39 +22,50 @@ package org.maxgamer.quickshop.api.economy;
import org.jetbrains.annotations.NotNull;
public enum EconomyType {
/*
* UNKNOWN = FALLBACK TO VAULT
* VAULT = USE VAULT API
* RESERVE = USE RESERVE API
* */
UNKNOWN(-1),
VAULT(0),
//RESERVE(1),
//MIXED(2),
GEMS_ECONOMY(3),
TNE(4);
* UNKNOWN = FALLBACK TO VAULT VAULT = USE VAULT API RESERVE = USE RESERVE API
*/
UNKNOWN(-1), VAULT(0),
// RESERVE(1),
// MIXED(2),
GEMS_ECONOMY(3), TNE(4);
private final int id;
EconomyType(int id) {
this.id = id;
}
@NotNull
public static EconomyType fromID(int id) {
for (EconomyType type : EconomyType.values()) {
if (type.id == id) {
return type;
}
}
return UNKNOWN;
}
public static int toID(@NotNull EconomyType economyType) {
return economyType.id;
}
public int toID() {
return id;
}
}
@@ -31,21 +31,29 @@ public abstract class AbstractQSEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList();
public AbstractQSEvent() {
super(!Bukkit.isPrimaryThread());
}
public AbstractQSEvent(boolean async) {
super(async);
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
@NotNull
@Override
public HandlerList getHandlers() {
return getHandlerList();
}
/**
@@ -54,11 +62,16 @@ public abstract class AbstractQSEvent extends Event {
* @return Returns true if cancelled, and false if didn't cancel
*/
public boolean callCancellableEvent() {
QuickShop.getInstance().getServer().getPluginManager().callEvent(this);
if (this instanceof Cancellable) {
return ((Cancellable) this).isCancelled();
}
return false;
}
}
@@ -27,9 +27,11 @@ import lombok.EqualsAndHashCode;
@AllArgsConstructor
@Data
public class CalendarEvent extends AbstractQSEvent {
private CalendarTriggerType calendarTriggerType;
public enum CalendarTriggerType {
NOTHING_CHANGED, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEAR
}
}
@@ -27,6 +27,7 @@ import org.maxgamer.quickshop.api.economy.EconomyTransaction;
* Calling when transaction will commit
*/
public class EconomyCommitEvent extends AbstractQSEvent implements Cancellable {
private final EconomyTransaction transaction;
private boolean cancelled;
@@ -36,7 +37,9 @@ public class EconomyCommitEvent extends AbstractQSEvent implements Cancellable {
* @param transaction transaction
*/
public EconomyCommitEvent(@NotNull EconomyTransaction transaction) {
this.transaction = transaction;
}
/**
@@ -45,28 +48,35 @@ public class EconomyCommitEvent extends AbstractQSEvent implements Cancellable {
* @return transaction
*/
public EconomyTransaction getTransaction() {
return transaction;
}
/**
* Gets the cancellation state of this event. A cancelled event will not
* be executed in the server, but will still pass to other plugins
* Gets the cancellation state of this event. A cancelled event will not be
* executed in the server, but will still pass to other plugins
*
* @return true if this event is cancelled
*/
@Override
public boolean isCancelled() {
return cancelled;
}
/**
* Sets the cancellation state of this event. A cancelled event will not
* be executed in the server, but will still pass to other plugins.
* Sets the cancellation state of this event. A cancelled event will not be
* executed in the server, but will still pass to other plugins.
*
* @param cancel true if you wish to cancel this event
*/
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
}
@@ -32,7 +32,6 @@ import org.maxgamer.quickshop.api.shop.Shop;
*/
public class PlayerShopClickEvent extends AbstractQSEvent implements Cancellable {
@Getter
private final Player player;
@@ -48,18 +47,24 @@ public class PlayerShopClickEvent extends AbstractQSEvent implements Cancellable
* @param player the player clicking shop
*/
public PlayerShopClickEvent(@NotNull Shop shop, Player player) {
this.shop = shop;
this.player = player;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -68,6 +73,9 @@ public class PlayerShopClickEvent extends AbstractQSEvent implements Cancellable
* @return Clicked shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -20,12 +20,15 @@
package org.maxgamer.quickshop.api.event;
public enum ProtectionCheckStatus {
BEGIN(0),
END(1);
BEGIN(0), END(1);
final int statusCode;
ProtectionCheckStatus(int statusCode) {
this.statusCode = statusCode;
}
}
@@ -31,10 +31,15 @@ public class QSConfigurationReloadEvent extends AbstractQSEvent {
* @param instance Quickshop instance
*/
public QSConfigurationReloadEvent(QuickShop instance) {
this.instance = instance;
}
public QuickShop getInstance() {
return instance;
}
}
@@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
@AllArgsConstructor
@Data
public class QSHandleChatEvent extends AbstractQSEvent {
private final Player sender;
private String message;
@@ -18,7 +19,9 @@ public class QSHandleChatEvent extends AbstractQSEvent {
* @return The chat sender
*/
public Player getSender() {
return sender;
}
/**
@@ -27,7 +30,9 @@ public class QSHandleChatEvent extends AbstractQSEvent {
* @return The chat content
*/
public String getMessage() {
return message;
}
/**
@@ -36,6 +41,9 @@ public class QSHandleChatEvent extends AbstractQSEvent {
* @param message The new chat content
*/
public void setMessage(String message) {
this.message = message;
}
}
@@ -44,17 +44,23 @@ public class ShopClickEvent extends AbstractQSEvent implements Cancellable {
* @param shop The shop bought from
*/
public ShopClickEvent(@NotNull Shop shop) {
this.shop = shop;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -63,6 +69,9 @@ public class ShopClickEvent extends AbstractQSEvent implements Cancellable {
* @return Clicked shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -28,6 +28,7 @@ import org.maxgamer.quickshop.api.shop.Shop;
* Calling when control panel opened for
*/
public class ShopControlPanelOpenEvent extends AbstractQSEvent implements Cancellable {
private final Shop shop;
private final CommandSender sender;
private boolean cancelled = false;
@@ -39,18 +40,24 @@ public class ShopControlPanelOpenEvent extends AbstractQSEvent implements Cancel
* @param sender The player which receiving shop control panel message
*/
public ShopControlPanelOpenEvent(@NotNull Shop shop, @NotNull CommandSender sender) {
this.shop = shop;
this.sender = sender;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean b) {
this.cancelled = b;
}
/**
@@ -59,7 +66,9 @@ public class ShopControlPanelOpenEvent extends AbstractQSEvent implements Cancel
* @return The shop
*/
public Shop getShop() {
return this.shop;
}
/**
@@ -68,6 +77,9 @@ public class ShopControlPanelOpenEvent extends AbstractQSEvent implements Cancel
* @return The sender
*/
public CommandSender getSender() {
return this.sender;
}
}
@@ -49,22 +49,29 @@ public class ShopCreateEvent extends AbstractQSEvent implements Cancellable {
* Call when have a new shop was creating.
*
* @param shop Target shop
* @param creator The player creating the shop, the player might offline/not exist if creating by a plugin.
* @param creator The player creating the shop, the player might offline/not
* exist if creating by a plugin.
*/
public ShopCreateEvent(@NotNull Shop shop, @NotNull UUID creator) {
this.shop = shop;
this.creator = creator;
this.player = QuickShop.getInstance().getServer().getPlayer(creator);
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -73,7 +80,9 @@ public class ShopCreateEvent extends AbstractQSEvent implements Cancellable {
* @return The creator, may be a online/offline/virtual player
*/
public @NotNull UUID getCreator() {
return this.creator;
}
/**
@@ -84,7 +93,9 @@ public class ShopCreateEvent extends AbstractQSEvent implements Cancellable {
*/
@Deprecated
public @Nullable Player getPlayer() {
return this.player;
}
/**
@@ -93,6 +104,9 @@ public class ShopCreateEvent extends AbstractQSEvent implements Cancellable {
* @return The shop that created
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -36,24 +36,32 @@ public class ShopDeleteEvent extends AbstractQSEvent implements Cancellable {
private boolean cancelled;
/**
* Call the event when shop is deleting. The ShopUnloadEvent will call after ShopDeleteEvent
* Call the event when shop is deleting. The ShopUnloadEvent will call after
* ShopDeleteEvent
*
* @param shop Target shop
* @param fromMemory Only delete from the memory? false = delete both in memory and database
* @param fromMemory Only delete from the memory? false = delete both in memory
* and database
*/
public ShopDeleteEvent(@NotNull Shop shop, boolean fromMemory) {
this.shop = shop;
this.fromMemory = fromMemory;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -62,7 +70,9 @@ public class ShopDeleteEvent extends AbstractQSEvent implements Cancellable {
* @return only from memory
*/
public boolean isFromMemory() {
return this.fromMemory;
}
/**
@@ -71,6 +81,9 @@ public class ShopDeleteEvent extends AbstractQSEvent implements Cancellable {
* @return The shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -50,7 +50,9 @@ public class ShopDisplayItemDespawnEvent extends AbstractQSEvent implements Canc
*/
@Deprecated
public ShopDisplayItemDespawnEvent(@NotNull Shop shop, @NotNull ItemStack itemStack) {
this(shop, itemStack, AbstractDisplayItem.getNowUsing());
}
/**
@@ -60,21 +62,28 @@ public class ShopDisplayItemDespawnEvent extends AbstractQSEvent implements Canc
* @param itemStack Target itemstacck
* @param displayType The displayType
*/
public ShopDisplayItemDespawnEvent(
@NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull DisplayType displayType) {
public ShopDisplayItemDespawnEvent(@NotNull Shop shop, @NotNull ItemStack itemStack,
@NotNull DisplayType displayType)
{
this.shop = shop;
this.itemStack = itemStack;
this.displayType = displayType;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -83,7 +92,9 @@ public class ShopDisplayItemDespawnEvent extends AbstractQSEvent implements Canc
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
/**
@@ -92,7 +103,9 @@ public class ShopDisplayItemDespawnEvent extends AbstractQSEvent implements Canc
* @return The ItemStack that display using
*/
public @NotNull ItemStack getItemStack() {
return this.itemStack;
}
/**
@@ -101,6 +114,9 @@ public class ShopDisplayItemDespawnEvent extends AbstractQSEvent implements Canc
* @return Display type that current using
*/
public @NotNull DisplayType getDisplayType() {
return this.displayType;
}
}
@@ -50,7 +50,9 @@ public class ShopDisplayItemSpawnEvent extends AbstractQSEvent implements Cancel
*/
@Deprecated
public ShopDisplayItemSpawnEvent(@NotNull Shop shop, @NotNull ItemStack itemStack) {
this(shop, itemStack, AbstractDisplayItem.getNowUsing());
}
/**
@@ -60,21 +62,28 @@ public class ShopDisplayItemSpawnEvent extends AbstractQSEvent implements Cancel
* @param displayType The displayType
* @param itemStack Target ItemStack
*/
public ShopDisplayItemSpawnEvent(
@NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull DisplayType displayType) {
public ShopDisplayItemSpawnEvent(@NotNull Shop shop, @NotNull ItemStack itemStack,
@NotNull DisplayType displayType)
{
this.shop = shop;
this.itemStack = itemStack;
this.displayType = displayType;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -83,7 +92,9 @@ public class ShopDisplayItemSpawnEvent extends AbstractQSEvent implements Cancel
* @return DisplayType
*/
public @NotNull DisplayType getDisplayType() {
return this.displayType;
}
/**
@@ -92,7 +103,9 @@ public class ShopDisplayItemSpawnEvent extends AbstractQSEvent implements Cancel
* @return The display ItemStack
*/
public @NotNull ItemStack getItemStack() {
return this.itemStack;
}
/**
@@ -101,6 +114,9 @@ public class ShopDisplayItemSpawnEvent extends AbstractQSEvent implements Cancel
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -9,6 +9,7 @@ import org.maxgamer.quickshop.api.shop.Shop;
@Data
@AllArgsConstructor
public class ShopInventoryCalculateEvent extends AbstractQSEvent {
private final Shop shop;
private final int space;
private final int stock;
@@ -19,7 +20,9 @@ public class ShopInventoryCalculateEvent extends AbstractQSEvent {
* @return The shop
*/
public Shop getShop() {
return shop;
}
/**
@@ -28,7 +31,9 @@ public class ShopInventoryCalculateEvent extends AbstractQSEvent {
* @return The inventory space (-1 if not get calculated)
*/
public int getSpace() {
return space;
}
/**
@@ -37,6 +42,9 @@ public class ShopInventoryCalculateEvent extends AbstractQSEvent {
* @return The inventory stock (-1 if not get calculated)
*/
public int getStock() {
return stock;
}
}
@@ -39,6 +39,7 @@ public class ShopInventoryEvent extends AbstractQSEvent {
* @param shop The shop bought from
*/
public ShopInventoryEvent(@NotNull Shop shop, @NotNull Inventory inventory) {
this.shop = shop;
this.inventory = inventory;
@@ -51,17 +52,20 @@ public class ShopInventoryEvent extends AbstractQSEvent {
*/
@NotNull
public Inventory getInventory() {
return inventory;
}
/**
* Sets the Inventory
*
* @param inventory new inventory for shop for this time.
* It is not persis.
* @param inventory new inventory for shop for this time. It is not persis.
*/
public void setInventory(@NotNull Inventory inventory) {
this.inventory = inventory;
}
/**
@@ -70,6 +74,9 @@ public class ShopInventoryEvent extends AbstractQSEvent {
* @return Clicked shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -44,18 +44,24 @@ public class ShopInventoryPreviewEvent extends AbstractQSEvent implements Cancel
* @param itemStack The preview item, with preview flag.
*/
public ShopInventoryPreviewEvent(@NotNull Player player, @NotNull ItemStack itemStack) {
this.player = player;
this.itemStack = itemStack;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -64,7 +70,9 @@ public class ShopInventoryPreviewEvent extends AbstractQSEvent implements Cancel
* @return The ItemStack
*/
public @NotNull ItemStack getItemStack() {
return this.itemStack;
}
/**
@@ -73,6 +81,9 @@ public class ShopInventoryPreviewEvent extends AbstractQSEvent implements Cancel
* @return The player
*/
public @NotNull Player getPlayer() {
return this.player;
}
}
@@ -28,6 +28,7 @@ import org.maxgamer.quickshop.api.shop.Shop;
* Calling when shop item was changed
*/
public class ShopItemChangeEvent extends AbstractQSEvent implements Cancellable {
private final ItemStack oldItem;
private final ItemStack newItem;
@@ -38,27 +39,33 @@ public class ShopItemChangeEvent extends AbstractQSEvent implements Cancellable
private boolean cancelled;
/**
* Will call when shop price was changed.
* All the item will be passed with a copy, so you can't change them
* Will call when shop price was changed. All the item will be passed with a
* copy, so you can't change them
*
* @param shop Target shop
* @param oldItem The old shop item
* @param newItem The new shop item
*/
public ShopItemChangeEvent(@NotNull Shop shop, ItemStack oldItem, ItemStack newItem) {
this.shop = shop;
this.oldItem = oldItem.clone();
this.newItem = newItem.clone();
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -67,7 +74,9 @@ public class ShopItemChangeEvent extends AbstractQSEvent implements Cancellable
* @return OldItem
*/
public ItemStack getOldItem() {
return this.oldItem;
}
/**
@@ -76,7 +85,9 @@ public class ShopItemChangeEvent extends AbstractQSEvent implements Cancellable
* @return NewItem
*/
public ItemStack getNewItem() {
return this.newItem;
}
/**
@@ -85,6 +96,9 @@ public class ShopItemChangeEvent extends AbstractQSEvent implements Cancellable
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -39,17 +39,23 @@ public class ShopLoadEvent extends AbstractQSEvent implements Cancellable {
* @param shop Target shop
*/
public ShopLoadEvent(@NotNull Shop shop) {
this.shop = shop;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -58,6 +64,9 @@ public class ShopLoadEvent extends AbstractQSEvent implements Cancellable {
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -35,15 +35,17 @@ public class ShopModeratorChangedEvent extends AbstractQSEvent {
private final Shop shop;
/**
* Will call when shop moderator was changed.
* Shop moderator included owner itself.
* Will call when shop moderator was changed. Shop moderator included owner
* itself.
*
* @param shop Target shop
* @param shopModerator The shop moderator
*/
public ShopModeratorChangedEvent(@NotNull Shop shop, @NotNull ShopModerator shopModerator) {
this.shop = shop;
this.moderator = shopModerator;
}
/**
@@ -52,7 +54,9 @@ public class ShopModeratorChangedEvent extends AbstractQSEvent {
* @return the shop
*/
public @NotNull ShopModerator getModerator() {
return this.moderator;
}
/**
@@ -61,6 +65,9 @@ public class ShopModeratorChangedEvent extends AbstractQSEvent {
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -25,6 +25,7 @@ import org.maxgamer.quickshop.api.shop.Shop;
import java.util.UUID;
public class ShopOngoingFeeEvent extends AbstractQSEvent implements Cancellable {
private final UUID player;
private final Shop shop;
@@ -33,9 +34,11 @@ public class ShopOngoingFeeEvent extends AbstractQSEvent implements Cancellable
private boolean cancelled;
public ShopOngoingFeeEvent(Shop shop, UUID player, double cost) {
this.shop = shop;
this.player = player;
this.cost = cost;
}
/**
@@ -44,7 +47,9 @@ public class ShopOngoingFeeEvent extends AbstractQSEvent implements Cancellable
* @return The ongoing fee
*/
public double getCost() {
return cost;
}
/**
@@ -53,7 +58,9 @@ public class ShopOngoingFeeEvent extends AbstractQSEvent implements Cancellable
* @param cost The ongoing fee
*/
public void setCost(double cost) {
this.cost = cost;
}
/**
@@ -62,7 +69,9 @@ public class ShopOngoingFeeEvent extends AbstractQSEvent implements Cancellable
* @return The shop triggered ongoing fee event
*/
public Shop getShop() {
return shop;
}
/**
@@ -71,16 +80,23 @@ public class ShopOngoingFeeEvent extends AbstractQSEvent implements Cancellable
* @return The player triggered ongoing fee event
*/
public UUID getPlayer() {
return player;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean b) {
this.cancelled = b;
}
}
@@ -7,6 +7,7 @@ import java.util.UUID;
@AllArgsConstructor
public class ShopOwnerNameGettingEvent extends AbstractQSEvent {
private final Shop shop;
private final UUID owner;
private String name;
@@ -17,7 +18,9 @@ public class ShopOwnerNameGettingEvent extends AbstractQSEvent {
* @return The shop
*/
public Shop getShop() {
return shop;
}
/**
@@ -26,7 +29,9 @@ public class ShopOwnerNameGettingEvent extends AbstractQSEvent {
* @return The shop owner unique id
*/
public UUID getOwner() {
return owner;
}
/**
@@ -35,15 +40,21 @@ public class ShopOwnerNameGettingEvent extends AbstractQSEvent {
* @return The shop owner display name
*/
public String getName() {
return name;
}
/**
* Sets the shop owner display name
*
* @param name New shop owner display name, just display, won't change actual shop owner
* @param name New shop owner display name, just display, won't change actual
* shop owner
*/
public void setName(String name) {
this.name = name;
}
}
@@ -25,8 +25,9 @@ import org.bukkit.event.Cancellable;
import org.jetbrains.annotations.NotNull;
/**
* This event is called before the shop creation request is sent. E.g. A player clicks a chest, this
* event is thrown, if successful, the player is asked how much they wish to trade for.
* This event is called before the shop creation request is sent. E.g. A player
* clicks a chest, this event is thrown, if successful, the player is asked how
* much they wish to trade for.
*/
public class ShopPreCreateEvent extends AbstractQSEvent implements Cancellable {
@@ -39,25 +40,31 @@ public class ShopPreCreateEvent extends AbstractQSEvent implements Cancellable {
private boolean cancelled;
/**
* Calling when shop pre-creating. Shop won't one-percent will create after this event, if you
* want get the shop created event, please use ShopCreateEvent
* Calling when shop pre-creating. Shop won't one-percent will create after this
* event, if you want get the shop created event, please use ShopCreateEvent
*
* @param player Target player
* @param location The location will create be shop
*/
public ShopPreCreateEvent(@NotNull Player player, @NotNull Location location) {
this.location = location;
this.player = player;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -66,7 +73,9 @@ public class ShopPreCreateEvent extends AbstractQSEvent implements Cancellable {
* @return The shop location
*/
public @NotNull Location getLocation() {
return this.location;
}
/**
@@ -75,6 +84,9 @@ public class ShopPreCreateEvent extends AbstractQSEvent implements Cancellable {
* @return creator
*/
public @NotNull Player getPlayer() {
return this.player;
}
}
@@ -45,19 +45,25 @@ public class ShopPriceChangeEvent extends AbstractQSEvent implements Cancellable
* @param newPrice The new shop price
*/
public ShopPriceChangeEvent(@NotNull Shop shop, double oldPrice, double newPrice) {
this.shop = shop;
this.oldPrice = oldPrice;
this.newPrice = newPrice;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -66,7 +72,9 @@ public class ShopPriceChangeEvent extends AbstractQSEvent implements Cancellable
* @return new price
*/
public double getNewPrice() {
return this.newPrice;
}
/**
@@ -75,7 +83,9 @@ public class ShopPriceChangeEvent extends AbstractQSEvent implements Cancellable
* @return old price
*/
public double getOldPrice() {
return this.oldPrice;
}
/**
@@ -84,6 +94,9 @@ public class ShopPriceChangeEvent extends AbstractQSEvent implements Cancellable
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -42,35 +42,37 @@ public class ShopProtectionCheckEvent extends AbstractQSEvent {
private final ProtectionCheckStatus status;
/**
* Will call when checking protection by other plugin,
* This event was used to compatible with QuickShop protection checking
* Which will fire a FAKE BlockBreakEvent
* Will call when checking protection by other plugin, This event was used to
* compatible with QuickShop protection checking Which will fire a FAKE
* BlockBreakEvent
*
* @param location Target location will execute protect check.
* @param status The checking status
* @param event The event will call to check the permissions.
* @param player The player in was mentions in this event
*/
public ShopProtectionCheckEvent(
@NotNull Location location,
@NotNull Player player,
@NotNull ProtectionCheckStatus status,
@NotNull Event event) {
public ShopProtectionCheckEvent(@NotNull Location location, @NotNull Player player,
@NotNull ProtectionCheckStatus status, @NotNull Event event)
{
this.loc = location;
this.player = player;
this.status = status;
this.event = event;
}
/**
* Get the event will used for permission check. WARN: This might not only BlockBreakEvent, you
* should check the event type before casting.
* Get the event will used for permission check. WARN: This might not only
* BlockBreakEvent, you should check the event type before casting.
*
* @return The protection check event.
*/
@NotNull
public Event getEvent() {
return event;
}
/**
@@ -79,7 +81,9 @@ public class ShopProtectionCheckEvent extends AbstractQSEvent {
* @return player
*/
public @NotNull Player getPlayer() {
return this.player;
}
/**
@@ -88,7 +92,9 @@ public class ShopProtectionCheckEvent extends AbstractQSEvent {
* @return location
*/
public @NotNull Location getLocation() {
return this.loc;
}
/**
@@ -97,6 +103,9 @@ public class ShopProtectionCheckEvent extends AbstractQSEvent {
* @return The status
*/
public @NotNull ProtectionCheckStatus getStatus() {
return this.status;
}
}
@@ -53,33 +53,42 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
private boolean cancelled;
/**
* Builds a new shop purchase event
* Will called when purchase starting
* For recording purchase, please listen to ShopSuccessPurchaseEvent.
* Builds a new shop purchase event Will called when purchase starting For
* recording purchase, please listen to ShopSuccessPurchaseEvent.
*
* @param shop The shop bought from
* @param purchaser The player buying, may offline if purchase by plugin
* @param purchaserInventory The purchaseing target inventory, *MAY NOT A PLAYER INVENTORY IF PLUGIN PURCHASE THIS*
* @param purchaser The player buying, may offline if purchase by
* plugin
* @param purchaserInventory The purchaseing target inventory, *MAY NOT A PLAYER
* INVENTORY IF PLUGIN PURCHASE THIS*
* @param amount The amount they're buying
* @param total The total balance in this purchase
*/
public ShopPurchaseEvent(@NotNull Shop shop, @NotNull UUID purchaser, @NotNull Inventory purchaserInventory, int amount, double total) {
public ShopPurchaseEvent(@NotNull Shop shop, @NotNull UUID purchaser, @NotNull Inventory purchaserInventory,
int amount, double total)
{
this.shop = shop;
this.purchaser = purchaser;
this.purchaserInventory = purchaserInventory;
this.amount = amount * shop.getItem().getAmount();
this.total = total;
this.player = Bukkit.getPlayer(purchaser);
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -88,7 +97,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
/**
@@ -97,7 +108,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
* @return The purchaser uuid
*/
public @NotNull UUID getPurchaser() {
return this.purchaser;
}
/**
@@ -108,7 +121,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
*/
@Deprecated
public @Nullable Player getPlayer() {
return this.player;
}
/**
@@ -117,7 +132,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
* @return The inventory
*/
public @NotNull Inventory getPurchaserInventory() {
return this.purchaserInventory;
}
/**
@@ -126,7 +143,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
* @return Item stack amounts
*/
public int getAmount() {
return this.amount;
}
/**
@@ -135,7 +154,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
* @return Total money
*/
public double getTotal() {
return this.total;
}
/**
@@ -144,6 +165,9 @@ public class ShopPurchaseEvent extends AbstractQSEvent implements Cancellable {
* @param total Total money
*/
public void setTotal(double total) {
this.total = total;
}
}
@@ -41,8 +41,10 @@ public class ShopSignUpdateEvent extends AbstractQSEvent {
* @param sign Updated sign
*/
public ShopSignUpdateEvent(@NotNull Shop shop, @NotNull Sign sign) {
this.shop = shop;
this.sign = sign;
}
/**
@@ -51,7 +53,9 @@ public class ShopSignUpdateEvent extends AbstractQSEvent {
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
/**
@@ -60,6 +64,9 @@ public class ShopSignUpdateEvent extends AbstractQSEvent {
* @return the sign
*/
public @NotNull Sign getSign() {
return this.sign;
}
}
@@ -51,24 +51,26 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
private final double tax;
private final double
total; // Don't use getter, we have important notice need told dev in javadoc.
private final double total; // Don't use getter, we have important notice need told dev in javadoc.
private boolean cancelled;
/**
* Builds a new shop purchase event
* Will called when purchase ended
* Builds a new shop purchase event Will called when purchase ended
*
* @param shop The shop bought from
* @param purchaser The player buying, may offline if purchase by plugin
* @param purchaserInventory The purchaseing target inventory, *MAY NOT A PLAYER INVENTORY IF PLUGIN PURCHASE THIS*
* @param purchaser The player buying, may offline if purchase by
* plugin
* @param purchaserInventory The purchaseing target inventory, *MAY NOT A PLAYER
* INVENTORY IF PLUGIN PURCHASE THIS*
* @param amount The amount they're buying
* @param tax The tax in this purchase
* @param total The money in this purchase
*/
public ShopSuccessPurchaseEvent(
@NotNull Shop shop, @NotNull UUID purchaser, @NotNull Inventory purchaserInventory, int amount, double total, double tax) {
public ShopSuccessPurchaseEvent(@NotNull Shop shop, @NotNull UUID purchaser, @NotNull Inventory purchaserInventory,
int amount, double total, double tax)
{
this.shop = shop;
this.purchaser = purchaser;
this.purchaserInventory = purchaserInventory;
@@ -76,36 +78,45 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
this.tax = tax;
this.total = total;
this.player = Bukkit.getPlayer(purchaser);
}
/**
* The total money changes in this purchase. Calculate tax, if you want get total without tax,
* please use getBalanceWithoutTax()
* The total money changes in this purchase. Calculate tax, if you want get
* total without tax, please use getBalanceWithoutTax()
*
* @return the total money with calculate tax
*/
public double getBalance() {
return this.total * (1 - tax);
}
/**
* The total money changes in this purchase. No calculate tax, if you want get total with tax,
* please use getBalance()
* The total money changes in this purchase. No calculate tax, if you want get
* total with tax, please use getBalance()
*
* @return the total money without calculate tax
*/
public double getBalanceWithoutTax() {
return this.total;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -114,7 +125,9 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
/**
@@ -123,7 +136,9 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
* @return Item stack amounts
*/
public int getAmount() {
return this.amount;
}
/**
@@ -132,7 +147,9 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
* @return The purchaser uuid
*/
public @NotNull UUID getPurchaser() {
return this.purchaser;
}
/**
@@ -143,7 +160,9 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
*/
@Deprecated
public @Nullable Player getPlayer() {
return this.player;
}
/**
@@ -152,7 +171,9 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
* @return The inventory
*/
public @NotNull Inventory getPurchaserInventory() {
return this.purchaserInventory;
}
/**
@@ -161,6 +182,9 @@ public class ShopSuccessPurchaseEvent extends AbstractQSEvent implements Cancell
* @return The tax
*/
public double getTax() {
return this.tax;
}
}
@@ -27,6 +27,7 @@ import java.util.UUID;
@AllArgsConstructor
public class ShopTaxAccountGettingEvent extends AbstractQSEvent {
private final Shop shop;
@Nullable
private UUID taxAccount;
@@ -38,7 +39,9 @@ public class ShopTaxAccountGettingEvent extends AbstractQSEvent {
*/
@Nullable
public UUID getTaxAccount() {
return taxAccount;
}
/**
@@ -47,7 +50,9 @@ public class ShopTaxAccountGettingEvent extends AbstractQSEvent {
* @param taxAccount The tax account
*/
public void setTaxAccount(@Nullable UUID taxAccount) {
this.taxAccount = taxAccount;
}
/**
@@ -56,6 +61,9 @@ public class ShopTaxAccountGettingEvent extends AbstractQSEvent {
* @return The shop
*/
public Shop getShop() {
return shop;
}
}
@@ -28,21 +28,25 @@ import java.util.UUID;
* Calling when shop tax calcing
*/
public class ShopTaxEvent extends AbstractQSEvent {
private final UUID user;
private final Shop shop;
private double tax;
/**
* Call when shop calc shop tax that will pay to system account and remove from shop owner/player received money
* Call when shop calc shop tax that will pay to system account and remove from
* shop owner/player received money
*
* @param shop The shop
* @param tax The tax
* @param user The user (buyer/seller)
*/
public ShopTaxEvent(@NotNull Shop shop, double tax, @NotNull UUID user) {
this.shop = shop;
this.tax = tax;
this.user = user;
}
/**
@@ -51,7 +55,9 @@ public class ShopTaxEvent extends AbstractQSEvent {
* @return User
*/
public UUID getUser() {
return this.user;
}
/**
@@ -60,7 +66,9 @@ public class ShopTaxEvent extends AbstractQSEvent {
* @return the shop
*/
public Shop getShop() {
return this.shop;
}
/**
@@ -69,7 +77,9 @@ public class ShopTaxEvent extends AbstractQSEvent {
* @return tax
*/
public double getTax() {
return this.tax;
}
/**
@@ -78,6 +88,9 @@ public class ShopTaxEvent extends AbstractQSEvent {
* @param tax New tax
*/
public void setTax(double tax) {
this.tax = tax;
}
}
@@ -28,6 +28,7 @@ import org.maxgamer.quickshop.api.shop.ShopType;
* Calling when shop item was changed
*/
public class ShopTypeChangeEvent extends AbstractQSEvent implements Cancellable {
private final ShopType oldType;
private final ShopType newType;
@@ -45,19 +46,25 @@ public class ShopTypeChangeEvent extends AbstractQSEvent implements Cancellable
* @param newType The new shop type
*/
public ShopTypeChangeEvent(@NotNull Shop shop, ShopType oldType, ShopType newType) {
this.shop = shop;
this.oldType = oldType;
this.newType = newType;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -66,7 +73,9 @@ public class ShopTypeChangeEvent extends AbstractQSEvent implements Cancellable
* @return old type
*/
public ShopType getOldType() {
return this.oldType;
}
/**
@@ -75,7 +84,9 @@ public class ShopTypeChangeEvent extends AbstractQSEvent implements Cancellable
* @return new type
*/
public ShopType getNewType() {
return this.newType;
}
/**
@@ -84,6 +95,9 @@ public class ShopTypeChangeEvent extends AbstractQSEvent implements Cancellable
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -36,7 +36,9 @@ public class ShopUnloadEvent extends AbstractQSEvent {
* @param shop The shop to unload
*/
public ShopUnloadEvent(@NotNull Shop shop) {
this.shop = shop;
}
/**
@@ -45,6 +47,9 @@ public class ShopUnloadEvent extends AbstractQSEvent {
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -39,18 +39,24 @@ public class ShopUpdateEvent extends AbstractQSEvent implements Cancellable {
* @param shop The shop bought from
*/
public ShopUpdateEvent(@NotNull Shop shop) {
super();
this.shop = shop;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
/**
@@ -59,6 +65,9 @@ public class ShopUpdateEvent extends AbstractQSEvent implements Cancellable {
* @return the shop
*/
public @NotNull Shop getShop() {
return this.shop;
}
}
@@ -22,10 +22,11 @@ package org.maxgamer.quickshop.api.eventmanager;
import org.bukkit.event.Event;
/**
* QuickEventManager allow user switch between bukkit and quickshop.
* QuickShop's EventManager can filter the Plugin listeners and skip it when calling events
* QuickEventManager allow user switch between bukkit and quickshop. QuickShop's
* EventManager can filter the Plugin listeners and skip it when calling events
*/
public interface QuickEventManager {
/**
* Calling an event use QuickShopEventManager
*
@@ -33,4 +34,5 @@ public interface QuickEventManager {
* @throws IllegalStateException Just like bukkit
*/
void callEvent(Event event) throws IllegalStateException;
}
@@ -20,10 +20,5 @@
package org.maxgamer.quickshop.api.integration;
public enum IntegrateStage {
onLoadBegin,
onLoadAfter,
onEnableBegin,
onEnableAfter,
onUnloadBegin,
onUnloadAfter
onLoadBegin, onLoadAfter, onEnableBegin, onEnableAfter, onUnloadBegin, onUnloadAfter
}
@@ -28,13 +28,14 @@ import org.maxgamer.quickshop.util.reload.Reloadable;
* Integration module
*/
public interface IntegratedPlugin extends Reloadable {
/**
* Return the integrated plugin name.
* For example, Residence
* Return the integrated plugin name. For example, Residence
*
* @return integrated plugin
*/
@NotNull String getName();
@NotNull
String getName();
/**
* Check if a player can create shop here
@@ -62,18 +63,19 @@ public interface IntegratedPlugin extends Reloadable {
* @return If you can delete the shop here
*/
default boolean canDeleteShopHere(@NotNull Player player, @NotNull Location location) {
return false;
}
/**
* Loading logic
* Execute Stage defined by IntegrationStage
* Loading logic Execute Stage defined by IntegrationStage
*/
void load();
/**
* Unloding logic
* Will execute when Quickshop unloading
* Unloding logic Will execute when Quickshop unloading
*/
void unload();
}
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map;
public interface IntegrationManager {
/**
* Check if a class is Integration module
*
@@ -33,7 +34,9 @@ public interface IntegrationManager {
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
static boolean isIntegrationClass(@NotNull Class<?> clazz) {
return clazz.getDeclaredAnnotation(IntegrationStage.class) != null;
}
/**
@@ -63,14 +66,16 @@ public interface IntegrationManager {
void register(@NotNull IntegratedPlugin integratedPlugin);
/**
* Register custom integrated module to QuickShop integration system from a class
* Register custom integrated module to QuickShop integration system from a
* class
*
* @param integratedPluginClass custom integrated module class
*/
void register(@NotNull Class<? extends IntegratedPlugin> integratedPluginClass);
/**
* Register custom integrated module to QuickShop integration system from a plugin name
* Register custom integrated module to QuickShop integration system from a
* plugin name
*
* @param integratedPluginName custom integrated module name
*/
@@ -102,4 +107,5 @@ public interface IntegrationManager {
* @return Registered
*/
boolean isRegistered(@NotNull String integrationName);
}
@@ -26,6 +26,7 @@ import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Inherited
public @interface IntegrationStage {
IntegrateStage loadStage() default IntegrateStage.onEnableAfter;
IntegrateStage unloadStage() default IntegrateStage.onUnloadBegin;
@@ -1,15 +1,23 @@
package org.maxgamer.quickshop.api.integration;
public class InvalidIntegratedPluginClassException extends IllegalArgumentException {
public InvalidIntegratedPluginClassException() {
super();
}
public InvalidIntegratedPluginClassException(String s) {
super(s);
}
public InvalidIntegratedPluginClassException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -3,23 +3,27 @@ package org.maxgamer.quickshop.api.localization.text;
import org.jetbrains.annotations.NotNull;
public interface Text {
/**
* Getting the text that use specify locale
*
* @param locale The minecraft locale code (like en_us)
* @return The text
*/
@NotNull String forLocale(@NotNull String locale);
@NotNull
String forLocale(@NotNull String locale);
/**
* Getting the text for player locale
*
* @return Getting the text for player locale
*/
@NotNull String forLocale();
@NotNull
String forLocale();
/**
* Send text to the player
*/
void send();
}
@@ -12,17 +12,20 @@ public interface TextList {
* @param locale The minecraft locale code (like en_us)
* @return The text
*/
@NotNull List<String> forLocale(@NotNull String locale);
@NotNull
List<String> forLocale(@NotNull String locale);
/**
* Getting the text for player locale
*
* @return Getting the text for player locale
*/
@NotNull List<String> forLocale();
@NotNull
List<String> forLocale();
/**
* Send text to the player
*/
void send();
}
@@ -30,6 +30,7 @@ import java.util.UUID;
* The TextManager that allow create user's locale specified message.
*/
public interface TextManager {
/**
* Gets specific locale status
*
@@ -39,7 +40,6 @@ public interface TextManager {
*/
boolean localeEnabled(@NotNull String locale, @NotNull List<String> regex);
/**
* Getting the translation with path with default locale
*
@@ -110,4 +110,5 @@ public interface TextManager {
*/
@NotNull
TextList ofList(@Nullable CommandSender sender, @NotNull String path, Object... args);
}
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface PostProcessor {
/**
* Process the string
*
@@ -34,4 +35,5 @@ public interface PostProcessor {
*/
@NotNull
String process(@NotNull String text, @Nullable CommandSender sender, Object... args);
}
@@ -23,10 +23,11 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
/**
* The permission query service provider
* QuickShop use that to perform a permission query request.
* The permission query service provider QuickShop use that to perform a
* permission query request.
*/
public interface PermissionProvider {
/**
* Test the sender has special permission
*
@@ -25,6 +25,7 @@ import lombok.Setter;
@AllArgsConstructor
public class ProviderIsEmptyException extends RuntimeException {
@Getter
@Setter
private String providerName;
@@ -25,7 +25,6 @@ import lombok.Getter;
import lombok.Setter;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
@@ -42,9 +41,8 @@ import org.maxgamer.quickshop.util.reload.Reloadable;
import java.util.logging.Level;
/**
* @author Netherfoam
* A display item, that spawns a block above the chest and cannot be interacted
* with.
* @author Netherfoam A display item, that spawns a block above the chest and
* cannot be interacted with.
*/
public abstract class AbstractDisplayItem implements Reloadable {
@@ -61,10 +59,12 @@ public abstract class AbstractDisplayItem implements Reloadable {
private boolean pendingRemoval;
protected AbstractDisplayItem(Shop shop) {
this.shop = shop;
this.originalItemStack = shop.getItem().clone();
PLUGIN.getReloadManager().register(this);
init();
}
/**
@@ -74,49 +74,85 @@ public abstract class AbstractDisplayItem implements Reloadable {
* @return Contains protect flag.
*/
public static boolean checkIsGuardItemStack(@Nullable final ItemStack itemStack) {
if (!PLUGIN.isDisplayEnabled()) {
return false;
}
if (getNowUsing() == DisplayType.VIRTUALITEM) {
return false;
}
//Util.ensureThread(false); // :(
// Util.ensureThread(false); // :(
if (itemStack == null) {
return false;
}
if (!itemStack.hasItemMeta()) {
return false;
}
ItemMeta iMeta = itemStack.getItemMeta();
if (!iMeta.hasLore()) {
return false;
}
String defaultMark = ShopProtectionFlag.getDefaultMark();
//noinspection ConstantConditions
// noinspection ConstantConditions
for (String lore : iMeta.getLore()) {
try {
if (!MsgUtil.isJson(lore)) {
continue;
}
ShopProtectionFlag shopProtectionFlag = JsonUtil.getGson().fromJson(lore, ShopProtectionFlag.class);
if (shopProtectionFlag == null) {
continue;
}
if (defaultMark.equals(ShopProtectionFlag.getMark())) {
return true;
}
if (shopProtectionFlag.getShopLocation() != null) {
return true;
}
if (shopProtectionFlag.getItemStackString() != null) {
return true;
}
} catch (JsonSyntaxException e) {
// Ignore
}
}
return false;
}
/**
@@ -127,49 +163,76 @@ public abstract class AbstractDisplayItem implements Reloadable {
* @return Is target shop's display
*/
public static boolean checkIsTargetShopDisplay(@NotNull final ItemStack itemStack, @NotNull Shop shop) {
//Is not needed to check current display
/*if (!PLUGIN.isDisplayEnabled()) {
return false;
}
if (getNowUsing() == DisplayType.VIRTUALITEM) {
return false;
}*/
// Is not needed to check current display
/*
* if (!PLUGIN.isDisplayEnabled()) { return false; } if (getNowUsing() ==
* DisplayType.VIRTUALITEM) { return false; }
*/
if (!itemStack.hasItemMeta()) {
return false;
}
ItemMeta iMeta = itemStack.getItemMeta();
if (!iMeta.hasLore()) {
return false;
}
String defaultMark = ShopProtectionFlag.getDefaultMark();
String shopLocation = shop.getLocation().toString();
String attachedShopLocation = "null";
if (shop.isRealDouble()) {
attachedShopLocation = shop.getAttachedShop().getLocation().toString();
}
//noinspection ConstantConditions
// noinspection ConstantConditions
for (String lore : iMeta.getLore()) {
try {
if (!lore.startsWith("{")) {
continue;
}
ShopProtectionFlag shopProtectionFlag = JsonUtil.getGson().fromJson(lore, ShopProtectionFlag.class);
if (shopProtectionFlag == null) {
continue;
}
if (!ShopProtectionFlag.getMark().equals(defaultMark)) {
continue;
}
if (shopProtectionFlag.getShopLocation().equals(shopLocation)
|| shopProtectionFlag.getShopLocation().equals(attachedShopLocation)) {
|| shopProtectionFlag.getShopLocation().equals(attachedShopLocation))
{
return true;
}
} catch (JsonSyntaxException e) {
// Ignore
}
}
return false;
}
/**
@@ -179,28 +242,43 @@ public abstract class AbstractDisplayItem implements Reloadable {
*/
@NotNull
public static DisplayType getNowUsing() {
DisplayType displayType = DisplayType.fromID(PLUGIN.getConfig().getInt("shop.display-type"));
//Falling back to RealDisplayItem when VirtualDisplayItem is unsupported
// Falling back to RealDisplayItem when VirtualDisplayItem is unsupported
if (isNotSupportVirtualItem && displayType == DisplayType.VIRTUALITEM) {
PLUGIN.getConfig().set("shop.display-type", 0);
PLUGIN.saveConfiguration();
PLUGIN.getLogger().log(Level.WARNING, "Falling back to RealDisplayItem because " + displayType.name() + " type is unsupported");
PLUGIN.getLogger().log(Level.WARNING,
"Falling back to RealDisplayItem because " + displayType.name() + " type is unsupported");
return DisplayType.REALITEM;
}
if (displayType == DisplayType.UNKNOWN) {
if (isNotSupportVirtualItem) {
PLUGIN.getConfig().set("shop.display-type", 0);
PLUGIN.saveConfiguration();
PLUGIN.getLogger().log(Level.WARNING, "Falling back to RealDisplayItem because " + displayType.name() + " type is unsupported");
PLUGIN.getLogger().log(Level.WARNING,
"Falling back to RealDisplayItem because " + displayType.name() + " type is unsupported");
return DisplayType.REALITEM;
} else {
PLUGIN.getConfig().set("shop.display-type", 2);
PLUGIN.saveConfiguration();
PLUGIN.getLogger().log(Level.WARNING, "Falling back to VirtualDisplayItem because " + displayType.name() + " type is unsupported");
PLUGIN.getLogger().log(Level.WARNING,
"Falling back to VirtualDisplayItem because " + displayType.name() + " type is unsupported");
return DisplayType.VIRTUALITEM;
}
}
return displayType;
}
/**
@@ -212,29 +290,47 @@ public abstract class AbstractDisplayItem implements Reloadable {
*/
@NotNull
public static ItemStack createGuardItemStack(@NotNull ItemStack itemStack, @NotNull Shop shop) {
itemStack = itemStack.clone();
ItemMeta iMeta = itemStack.getItemMeta();
if (iMeta == null) {
iMeta = PLUGIN.getServer().getItemFactory().getItemMeta(itemStack.getType());
}
if (iMeta == null) {
Util.debugLog("ItemStack " + itemStack + " cannot getting or creating ItemMeta, failed to create guarded ItemStack.");
Util.debugLog("ItemStack " + itemStack
+ " cannot getting or creating ItemMeta, failed to create guarded ItemStack.");
return itemStack;
}
if (PLUGIN.getConfig().getBoolean("shop.display-item-use-name")) {
if (iMeta.hasDisplayName()) {
iMeta.setDisplayName(iMeta.getDisplayName());
} else {
iMeta.setDisplayName(Util.getItemStackName(itemStack));
}
} else {
iMeta.setDisplayName(null);
}
ShopProtectionFlag shopProtectionFlag = createShopProtectionFlag(itemStack, shop);
String protectFlag = JsonUtil.getGson().toJson(shopProtectionFlag);
iMeta.setLore(Lists.newArrayList(protectFlag));
itemStack.setItemMeta(iMeta);
return itemStack;
}
/**
@@ -245,35 +341,47 @@ public abstract class AbstractDisplayItem implements Reloadable {
* @return ShopProtectionFlag obj
*/
@NotNull
public static ShopProtectionFlag createShopProtectionFlag(
@NotNull ItemStack itemStack, @NotNull Shop shop) {
public static ShopProtectionFlag createShopProtectionFlag(@NotNull ItemStack itemStack, @NotNull Shop shop) {
return new ShopProtectionFlag(shop.getLocation().toString(), Util.serialize(itemStack));
}
protected void init() {
DISPLAY_ALLOW_STACKS = PLUGIN.getConfig().getBoolean("shop.display-allow-stacks");
if (DISPLAY_ALLOW_STACKS) {
//Prevent stack over the normal size
// Prevent stack over the normal size
originalItemStack.setAmount(Math.min(originalItemStack.getAmount(), originalItemStack.getMaxStackSize()));
} else {
this.originalItemStack.setAmount(1);
}
}
@Override
public ReloadResult reloadModule() {
init();
return ReloadResult.builder().status(ReloadStatus.SUCCESS).build();
}
/**
* Gets the original ItemStack (without protection mark, should same with shop trading item.
* Gets the original ItemStack (without protection mark, should same with shop
* trading item.
*
* @return ItemStack
*/
@NotNull
public ItemStack getOriginalItemStack() {
return originalItemStack;
}
/**
@@ -326,8 +434,8 @@ public abstract class AbstractDisplayItem implements Reloadable {
public abstract void respawn();
/**
* Add the protect flags for entity or entity's hand item. Target entity will got protect by
* QuickShop
* Add the protect flags for entity or entity's hand item. Target entity will
* got protect by QuickShop
*
* @param entity Target entity
*/
@@ -346,27 +454,37 @@ public abstract class AbstractDisplayItem implements Reloadable {
public abstract Entity getDisplay();
/**
* Gets the display location for an item. If it is a double shop and it is not the left shop,
* it will average the locations of the two chests comprising it to be perfectly in the middle.
* If it is the left shop, it will return null since the left shop does not spawn an item.
* Otherwise, it will give you the middle of the single chest.
* Gets the display location for an item. If it is a double shop and it is not
* the left shop, it will average the locations of the two chests comprising it
* to be perfectly in the middle. If it is the left shop, it will return null
* since the left shop does not spawn an item. Otherwise, it will give you the
* middle of the single chest.
*
* @return The Location that the item *should* be displaying at.
*/
public @Nullable Location getDisplayLocation() {
//TODO: Rewrite centering item feature, currently implement is buggy and mess
// TODO: Rewrite centering item feature, currently implement is buggy and mess
Util.ensureThread(shop, false);
if (shop.isRealDouble()) {
if (shop.isLeftShop()) {
Util.debugLog("Shop is left shop, so location is null.");
return null;
}
double avgX = (shop.getLocation().getX() + shop.getAttachedShop().getLocation().getX()) / 2;
double avgZ = (shop.getLocation().getZ() + shop.getAttachedShop().getLocation().getZ()) / 2;
Location newloc = new Location(shop.getLocation().getWorld(), avgX, shop.getLocation().getY(), avgZ, shop.getLocation().getYaw(), shop.getLocation().getPitch());
Location newloc = new Location(shop.getLocation().getWorld(), avgX, shop.getLocation().getY(), avgZ,
shop.getLocation().getYaw(), shop.getLocation().getPitch());
return newloc.add(0.5, 1.2, 0.5);
}
return this.shop.getLocation().clone().add(0.5, 1.2, 0.5);
}
/**
@@ -380,7 +498,9 @@ public abstract class AbstractDisplayItem implements Reloadable {
* Sets this display item should be remove
*/
public void pendingRemoval() {
pendingRemoval = true;
}
/**
@@ -389,7 +509,9 @@ public abstract class AbstractDisplayItem implements Reloadable {
* @return the status
*/
public boolean isPendingRemoval() {
return pendingRemoval;
}
}
@@ -29,51 +29,72 @@ import java.util.HashMap;
import java.util.Map;
public enum DisplayType {
/*
* REALITEM = USE REAL DROPPED ITEM
* ARMORSTAND = USE ARMORSTAND DISPLAY
* REALITEM = USE REAL DROPPED ITEM ARMORSTAND = USE ARMORSTAND DISPLAY
* VIRTUALITEM = USE VIRTUAL DROPPED ITEM (CLIENT SIDE)
* */
UNKNOWN(-1),
REALITEM(0),
*/
UNKNOWN(-1), REALITEM(0),
// ARMORSTAND(1),
VIRTUALITEM(2);
private static final Map<Integer, DisplayType> TYPE_MAP;
static {
Map<Integer, DisplayType> map = new HashMap<>(values().length);
for (DisplayType type : values()) {
map.put(type.id, type);
}
TYPE_MAP = Collections.unmodifiableMap(map);
}
private final int id;
DisplayType(int id) {
this.id = id;
}
public static @NotNull DisplayType fromID(int id) {
return TYPE_MAP.getOrDefault(id, UNKNOWN);
}
public static int toID(@NotNull DisplayType displayType) {
return displayType.id;
}
public static DisplayType typeIs(@Nullable AbstractDisplayItem displayItem) {
if (displayItem instanceof RealDisplayItem) {
return REALITEM;
}
if (displayItem instanceof VirtualDisplayItem) {
return VIRTUALITEM;
}
return UNKNOWN;
}
public int toID() {
return id;
}
}
@@ -29,27 +29,32 @@ import org.jetbrains.annotations.Nullable;
* Shop simple info, used for shop processing and shop creation.
*/
public interface Info {
/**
* @return ShopAction action, Get shop action.
*/
@NotNull ShopAction getAction();
@NotNull
ShopAction getAction();
void setAction(@NotNull ShopAction action);
/**
* @return ItemStack iStack, Get Shop's selling/buying item's ItemStack.
*/
@NotNull ItemStack getItem();
@NotNull
ItemStack getItem();
/**
* @return Location loc, Get shop's location,
*/
@NotNull Location getLocation();
@NotNull
Location getLocation();
/**
* @return Block signBlock, Get block of shop's sign, may return the null.
*/
@Nullable Block getSignBlock();
@Nullable
Block getSignBlock();
/**
* Get shop is or not has changed.
@@ -67,7 +72,8 @@ public interface Info {
void setShopType(ShopType shopType);
/**
* @return Pending create message, use as temporary store when creating shop needs select shop type.
* @return Pending create message, use as temporary store when creating shop
* needs select shop type.
*/
String getPendingCreateMessage();
@@ -28,27 +28,31 @@ import org.jetbrains.annotations.Nullable;
* A custom impl that matching items between two ItemStack
*/
public interface ItemMatcher {
/**
* Gets the ItemMatcher provider name
*
* @return Provider name
*/
@NotNull String getName();
@NotNull
String getName();
/**
* Gets the ItemMatcher provider plugin instance
*
* @return Provider Plugin instance
*/
@NotNull Plugin getPlugin();
@NotNull
Plugin getPlugin();
/**
* Tests ItemStacks is matches
* BEWARE: Different order of itemstacks might get different results
* Tests ItemStacks is matches BEWARE: Different order of itemstacks might get
* different results
*
* @param original The original ItemStack
* @param tester The ItemStack will test matches with original itemstack.
* @return The result of tests
*/
boolean matches(@Nullable ItemStack original, @Nullable ItemStack tester);
}
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
* Utility used for shop price validating
*/
public interface PriceLimiter {
/**
* Checks a stack with a price is allowed
*
@@ -27,6 +27,7 @@ import org.maxgamer.quickshop.util.MsgUtil;
* Result of PriceLimiter check
*/
public interface PriceLimiterCheckResult {
/**
* Getting final result
*
@@ -54,7 +55,9 @@ public interface PriceLimiterCheckResult {
* @return the max digit limit
*/
default int getMaxDigit() {
return -1;
}
/**
@@ -63,28 +66,35 @@ public interface PriceLimiterCheckResult {
* @return the price after adjusted
*/
default double getPriceShouldBe() {
return getMin();
}
default void sendErrorMsg(QuickShop plugin, CommandSender sender, String input, String itemName) {
boolean decFormat = plugin.getConfig().getBoolean("use-decimal-format");
String maxPriceStr;
String minPriceStr;
if (decFormat) {
maxPriceStr = MsgUtil.decimalFormat(getMax());
minPriceStr = MsgUtil.decimalFormat(getMin());
} else {
maxPriceStr = Double.toString(getMax());
minPriceStr = Double.toString(getMin());
}
switch (getStatus()) {
case REACHED_PRICE_MIN_LIMIT:
plugin.text().of(sender, "price-too-cheap",
minPriceStr).send();
plugin.text().of(sender, "price-too-cheap", minPriceStr).send();
break;
case REACHED_PRICE_MAX_LIMIT:
plugin.text().of(sender, "price-too-high",
maxPriceStr).send();
plugin.text().of(sender, "price-too-high", maxPriceStr).send();
break;
case NOT_VALID:
plugin.text().of(sender, "not-a-number", input).send();
@@ -96,10 +106,10 @@ public interface PriceLimiterCheckResult {
plugin.text().of(sender, "digits-reach-the-limit", String.valueOf(getMaxDigit())).send();
break;
default:
plugin.text().of(sender, "restricted-prices",
itemName,
minPriceStr,
maxPriceStr).send();
plugin.text().of(sender, "restricted-prices", itemName, minPriceStr, maxPriceStr).send();
}
}
}
@@ -1,11 +1,6 @@
package org.maxgamer.quickshop.api.shop;
public enum PriceLimiterStatus {
PASS,
REACHED_PRICE_MAX_LIMIT,
REACHED_PRICE_MIN_LIMIT,
PRICE_RESTRICTED,
NOT_A_WHOLE_NUMBER,
NOT_VALID,
PASS, REACHED_PRICE_MAX_LIMIT, REACHED_PRICE_MIN_LIMIT, PRICE_RESTRICTED, NOT_A_WHOLE_NUMBER, NOT_VALID,
REACH_DIGITS_LIMIT,
}
@@ -44,6 +44,7 @@ import java.util.UUID;
* A shop
*/
public interface Shop {
NamespacedKey SHOP_NAMESPACED_KEY = new NamespacedKey(QuickShop.getInstance(), "shopsign");
String SHOP_SIGN_PATTERN = "§d§o ";
@@ -68,7 +69,8 @@ public interface Shop {
*
* @param buyer The player buying
* @param buyerInventory The buyer inventory ( may not a player inventory )
* @param loc2Drop The location to drops items if player inventory are full
* @param loc2Drop The location to drops items if player inventory are
* full
* @param paramInt How many buyed?
*/
void buy(@NotNull UUID buyer, @NotNull Inventory buyerInventory, @NotNull Location loc2Drop, int paramInt);
@@ -107,7 +109,8 @@ public interface Shop {
/**
* Delete shop from ram or ram and database
*
* @param memoryOnly true = only delete from ram, false = delete from both ram and database
* @param memoryOnly true = only delete from ram, false = delete from both ram
* and database
*/
void delete(boolean memoryOnly);
@@ -143,7 +146,8 @@ public interface Shop {
void onUnload();
/**
* Get shop's owner name, it will return owner name or Admin Shop(i18n) when it is unlimited
* Get shop's owner name, it will return owner name or Admin Shop(i18n) when it
* is unlimited
*
* @param forceUsername Force returns username of shop
* @return owner name
@@ -152,7 +156,8 @@ public interface Shop {
String ownerName(boolean forceUsername);
/**
* Get shop's owner name, it will return owner name or Admin Shop(i18n) when it is unlimited
* Get shop's owner name, it will return owner name or Admin Shop(i18n) when it
* is unlimited
*
* @return owner name
*/
@@ -172,7 +177,9 @@ public interface Shop {
*
* @param seller Seller
* @param sellerInventory Seller's inventory ( may not a player inventory )
* @param loc2Drop The location to be drop if buyer inventory full ( if player enter a number that < 0, it will turn to buying item)
* @param loc2Drop The location to be drop if buyer inventory full ( if
* player enter a number that < 0, it will turn to buying
* item)
* @param paramInt How many sold?
*/
void sell(@NotNull UUID seller, @NotNull Inventory sellerInventory, @NotNull Location loc2Drop, int paramInt);
@@ -186,16 +193,14 @@ public interface Shop {
* Get sign texts on shop's sign.
*
* @param locale The locale to be created for
* @return String arrays represents sign texts:
* Index | Content
* Line 0: Header
* Line 1: Shop Type
* Line 2: Shop Item Name
* Line 3: Price
* @return String arrays represents sign texts: Index | Content Line 0: Header
* Line 1: Shop Type Line 2: Shop Item Name Line 3: Price
*/
default List<ComponentPackage> getSignText(String locale) {
//backward support
// backward support
throw new UnsupportedOperationException();
}
/**
@@ -263,7 +268,8 @@ public interface Shop {
/**
* Get shop's owner UUID
*
* @return Shop's owner UUID, can use Bukkit.getOfflinePlayer to convert to the OfflinePlayer.
* @return Shop's owner UUID, can use Bukkit.getOfflinePlayer to convert to the
* OfflinePlayer.
*/
@NotNull
UUID getOwner();
@@ -392,8 +398,7 @@ public interface Shop {
AbstractDisplayItem getDisplay();
/**
* Gets if shop is dirty
* (so shop will be save)
* Gets if shop is dirty (so shop will be save)
*
* @return Is dirty
*/
@@ -411,7 +416,6 @@ public interface Shop {
*/
void setDirty();
/**
* Save the plugin extra data to Json format
*
@@ -424,7 +428,8 @@ public interface Shop {
* Getting ConfigurationSection (extra data) instance of your plugin namespace)
*
* @param plugin The plugin and plugin name will used for namespace
* @return ExtraSection, save it through Shop#setExtra. If you don't save it, it may randomly loose or save
* @return ExtraSection, save it through Shop#setExtra. If you don't save it, it
* may randomly loose or save
*/
@NotNull
ConfigurationSection getExtra(@NotNull Plugin plugin);
@@ -445,12 +450,13 @@ public interface Shop {
boolean isStackingShop();
/**
* WARNING: This UUID will changed after plugin reload, shop reload or server restart
* DO NOT USE IT TO STORE DATA!
* WARNING: This UUID will changed after plugin reload, shop reload or server
* restart DO NOT USE IT TO STORE DATA!
*
* @return Random UUID
*/
@NotNull UUID getRuntimeRandomUniqueId();
@NotNull
UUID getRuntimeRandomUniqueId();
/**
* Gets the currency that shop use
@@ -489,8 +495,8 @@ public interface Shop {
boolean isRealDouble();
/**
* Updates the attachedShop variable to reflect the currently attached shop, if any.
* Also updates the left shop status.
* Updates the attachedShop variable to reflect the currently attached shop, if
* any. Also updates the left shop status.
*/
void updateAttachedShop();
@@ -523,7 +529,8 @@ public interface Shop {
void setDisableDisplay(boolean disabled);
/**
* Getting the shop tax account for using, it can be specific uuid or general tax account
* Getting the shop tax account for using, it can be specific uuid or general
* tax account
*
* @return Shop Tax Account or fallback to general tax account
*/
@@ -560,51 +567,75 @@ public interface Shop {
* @return Is shop info sign
*/
default boolean isShopSign(@NotNull Sign sign) {
// Check for new shop sign
String[] lines = sign.getLines();
// Can be claim
if (lines[0].isEmpty() && lines[1].isEmpty() && lines[2].isEmpty() && lines[3].isEmpty()) {
return true;
}
// Check for exists shop sign (modern)
ShopSignStorage shopSignStorage = sign.getPersistentDataContainer().get(SHOP_NAMESPACED_KEY, ShopSignPersistentDataType.INSTANCE);
ShopSignStorage shopSignStorage = sign.getPersistentDataContainer().get(SHOP_NAMESPACED_KEY,
ShopSignPersistentDataType.INSTANCE);
if (shopSignStorage != null) {
return shopSignStorage.equals(getLocation().getWorld().getName(), getLocation().getBlockX(), getLocation().getBlockY(), getLocation().getBlockZ());
return shopSignStorage.equals(getLocation().getWorld().getName(), getLocation().getBlockX(),
getLocation().getBlockY(), getLocation().getBlockZ());
}
// Check for exists shop sign (legacy upgrade)
//Check if attached with the shop block
// Check if attached with the shop block
if (!isAttached(sign.getBlock())) {
return false;
}
//Check sign content
// Check sign content
if (lines[1].startsWith(SHOP_SIGN_PATTERN)) {
return true;
} else {
if (!QuickShop.getInstance().getConfig().getBoolean("legacy-updater.shop-sign", false)) {
return false;
}
String header = lines[0];
TextManager textManager = QuickShop.getInstance().text();
String ownerName = this.ownerName(true);
//Raw text matching
String adminShopHeader = textManager.of("signs.header", textManager.of("admin-shop").forLocale()).forLocale();
// Raw text matching
String adminShopHeader = textManager.of("signs.header", textManager.of("admin-shop").forLocale())
.forLocale();
String userShopHeader = textManager.of("signs.header", ownerName).forLocale();
if (header.contains(adminShopHeader) || header.contains(userShopHeader)) {
return true;
//TEXT SIGN
//continue
// TEXT SIGN
// continue
} else {
//Try no color matching
//arg[0] is name, arg[1] is color code
adminShopHeader = textManager.of("signs.header", textManager.of("admin-shop").forLocale(), "").forLocale();
// Try no color matching
// arg[0] is name, arg[1] is color code
adminShopHeader = textManager.of("signs.header", textManager.of("admin-shop").forLocale(), "")
.forLocale();
userShopHeader = textManager.of("signs.header", ownerName, "").forLocale();
adminShopHeader = ChatColor.stripColor(adminShopHeader);
userShopHeader = ChatColor.stripColor(userShopHeader);
return header.contains(adminShopHeader) || header.contains(userShopHeader);
}
}
}
/**
@@ -618,7 +649,9 @@ public interface Shop {
* If this shop is always counting space or stocks, even is unlimited
*/
default boolean isAlwaysCountingContainer() {
return false;
}
/**
@@ -627,7 +660,10 @@ public interface Shop {
* @param value is always counting space or stocks
*/
default void setAlwaysCountingContainer(boolean value) {
//For back-ward compatibility
// For back-ward compatibility
throw new UnsupportedOperationException("setAlwaysCountingContainer is not implemented");
}
}
@@ -21,8 +21,5 @@ package org.maxgamer.quickshop.api.shop;
public enum ShopAction {
// buy = trading create = creating shop cancelled = stopped
BUY,
CREATE,
CREATE_TYPE_INPUT,
CANCELLED
BUY, CREATE, CREATE_TYPE_INPUT, CANCELLED
}
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
* Shop chunk based searching
*/
public interface ShopChunk {
boolean isSame(@NotNull World world, int x, int z);
boolean isSame(@NotNull String world, int x, int z);
@@ -35,4 +36,5 @@ public interface ShopChunk {
int getX();
int getZ();
}
@@ -34,6 +34,7 @@ import java.util.UUID;
@Data
@Builder
public class ShopInfoStorage {
private final String world;
private final BlockPosition position;
private final String moderator;
@@ -47,6 +48,9 @@ public class ShopInfoStorage {
private final UUID taxAccount;
public String toJson() {
return JsonUtil.standard().toJson(this);
}
}
@@ -38,7 +38,8 @@ import java.util.*;
public interface ShopManager {
/**
* Checks other plugins to make sure they can use the chest they're making a shop.
* Checks other plugins to make sure they can use the chest they're making a
* shop.
*
* @param p The player to check
* @param b The block to check
@@ -52,40 +53,46 @@ public interface ShopManager {
*
* @return a map of World - Chunk - Shop
*/
@NotNull Map<String, Map<ShopChunk, Map<Location, Shop>>> getShops();
@NotNull
Map<String, Map<ShopChunk, Map<Location, Shop>>> getShops();
/**
* Returns a new shop iterator object, allowing iteration over shops easily, instead of sorting
* through a 3D map.
* Returns a new shop iterator object, allowing iteration over shops easily,
* instead of sorting through a 3D map.
*
* @return a new shop iterator object.
*/
@NotNull Iterator<Shop> getShopIterator();
@NotNull
Iterator<Shop> getShopIterator();
/**
* Removes all shops from memory and the world. Does not delete them from the database. Call
* this on plugin disable ONLY.
* Removes all shops from memory and the world. Does not delete them from the
* database. Call this on plugin disable ONLY.
*/
void clear();
/**
* Returns a map of Shops
*
* @param c The chunk to search. Referencing doesn't matter, only coordinates and world are
* used.
* @param c The chunk to search. Referencing doesn't matter, only coordinates
* and world are used.
* @return Shops
*/
@Nullable Map<Location, Shop> getShops(@NotNull Chunk c);
@Nullable
Map<Location, Shop> getShops(@NotNull Chunk c);
@Nullable Map<Location, Shop> getShops(@NotNull String world, int chunkX, int chunkZ);
@Nullable
Map<Location, Shop> getShops(@NotNull String world, int chunkX, int chunkZ);
/**
* Returns a map of Chunk - Shop
*
* @param world The name of the world (case sensitive) to get the list of shops from
* @param world The name of the world (case sensitive) to get the list of shops
* from
* @return a map of Chunk - Shop
*/
@Nullable Map<ShopChunk, Map<Location, Shop>> getShops(@NotNull String world);
@Nullable
Map<ShopChunk, Map<Location, Shop>> getShops(@NotNull String world);
/**
* Create a shop use Shop and Info object.
@@ -103,7 +110,8 @@ public interface ShopManager {
* @param world shop world
* @return formated price
*/
@Nullable String format(double d, @NotNull World world, @Nullable String currency);
@Nullable
String format(double d, @NotNull World world, @Nullable String currency);
/**
* Format the price use formatter
@@ -112,57 +120,68 @@ public interface ShopManager {
* @param shop The shop
* @return formated price
*/
@Nullable String format(double d, @NotNull Shop shop);
@Nullable
String format(double d, @NotNull Shop shop);
/**
* Gets a shop in a specific location
* ATTENTION: This not include attached shops (double-chest)
* Gets a shop in a specific location ATTENTION: This not include attached shops
* (double-chest)
*
* @param loc The location to get the shop from
* @return The shop at that location
*/
@Nullable Shop getShop(@NotNull Location loc);
@Nullable
Shop getShop(@NotNull Location loc);
/**
* Gets a shop in a specific location
* ATTENTION: This not include attached shops (double-chest)
* Gets a shop in a specific location ATTENTION: This not include attached shops
* (double-chest)
*
* @param loc The location to get the shop from
* @param skipShopableChecking whether to check is shopable
* @return The shop at that location
*/
@Nullable Shop getShop(@NotNull Location loc, boolean skipShopableChecking);
@Nullable
Shop getShop(@NotNull Location loc, boolean skipShopableChecking);
/**
* Gets a shop in a specific location Include the attached shop, e.g DoubleChest shop.
* Gets a shop in a specific location Include the attached shop, e.g DoubleChest
* shop.
*
* @param loc The location to get the shop from
* @return The shop at that location
*/
@Nullable Shop getShopIncludeAttached(@Nullable Location loc);
@Nullable
Shop getShopIncludeAttached(@Nullable Location loc);
/**
* Gets a shop in a specific location Include the attached shop, e.g DoubleChest shop.
* Gets a shop in a specific location Include the attached shop, e.g DoubleChest
* shop.
*
* @param loc The location to get the shop from
* @param useCache whether to use cache
* @return The shop at that location
*/
@Nullable Shop getShopIncludeAttached(@Nullable Location loc, boolean useCache);
@Nullable
Shop getShopIncludeAttached(@Nullable Location loc, boolean useCache);
void bakeShopRuntimeRandomUniqueIdCache(@NotNull Shop shop);
@Nullable Shop getShopFromRuntimeRandomUniqueId(@NotNull UUID runtimeRandomUniqueId);
@Nullable
Shop getShopFromRuntimeRandomUniqueId(@NotNull UUID runtimeRandomUniqueId);
@Nullable Shop getShopFromRuntimeRandomUniqueId(@NotNull UUID runtimeRandomUniqueId, boolean includeInvalid);
@Nullable
Shop getShopFromRuntimeRandomUniqueId(@NotNull UUID runtimeRandomUniqueId, boolean includeInvalid);
void handleChat(@NotNull Player p, @NotNull String msg);
// void handleChat(@NotNull Player p, @NotNull String msg, boolean bypassProtectionChecks);
// void handleChat(@NotNull Player p, @NotNull String msg, boolean
// bypassProtectionChecks);
/**
* Load shop method for loading shop into mapping, so getShops method will can find it. It also
* effects a lots of feature, make sure load it after create it.
* Load shop method for loading shop into mapping, so getShops method will can
* find it. It also effects a lots of feature, make sure load it after create
* it.
*
* @param world The world the shop is in
* @param shop The shop to load
@@ -170,8 +189,8 @@ public interface ShopManager {
void loadShop(@NotNull String world, @NotNull Shop shop);
/**
* Adds a shop to the world. Does NOT require the chunk or world to be loaded Call shop.onLoad
* by yourself
* Adds a shop to the world. Does NOT require the chunk or world to be loaded
* Call shop.onLoad by yourself
*
* @param world The name of the world
* @param shop The shop to add
@@ -179,8 +198,8 @@ public interface ShopManager {
void addShop(@NotNull String world, @NotNull Shop shop);
/**
* Removes a shop from the world. Does NOT remove it from the database. * REQUIRES * the world
* to be loaded Call shop.onUnload by your self.
* Removes a shop from the world. Does NOT remove it from the database. *
* REQUIRES * the world to be loaded Call shop.onUnload by your self.
*
* @param shop The shop to remove
*/
@@ -189,33 +208,40 @@ public interface ShopManager {
/**
* @return Returns the Map. Info contains what their last question etc was.
*/
@NotNull Map<UUID, Info> getActions();
@NotNull
Map<UUID, Info> getActions();
/**
* Get all loaded shops.
*
* @return All loaded shops.
*/
@NotNull Set<Shop> getLoadedShops();
@NotNull
Set<Shop> getLoadedShops();
/**
* Get a players all shops.
*
* <p>Make sure you have caching this, because this need a while to get player's all shops
* <p>
* Make sure you have caching this, because this need a while to get player's
* all shops
*
* @param playerUUID The player's uuid.
* @return The list have this player's all shops.
*/
@NotNull List<Shop> getPlayerAllShops(@NotNull UUID playerUUID);
@NotNull
List<Shop> getPlayerAllShops(@NotNull UUID playerUUID);
/**
* Returns all shops in the whole database, include unloaded.
*
* <p>Make sure you have caching this, because this need a while to get all shops
* <p>
* Make sure you have caching this, because this need a while to get all shops
*
* @return All shop in the database
*/
@NotNull List<Shop> getAllShops();
@NotNull
List<Shop> getAllShops();
/**
* Get the all shops in the world.
@@ -223,7 +249,8 @@ public interface ShopManager {
* @param world The world you want get the shops.
* @return The list have this world all shops
*/
@NotNull List<Shop> getShopsInWorld(@NotNull World world);
@NotNull
List<Shop> getShopsInWorld(@NotNull World world);
@Deprecated
double getTax(@NotNull Shop shop, @NotNull Player p);
@@ -233,8 +260,7 @@ public interface ShopManager {
boolean shopIsNotValid(@NotNull UUID uuid, @NotNull Info info, @NotNull Shop shop);
/**
* Change the owner to unlimited shop owner.
* It defined in configuration.
* Change the owner to unlimited shop owner. It defined in configuration.
*/
void migrateOwnerToUnlimitedShopOwner(Shop shop);
@@ -28,10 +28,11 @@ import java.util.List;
import java.util.UUID;
/**
* Contains shop's moderators infomations, owner, staffs etc.
* You must save the ContainerShop after modify this
* Contains shop's moderators infomations, owner, staffs etc. You must save the
* ContainerShop after modify this
*/
public interface ShopModerator {
/**
* Deserialize a ShopModerator using Gson
*
@@ -40,9 +41,11 @@ public interface ShopModerator {
* @throws JsonSyntaxException incorrect json string
*/
static ShopModerator deserialize(@NotNull String serilized) throws JsonSyntaxException {
// Use Gson deserialize data
Gson gson = JsonUtil.getGson();
return gson.fromJson(serilized, ShopModerator.class);
}
/**
@@ -52,8 +55,10 @@ public interface ShopModerator {
* @return Json String
*/
static String serialize(@NotNull ShopModerator shopModerator) {
Gson gson = JsonUtil.getGson();
return gson.toJson(shopModerator); // Use Gson serialize this class
}
/**
@@ -69,10 +74,12 @@ public interface ShopModerator {
*/
void clearStaffs();
@NotNull ShopModerator clone();
@NotNull
ShopModerator clone();
@Override
@NotNull String toString();
@NotNull
String toString();
/**
* Remove moderators staff from staff list
@@ -111,7 +118,8 @@ public interface ShopModerator {
*
* @return Owner's UUID
*/
@NotNull UUID getOwner();
@NotNull
UUID getOwner();
/**
* Set moderators owner (Shop Owner)
@@ -125,7 +133,8 @@ public interface ShopModerator {
*
* @return Staffs
*/
@NotNull List<UUID> getStaffs();
@NotNull
List<UUID> getStaffs();
/**
* Set moderators staffs
@@ -22,30 +22,44 @@ package org.maxgamer.quickshop.api.shop;
import org.jetbrains.annotations.NotNull;
public enum ShopType {
// SELLING = SELLMODE BUYING = BUY MODE
SELLING(0),
BUYING(1);
SELLING(0), BUYING(1);
private final int id;
ShopType(int id) {
this.id = id;
}
public static @NotNull ShopType fromID(int id) {
for (ShopType type : ShopType.values()) {
if (type.id == id) {
return type;
}
}
return SELLING;
}
public static int toID(@NotNull ShopType shopType) {
return shopType.id;
}
public int toID() {
return id;
}
}
@@ -29,15 +29,21 @@ import org.maxgamer.quickshop.api.chat.QuickComponent;
@Builder
@Data
public class QuickComponentImpl implements QuickComponent {
private Object component;
@Override
public @NotNull Object get() {
return this.component;
}
@Override
public void set(@NotNull Object component) {
this.component = component;
}
}
@@ -60,189 +60,298 @@ import java.util.logging.Level;
*/
@AllArgsConstructor
public class BungeeQuickChat implements QuickChat {
private final QuickShop plugin;
private final String[] indexStrCache = {"{0}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}", "{8}", "{9}"};
private final String[] indexStrCache = { "{0}", "{1}", "{2}", "{3}", "{4}", "{5}", "{6}", "{7}", "{8}", "{9}" };
public static BaseComponent[] fromLegacyText(String text) {
return TextComponent.fromLegacyText(text, net.md_5.bungee.api.ChatColor.RESET);
}
public static String toLegacyText(BaseComponent[] components) {
StringBuilder builder = new StringBuilder();
BaseComponent lastComponent = null;
for (BaseComponent component : components) {
net.md_5.bungee.api.ChatColor color = component.getColorRaw();
String legacyText = component.toLegacyText();
if (color == null && legacyText.startsWith("§f")) {
//Remove redundant §f added by toLegacyText
// Remove redundant §f added by toLegacyText
legacyText = legacyText.substring(2);
}
if (lastComponent != null && (
lastComponent.isBold() != component.isBold() ||
lastComponent.isItalic() != component.isItalic() ||
lastComponent.isObfuscated() != component.isObfuscated() ||
lastComponent.isStrikethrough() != component.isStrikethrough() ||
lastComponent.isUnderlined() != lastComponent.isUnderlined()
)) {
if (lastComponent != null
&& (lastComponent.isBold() != component.isBold() || lastComponent.isItalic() != component.isItalic()
|| lastComponent.isObfuscated() != component.isObfuscated()
|| lastComponent.isStrikethrough() != component.isStrikethrough()
|| lastComponent.isUnderlined() != lastComponent.isUnderlined()))
{
builder.append("§r");
}
builder.append(legacyText);
lastComponent = component;
}
return builder.toString();
}
@Override
public void send(@NotNull CommandSender receiver, @Nullable QuickComponent component) {
if (component == null) {
return;
}
if (component.get() instanceof BaseComponent[]) {
receiver.spigot().sendMessage((BaseComponent[]) component.get());
return;
}
if (component.get() instanceof BaseComponent) {
receiver.spigot().sendMessage((BaseComponent) component.get());
return;
}
Util.debugLog("Illegal component " + component.get().getClass().getName() + " sending to " + this.getClass().getName() + " processor, trying force sending.");
Util.debugLog("Illegal component " + component.get().getClass().getName() + " sending to "
+ this.getClass().getName() + " processor, trying force sending.");
}
@Override
public void send(@NotNull CommandSender receiver, @Nullable String message) {
if (StringUtils.isEmpty(message)) {
return;
}
receiver.spigot().sendMessage(fromLegacyText(message));
}
@Override
public void sendItemHologramChat(@NotNull Player player, @NotNull String text, @NotNull ItemStack itemStack) {
sendItemHologramChat(player, text, itemStack, false);
}
private BungeeComponentBuilder appendItemHoloChat(@Nullable String itemJson, @NotNull String message) {
BungeeComponentBuilder builder = new BungeeComponentBuilder();
TextSplitter.SpilledString spilledString = TextSplitter.deBakeItem(message);
if (itemJson == null) {
if (spilledString == null) {
builder.appendLegacy(message);
} else {
builder.appendLegacyAndItem(spilledString.getLeft()
, spilledString.getComponents()
, spilledString.getRight());
}
} else {
HoverEvent itemHoverEvent = new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(itemJson).create());
if (spilledString == null) {
builder.event(itemHoverEvent);
builder.appendLegacy(message);
//Dummy for not included hover event
builder.append(new TextComponent());
builder.event((HoverEvent) null);
} else {
//Only show item on item name side
for (BaseComponent component : spilledString.getComponents()) {
component.setHoverEvent(itemHoverEvent);
}
builder.appendLegacyAndItem(spilledString.getLeft()
, spilledString.getComponents()
, spilledString.getRight());
}
}
return builder;
builder.appendLegacyAndItem(spilledString.getLeft(), spilledString.getComponents(),
spilledString.getRight());
}
private void sendItemHologramChat(@NotNull Player player, @NotNull String text, @NotNull ItemStack itemStack, boolean skipItemHoloChat) {
TextComponent errorComponent = new TextComponent(plugin.text().of(player, "menu.item-holochat-error").forLocale());
} else {
HoverEvent itemHoverEvent = new HoverEvent(HoverEvent.Action.SHOW_ITEM,
new ComponentBuilder(itemJson).create());
if (spilledString == null) {
builder.event(itemHoverEvent);
builder.appendLegacy(message);
// Dummy for not included hover event
builder.append(new TextComponent());
builder.event((HoverEvent) null);
} else {
// Only show item on item name side
for (BaseComponent component : spilledString.getComponents()) {
component.setHoverEvent(itemHoverEvent);
}
builder.appendLegacyAndItem(spilledString.getLeft(), spilledString.getComponents(),
spilledString.getRight());
}
}
return builder;
}
private void sendItemHologramChat(@NotNull Player player, @NotNull String text, @NotNull ItemStack itemStack,
boolean skipItemHoloChat)
{
TextComponent errorComponent = new TextComponent(
plugin.text().of(player, "menu.item-holochat-error").forLocale());
try {
BungeeComponentBuilder builder;
if (skipItemHoloChat) {
builder = appendItemHoloChat(null, text);
} else {
builder = appendItemHoloChat(ReflectFactory.convertBukkitItemStackToJson(itemStack), text);
}
BaseComponent[] result = builder.create();
String resultStr = ComponentSerializer.toString(result);
Util.debugLog("Sending debug: " + resultStr);
//The limit in vanilla server is 32767
// The limit in vanilla server is 32767
if (resultStr.getBytes(StandardCharsets.UTF_8).length > 32767) {
if (skipItemHoloChat) {
//If still too large after skipItemHoloChat, just send the error message
// If still too large after skipItemHoloChat, just send the error message
plugin.text().of(player, "menu.item-holochat-data-too-large").send();
} else {
sendItemHologramChat(player, text, itemStack, true);
}
} else {
player.spigot().sendMessage(result);
}
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException |
InstantiationException e) {
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException
| InstantiationException e)
{
plugin.getLogger().log(Level.WARNING, "Failed to process chat component", e);
player.spigot().sendMessage(errorComponent);
}
}
@Override
public @NotNull QuickComponent getItemHologramChat(@NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull Player player, @NotNull String message) {
public @NotNull QuickComponent getItemHologramChat(@NotNull Shop shop, @NotNull ItemStack itemStack,
@NotNull Player player, @NotNull String message)
{
return getItemHologramChat(shop, itemStack, player, message, false);
}
private @NotNull QuickComponent getItemHologramChat(@NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull Player player, @NotNull String message, boolean skipItemHoloChat) {
TextComponent errorComponent = new TextComponent(plugin.text().of(player, "menu.item-holochat-error").forLocale());
private @NotNull QuickComponent getItemHologramChat(@NotNull Shop shop, @NotNull ItemStack itemStack,
@NotNull Player player, @NotNull String message, boolean skipItemHoloChat)
{
TextComponent errorComponent = new TextComponent(
plugin.text().of(player, "menu.item-holochat-error").forLocale());
try {
BungeeComponentBuilder builder;
if (skipItemHoloChat) {
builder = appendItemHoloChat(null, message);
} else {
builder = appendItemHoloChat(ReflectFactory.convertBukkitItemStackToJson(itemStack), message);
}
if (QuickShop.getPermissionManager().hasPermission(player, "quickshop.preview")) {
//Skip the previous component, avoid it was applied with click event
// Skip the previous component, avoid it was applied with click event
builder.append(" ");
builder.event(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
MsgUtil.fillArgs(
"/qs silentpreview {0}",
shop.getRuntimeRandomUniqueId().toString())));
builder.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
MsgUtil.fillArgs("/qs silentpreview {0}", shop.getRuntimeRandomUniqueId().toString())));
builder.appendLegacy(plugin.text().of(player, "menu.preview").forLocale());
}
BaseComponent[] result = builder.create();
//The limit in vanilla server is 32767
// The limit in vanilla server is 32767
if (ComponentSerializer.toString(result).getBytes(StandardCharsets.UTF_8).length > 32767) {
if (skipItemHoloChat) {
//If still too large after skipItemHoloChat, just send the error message
return new QuickComponentImpl(plugin.text().of(player, "menu.item-holochat-data-too-large").forLocale());
// If still too large after skipItemHoloChat, just send the error message
return new QuickComponentImpl(
plugin.text().of(player, "menu.item-holochat-data-too-large").forLocale());
} else {
return getItemHologramChat(shop, itemStack, player, message, true);
}
} else {
return new QuickComponentImpl(result);
}
} catch (Exception t) {
plugin.getLogger().log(Level.WARNING, "Failed to process chat component", t);
return new QuickComponentImpl(errorComponent);
}
}
@Override
public @NotNull QuickComponent getItemTextComponent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull String normalText) {
TextComponent errorComponent = new TextComponent(plugin.text().of(player, "menu.item-holochat-error").forLocale());
public @NotNull QuickComponent getItemTextComponent(@NotNull Player player, @NotNull ItemStack itemStack,
@NotNull String normalText)
{
TextComponent errorComponent = new TextComponent(
plugin.text().of(player, "menu.item-holochat-error").forLocale());
String json;
try {
json = ReflectFactory.convertBukkitItemStackToJson(itemStack);
} catch (Exception throwable) {
plugin.getLogger().log(Level.SEVERE, "Failed to saving item to json for holochat", throwable);
return new QuickComponentImpl(errorComponent);
}
if (json == null) {
return new QuickComponentImpl(errorComponent);
}
TextComponent component = new TextComponent(normalText + " " + plugin.text().of(player, "menu.preview").forLocale());
if (json == null) {
return new QuickComponentImpl(errorComponent);
}
TextComponent component = new TextComponent(
normalText + " " + plugin.text().of(player, "menu.preview").forLocale());
ComponentBuilder cBuilder = new ComponentBuilder(json);
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, cBuilder.create()));
return new QuickComponentImpl(component);
@@ -250,23 +359,31 @@ public class BungeeQuickChat implements QuickChat {
}
public String getIndexStr(int index) {
return index <= 9 ? indexStrCache[index] : "{" + index + "}";
}
@Override
public void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message, Map.Entry<String, String>... textToCommandMapping) {
public void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message,
Map.Entry<String, String>... textToCommandMapping)
{
List<BaseComponent> components = new ArrayList<>(Arrays.asList(fromLegacyText(message)));
Iterator<Map.Entry<String, String>> iterator = Arrays.asList(textToCommandMapping).iterator();
int index = 0;
replace:
while (iterator.hasNext()) {
replace: while (iterator.hasNext()) {
Map.Entry<String, String> replacement = iterator.next();
for (int i = 0; i < components.size(); i++) {
BaseComponent component = components.get(i);
if (component instanceof TextComponent) {
String text = ((TextComponent) component).getText();
if (text.contains(getIndexStr(index))) {
String[] strings = text.split(getIndexStr(index).replace("{", "\\{").replace("}", "\\}"), 2);
TextComponent component1 = new TextComponent(strings[0]);
TextComponent component2 = new TextComponent(strings[1]);
@@ -274,108 +391,161 @@ public class BungeeQuickChat implements QuickChat {
component2.copyFormatting(component);
BaseComponent[] replacementComponents = fromLegacyText(replacement.getKey());
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, replacement.getValue());
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, fromLegacyText(replacement.getKey()));
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT,
fromLegacyText(replacement.getKey()));
for (BaseComponent baseComponent : replacementComponents) {
baseComponent.setClickEvent(clickEvent);
baseComponent.setHoverEvent(hoverEvent);
component1.addExtra(baseComponent);
}
components.remove(i);
components.add(i, component2);
components.add(i, component1);
index++;
continue replace;
}
}
}
}
receiver.spigot().sendMessage(components.toArray(new BaseComponent[0]));
}
@Override
public void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText, @NotNull String command) {
BaseComponent[] components =
fromLegacyText(ChatColor.DARK_PURPLE + plugin.text().of(receiver, "tableformat.left_begin").forLocale() + message);
public void sendExecutableChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText,
@NotNull String command)
{
BaseComponent[] components = fromLegacyText(
ChatColor.DARK_PURPLE + plugin.text().of(receiver, "tableformat.left_begin").forLocale() + message);
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, command);
//FIXME: Update this when drop 1.15 supports
// FIXME: Update this when drop 1.15 supports
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, fromLegacyText(hoverText));
for (BaseComponent component : components) {
component.setClickEvent(clickEvent);
component.setHoverEvent(
hoverEvent); //FIXME: Update this when drop 1.15 supports
component.setHoverEvent(hoverEvent); // FIXME: Update this when drop 1.15 supports
}
receiver.spigot().sendMessage(components);
}
@Override
public void sendSuggestedChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText, @NotNull String command) {
BaseComponent[] components =
fromLegacyText(ChatColor.DARK_PURPLE + plugin.text().of(receiver, "tableformat.left_begin").forLocale() + message);
public void sendSuggestedChat(@NotNull CommandSender receiver, @NotNull String message, @NotNull String hoverText,
@NotNull String command)
{
BaseComponent[] components = fromLegacyText(
ChatColor.DARK_PURPLE + plugin.text().of(receiver, "tableformat.left_begin").forLocale() + message);
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command);
//FIXME: Update this when drop 1.15 supports
// FIXME: Update this when drop 1.15 supports
HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, fromLegacyText(hoverText));
for (BaseComponent component : components) {
component.setClickEvent(clickEvent);
component.setHoverEvent(hoverEvent);
}
receiver.spigot().sendMessage(components);
}
public static class BungeeComponentBuilder {
private static final boolean isUsingResetCommitVersion = Util
.isMethodAvailable(BaseComponent.class, "isReset");
private static final boolean isUsingResetCommitVersion = Util.isMethodAvailable(BaseComponent.class, "isReset");
private final ComponentBuilder builder;
public BungeeComponentBuilder() {
builder = new ComponentBuilder("");
builder.removeComponent(0);
}
public BungeeComponentBuilder append(BaseComponent component) {
if (builder.getCursor() == -1) {
append(component, ComponentBuilder.FormatRetention.EVENTS);
} else {
append(component, ComponentBuilder.FormatRetention.ALL);
}
return this;
}
return this;
}
public BungeeComponentBuilder append(BaseComponent[] components) {
for (BaseComponent component : components) {
append(component);
}
return this;
}
public BungeeComponentBuilder append(String text) {
if (builder.getCursor() == -1) {
append(text, ComponentBuilder.FormatRetention.EVENTS);
} else {
append(text, ComponentBuilder.FormatRetention.ALL);
}
return this;
}
public BungeeComponentBuilder appendLegacy(String... text) {
if (text == null || text.length == 0) {
return this;
}
StringBuilder stringBuilder = new StringBuilder(text[0]);
for (int i = 1; i < text.length; i++) {
stringBuilder.append(text[i]);
}
append(fromLegacyText(stringBuilder.toString()), ComponentBuilder.FormatRetention.EVENTS);
return this;
}
public BungeeComponentBuilder appendLegacyAndItem(String left, BaseComponent[] itemsComponent, String right) {
String uuidStr = UUID.randomUUID().toString();
BaseComponent[] components = fromLegacyText(left + uuidStr + right);
boolean centerFound = false;
for (BaseComponent component : components) {
//Find center value
// Find center value
if (!centerFound && component.toPlainText().contains(uuidStr)) {
centerFound = true;
String[] text = ((TextComponent) component).getText().split(uuidStr, 2);
TextComponent leftComponent = new TextComponent(text[0]);
@@ -383,90 +553,132 @@ public class BungeeQuickChat implements QuickChat {
TextComponent rightComponent = new TextComponent(text[1]);
rightComponent.copyFormatting(component);
for (BaseComponent baseComponent : itemsComponent) {
leftComponent.addExtra(baseComponent);
}
append(leftComponent, ComponentBuilder.FormatRetention.EVENTS);
append(rightComponent, ComponentBuilder.FormatRetention.EVENTS);
} else {
append(component, ComponentBuilder.FormatRetention.EVENTS);
}
}
return this;
}
}
return this;
}
public BungeeComponentBuilder appendLegacy(String text) {
append(fromLegacyText(text), ComponentBuilder.FormatRetention.EVENTS);
return this;
}
public BungeeComponentBuilder event(ClickEvent clickEvent) {
builder.event(clickEvent);
return this;
}
public BungeeComponentBuilder event(HoverEvent hoverEvent) {
builder.event(hoverEvent);
return this;
}
public BungeeComponentBuilder reset() {
builder.reset();
return this;
}
public BaseComponent[] create() {
return builder.create();
}
public ComponentBuilder color(net.md_5.bungee.api.ChatColor color) {
return builder.color(color);
}
/**
* The dump method for fixing append always care about reset
*/
//dump start
// dump start
private ComponentBuilder append(BaseComponent component, ComponentBuilder.FormatRetention retention) {
if (!isUsingResetCommitVersion) {
builder.append(component, retention);
return builder;
}
List<BaseComponent> parts = builder.getParts();
BaseComponent previous = (parts.isEmpty()) ? null : parts.get(parts.size() - 1);
if (component.isReset() && retention == ComponentBuilder.FormatRetention.ALL) {
retention = ComponentBuilder.FormatRetention.EVENTS;
}
//Hacky method to replace dummy components
// Hacky method to replace dummy components
if (previous == null && builder.getCursor() == -1) {
previous = new TextComponent("");
builder.append(previous);
}
if (previous != null && (!component.isReset() || retention == ComponentBuilder.FormatRetention.EVENTS)) {
component.copyFormatting(previous, retention, false);
parts.add(component);
builder.resetCursor();
} else {
//follow the original logic
// follow the original logic
builder.append(component, retention);
}
return builder;
}
private ComponentBuilder append(String text, ComponentBuilder.FormatRetention retention) {
return append(new TextComponent(text), retention);
}
private ComponentBuilder append(BaseComponent[] components, ComponentBuilder.FormatRetention retention) {
for (BaseComponent component : components) {
append(component, retention);
}
return builder;
}
//dump end
// dump end
}
}
@@ -45,338 +45,153 @@ import java.util.Set;
@Data
@SuppressWarnings("unchecked")
public class SimpleCommandManager implements CommandManager, TabCompleter, CommandExecutor {
private static final String[] EMPTY_ARGS = new String[0];
private final Set<CommandContainer> cmds = Sets.newCopyOnWriteArraySet(); //Because we open to allow register, so this should be thread-safe
private final Set<CommandContainer> cmds = Sets.newCopyOnWriteArraySet(); // Because we open to allow register, so
// this should be thread-safe
private final QuickShop plugin;
private final CommandContainer rootContainer;
public SimpleCommandManager(QuickShop plugin) {
this.plugin = plugin;
this.rootContainer = CommandContainer.builder()
.prefix("")
.permission(null)
.executor(new SubCommand_ROOT(plugin))
.build();
registerCmd(
CommandContainer.builder()
.prefix("help")
.permission(null)
.executor(new SubCommand_Help(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("unlimited")
.permission("quickshop.unlimited")
.executor(new SubCommand_Unlimited(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("silentunlimited")
.hidden(true)
.permission("quickshop.unlimited")
.executor(new SubCommand_SilentUnlimited(plugin))
this.rootContainer = CommandContainer.builder().prefix("").permission(null)
.executor(new SubCommand_ROOT(plugin)).build();
registerCmd(CommandContainer.builder().prefix("help").permission(null).executor(new SubCommand_Help(plugin))
.build());
registerCmd(CommandContainer.builder().prefix("unlimited").permission("quickshop.unlimited")
.executor(new SubCommand_Unlimited(plugin)).build());
registerCmd(CommandContainer.builder().prefix("silentunlimited").hidden(true).permission("quickshop.unlimited")
.executor(new SubCommand_SilentUnlimited(plugin)).build());
/*
registerCmd(
CommandContainer.builder()
.prefix("alwayscounting")
.hidden(false)
.permission("quickshop.alwayscounting")
.executor(new SubCommand_AlwaysCounting(plugin))
.build());
* registerCmd( CommandContainer.builder() .prefix("alwayscounting")
* .hidden(false) .permission("quickshop.alwayscounting") .executor(new
* SubCommand_AlwaysCounting(plugin)) .build());
*/
registerCmd(
CommandContainer.builder()
.prefix("silentalwayscounting")
.hidden(true)
.permission("quickshop.alwayscounting")
.executor(new SubCommand_SilentAlwaysCounting(plugin))
registerCmd(CommandContainer.builder().prefix("silentalwayscounting").hidden(true)
.permission("quickshop.alwayscounting").executor(new SubCommand_SilentAlwaysCounting(plugin)).build());
registerCmd(CommandContainer.builder().prefix("transfer").permission("quickshop.transfer")
.executor(new SubCommand_Transfer(plugin)).build());
registerCmd(CommandContainer.builder().prefix("setowner").permission("quickshop.setowner")
.executor(new SubCommand_SetOwner(plugin)).build());
registerCmd(CommandContainer.builder().prefix("owner").hidden(true).permission("quickshop.setowner")
.executor(new SubCommand_SetOwner(plugin)).build());
registerCmd(CommandContainer.builder().prefix("amount").permission(null).executor(new SubCommand_Amount(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("transfer")
.permission("quickshop.transfer")
.executor(new SubCommand_Transfer(plugin))
registerCmd(CommandContainer.builder().prefix("setbuy").permission("quickshop.create.buy")
.executor(new SubCommand_Buy(plugin)).build());
registerCmd(CommandContainer.builder().prefix("setsell").permission("quickshop.create.sell")
.executor(new SubCommand_Sell(plugin)).build());
registerCmd(CommandContainer.builder().prefix("silentbuy").hidden(true).permission("quickshop.create.buy")
.executor(new SubCommand_SilentBuy(plugin)).build());
registerCmd(CommandContainer.builder().prefix("silentsell").hidden(true).permission("quickshop.create.sell")
.executor(new SubCommand_SilentSell(plugin)).build());
registerCmd(CommandContainer.builder().prefix("price").permission("quickshop.create.changeprice")
.executor(new SubCommand_Price(plugin)).build());
registerCmd(CommandContainer.builder().prefix("remove").permission(null).executor(new SubCommand_Remove(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("setowner")
.permission("quickshop.setowner")
.executor(new SubCommand_SetOwner(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("owner")
.hidden(true)
.permission("quickshop.setowner")
.executor(new SubCommand_SetOwner(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("amount")
.permission(null)
.executor(new SubCommand_Amount(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("setbuy")
.permission("quickshop.create.buy")
.executor(new SubCommand_Buy(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("setsell")
.permission("quickshop.create.sell")
.executor(new SubCommand_Sell(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("silentbuy")
.hidden(true)
.permission("quickshop.create.buy")
.executor(new SubCommand_SilentBuy(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("silentsell")
.hidden(true)
.permission("quickshop.create.sell")
.executor(new SubCommand_SilentSell(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("price")
.permission("quickshop.create.changeprice")
.executor(new SubCommand_Price(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("remove")
.permission(null)
.executor(new SubCommand_Remove(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("silentremove")
.hidden(true)
.permission(null)
.executor(new SubCommand_SilentRemove(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("empty")
.permission("quickshop.empty")
.executor(new SubCommand_Empty(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("refill")
.permission("quickshop.refill")
.executor(new SubCommand_Refill(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("silentempty")
.hidden(true)
.permission("quickshop.empty")
.executor(new SubCommand_SilentEmpty(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("silentpreview")
.hidden(true)
.permission("quickshop.preview")
.executor(new SubCommand_SilentPreview(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("clean")
.permission("quickshop.clean")
.executor(new SubCommand_Clean(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("reload")
.permission("quickshop.reload")
.executor(new SubCommand_Reload(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("about")
.permission("quickshop.about")
.executor(new SubCommand_About(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("debug")
.permission("quickshop.debug")
.executor(new SubCommand_Debug(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("fetchmessage")
.permission("quickshop.fetchmessage")
.executor(new SubCommand_FetchMessage())
.build());
registerCmd(
CommandContainer.builder()
.prefix("info")
.permission("quickshop.info")
.executor(new SubCommand_Info(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("paste")
.permission("quickshop.paste")
.executor(new SubCommand_Paste(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("staff")
.permission("quickshop.staff")
.executor(new SubCommand_Staff(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("create")
.permission("quickshop.create.cmd")
.permission("quickshop.create.sell")
.executor(new SubCommand_Create(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("update")
.hidden(true)
.permission("quickshop.alerts")
.executor(new SubCommand_Update(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("find")
.permission("quickshop.find")
.executor(new SubCommand_Find(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("supercreate")
.permission("quickshop.create.admin")
.permission("quickshop.create.sell")
.executor(new SubCommand_SuperCreate(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("cleanghost")
.permission("quickshop.cleanghost")
.hidden(true)
.executor(new SubCommand_CleanGhost(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("reset")
.hidden(true)
.permission("quickshop.reset")
.executor(new SubCommand_Reset(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("convertlog")
.hidden(true)
.permission("quickshop.convertlog")
.executor(new SubCommand_LogConvert(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("recovery")
.hidden(true)
.permission("quickshop.recovery")
.executor(new SubCommand_Recovery(plugin))
.build());
registerCmd(
CommandContainer.builder()
.prefix("export")
.hidden(true)
.permission("quickshop.export")
.executor(new SubCommand_Export())
.build());
registerCmd(
CommandContainer.builder()
.prefix("convert")
.hidden(true)
.permission("quickshop.convert")
.executor(new SubCommand_Convert(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("size")
.permission("quickshop.create.stacks")
.permission("quickshop.create.changeamount")
.executor(new SubCommand_Size(plugin))
registerCmd(CommandContainer.builder().prefix("silentremove").hidden(true).permission(null)
.executor(new SubCommand_SilentRemove(plugin)).build());
registerCmd(CommandContainer.builder().prefix("empty").permission("quickshop.empty")
.executor(new SubCommand_Empty(plugin)).build());
registerCmd(CommandContainer.builder().prefix("refill").permission("quickshop.refill")
.executor(new SubCommand_Refill(plugin)).build());
registerCmd(CommandContainer.builder().prefix("silentempty").hidden(true).permission("quickshop.empty")
.executor(new SubCommand_SilentEmpty(plugin)).build());
registerCmd(CommandContainer.builder().prefix("silentpreview").hidden(true).permission("quickshop.preview")
.executor(new SubCommand_SilentPreview(plugin)).build());
registerCmd(CommandContainer.builder().prefix("clean").permission("quickshop.clean")
.executor(new SubCommand_Clean(plugin)).build());
registerCmd(CommandContainer.builder().prefix("reload").permission("quickshop.reload")
.executor(new SubCommand_Reload(plugin)).build());
registerCmd(CommandContainer.builder().prefix("about").permission("quickshop.about")
.executor(new SubCommand_About(plugin)).build());
registerCmd(CommandContainer.builder().prefix("debug").permission("quickshop.debug")
.executor(new SubCommand_Debug(plugin)).build());
registerCmd(CommandContainer.builder().prefix("fetchmessage").permission("quickshop.fetchmessage")
.executor(new SubCommand_FetchMessage()).build());
registerCmd(CommandContainer.builder().prefix("info").permission("quickshop.info")
.executor(new SubCommand_Info(plugin)).build());
registerCmd(CommandContainer.builder().prefix("paste").permission("quickshop.paste")
.executor(new SubCommand_Paste(plugin)).build());
registerCmd(CommandContainer.builder().prefix("staff").permission("quickshop.staff")
.executor(new SubCommand_Staff(plugin)).build());
registerCmd(CommandContainer.builder().prefix("create").permission("quickshop.create.cmd")
.permission("quickshop.create.sell").executor(new SubCommand_Create(plugin)).build());
registerCmd(CommandContainer.builder().prefix("update").hidden(true).permission("quickshop.alerts")
.executor(new SubCommand_Update(plugin)).build());
registerCmd(CommandContainer.builder().prefix("find").permission("quickshop.find")
.executor(new SubCommand_Find(plugin)).build());
registerCmd(CommandContainer.builder().prefix("supercreate").permission("quickshop.create.admin")
.permission("quickshop.create.sell").executor(new SubCommand_SuperCreate(plugin)).build());
registerCmd(CommandContainer.builder().prefix("cleanghost").permission("quickshop.cleanghost").hidden(true)
.executor(new SubCommand_CleanGhost(plugin)).build());
registerCmd(CommandContainer.builder().prefix("reset").hidden(true).permission("quickshop.reset")
.executor(new SubCommand_Reset(plugin)).build());
registerCmd(CommandContainer.builder().prefix("convertlog").hidden(true).permission("quickshop.convertlog")
.executor(new SubCommand_LogConvert(plugin)).build());
registerCmd(CommandContainer.builder().prefix("recovery").hidden(true).permission("quickshop.recovery")
.executor(new SubCommand_Recovery(plugin)).build());
registerCmd(CommandContainer.builder().prefix("export").hidden(true).permission("quickshop.export")
.executor(new SubCommand_Export()).build());
registerCmd(CommandContainer.builder().prefix("convert").hidden(true).permission("quickshop.convert")
.executor(new SubCommand_Convert(plugin)).build());
registerCmd(CommandContainer.builder().prefix("size").permission("quickshop.create.stacks")
.permission("quickshop.create.changeamount").executor(new SubCommand_Size(plugin))
.disabledSupplier(() -> !plugin.isAllowStack())
.disablePlaceholder(plugin.text().of("command.feature-not-enabled").forLocale())
.build());
registerCmd(CommandContainer.builder()
.prefix("item")
.permission("quickshop.create.changeitem")
.executor(new SubCommand_Item(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("removeall")
.selectivePermission("quickshop.removeall.other")
.selectivePermission("quickshop.removeall.self")
.executor(new SubCommand_RemoveAll(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("removeworld")
.permission("quickshop.removeworld")
.executor(new SubCommand_RemoveWorld(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("currency")
.permission("quickshop.currency")
.executor(new SubCommand_Currency(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("taxaccount")
.permission("quickshop.taxaccount")
.executor(new SubCommand_TaxAccount(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("toggledisplay")
.permission("quickshop.toggledisplay")
.executor(new SubCommand_ToggleDisplay(plugin))
.build());
registerCmd(CommandContainer.builder()
.prefix("purge")
.permission("quickshop.purge")
.disablePlaceholder(plugin.text().of("command.feature-not-enabled").forLocale()).build());
registerCmd(CommandContainer.builder().prefix("item").permission("quickshop.create.changeitem")
.executor(new SubCommand_Item(plugin)).build());
registerCmd(CommandContainer.builder().prefix("removeall").selectivePermission("quickshop.removeall.other")
.selectivePermission("quickshop.removeall.self").executor(new SubCommand_RemoveAll(plugin)).build());
registerCmd(CommandContainer.builder().prefix("removeworld").permission("quickshop.removeworld")
.executor(new SubCommand_RemoveWorld(plugin)).build());
registerCmd(CommandContainer.builder().prefix("currency").permission("quickshop.currency")
.executor(new SubCommand_Currency(plugin)).build());
registerCmd(CommandContainer.builder().prefix("taxaccount").permission("quickshop.taxaccount")
.executor(new SubCommand_TaxAccount(plugin)).build());
registerCmd(CommandContainer.builder().prefix("toggledisplay").permission("quickshop.toggledisplay")
.executor(new SubCommand_ToggleDisplay(plugin)).build());
registerCmd(CommandContainer.builder().prefix("purge").permission("quickshop.purge")
.disabledSupplier(() -> !plugin.getConfig().getBoolean("purge.enabled"))
.executor(new SubCommand_Purge(plugin))
.build());
.executor(new SubCommand_Purge(plugin)).build());
}
/**
* This is a interface to allow addons to register the subcommand into quickshop command manager.
* This is a interface to allow addons to register the subcommand into quickshop
* command manager.
*
* @param container The command container to register
* @throws IllegalStateException Will throw the error if register conflict.
*/
@Override
public void registerCmd(@NotNull CommandContainer container) {
if (cmds.contains(container)) {
Util.debugLog("Dupe subcommand registering: " + container);
return;
}
container.bakeExecutorType();
cmds.removeIf(commandContainer -> commandContainer.getPrefix().equalsIgnoreCase(container.getPrefix()));
cmds.add(container);
}
/**
* This is a interface to allow addons to unregister the registered/butil-in subcommand from command manager.
* This is a interface to allow addons to unregister the registered/butil-in
* subcommand from command manager.
*
* @param container The command container to unregister
*/
@Override
public void unregisterCmd(@NotNull CommandContainer container) {
cmds.remove(container);
}
/**
@@ -387,207 +202,314 @@ public class SimpleCommandManager implements CommandManager, TabCompleter, Comma
@Override
@NotNull
public List<CommandContainer> getRegisteredCommands() {
return new ArrayList<>(this.getCmds());
}
@Override
public boolean onCommand(
@NotNull CommandSender sender,
@NotNull Command command,
@NotNull String commandLabel,
@NotNull String[] cmdArg) {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String commandLabel,
@NotNull String[] cmdArg)
{
if (plugin.getBootError() != null) {
if (cmdArg.length <= 0) {
plugin.getBootError().printErrors(sender);
return true;
}
if (!"paste".equalsIgnoreCase(cmdArg[0])) {
plugin.getBootError().printErrors(sender);
return true;
}
}
if (sender instanceof Player && plugin.getConfig().getBoolean("effect.sound.oncommand")) {
Player player = (Player) sender;
((Player) sender)
.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 80.0F, 1.0F);
((Player) sender).playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 80.0F, 1.0F);
}
if (cmdArg.length == 0) {
//Handle main command
// Handle main command
Util.debugLog("Print help cause no args (/qs)");
rootContainer.getExecutor().onCommand(capture(sender), commandLabel, EMPTY_ARGS);
} else {
//Handle subcommand
// Handle subcommand
String[] passThroughArgs = new String[cmdArg.length - 1];
System.arraycopy(cmdArg, 1, passThroughArgs, 0, passThroughArgs.length);
for (CommandContainer container : cmds) {
if (!container.getPrefix().equalsIgnoreCase(cmdArg[0])) {
continue;
}
if (container.isDisabled() || (container.getDisabledSupplier() != null && container.getDisabledSupplier().get())) {
if (container.isDisabled()
|| (container.getDisabledSupplier() != null && container.getDisabledSupplier().get()))
{
MsgUtil.sendDirectMessage(sender, container.getDisableText(sender));
return true;
}
if (!isAdapt(container, sender)) {
plugin.text().of(sender, "command-type-mismatch", container.getExecutorType().getSimpleName()).send();
plugin.text().of(sender, "command-type-mismatch", container.getExecutorType().getSimpleName())
.send();
return true;
}
List<String> requirePermissions = container.getPermissions();
List<String> selectivePermissions = container.getSelectivePermissions();
if (!checkPermissions(sender, commandLabel, passThroughArgs, requirePermissions, SimpleCommandManager.PermissionType.REQUIRE, SimpleCommandManager.Action.EXECUTE)) {
if (!checkPermissions(sender, commandLabel, passThroughArgs, requirePermissions,
SimpleCommandManager.PermissionType.REQUIRE, SimpleCommandManager.Action.EXECUTE))
{
plugin.text().of(sender, "no-permission").send();
return true;
}
if (!checkPermissions(sender, commandLabel, passThroughArgs, selectivePermissions, SimpleCommandManager.PermissionType.SELECTIVE, SimpleCommandManager.Action.EXECUTE)) {
if (!checkPermissions(sender, commandLabel, passThroughArgs, selectivePermissions,
SimpleCommandManager.PermissionType.SELECTIVE, SimpleCommandManager.Action.EXECUTE))
{
plugin.text().of(sender, "no-permission").send();
return true;
}
Util.debugLog("Execute container: " + container.getPrefix() + " - " + cmdArg[0]);
container.getExecutor().onCommand(capture(sender), commandLabel, passThroughArgs);
return true;
}
Util.debugLog("All checks failed, print helps");
rootContainer.getExecutor().onCommand(capture(sender), commandLabel, passThroughArgs);
}
return true;
}
/**
* Method for capturing generic type
*/
private <T1, T2 extends T1> T2 capture(T1 type) {
return (T2) type;
}
private boolean checkPermissions(CommandSender sender, String commandLabel, String[] cmdArg, List<String> permissionList, SimpleCommandManager.PermissionType permissionType, SimpleCommandManager.Action action) {
private boolean checkPermissions(CommandSender sender, String commandLabel, String[] cmdArg,
List<String> permissionList, SimpleCommandManager.PermissionType permissionType,
SimpleCommandManager.Action action)
{
if (permissionList == null || permissionList.isEmpty()) {
return true;
}
if (permissionType == SimpleCommandManager.PermissionType.REQUIRE) {
for (String requirePermission : permissionList) {
if (requirePermission != null
&& !requirePermission.isEmpty()
&& !QuickShop.getPermissionManager().hasPermission(sender, requirePermission)) {
Util.debugLog(
"Sender "
+ sender.getName()
+ " trying " + action.getName() + " the command: "
+ commandLabel
+ " "
+ Util.array2String(cmdArg)
+ ", but no permission "
if (requirePermission != null && !requirePermission.isEmpty()
&& !QuickShop.getPermissionManager().hasPermission(sender, requirePermission))
{
Util.debugLog("Sender " + sender.getName() + " trying " + action.getName() + " the command: "
+ commandLabel + " " + Util.array2String(cmdArg) + ", but no permission "
+ requirePermission);
return false;
}
}
return true;
} else {
for (String selectivePermission : permissionList) {
if (selectivePermission != null && !selectivePermission.isEmpty()) {
if (QuickShop.getPermissionManager().hasPermission(sender, selectivePermission)) {
return true;
}
}
}
Util.debugLog(
"Sender "
+ sender.getName()
+ " trying " + action + " the command: "
+ commandLabel
+ " "
+ Util.array2String(cmdArg)
+ ", but does no have one of those permissions: "
+ permissionList);
return false;
}
}
}
return true;
} else {
for (String selectivePermission : permissionList) {
if (selectivePermission != null && !selectivePermission.isEmpty()) {
if (QuickShop.getPermissionManager().hasPermission(sender, selectivePermission)) {
return true;
}
}
}
Util.debugLog("Sender " + sender.getName() + " trying " + action + " the command: " + commandLabel + " "
+ Util.array2String(cmdArg) + ", but does no have one of those permissions: " + permissionList);
return false;
}
}
private boolean isAdapt(CommandContainer container, CommandSender sender) {
return container.getExecutorType().isInstance(sender);
}
@Override
public @Nullable List<String> onTabComplete(
@NotNull CommandSender sender,
@NotNull Command command,
@NotNull String commandLabel,
@NotNull String[] cmdArg) {
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String commandLabel, @NotNull String[] cmdArg)
{
// No args, it shouldn't happened
if (plugin.getBootError() != null) {
return Collections.emptyList();
}
if (sender instanceof Player && plugin.getConfig().getBoolean("effect.sound.ontabcomplete")) {
Player player = (Player) sender;
((Player) sender).playSound(player.getLocation(), Sound.BLOCK_DISPENSER_FAIL, 80.0F, 1.0F);
}
if (cmdArg.length <= 1) {
//If no args or one args passed, return the sub command list matching
// If no args or one args passed, return the sub command list matching
final List<String> candidate = new ArrayList<>();
String firstArg = cmdArg.length > 0 ? cmdArg[0] : "";
for (CommandContainer container : cmds) {
if (!container.getPrefix().startsWith(firstArg)) {
continue;
}
final List<String> requirePermissions = container.getPermissions();
final List<String> selectivePermissions = container.getSelectivePermissions();
if (!checkPermissions(sender, commandLabel, EMPTY_ARGS, requirePermissions, SimpleCommandManager.PermissionType.REQUIRE, SimpleCommandManager.Action.TAB_COMPLETE)) {
if (!checkPermissions(sender, commandLabel, EMPTY_ARGS, requirePermissions,
SimpleCommandManager.PermissionType.REQUIRE, SimpleCommandManager.Action.TAB_COMPLETE))
{
continue;
}
if (!checkPermissions(sender, commandLabel, EMPTY_ARGS, selectivePermissions, SimpleCommandManager.PermissionType.SELECTIVE, SimpleCommandManager.Action.TAB_COMPLETE)) {
if (!checkPermissions(sender, commandLabel, EMPTY_ARGS, selectivePermissions,
SimpleCommandManager.PermissionType.SELECTIVE, SimpleCommandManager.Action.TAB_COMPLETE))
{
continue;
}
if (!container.isHidden() && !(container.isDisabled() || (container.getDisabledSupplier() != null && container.getDisabledSupplier().get()))) {
if (!container.isHidden() && !(container.isDisabled()
|| (container.getDisabledSupplier() != null && container.getDisabledSupplier().get())))
{
candidate.add(container.getPrefix());
}
}
return candidate;
} else {
// If two args passed, tab-completing the subcommand args
String[] passThroughArgs = new String[cmdArg.length - 1];
System.arraycopy(cmdArg, 1, passThroughArgs, 0, passThroughArgs.length);
for (CommandContainer container : cmds) {
if (!container.getPrefix().toLowerCase().startsWith(cmdArg[0])) {
continue;
}
if (!isAdapt(container, sender)) {
return Collections.emptyList();
}
List<String> requirePermissions = container.getPermissions();
List<String> selectivePermissions = container.getSelectivePermissions();
if (!checkPermissions(sender, commandLabel, passThroughArgs, requirePermissions, SimpleCommandManager.PermissionType.REQUIRE, SimpleCommandManager.Action.TAB_COMPLETE)) {
if (!checkPermissions(sender, commandLabel, passThroughArgs, requirePermissions,
SimpleCommandManager.PermissionType.REQUIRE, SimpleCommandManager.Action.TAB_COMPLETE))
{
return Collections.emptyList();
}
if (!checkPermissions(sender, commandLabel, passThroughArgs, selectivePermissions, SimpleCommandManager.PermissionType.SELECTIVE, SimpleCommandManager.Action.TAB_COMPLETE)) {
if (!checkPermissions(sender, commandLabel, passThroughArgs, selectivePermissions,
SimpleCommandManager.PermissionType.SELECTIVE, SimpleCommandManager.Action.TAB_COMPLETE))
{
return Collections.emptyList();
}
Util.debugLog("Tab-complete container: " + container.getPrefix());
return container.getExecutor().onTabComplete(capture(sender), commandLabel, passThroughArgs);
}
return Collections.emptyList();
}
}
private enum Action {
EXECUTE("execute"),
TAB_COMPLETE("tab-complete");
EXECUTE("execute"), TAB_COMPLETE("tab-complete");
final String name;
Action(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
enum PermissionType {
REQUIRE,
SELECTIVE
REQUIRE, SELECTIVE
}
}
@@ -30,54 +30,37 @@ import org.maxgamer.quickshop.util.Util;
@AllArgsConstructor
public class SubCommand_About implements CommandHandler<CommandSender> {
private final QuickShop plugin;
@Override
public void onCommand(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) {
MsgUtil.sendDirectMessage(sender, ChatColor.AQUA + "QuickShop " + ChatColor.YELLOW + QuickShop.getFork());
MsgUtil.sendDirectMessage(sender,
ChatColor.AQUA + "QuickShop " + ChatColor.YELLOW + QuickShop.getFork());
MsgUtil.sendDirectMessage(sender,
ChatColor.AQUA
+ "Version "
+ ChatColor.YELLOW
+ ">> "
+ ChatColor.GREEN
+ QuickShop.getVersion());
ChatColor.AQUA + "Version " + ChatColor.YELLOW + ">> " + ChatColor.GREEN + QuickShop.getVersion());
if (QuickShop.getInstance().getBuildInfo().getGitBranch().toUpperCase().contains("LTS")) {
MsgUtil.sendDirectMessage(sender,
ChatColor.AQUA
+ "Release "
+ ChatColor.YELLOW
+ ">> "
+ ChatColor.GREEN
MsgUtil.sendDirectMessage(sender, ChatColor.AQUA + "Release " + ChatColor.YELLOW + ">> " + ChatColor.GREEN
+ plugin.text().of(sender, "updatenotify.label.lts").forLocale());
} else if (QuickShop.getInstance().getBuildInfo().getGitBranch().toUpperCase().contains("RELEASE")) {
MsgUtil.sendDirectMessage(sender,
ChatColor.AQUA
+ "Release "
+ ChatColor.YELLOW
+ ">> "
+ ChatColor.GREEN
MsgUtil.sendDirectMessage(sender, ChatColor.AQUA + "Release " + ChatColor.YELLOW + ">> " + ChatColor.GREEN
+ plugin.text().of(sender, "updatenotify.label.stable").forLocale());
} else {
MsgUtil.sendDirectMessage(sender,
ChatColor.AQUA
+ "Release "
+ ChatColor.YELLOW
+ ">> "
+ ChatColor.GREEN
MsgUtil.sendDirectMessage(sender, ChatColor.AQUA + "Release " + ChatColor.YELLOW + ">> " + ChatColor.GREEN
+ plugin.text().of(sender, "updatenotify.label.unstable").forLocale());
}
MsgUtil.sendDirectMessage(sender,
ChatColor.AQUA
+ "Developers "
+ ChatColor.YELLOW
+ ">> "
+ ChatColor.GREEN
MsgUtil.sendDirectMessage(sender, ChatColor.AQUA + "Developers " + ChatColor.YELLOW + ">> " + ChatColor.GREEN
+ Util.list2String(plugin.getDescription().getAuthors()));
MsgUtil.sendDirectMessage(sender, ChatColor.GOLD + "Powered by PotatoCraft Studio");
MsgUtil.sendDirectMessage(sender, ChatColor.RED + "Made with ❤");
}
}
Loaded 100 of 349 files, more files were not shown because too many files have changed in this diff. Show more