Merge upstream updates from EarthMC/QuickShop-Reremake (PR #3)
Remove Metrics, Sentry/Rollbar error reporting, FabledSkyblock integration, environment checker, Bootstrap GUI, Spartan compatibility, and all tests. Adopt Adventure API for item hover chat, simplify ReflectFactory methods, cache hopper protection config. Retain 1.19.4 API compatibility (EntityType.DROPPED_ITEM, PotionData, NMS-based item JSON serialization). Clean up build.gradle.kts to match removed code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit was merged in pull request #3.
This commit is contained in:
commit
afe9033684
56 files changed
+82
-5358
No files matched your search
@@ -1,10 +0,0 @@
|
||||
component_depth: 100
|
||||
languages:
|
||||
- java
|
||||
- script
|
||||
exclude:
|
||||
- /src/main/resources
|
||||
- /src/test/
|
||||
- /.github
|
||||
- /.idea
|
||||
- /lib
|
||||
@@ -1,20 +0,0 @@
|
||||
version = 1
|
||||
|
||||
[[analyzers]]
|
||||
name = "shell"
|
||||
enabled = true
|
||||
|
||||
[[analyzers]]
|
||||
name = "sql"
|
||||
enabled = true
|
||||
|
||||
[[analyzers]]
|
||||
name = "test-coverage"
|
||||
enabled = true
|
||||
|
||||
[[analyzers]]
|
||||
name = "java"
|
||||
enabled = true
|
||||
|
||||
[analyzers.meta]
|
||||
runtime_version = "15"
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
language: java
|
||||
sudo: required
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.m2/repository"
|
||||
jdk:
|
||||
- openjdk8
|
||||
install: skip
|
||||
#script:
|
||||
# - export PROJECT_NAME=QuickShop-Reremake #Set project name
|
||||
# - git clone --depth=1 https://github.com/Ghost-chu/$PROJECT_NAME.git $PROJECT_NAME #Clone project
|
||||
# - cd $PROJECT_NAME #Cd into project
|
||||
# - mvn clean #Clean up
|
||||
# - mvn -T 4 install #Install
|
||||
after_success:
|
||||
- rm -rf push # GITHUB - CLEANUP
|
||||
#Script to release to Github Release
|
||||
- mkdir push
|
||||
- cp -r ./target/*.jar ./push/
|
||||
- rm -f ./push/original-*.jar
|
||||
- rm -f ./push/*-shaded.jar
|
||||
- rm -f ./push/*-sources.jar
|
||||
- mv -f ./push/*-javadoc.jar ./push/JavaDocument.zip
|
||||
# #Script to release to Bukkit Dev
|
||||
# - mkdir devbukkit
|
||||
# - cp -r ./target/*.jar ./devbukkit/
|
||||
# - rm -f ./devbukkit/original-*.jar
|
||||
# - rm -f ./devbukkit/*-javadoc.jar
|
||||
# - rm -f ./devbukkit/*-shaded.jar
|
||||
# - rm -f ./devbukkit/*-sources.jar
|
||||
# - rm -f ./target/original-*.jar
|
||||
# - ls ./devbukkit -1 | grep ".jar$" > jarname.txt
|
||||
deploy:
|
||||
skip_cleanup: true
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: xsJTi70QvH4lqKDhpJvqpfBBKSlxrTxkLofeJND58ZYPFhVk4egTalBYz/fT54s4G8YQHflSUNocl+W9zn/4lpdsdI1acMhCpBz014TJOMeEuwXN7yMslGO8eUKaZUiVjhygzrCp0RKwmY3TcpcFI98lbDAsVgFegzBdQpGk3gtlF3O/PAFEcHnhkEdohNJHlBrPFIdahnM8/saYbyzSzcjGRLkIOt75yzY/+AE0pQh24yI1K6xGA2FzO9LVBmNE15HvoqQhmZ8amKMbbsOJNe9OLJYHZRmWViudtaQibZtKWLLH+S+kjJ280PA96NtqCQ4xI/bDTfgxg34VWwKh3NtuAAS1mcnLpSTIQddI2D+R2pfG5igq69qXkK/Xedgv06H9y8dHw+ygBUm5J+cooktASw3WCgwncesU5oO5G2vd/NxbcpDSm5LookdpWtxHL36dg1gafPKJI2sthileN4LfIp9cBMgIN4bDdp9CLjzayzbVeRAqFrvbCV+qW5Eub5cMun0BEZpIEcAFnugMLrkMGm5wtLkFKwhE8Qy7ZmsArGOVFjaQloTWHhrae0avqbBbJPglbWeYT0Bm4M1fqNU80e8bwPaC24yJpTN+MoUZ4cvJ7c09++4b0Q4VK5ordyqipK0/2jalclGNRZAXkDr+dQO6vBCLYZPEjShW3nY=
|
||||
file:
|
||||
- ./push/*
|
||||
file_glob: true
|
||||
on:
|
||||
tags: true
|
||||
overwrite: true
|
||||
#after_deploy:
|
||||
# #Confirm release to Bukkit Dev
|
||||
# - chmod +x deploy.sh
|
||||
# - "./deploy.sh $Curse_token"
|
||||
# #Deploy to the mvn-repo
|
||||
# - echo "Deploying to the Github..."
|
||||
# - git clone --depth=1 https://$Github_token@github.com/Ghost-chu/maven-repo.git maven-repo
|
||||
# - mvn deploy -DaltDeploymentRepository=mvn-repo::default::file:./maven-repo
|
||||
# - cd maven-repo
|
||||
# - git add .
|
||||
# - git commit -m "Auto update by Travis-CI bot"
|
||||
# - git push --force
|
||||
# - cd ..
|
||||
# - echo "Finish upload to Maven Repository"
|
||||
#after_script:
|
||||
# #Upload data to BinaryRepository
|
||||
# - git clone --depth=1 https://$Github_token@github.com/Ghost-chu/BinaryRepository.git BinaryRepository
|
||||
# - mkdir -p ./BinaryRepository/$PROJECT_NAME/$TRAVIS_BUILD_NUMBER
|
||||
# - mkdir -p ./BinaryRepository/$PROJECT_NAME/$TRAVIS_BUILD_NUMBER/target
|
||||
# - cp -r ./target/* ./BinaryRepository/$PROJECT_NAME/$TRAVIS_BUILD_NUMBER/target
|
||||
# - echo -e "== Built by Travis-CI ==\nBuild Number [$TRAVIS_BUILD_NUMBER]\nBuild Type
|
||||
# [$TRAVIS_EVENT_TYPE]\nTag [$TRAVIS_TAG]\nCommit [$TRAVIS_COMMIT] - [$TRAVIS_COMMIT_MESSAGE]"
|
||||
# > ./BinaryRepository/$PROJECT_NAME/$TRAVIS_BUILD_NUMBER/BUILDINFO
|
||||
# - cd BinaryRepository
|
||||
# - git add .
|
||||
# - git commit -m "Auto update by Bot"
|
||||
# - git push --force
|
||||
# - cd .. #Back root
|
||||
# - echo "Finish upload to BinaryRepository"
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"scanSettings": {
|
||||
"baseBranches": []
|
||||
},
|
||||
"checkRunSettings": {
|
||||
"vulnerableCheckRunConclusionLevel": "failure",
|
||||
"displayMode": "diff"
|
||||
},
|
||||
"issueSettings": {
|
||||
"minSeverityLevel": "LOW"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -44,8 +44,6 @@ repositories {
|
||||
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/")
|
||||
}
|
||||
|
||||
@@ -62,27 +60,17 @@ dependencies {
|
||||
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")
|
||||
@@ -99,10 +87,7 @@ dependencies {
|
||||
|
||||
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") {
|
||||
@@ -114,8 +99,6 @@ tasks.named<ProcessResources>("processResources") {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach { useJUnitPlatform() }
|
||||
|
||||
tasks.withType<AbstractArchiveTask>().configureEach {
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
@@ -165,7 +148,6 @@ tasks.named<ShadowJar>("shadowJar") {
|
||||
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",
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
project_id_env: CROWDIN_PROJECT_ID
|
||||
api_token_env: CROWDIN_PERSONAL_TOKEN
|
||||
preserve_hierarchy: true
|
||||
files:
|
||||
- source: /src/main/resources/lang/*.json
|
||||
translation: /crowdin/lang/%locale%/%original_file_name%
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This file is a part of project QuickShop, the name is deploy.sh
|
||||
# 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/>.
|
||||
#
|
||||
#
|
||||
|
||||
echo "Deploy jar to dev.bukkit.org"
|
||||
|
||||
xToken=$1
|
||||
curl -X POST -H "X-Api-Token: $xToken" -F 'metadata={"changelog":"Auto upload by Jenkins CI, see update details at https://www.spigotmc.org/resources/62575/updates","gameVersions":[8503,7915,7667,7330,7105,8849,8897,9016,9189,9261,9560,9561],"releaseType":"release"}' -F "file=@./target/QuickShop.jar" -s "https://dev.bukkit.org/api/projects/320536/upload-file" >fileid.json
|
||||
cat fileid.json
|
||||
echo "Finished upload to dev.bukkit.org."
|
||||
|
||||
exit 0
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -113,17 +113,9 @@ import org.maxgamer.quickshop.util.compatibility.SimpleCompatibilityManager;
|
||||
import org.maxgamer.quickshop.util.config.ConfigCommentUpdater;
|
||||
import org.maxgamer.quickshop.util.config.ConfigProvider;
|
||||
import org.maxgamer.quickshop.util.config.ConfigurationFixer;
|
||||
import org.maxgamer.quickshop.util.envcheck.CheckResult;
|
||||
import org.maxgamer.quickshop.util.envcheck.EnvCheckEntry;
|
||||
import org.maxgamer.quickshop.util.envcheck.EnvironmentChecker;
|
||||
import org.maxgamer.quickshop.util.envcheck.ResultContainer;
|
||||
import org.maxgamer.quickshop.util.envcheck.ResultReport;
|
||||
import org.maxgamer.quickshop.util.matcher.item.BukkitItemMatcherImpl;
|
||||
import org.maxgamer.quickshop.util.matcher.item.QuickShopItemMatcherImpl;
|
||||
import org.maxgamer.quickshop.util.reload.ReloadManager;
|
||||
import org.maxgamer.quickshop.util.reporter.error.EmptyErrorReporter;
|
||||
import org.maxgamer.quickshop.util.reporter.error.IErrorReporter;
|
||||
import org.maxgamer.quickshop.util.reporter.error.RollbarErrorReporter;
|
||||
import org.maxgamer.quickshop.watcher.CalendarWatcher;
|
||||
import org.maxgamer.quickshop.watcher.DisplayAutoDespawnWatcher;
|
||||
import org.maxgamer.quickshop.watcher.DisplayDupeRemoverWatcher;
|
||||
@@ -140,7 +132,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
@@ -154,7 +145,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
@@ -244,10 +234,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
@Nullable
|
||||
@Getter
|
||||
private LogWatcher logWatcher;
|
||||
/**
|
||||
* bStats, good helper for metrics.
|
||||
*/
|
||||
private Metrics metrics;
|
||||
/**
|
||||
* The plugin OpenInv (null if not present)
|
||||
*/
|
||||
@@ -263,11 +249,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
*/
|
||||
@Getter
|
||||
private PermissionChecker permissionChecker;
|
||||
/**
|
||||
* The error reporter to help devs report errors to Sentry.io
|
||||
*/
|
||||
@Getter
|
||||
private IErrorReporter sentryErrorReporter = new EmptyErrorReporter();
|
||||
/**
|
||||
* The server UniqueID, use to the ErrorReporter
|
||||
*/
|
||||
@@ -303,8 +284,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
@Getter
|
||||
private boolean includeOfflinePlayer;
|
||||
@Getter
|
||||
private EnvironmentChecker environmentChecker;
|
||||
@Getter
|
||||
@Nullable
|
||||
private UpdateWatcher updateWatcher;
|
||||
@Getter
|
||||
@@ -816,7 +795,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
|
||||
} catch (Throwable e) {
|
||||
|
||||
this.getSentryErrorReporter().ignoreThrow();
|
||||
getLogger().log(Level.WARNING, "Something going wrong when loading up economy system", e);
|
||||
getLogger().severe("QuickShop could not hook into a economy/Not found Vault or Reserve!");
|
||||
getLogger().severe("QuickShop CANNOT start!");
|
||||
@@ -918,7 +896,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
getLogger().info("QuickShop " + getFork() + " - Early boot step - Booting up");
|
||||
// BEWARE THESE ONLY RUN ONCE
|
||||
this.buildInfo = new BuildInfo(getResource("BUILDINFO"));
|
||||
runtimeCheck(EnvCheckEntry.Stage.ON_LOAD);
|
||||
getLogger().info("Reading the configuration...");
|
||||
this.initConfiguration();
|
||||
this.bootError = null;
|
||||
@@ -949,11 +926,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
public final void onDisable() {
|
||||
|
||||
getLogger().info("QuickShop is finishing remaining work, this may need a while...");
|
||||
if (sentryErrorReporter != null) {
|
||||
|
||||
sentryErrorReporter.unregister();
|
||||
|
||||
}
|
||||
|
||||
if (this.integrationHelper != null) {
|
||||
|
||||
@@ -999,7 +971,9 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
|
||||
}
|
||||
|
||||
if (AbstractDisplayItem.getNowUsing() == DisplayType.VIRTUALITEM) {
|
||||
if (AbstractDisplayItem.getNowUsing() == DisplayType.VIRTUALITEM && this.display
|
||||
&& Bukkit.getPluginManager().getPlugin("ProtocolLib") != null)
|
||||
{
|
||||
|
||||
VirtualDisplayItem.VirtualDisplayItemManager.unload();
|
||||
|
||||
@@ -1170,126 +1144,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
|
||||
}
|
||||
|
||||
private void runtimeCheck(@NotNull EnvCheckEntry.Stage stage) {
|
||||
|
||||
testing = true;
|
||||
environmentChecker = new org.maxgamer.quickshop.util.envcheck.EnvironmentChecker(this);
|
||||
ResultReport resultReport = environmentChecker.run(stage);
|
||||
StringJoiner joiner = new StringJoiner("\n", "", "");
|
||||
if (resultReport.getFinalResult().ordinal() > CheckResult.WARNING.ordinal()) {
|
||||
|
||||
for (Entry<EnvCheckEntry, ResultContainer> result : resultReport.getResults().entrySet()) {
|
||||
|
||||
if (result.getValue().getResult().ordinal() > CheckResult.WARNING.ordinal()) {
|
||||
|
||||
joiner.add(String.format("- [%s/%s] %s", result.getValue().getResult().getDisplay(),
|
||||
result.getKey().name(), result.getValue().getResultMessage()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Check If we need kill the server or disable plugin
|
||||
|
||||
switch (resultReport.getFinalResult()) {
|
||||
|
||||
case DISABLE_PLUGIN:
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
break;
|
||||
case STOP_WORKING:
|
||||
setupBootError(new BootError(this.getLogger(), joiner.toString()), true);
|
||||
PluginCommand command = getCommand("qs");
|
||||
if (command != null) {
|
||||
|
||||
command.setTabCompleter(this); // Disable tab completer
|
||||
|
||||
}
|
||||
break;
|
||||
case KILL_SERVER:
|
||||
getLogger().severe(
|
||||
"[Security Risk Detected] QuickShop forcing crash the server for security, contact the developer for details.");
|
||||
String result = environmentChecker.getReportMaker().bake();
|
||||
File reportFile = writeSecurityReportToFile();
|
||||
URI uri = null;
|
||||
if (reportFile != null) {
|
||||
|
||||
uri = reportFile.toURI();
|
||||
|
||||
}
|
||||
if (uri != null) {
|
||||
|
||||
getLogger().warning("[Security Risk Detected] To get more details, please check: " + uri);
|
||||
try {
|
||||
|
||||
if (java.awt.Desktop.isDesktopSupported()) {
|
||||
|
||||
java.awt.Desktop dp = java.awt.Desktop.getDesktop();
|
||||
if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||
|
||||
dp.browse(uri);
|
||||
getLogger().warning("[Security Risk Detected] A browser already open for you. ");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
// If failed, write directly to console
|
||||
getLogger().severe(result);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// If write failed, write directly to console
|
||||
getLogger().severe(result);
|
||||
|
||||
}
|
||||
// Wait for a while for user and logger outputting
|
||||
try {
|
||||
|
||||
// 10 seconds
|
||||
Thread.yield();
|
||||
Thread.sleep(10000);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
// Halt the process, kill the server
|
||||
Runtime.getRuntime().halt(-1);
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
testing = false;
|
||||
|
||||
}
|
||||
|
||||
private File writeSecurityReportToFile() {
|
||||
|
||||
File file = new File(getDataFolder(), UUID.randomUUID() + ".security.letter.txt");
|
||||
try {
|
||||
|
||||
Files.write(new File(getDataFolder(), UUID.randomUUID() + ".security.letter.txt").toPath(),
|
||||
environmentChecker.getReportMaker().bake().getBytes(StandardCharsets.UTF_8));
|
||||
file = file.getCanonicalFile();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
getLogger().log(Level.SEVERE, "Failed to write security report!", e);
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return file;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onEnable() {
|
||||
|
||||
@@ -1310,42 +1164,9 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
Timer enableTimer = new Timer(true);
|
||||
this.integrationHelper.callIntegrationsLoad(IntegrateStage.onEnableBegin);
|
||||
|
||||
getLogger().info("QuickShop " + getFork());
|
||||
|
||||
/* Check the running envs is support or not. */
|
||||
getLogger().info("Starting plugin self-test, please wait...");
|
||||
runtimeCheck(EnvCheckEntry.Stage.ON_ENABLE);
|
||||
|
||||
getLogger().info("Reading the configuration...");
|
||||
this.initConfiguration();
|
||||
|
||||
getLogger().info("Developers: " + Util.list2String(this.getDescription().getAuthors()));
|
||||
getLogger().info("Original author: Netherfoam, Timtower, KaiNoMood");
|
||||
getLogger().info("Let's start loading the plugin");
|
||||
getLogger().info("Chat processor selected: Hardcoded BungeeChat Lib");
|
||||
/* Process Metrics and Sentry error reporter. */
|
||||
metrics = new Metrics(this, 3320);
|
||||
|
||||
try {
|
||||
|
||||
if (!getConfig().getBoolean("auto-report-errors")) {
|
||||
|
||||
Util.debugLog("Error reporter was disabled!");
|
||||
|
||||
} else {
|
||||
|
||||
sentryErrorReporter = new RollbarErrorReporter(this);
|
||||
|
||||
}
|
||||
|
||||
} catch (Throwable th) {
|
||||
|
||||
getLogger().warning("Cannot load the Sentry Error Reporter: " + th.getMessage());
|
||||
getLogger().warning(
|
||||
"Because our error reporter doesn't work, please report this error to developer, thank you!");
|
||||
|
||||
}
|
||||
|
||||
/* Initalize the Utils */
|
||||
this.loadItemMatcher();
|
||||
Util.initialize();
|
||||
@@ -1386,7 +1207,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
|
||||
}
|
||||
|
||||
getLogger().info("Registering commands...");
|
||||
/* PreInit for BootError feature */
|
||||
commandManager = new SimpleCommandManager(this);
|
||||
// noinspection ConstantConditions
|
||||
@@ -1445,7 +1265,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
shopLoader = new ShopLoader(this);
|
||||
shopLoader.loadShops();
|
||||
|
||||
getLogger().info("Registering listeners...");
|
||||
// Register events
|
||||
// Listeners (These don't)
|
||||
new BlockListener(this, this.shopCache).register();
|
||||
@@ -1569,8 +1388,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
|
||||
integrationHelper.searchAndRegisterPlugins();
|
||||
this.integrationHelper.callIntegrationsLoad(IntegrateStage.onEnableAfter);
|
||||
getLogger().info("Registering bStats metrics...");
|
||||
submitMetrics();
|
||||
if (loaded) {
|
||||
|
||||
getServer().getPluginManager().callEvent(new QSConfigurationReloadEvent(this));
|
||||
@@ -1712,82 +1529,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
|
||||
}
|
||||
|
||||
private void submitMetrics() {
|
||||
|
||||
if (!getConfig().getBoolean("disabled-metrics")) {
|
||||
|
||||
String vaultVer;
|
||||
Plugin vault = Bukkit.getPluginManager().getPlugin("Vault");
|
||||
if (vault != null) {
|
||||
|
||||
vaultVer = vault.getDescription().getVersion();
|
||||
|
||||
} else {
|
||||
|
||||
vaultVer = "Vault not found";
|
||||
|
||||
}
|
||||
|
||||
// Use internal Metric class not Maven for solve plugin name issues
|
||||
String economyType = AbstractEconomy.getNowUsing().name();
|
||||
if (getEconomy() != null) {
|
||||
|
||||
economyType = this.getEconomy().getName();
|
||||
|
||||
}
|
||||
|
||||
String eventAdapter;
|
||||
if (getConfig().getInt("shop.protection-checking-handler") == 1) {
|
||||
|
||||
eventAdapter = "QUICKSHOP";
|
||||
|
||||
} else {
|
||||
|
||||
eventAdapter = "BUKKIT";
|
||||
|
||||
}
|
||||
|
||||
// Version
|
||||
metrics.addCustomChart(new Metrics.SimplePie("server_version", Bukkit::getVersion));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("bukkit_version", Bukkit::getBukkitVersion));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("vault_version", () -> vaultVer));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_display_items",
|
||||
() -> Util.boolean2Status(getConfig().getBoolean("shop.display-items"))));
|
||||
metrics.addCustomChart(
|
||||
new Metrics.SimplePie("use_locks", () -> Util.boolean2Status(getConfig().getBoolean("shop.lock"))));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_sneak_action",
|
||||
() -> Util.boolean2Status(getConfig().getBoolean("shop.interact.sneak-to-create")
|
||||
|| getConfig().getBoolean("shop.interact.sneak-to-trade")
|
||||
|| getConfig().getBoolean("shop.interact.sneak-to-control"))));
|
||||
String finalEconomyType = economyType;
|
||||
metrics.addCustomChart(new Metrics.SimplePie("economy_type", () -> finalEconomyType));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_display_auto_despawn",
|
||||
() -> String.valueOf(getConfig().getBoolean("shop.display-auto-despawn"))));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_enhance_display_protect",
|
||||
() -> String.valueOf(getConfig().getBoolean("shop.enchance-display-protect"))));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_enhance_shop_protect",
|
||||
() -> String.valueOf(getConfig().getBoolean("shop.enchance-shop-protect"))));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_ongoing_fee",
|
||||
() -> String.valueOf(getConfig().getBoolean("shop.ongoing-fee.enable"))));
|
||||
metrics.addCustomChart(
|
||||
new Metrics.SimplePie("database_type", () -> this.getDatabaseManager().getDatabase().getName()));
|
||||
metrics.addCustomChart(
|
||||
new Metrics.SimplePie("display_type", () -> AbstractDisplayItem.getNowUsing().name()));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("itemmatcher_type", () -> this.getItemMatcher().getName()));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("use_stack_item", () -> String.valueOf(this.isAllowStack())));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("chat_adapter", () -> "Hardcoded Adventure"));
|
||||
metrics.addCustomChart(new Metrics.SimplePie("event_adapter", () -> eventAdapter));
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("shops_created_on_all_servers",
|
||||
() -> this.getShopManager().getAllShops().size()));
|
||||
|
||||
} else {
|
||||
|
||||
getLogger().info("You have disabled mertics, Skipping...");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Refactor it
|
||||
private void updateConfig(int selectedVersion) throws IOException {
|
||||
|
||||
@@ -3369,7 +3110,6 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
|
||||
try {
|
||||
|
||||
ReflectFactory.getCommandMap().register("qs", quickShopCommand);
|
||||
ReflectFactory.syncCommands();
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
package org.maxgamer.quickshop.chat.platform.minedown;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -38,13 +39,8 @@ import org.maxgamer.quickshop.api.chat.QuickChat;
|
||||
import org.maxgamer.quickshop.api.chat.QuickComponent;
|
||||
import org.maxgamer.quickshop.api.shop.Shop;
|
||||
import org.maxgamer.quickshop.chat.QuickComponentImpl;
|
||||
import org.maxgamer.quickshop.util.MsgUtil;
|
||||
import org.maxgamer.quickshop.util.ReflectFactory;
|
||||
import org.maxgamer.quickshop.util.TextSplitter;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@@ -128,6 +124,13 @@ public class BungeeQuickChat implements QuickChat {
|
||||
|
||||
}
|
||||
|
||||
if (component.get() instanceof Component adventureComponent) {
|
||||
|
||||
receiver.sendMessage(adventureComponent);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
Util.debugLog("Illegal component " + component.get().getClass().getName() + " sending to "
|
||||
+ this.getClass().getName() + " processor, trying force sending.");
|
||||
|
||||
@@ -149,109 +152,7 @@ public class BungeeQuickChat implements QuickChat {
|
||||
@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;
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
if (resultStr.getBytes(StandardCharsets.UTF_8).length > 32767) {
|
||||
|
||||
if (skipItemHoloChat) {
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to process chat component", e);
|
||||
player.spigot().sendMessage(errorComponent);
|
||||
|
||||
}
|
||||
player.sendMessage(LegacyComponentSerializer.legacySection().deserialize(text).hoverEvent(itemStack));
|
||||
|
||||
}
|
||||
|
||||
@@ -260,65 +161,26 @@ public class BungeeQuickChat implements QuickChat {
|
||||
@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());
|
||||
try {
|
||||
|
||||
BungeeComponentBuilder builder;
|
||||
if (skipItemHoloChat) {
|
||||
|
||||
builder = appendItemHoloChat(null, message);
|
||||
|
||||
} else {
|
||||
|
||||
builder = appendItemHoloChat(ReflectFactory.convertBukkitItemStackToJson(itemStack), message);
|
||||
|
||||
}
|
||||
|
||||
final net.kyori.adventure.text.TextComponent.Builder builder = LegacyComponentSerializer.legacySection()
|
||||
.deserialize(message).hoverEvent(itemStack).toBuilder();
|
||||
if (QuickShop.getPermissionManager().hasPermission(player, "quickshop.preview")) {
|
||||
|
||||
// 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.appendLegacy(plugin.text().of(player, "menu.preview").forLocale());
|
||||
builder.clickEvent(net.kyori.adventure.text.event.ClickEvent
|
||||
.runCommand("/qs silentpreview " + shop.getRuntimeRandomUniqueId()));
|
||||
builder.append(LegacyComponentSerializer.legacySection()
|
||||
.deserialize(plugin.text().of(player, "menu.preview").forLocale()));
|
||||
|
||||
}
|
||||
|
||||
BaseComponent[] result = builder.create();
|
||||
// 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());
|
||||
|
||||
} else {
|
||||
|
||||
return getItemHologramChat(shop, itemStack, player, message, true);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
return new QuickComponentImpl(result);
|
||||
|
||||
}
|
||||
return new QuickComponentImpl(builder.build());
|
||||
|
||||
} catch (Exception t) {
|
||||
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to process chat component", t);
|
||||
return new QuickComponentImpl(errorComponent);
|
||||
return new QuickComponentImpl(
|
||||
new TextComponent(plugin.text().of(player, "menu.item-holochat-error").forLocale()));
|
||||
|
||||
}
|
||||
|
||||
@@ -329,31 +191,10 @@ public class BungeeQuickChat implements QuickChat {
|
||||
@NotNull String normalText)
|
||||
{
|
||||
|
||||
TextComponent errorComponent = new TextComponent(
|
||||
plugin.text().of(player, "menu.item-holochat-error").forLocale());
|
||||
final Component component = LegacyComponentSerializer.legacySection()
|
||||
.deserialize(normalText + " " + plugin.text().of(player, "menu.preview").forLocale())
|
||||
.hoverEvent(itemStack);
|
||||
|
||||
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());
|
||||
ComponentBuilder cBuilder = new ComponentBuilder(json);
|
||||
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, cBuilder.create()));
|
||||
return new QuickComponentImpl(component);
|
||||
|
||||
}
|
||||
|
||||
@@ -125,7 +125,6 @@ public class SubCommand_Paste implements CommandHandler<CommandSender> {
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"Failed to save paste locally! The content will be send to the console", e);
|
||||
sender.sendMessage("Paste save failed! Sending paste to the console...");
|
||||
|
||||
@@ -80,7 +80,6 @@ public class SubCommand_Update implements CommandHandler<CommandSender> {
|
||||
|
||||
MsgUtil.sendDirectMessage(sender,
|
||||
ChatColor.RED + "Update failed! Please check your console for more information.");
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to update QuickShop because of the following error:", e);
|
||||
return;
|
||||
|
||||
|
||||
@@ -271,7 +271,6 @@ public class DatabaseManager implements Reloadable {
|
||||
|
||||
} catch (SQLException sqle) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
this.plugin.getLogger().log(Level.WARNING,
|
||||
"Database connection may lost, we are trying reconnecting, if this message appear too many times, you should check your database file(sqlite) and internet connection(mysql).",
|
||||
sqle);
|
||||
|
||||
@@ -110,7 +110,6 @@ public class Economy_Reserve extends AbstractEconomy {
|
||||
|
||||
} catch (Exception throwable) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, errorMsg, throwable);
|
||||
return false;
|
||||
|
||||
@@ -145,7 +144,6 @@ public class Economy_Reserve extends AbstractEconomy {
|
||||
|
||||
} catch (Exception throwable) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, errorMsg, throwable);
|
||||
return formatInternal(balance);
|
||||
|
||||
@@ -182,7 +180,6 @@ public class Economy_Reserve extends AbstractEconomy {
|
||||
|
||||
} catch (Exception throwable) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, errorMsg, throwable);
|
||||
return 0.0;
|
||||
|
||||
@@ -220,7 +217,6 @@ public class Economy_Reserve extends AbstractEconomy {
|
||||
|
||||
} catch (Exception throwable) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, errorMsg, throwable);
|
||||
return false;
|
||||
|
||||
@@ -245,7 +241,6 @@ public class Economy_Reserve extends AbstractEconomy {
|
||||
|
||||
} catch (Exception throwable) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, errorMsg, throwable);
|
||||
return false;
|
||||
|
||||
|
||||
@@ -190,7 +190,6 @@ public class Economy_Vault extends AbstractEconomy implements Listener {
|
||||
|
||||
} catch (Exception t) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
if (trader.getName() == null) {
|
||||
|
||||
plugin.getLogger().warning("Deposit failed and player name is NULL, Player uuid: "
|
||||
@@ -281,7 +280,6 @@ public class Economy_Vault extends AbstractEconomy implements Listener {
|
||||
|
||||
} catch (Exception t) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, String.format(ERROR_MESSAGE, getProviderName()), t);
|
||||
return 0.0;
|
||||
|
||||
@@ -331,7 +329,6 @@ public class Economy_Vault extends AbstractEconomy implements Listener {
|
||||
|
||||
} catch (Exception t) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
if (trader.getName() == null) {
|
||||
|
||||
plugin.getLogger().warning("Withdraw failed and player name is NULL, Player uuid: "
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.api.integration.*;
|
||||
import org.maxgamer.quickshop.integration.advancedregionmarket.AdvancedShopRegionMarketIntegration;
|
||||
import org.maxgamer.quickshop.integration.fabledskyblock.FabledIntegration;
|
||||
import org.maxgamer.quickshop.integration.factionsuuid.FactionsUUIDIntegration;
|
||||
import org.maxgamer.quickshop.integration.griefprevention.GriefPreventionIntegration;
|
||||
import org.maxgamer.quickshop.integration.iridiumskyblock.IridiumSkyblockIntegration;
|
||||
@@ -46,7 +45,7 @@ import java.util.logging.Level;
|
||||
|
||||
public class SimpleIntegrationManager extends QuickShopInstanceHolder implements IntegrationManager {
|
||||
|
||||
private static final Map<String, Class<? extends IntegratedPlugin>> INTEGRATION_MAPPING = new HashMap<>(7);
|
||||
private static final Map<String, Class<? extends IntegratedPlugin>> INTEGRATION_MAPPING = new HashMap<>();
|
||||
|
||||
static {
|
||||
|
||||
@@ -57,7 +56,6 @@ public class SimpleIntegrationManager extends QuickShopInstanceHolder implements
|
||||
INTEGRATION_MAPPING.put("Residence", ResidenceIntegration.class);
|
||||
INTEGRATION_MAPPING.put("Towny", TownyIntegration.class);
|
||||
INTEGRATION_MAPPING.put("WorldGuard", WorldGuardIntegration.class);
|
||||
INTEGRATION_MAPPING.put("FabledSkyblock", FabledIntegration.class);
|
||||
INTEGRATION_MAPPING.put("IridiumSkyblock", IridiumSkyblockIntegration.class);
|
||||
INTEGRATION_MAPPING.put("SuperiorSkyblock", SuperiorSkyblock2Integration.class);
|
||||
INTEGRATION_MAPPING.put("AdvancedRegionMarket", AdvancedShopRegionMarketIntegration.class);
|
||||
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is FabledIntegration.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.integration.fabledskyblock;
|
||||
|
||||
import com.songoda.skyblock.api.SkyBlockAPI;
|
||||
import com.songoda.skyblock.api.island.Island;
|
||||
import com.songoda.skyblock.api.island.IslandRole;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.api.integration.IntegrateStage;
|
||||
import org.maxgamer.quickshop.api.integration.IntegrationStage;
|
||||
import org.maxgamer.quickshop.integration.AbstractQSIntegratedPlugin;
|
||||
import org.maxgamer.quickshop.util.reload.ReloadResult;
|
||||
import org.maxgamer.quickshop.util.reload.ReloadStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@IntegrationStage(loadStage = IntegrateStage.onEnableAfter)
|
||||
public class FabledIntegration extends AbstractQSIntegratedPlugin {
|
||||
|
||||
private boolean ignoreDisabledWorlds;
|
||||
private boolean whitelist;
|
||||
private List<IslandRole> islandRoleList = new ArrayList<>();
|
||||
|
||||
public FabledIntegration(QuickShop plugin) {
|
||||
|
||||
super(plugin);
|
||||
plugin.getReloadManager().register(this);
|
||||
loadConfiguration();
|
||||
registerListener();
|
||||
|
||||
}
|
||||
|
||||
private void loadConfiguration() {
|
||||
|
||||
ignoreDisabledWorlds = plugin.getConfig().getBoolean("integration.fabledskyblock.ignore-disabled-worlds");
|
||||
whitelist = plugin.getConfig().getBoolean("integration.fabledskyblock.whitelist-mode");
|
||||
this.islandRoleList = new ArrayList<>();
|
||||
for (String roleStr : plugin.getConfig().getStringList("integration.fabledskyblock.create")) {
|
||||
|
||||
try {
|
||||
|
||||
IslandRole role = IslandRole.valueOf(roleStr.toUpperCase(Locale.ENGLISH));
|
||||
this.islandRoleList.add(role);
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
plugin.getLogger().warning("Invalid FabledSkyBlock setting role in config: " + roleStr);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the integrated plugin name. For example, Residence
|
||||
*
|
||||
* @return integrated plugin
|
||||
*/
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
|
||||
return "FabledSkyblock";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can create shop here
|
||||
*
|
||||
* @param player the player want to create shop
|
||||
* @param location shop location
|
||||
* @return If you can create shop here
|
||||
*/
|
||||
@Override
|
||||
public boolean canCreateShopHere(@NotNull Player player, @NotNull Location location) {
|
||||
|
||||
Island island = SkyBlockAPI.getIslandManager().getIslandAtLocation(location);
|
||||
if (island == null)
|
||||
return whitelist;
|
||||
return this.islandRoleList.contains(island.getRole(player));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can trade with shop here
|
||||
*
|
||||
* @param player the player want to trade with shop
|
||||
* @param location shop location
|
||||
* @return If you can trade with shop here
|
||||
*/
|
||||
@Override
|
||||
public boolean canTradeShopHere(@NotNull Player player, @NotNull Location location) {
|
||||
|
||||
if (SkyBlockAPI.getIslandManager().getIslandAtLocation(location) == null) {
|
||||
|
||||
return ignoreDisabledWorlds;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can delete a shop here
|
||||
*
|
||||
* @param player the player want to delete the shop
|
||||
* @param location shop location
|
||||
* @return If you can delete the shop here
|
||||
*/
|
||||
@Override
|
||||
public boolean canDeleteShopHere(@NotNull Player player, @NotNull Location location) {
|
||||
|
||||
Island island = SkyBlockAPI.getIslandManager().getIslandAtLocation(location);
|
||||
if (island == null)
|
||||
return whitelist;
|
||||
return this.islandRoleList.contains(island.getRole(player));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loading logic Execute Stage defined by IntegrationStage
|
||||
*/
|
||||
@Override
|
||||
public void load() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloding logic Will execute when Quickshop unloading
|
||||
*/
|
||||
@Override
|
||||
public void unload() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReloadResult reloadModule() throws Exception {
|
||||
|
||||
loadConfiguration();
|
||||
return ReloadResult.builder().status(ReloadStatus.SUCCESS).build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is Bootstrap.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.javaw.bootstrap;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Java default bootstrap if user trying launch QuickShop directly
|
||||
*
|
||||
* @author Ghost_chu
|
||||
*/
|
||||
public class Bootstrap {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.out.println("QuickShop is a Spigot plugin.");
|
||||
System.out.println(
|
||||
"You cannot directly execute this jar file, please install it as server plugin following the tutorials.");
|
||||
System.out.println("https://www.spigotmc.org/wiki/spigot-installation.");
|
||||
if (java.awt.Desktop.isDesktopSupported()) {
|
||||
|
||||
try {
|
||||
|
||||
java.net.URI uri = java.net.URI.create("https://www.spigotmc.org/wiki/spigot-installation/#plugins");
|
||||
java.awt.Desktop dp = java.awt.Desktop.getDesktop();
|
||||
if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
|
||||
|
||||
createAndShowGUI(true);
|
||||
dp.browse(uri);
|
||||
|
||||
} else {
|
||||
|
||||
createAndShowGUI(false);
|
||||
|
||||
}
|
||||
|
||||
} catch (java.io.IOException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
createAndShowGUI(false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void createAndShowGUI(boolean supportBrowse) {
|
||||
|
||||
try {
|
||||
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
|
||||
} catch (ClassNotFoundException | UnsupportedLookAndFeelException | IllegalAccessException
|
||||
| InstantiationException e)
|
||||
{
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
if (supportBrowse) {
|
||||
|
||||
JOptionPane.showMessageDialog(new JPanel(), "<html><body><p>QuickShop is a Spigot plugin.</p>"
|
||||
+ "<p>You cannot directly execute this jar file, please install it as server plugin following the <a href=\"https://www.spigotmc.org/wiki/spigot-installation/\">tutorials</a>."
|
||||
+ "<p>Press \"OK\" button to open Spigot's plugin installation tutorial.</p>" + "</body></html>",
|
||||
"QuickShop Alert", JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
} else {
|
||||
|
||||
JOptionPane.showMessageDialog(new JPanel(), "<html><body><p>QuickShop is a Spigot plugin.</p>"
|
||||
+ "<p>You cannot directly execute this jar file, please install it as server plugin following the tutorials."
|
||||
+ "<p>Please open the link https://www.spigotmc.org/wiki/spigot-installation/ in your browser to view.</p>"
|
||||
+ "</body></html>", "QuickShop Alert", JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -455,7 +455,7 @@ public class ShopProtectionListener extends AbstractProtectionListener {
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||
public void onInventoryMove(InventoryMoveItemEvent event) {
|
||||
|
||||
if (!plugin.getConfig().getBoolean("protect.hopper")) {
|
||||
if (!protectHoppers) {
|
||||
|
||||
return;
|
||||
|
||||
|
||||
+3
-10
@@ -268,9 +268,6 @@ public class MojangGameLanguageImpl extends BukkitGameLanguageImpl implements Ga
|
||||
|
||||
}
|
||||
|
||||
private static final boolean isPotionSupportMinecraftKey = Util
|
||||
.isMethodAvailable("org.bukkit.potion.PotionEffectType", "getKey");
|
||||
|
||||
@Override
|
||||
public @NotNull String getPotion(@NotNull PotionEffectType potionEffectType) {
|
||||
|
||||
@@ -281,14 +278,11 @@ public class MojangGameLanguageImpl extends BukkitGameLanguageImpl implements Ga
|
||||
|
||||
}
|
||||
|
||||
JsonElement jsonElement;
|
||||
if (isPotionSupportMinecraftKey) {
|
||||
JsonElement jsonElement = lang.get().get("item.minecraft.potion.effect." + potionEffectType.getKey().getKey());
|
||||
|
||||
jsonElement = lang.get().get("effect.minecraft." + potionEffectType.getKey().getKey().toLowerCase());
|
||||
if (jsonElement == null) {
|
||||
|
||||
} else {
|
||||
|
||||
jsonElement = lang.get().get("effect.minecraft." + potionEffectType.getName().toLowerCase());
|
||||
jsonElement = lang.get().get("effect.minecraft." + potionEffectType.getKey().getKey());
|
||||
|
||||
}
|
||||
|
||||
@@ -553,7 +547,6 @@ public class MojangGameLanguageImpl extends BukkitGameLanguageImpl implements Ga
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
plugin.getSentryErrorReporter().ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING, "Something going wrong when loading game translation assets", e);
|
||||
|
||||
} finally {
|
||||
|
||||
@@ -219,8 +219,8 @@ public class ContainerShop implements Shop {
|
||||
this.taxAccount = taxAccount;
|
||||
initDisplayItem();
|
||||
this.dirty = false;
|
||||
// updateShopData();
|
||||
|
||||
// updateShopData();
|
||||
}
|
||||
|
||||
private void updateShopData() {
|
||||
|
||||
@@ -1788,6 +1788,8 @@ public class SimpleShopManager implements ShopManager, Reloadable {
|
||||
|
||||
for (PotionEffect potionEffect : effectsToPrint) {
|
||||
|
||||
// Internal api notes: amplifier starts from zero, so plus one to get the
|
||||
// correct result
|
||||
int level = potionEffect.getAmplifier() + 1;
|
||||
chatSheetPrinter.printLine(ChatColor.YELLOW + MsgUtil.getPotioni18n(potionEffect.getType()) + " "
|
||||
+ (level <= 10 ? RomanNumber.toRoman(potionEffect.getAmplifier()) : level));
|
||||
|
||||
@@ -51,6 +51,7 @@ public enum GameVersion {
|
||||
v1_19_R1(true, false, true, true, true, true), v1_19_R2(true, false, true, true, true, true),
|
||||
v1_19_R3(true, false, true, true, true, true), v1_20_R1(true, false, true, true, true, true),
|
||||
v1_20_R2(true, false, true, true, true, true), v1_20_R3(true, false, true, true, true, true),
|
||||
v1_21_4(true, false, true, true, true, true),
|
||||
|
||||
UNKNOWN(true, false, false, true, true, true);
|
||||
|
||||
|
||||
@@ -888,7 +888,6 @@ public class MsgUtil {
|
||||
|
||||
Util.debugLog("Content is null");
|
||||
Throwable throwable = new Throwable("Known issue: Global Alert accepted null string, what the fuck");
|
||||
plugin.getSentryErrorReporter().sendError(throwable, "NullCheck");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,14 @@
|
||||
|
||||
package org.maxgamer.quickshop.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandMap;
|
||||
@@ -28,17 +35,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* ReflectFactory is library builtin QuickShop to get/execute stuff that cannot
|
||||
* be access with BukkitAPI with reflect way.
|
||||
@@ -47,17 +43,10 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class ReflectFactory {
|
||||
|
||||
private static String cachedVersion = null;
|
||||
private static Method craftItemStack_asNMSCopyMethod;
|
||||
private static Method itemStack_saveMethod;
|
||||
private static Class<?> nbtTagCompoundClass;
|
||||
private static Class<?> craftServerClass;
|
||||
private static Class<?> cachedNMSClass;
|
||||
private static String nmsVersion;
|
||||
private static Method getMinecraftKeyNameMethod;
|
||||
private static final boolean isMinecraftKeyNameMethodUnavailable = false;
|
||||
// private static Object serverInstance;
|
||||
// private static Field tpsField;
|
||||
|
||||
static {
|
||||
|
||||
@@ -81,8 +70,6 @@ public class ReflectFactory {
|
||||
|
||||
Class<?> returnType = method.getReturnType();
|
||||
Parameter[] parameters = method.getParameters();
|
||||
// Save method sign is
|
||||
// foo(net/minecraft/nbt/NBTTagCompound)L(net/minecraft/nbt/NBTTagCompound)
|
||||
return !method.isSynthetic() && !method.isBridge() && parameters.length == 1
|
||||
&& returnType.equals(nbtTagCompoundClass)
|
||||
&& parameters[0].getType().equals(nbtTagCompoundClass);
|
||||
@@ -108,8 +95,6 @@ public class ReflectFactory {
|
||||
|
||||
}
|
||||
|
||||
craftServerClass = Class.forName("org.bukkit.craftbukkit." + nmsVersion + ".CraftServer");
|
||||
|
||||
} catch (Exception t) {
|
||||
|
||||
QuickShop.getInstance().getLogger().log(Level.WARNING,
|
||||
@@ -144,100 +129,12 @@ public class ReflectFactory {
|
||||
|
||||
return QuickShop.getInstance().getTpsWatcher().getAverageTPS();
|
||||
|
||||
// if (serverInstance == null || tpsField == null) {
|
||||
// try {
|
||||
// serverInstance = getNMSClass("MinecraftServer").getMethod("getServer").invoke(null);
|
||||
// tpsField = serverInstance.getClass().getField("recentTps");
|
||||
// } catch (NoSuchFieldException
|
||||
// | SecurityException
|
||||
// | IllegalAccessException
|
||||
// | IllegalArgumentException
|
||||
// | InvocationTargetException
|
||||
// | NoSuchMethodException e) {
|
||||
// serverInstance = null;
|
||||
// tpsField = null;
|
||||
// Util.debugLog("Failed to get TPS " + e.getMessage());
|
||||
// try {
|
||||
//
|
||||
// }catch (Exception exception){
|
||||
// return 20.0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// try {
|
||||
// double[] tps = ((double[]) tpsField.get(serverInstance));
|
||||
// return tps[0];
|
||||
// } catch (IllegalAccessException ignored) {
|
||||
// return 20.0;
|
||||
// }
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Class<?> getNMSClass(@Nullable String className) {
|
||||
|
||||
if (cachedNMSClass != null) {
|
||||
|
||||
return cachedNMSClass;
|
||||
|
||||
}
|
||||
|
||||
if (className == null) {
|
||||
|
||||
className = "MinecraftServer";
|
||||
|
||||
}
|
||||
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
String version = name.substring(name.lastIndexOf('.') + 1);
|
||||
try {
|
||||
|
||||
cachedNMSClass = Class.forName("net.minecraft.server." + version + "." + className);
|
||||
return cachedNMSClass;
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
throw new RuntimeException(e);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getServerVersion() {
|
||||
|
||||
if (cachedVersion != null) {
|
||||
|
||||
return cachedVersion;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Field consoleField = Bukkit.getServer().getClass().getDeclaredField("console");
|
||||
// protected
|
||||
consoleField.setAccessible(true);
|
||||
// dedicated server
|
||||
Object console = consoleField.get(Bukkit.getServer());
|
||||
cachedVersion = String.valueOf(console.getClass().getSuperclass().getMethod("getVersion").invoke(console));
|
||||
return cachedVersion;
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
// Fallback to common substring
|
||||
String[] strings = StringUtils.substringsBetween(Bukkit.getServer().getVersion(), "(MC: ", ")");
|
||||
if (strings != null && strings.length == 1) {
|
||||
|
||||
cachedVersion = strings[0];
|
||||
|
||||
} else {
|
||||
|
||||
cachedVersion = "Unknown";
|
||||
|
||||
}
|
||||
|
||||
return cachedVersion;
|
||||
|
||||
}
|
||||
return Bukkit.getServer().getMinecraftVersion();
|
||||
|
||||
}
|
||||
|
||||
@@ -246,10 +143,6 @@ public class ReflectFactory {
|
||||
*
|
||||
* @param bStack ItemStack
|
||||
* @return The json for ItemStack.
|
||||
* @throws InvocationTargetException throws
|
||||
* @throws IllegalAccessException throws
|
||||
* @throws NoSuchMethodException throws
|
||||
* @throws InstantiationException throws
|
||||
*/
|
||||
@Nullable
|
||||
public static String convertBukkitItemStackToJson(@NotNull ItemStack bStack)
|
||||
@@ -272,164 +165,16 @@ public class ReflectFactory {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save ItemStack to Json through the NMS.
|
||||
*
|
||||
* @param bStack ItemStack
|
||||
* @return The json for ItemStack.
|
||||
* @throws InvocationTargetException throws
|
||||
* @throws IllegalAccessException throws
|
||||
* @throws NoSuchMethodException throws
|
||||
* @throws InstantiationException throws
|
||||
*/
|
||||
@Nullable
|
||||
public static Object convertBukkitItemStackToMojangItemStack(@NotNull ItemStack bStack)
|
||||
throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException
|
||||
{
|
||||
public static CommandMap getCommandMap() {
|
||||
|
||||
if (bStack.getType() == Material.AIR) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
Object mcStack = craftItemStack_asNMSCopyMethod.invoke(null, bStack);
|
||||
Object nbtTagCompound = nbtTagCompoundClass.getDeclaredConstructor().newInstance();
|
||||
|
||||
itemStack_saveMethod.invoke(mcStack, nbtTagCompound);
|
||||
return nbtTagCompound.toString();
|
||||
|
||||
}
|
||||
|
||||
public static CommandMap getCommandMap() throws NoSuchFieldException, IllegalAccessException {
|
||||
|
||||
Field commandMapField = Bukkit.getServer().getClass().getDeclaredField("commandMap");
|
||||
commandMapField.setAccessible(true);
|
||||
return (CommandMap) commandMapField.get(Bukkit.getServer());
|
||||
|
||||
}
|
||||
|
||||
public static void syncCommands() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
|
||||
Method method = craftServerClass.getDeclaredMethod("syncCommands");
|
||||
try {
|
||||
|
||||
method.setAccessible(true);
|
||||
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
|
||||
method.invoke(Bukkit.getServer(), (Object[]) null);
|
||||
|
||||
}
|
||||
|
||||
private static Method findMethod(Class<?> targetClass, Class<?> returnType, Predicate<Method> filter,
|
||||
Class<?>... args)
|
||||
{
|
||||
|
||||
FindProcess: for (Method method : targetClass.getMethods()) {
|
||||
|
||||
if (method.isBridge() && method.isSynthetic()) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (method.getReturnType() == returnType) {
|
||||
|
||||
if (method.getParameterCount() == args.length) {
|
||||
|
||||
Parameter[] parameters = method.getParameters();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
|
||||
if (parameters[i].getType() != args[i]) {
|
||||
|
||||
continue FindProcess;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (filter.test(method)) {
|
||||
|
||||
return method;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
return Bukkit.getServer().getCommandMap();
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getMaterialMinecraftNamespacedKey(Material material) {
|
||||
|
||||
Object nmsItem;
|
||||
try {
|
||||
|
||||
nmsItem = Class.forName("org.bukkit.craftbukkit." + getNMSVersion() + ".util.CraftMagicNumbers")
|
||||
.getMethod("getItem", Material.class).invoke(null, material);
|
||||
|
||||
if (nmsItem == null) {
|
||||
|
||||
Util.debugLog("nmsItem null");
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
getMinecraftKeyNameMethod = nmsItem.getClass().getMethod("getName");
|
||||
|
||||
} catch (NoSuchMethodException exception) {
|
||||
|
||||
Util.debugLog("Mapping changed during minecraft update, dynamic searching...");
|
||||
getMinecraftKeyNameMethod = findMethod(nmsItem.getClass(), String.class, method -> {
|
||||
|
||||
try {
|
||||
|
||||
return !"toString".equals(method.getName()) && ((String) method.invoke(nmsItem)).toLowerCase()
|
||||
.contains(material.getKey().getKey().toLowerCase(Locale.ROOT));
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (getMinecraftKeyNameMethod == null) {
|
||||
|
||||
Util.debugLog("getMinecraftKeyNameMethod is null");
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
||||
return (String) getMinecraftKeyNameMethod.invoke(nmsItem);
|
||||
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException
|
||||
| InvocationTargetException e)
|
||||
{
|
||||
|
||||
Util.debugLog("getMinecraftKeyNameMethod, error: " + e);
|
||||
return null;
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
|
||||
Util.debugLog("getMinecraftKeyNameMethod, Unknown error: " + throwable);
|
||||
return null;
|
||||
|
||||
}
|
||||
return material.isItem() ? material.getItemTranslationKey() : material.getBlockTranslationKey();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.maxgamer.quickshop.api.shop.Shop;
|
||||
import org.maxgamer.quickshop.economy.Economy_Vault;
|
||||
import org.maxgamer.quickshop.shop.ShopLoader;
|
||||
import org.maxgamer.quickshop.util.MsgUtil;
|
||||
import org.maxgamer.quickshop.util.ReflectFactory;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
import org.maxgamer.quickshop.util.collector.CollectResolver;
|
||||
import org.maxgamer.quickshop.util.collector.CollectType;
|
||||
@@ -108,7 +107,6 @@ public class CollectorAdapter {
|
||||
data.put("name", plugin.getServer().getName());
|
||||
data.put("software", plugin.getServer().getVersion());
|
||||
data.put("version", plugin.getServer().getVersion());
|
||||
data.put("version_internal", ReflectFactory.getNMSVersion());
|
||||
data.put("version_data", plugin.getServer().getUnsafe().getDataVersion());
|
||||
data.put("online_mode", plugin.getServer().getOnlineMode());
|
||||
data.put("view_distance", plugin.getServer().getViewDistance());
|
||||
|
||||
-1
@@ -43,7 +43,6 @@ public class SimpleCompatibilityManager extends QuickShopInstanceHolder implemen
|
||||
static {
|
||||
|
||||
MODULE_MAP.put("NoCheatPlus", NCPCompatibilityModule.class);
|
||||
MODULE_MAP.put("Spartan", SpartanCompatibilityModule.class);
|
||||
|
||||
}
|
||||
|
||||
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is SpartanCompatibilityModule.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.compatibility;
|
||||
|
||||
import me.vagdedes.spartan.api.API;
|
||||
import me.vagdedes.spartan.api.PlayerViolationEvent;
|
||||
import me.vagdedes.spartan.system.Enums;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.api.compatibility.AbstractQSCompatibilityModule;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
||||
public class SpartanCompatibilityModule extends AbstractQSCompatibilityModule implements Listener {
|
||||
|
||||
public SpartanCompatibilityModule(QuickShop plugin) {
|
||||
|
||||
super(plugin);
|
||||
|
||||
}
|
||||
|
||||
private final Set<UUID> ignoreList = new ConcurrentSkipListSet<>();
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
|
||||
return "Spartan";
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onPlayerViolation(PlayerViolationEvent event) {
|
||||
|
||||
if (ignoreList.contains(event.getPlayer().getUniqueId())) {
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggle(@NotNull Player player, boolean status) {
|
||||
|
||||
if (status) {
|
||||
|
||||
Util.debugLog("Calling Spartan continue follow " + player.getName() + " cheats detection.");
|
||||
ignoreList.remove(player.getUniqueId());
|
||||
for (Enums.HackType value : Enums.HackType.values()) {
|
||||
|
||||
API.startCheck(player, value);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ignoreList.add(player.getUniqueId());
|
||||
Util.debugLog("Calling Spartan ignore " + player.getName()
|
||||
+ " cheats detection until we finished permission checks.");
|
||||
for (Enums.HackType value : Enums.HackType.values()) {
|
||||
|
||||
API.stopCheck(player, value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is CheckResult.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.envcheck;
|
||||
|
||||
public enum CheckResult {
|
||||
|
||||
SKIPPED("Skip"), PASSED("Pass"), WARNING("Warning"), STOP_WORKING("Error"), DISABLE_PLUGIN("Fatal"),
|
||||
KILL_SERVER("Kill");
|
||||
|
||||
private final String display;
|
||||
|
||||
CheckResult(String display) {
|
||||
|
||||
this.display = display;
|
||||
|
||||
}
|
||||
|
||||
public String getDisplay() {
|
||||
|
||||
return display;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is EnvCheckEntry.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.envcheck;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Inherited
|
||||
public @interface EnvCheckEntry {
|
||||
|
||||
String name() default "Unknown EnvCheck Test";
|
||||
|
||||
int priority() default 50;
|
||||
|
||||
Stage[] stage() default Stage.ON_ENABLE;
|
||||
|
||||
enum Stage {
|
||||
CONSTRUCTOR, ON_LOAD, ON_ENABLE
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,709 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is EnvironmentChecker.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.envcheck;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.api.shop.AbstractDisplayItem;
|
||||
import org.maxgamer.quickshop.api.shop.DisplayType;
|
||||
import org.maxgamer.quickshop.shop.VirtualDisplayItem;
|
||||
import org.maxgamer.quickshop.util.GameVersion;
|
||||
import org.maxgamer.quickshop.util.JsonUtil;
|
||||
import org.maxgamer.quickshop.util.MsgUtil;
|
||||
import org.maxgamer.quickshop.util.ReflectFactory;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
import org.maxgamer.quickshop.util.security.JarVerifyTool;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public final class EnvironmentChecker {
|
||||
|
||||
private final QuickShop plugin;
|
||||
private final List<Method> tests = new ArrayList<>();
|
||||
@Getter
|
||||
private final SecurityReport reportMaker = new SecurityReport();
|
||||
|
||||
public EnvironmentChecker(QuickShop plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
this.registerTests(this.getClass()); // register self
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register tests to QuickShop EnvChecker
|
||||
*
|
||||
* @param clazz The class contains test
|
||||
*/
|
||||
public void registerTests(@NotNull Class<?> clazz) {
|
||||
|
||||
for (Method declaredMethod : clazz.getDeclaredMethods()) {
|
||||
|
||||
registerTest(declaredMethod);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register test to QuickShop EnvChecker
|
||||
*
|
||||
* @param method The test method
|
||||
*/
|
||||
public void registerTest(@NotNull Method method) {
|
||||
|
||||
EnvCheckEntry envCheckEntry = method.getAnnotation(EnvCheckEntry.class);
|
||||
if (envCheckEntry == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (method.getReturnType() != ResultContainer.class) {
|
||||
|
||||
plugin.getLogger().warning("Failed loading EncCheckEntry [" + method.getName() + "]: Illegal test returns");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
tests.add(method);
|
||||
|
||||
}
|
||||
|
||||
private void sortTests() {
|
||||
|
||||
tests.sort((o1, o2) -> {
|
||||
|
||||
EnvCheckEntry e1 = o1.getAnnotation(EnvCheckEntry.class);
|
||||
EnvCheckEntry e2 = o2.getAnnotation(EnvCheckEntry.class);
|
||||
return Integer.compare(e1.priority(), e2.priority());
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public ResultReport run(EnvCheckEntry.Stage stage) {
|
||||
|
||||
sortTests();
|
||||
|
||||
Map<EnvCheckEntry, ResultContainer> results = new LinkedHashMap<>();
|
||||
boolean skipAllTest = false;
|
||||
ResultContainer executeResult = null;
|
||||
|
||||
Properties properties = System.getProperties();
|
||||
CheckResult gResult = CheckResult.PASSED;
|
||||
for (Method declaredMethod : this.tests) {
|
||||
|
||||
if (skipAllTest) {
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
CheckResult result = CheckResult.PASSED;
|
||||
try {
|
||||
|
||||
EnvCheckEntry envCheckEntry = declaredMethod.getAnnotation(EnvCheckEntry.class);
|
||||
if (Arrays.stream(envCheckEntry.stage()).noneMatch(entry -> entry == stage)) {
|
||||
|
||||
Util.debugLog("Skip test: " + envCheckEntry.name() + ": Except stage: "
|
||||
+ Arrays.toString(envCheckEntry.stage()) + " Current stage: " + stage);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (false && !properties.containsKey("org.maxgamer.quickshop.util.envcheck.skip."
|
||||
+ envCheckEntry.name().toUpperCase(Locale.ROOT).replace(" ", "_")))
|
||||
{
|
||||
|
||||
executeResult = (ResultContainer) declaredMethod.invoke(this);
|
||||
if (executeResult.getResult().ordinal() > result.ordinal()) { // set bad result if its worse than
|
||||
// the latest one.
|
||||
|
||||
result = executeResult.getResult();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
result = CheckResult.SKIPPED;
|
||||
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
|
||||
case SKIPPED:
|
||||
plugin.getLogger().info("[SKIP] " + envCheckEntry.name());
|
||||
Util.debugLog("Runtime check [" + envCheckEntry.name() + "] has been skipped (Startup Flag).");
|
||||
break;
|
||||
case PASSED:
|
||||
if (Util.isDevEdition() || Util.isDevMode()) {
|
||||
|
||||
plugin.getLogger().info("[OK] " + envCheckEntry.name());
|
||||
Util.debugLog("[Pass] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
|
||||
}
|
||||
break;
|
||||
case WARNING:
|
||||
plugin.getLogger()
|
||||
.warning("[WARN] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
Util.debugLog("[Warning] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
break;
|
||||
case STOP_WORKING:
|
||||
plugin.getLogger()
|
||||
.warning("[STOP] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
Util.debugLog(
|
||||
"[Stop-Freeze] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
// It's okay, QuickShop should continue executing checks to collect more data.
|
||||
// And show user all errors at once.
|
||||
break;
|
||||
case DISABLE_PLUGIN:
|
||||
plugin.getLogger()
|
||||
.warning("[FATAL] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
Util.debugLog(
|
||||
"[Fatal-Disable] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
skipAllTest = true; // We need to disable the plugin NOW! Some HUGE exception is happening here,
|
||||
// hurry up!
|
||||
break;
|
||||
case KILL_SERVER:
|
||||
plugin.getLogger()
|
||||
.warning("[FATAL] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
Util.debugLog("[Fatal-Kill] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
skipAllTest = true; // We need to disable the plugin NOW! Some HUGE exception is happening here,
|
||||
// hurry up!
|
||||
break;
|
||||
default:
|
||||
plugin.getLogger().warning(
|
||||
"[UNDEFINED] " + envCheckEntry.name() + ": " + executeResult.getResultMessage());
|
||||
|
||||
}
|
||||
|
||||
if (executeResult != null) {
|
||||
|
||||
results.put(envCheckEntry, executeResult);
|
||||
|
||||
} else {
|
||||
|
||||
results.put(envCheckEntry, new ResultContainer(CheckResult.SKIPPED,
|
||||
"Startup flag mark this check should be skipped."));
|
||||
|
||||
}
|
||||
|
||||
if (result.ordinal() > gResult.ordinal()) { // set bad result if its worse than the latest one.
|
||||
|
||||
gResult = result;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to execute EnvCheckEntry [" + declaredMethod.getName()
|
||||
+ "]: Exception thrown out without getting caught. Something went wrong!", e);
|
||||
plugin.getLogger().warning("[FAIL] " + declaredMethod.getName());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new ResultReport(gResult, results);
|
||||
|
||||
}
|
||||
|
||||
public boolean isOutdatedJvm() {
|
||||
|
||||
String jvmVersion = System.getProperty("java.version"); // Use java version not jvm version.
|
||||
String[] splitVersion = jvmVersion.split("\\.");
|
||||
if (splitVersion.length < 1) {
|
||||
|
||||
Util.debugLog("Failed to parse jvm version to check: " + jvmVersion);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
int majorVersion = Integer.parseInt(splitVersion[0]);
|
||||
return majorVersion < 16; // Target JDK/JRE version
|
||||
|
||||
} catch (NumberFormatException ignored) {
|
||||
|
||||
Util.debugLog("Failed to parse jvm major version to check: " + splitVersion[0]);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@EnvCheckEntry(name = "Signature Verify", priority = 0, stage =
|
||||
{ EnvCheckEntry.Stage.ON_LOAD, EnvCheckEntry.Stage.ON_ENABLE })
|
||||
public ResultContainer securityVerify() {
|
||||
|
||||
JarVerifyTool tool = new JarVerifyTool();
|
||||
JarFile jarFile = null;
|
||||
try {
|
||||
|
||||
ClassLoader loader = this.getClass().getClassLoader();
|
||||
try (InputStream stream1 = loader.getResourceAsStream("META-INF/MANIFEST.MF");
|
||||
InputStream stream2 = loader.getResourceAsStream("META-INF/SELFSIGN.DSA");
|
||||
InputStream stream3 = loader.getResourceAsStream("META-INF/SELFSIGN.SF"))
|
||||
{
|
||||
|
||||
if (stream1 == null || stream2 == null || stream3 == null) {
|
||||
|
||||
if (stream1 == null) {
|
||||
|
||||
this.reportMaker.signatureFileMissing("META-INF/MANIFEST.MF");
|
||||
|
||||
}
|
||||
|
||||
if (stream2 == null) {
|
||||
|
||||
this.reportMaker.signatureFileMissing("META-INF/SELFSIGN.DSA");
|
||||
|
||||
}
|
||||
|
||||
if (stream3 == null) {
|
||||
|
||||
this.reportMaker.signatureFileMissing("META-INF/SELFSIGN.SF");
|
||||
|
||||
}
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"The signature could not be found! The QuickShop jar has been modified or you're running a custom build.");
|
||||
return new ResultContainer(CheckResult.KILL_SERVER,
|
||||
"Security risk detected, QuickShop jar has been modified.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String jarPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
|
||||
jarPath = URLDecoder.decode(jarPath, "UTF-8");
|
||||
Util.debugLog("JarPath selected: " + jarPath);
|
||||
jarFile = new JarFile(jarPath);
|
||||
List<JarEntry> modifiedEntry = tool.verify(jarFile);
|
||||
if (modifiedEntry.isEmpty()) {
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "The jar is valid. No issues detected.");
|
||||
|
||||
} else {
|
||||
|
||||
modifiedEntry.forEach(jarEntry -> {
|
||||
|
||||
this.reportMaker.signatureVerifyFail(jarEntry);
|
||||
plugin.getLogger().warning(">> Modified Class Detected <<");
|
||||
plugin.getLogger().warning("Name: " + jarEntry.getName());
|
||||
plugin.getLogger().warning("CRC: " + jarEntry.getCrc());
|
||||
plugin.getLogger().warning(JsonUtil.getGson().toJson(jarEntry));
|
||||
|
||||
});
|
||||
plugin.getLogger().severe(
|
||||
"QuickShop detected that the jar has been modified! This is usually caused by the file being corrupted or virus infected.");
|
||||
plugin.getLogger().severe("To prevent severe server failure, QuickShop has been disabled.");
|
||||
plugin.getLogger().severe(
|
||||
"For further information, Please join our support Discord server: https://discord.com/invite/bfefw2E.");
|
||||
return new ResultContainer(CheckResult.KILL_SERVER,
|
||||
"Security risk detected, QuickShop jar has been modified.");
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception ioException) {
|
||||
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"ALERT: QuickShop cannot validate itself. This may be caused by you having deleted QuickShop's jar while the server is running.",
|
||||
ioException);
|
||||
return new ResultContainer(CheckResult.KILL_SERVER,
|
||||
"Failed to validate digital signature! Security may be compromised!");
|
||||
|
||||
} finally {
|
||||
|
||||
if (jarFile != null) {
|
||||
|
||||
try {
|
||||
|
||||
jarFile.close();
|
||||
|
||||
} catch (IOException ignored) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "Plugin Manifest Check", priority = 1, stage = { EnvCheckEntry.Stage.ON_LOAD,
|
||||
EnvCheckEntry.Stage.ON_ENABLE })
|
||||
public ResultContainer manifestCheck() {
|
||||
|
||||
String mainClass = plugin.getDescription().getMain();
|
||||
if (!mainClass.equals("org.maxgamer.quickshop.QuickShop")) {
|
||||
|
||||
this.reportMaker.manifestModified(plugin.getDescription());
|
||||
plugin.getLogger().warning("ALERT: Detected main class has been modified!");
|
||||
plugin.getLogger().warning("Should be: org.maxgamer.quickshop.QuickShop");
|
||||
plugin.getLogger().warning("Actually: " + mainClass);
|
||||
return new ResultContainer(CheckResult.KILL_SERVER,
|
||||
"Failed to validate main class! Security may be compromised!");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Check passed.");
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "Potential Infection Characteristics Check", priority = 1, stage = {
|
||||
EnvCheckEntry.Stage.ON_LOAD, EnvCheckEntry.Stage.ON_ENABLE })
|
||||
public ResultContainer potentialCheck() {
|
||||
|
||||
String jarPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
|
||||
try {
|
||||
|
||||
jarPath = URLDecoder.decode(jarPath, "UTF-8");
|
||||
Util.debugLog("JarPath selected: " + jarPath);
|
||||
ZipFile zipFile = new ZipFile(jarPath);
|
||||
Enumeration<? extends ZipEntry> zipEntryEnumeration = zipFile.entries();
|
||||
boolean found = false;
|
||||
while (zipEntryEnumeration.hasMoreElements()) {
|
||||
|
||||
ZipEntry entry = zipEntryEnumeration.nextElement();
|
||||
if (entry.getName().startsWith("javassist") || entry.getName().startsWith(".")) {
|
||||
|
||||
found = true;
|
||||
this.reportMaker.potentialInfected(entry);
|
||||
plugin.getLogger().log(Level.WARNING, "Potential Infection Detected:");
|
||||
plugin.getLogger().log(Level.WARNING, "File: " + entry.getName());
|
||||
plugin.getLogger().log(Level.WARNING, "CRC: " + entry.getCrc());
|
||||
plugin.getLogger().log(Level.WARNING, "Time: " + entry.getTime());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (found) {
|
||||
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"ALERT: QuickShop detected Potential Infection, this jar may already infected by malware, stop the server and create full server backup immediately, run virus scan and contact the QuickShop support if you need!");
|
||||
return new ResultContainer(CheckResult.KILL_SERVER,
|
||||
"Potential Infection detected, Killing server process...");
|
||||
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"ALERT: QuickShop cannot validate itself. This may be caused by you having deleted QuickShop's jar while the server is running.",
|
||||
e);
|
||||
return new ResultContainer(CheckResult.KILL_SERVER,
|
||||
"Failed to validate files in jar! Security may be compromised!");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Check passed.");
|
||||
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@EnvCheckEntry(name = "Java Runtime Environment Version Test", priority = 1, stage = EnvCheckEntry.Stage.ON_ENABLE)
|
||||
public ResultContainer jrevTest() {
|
||||
|
||||
if (isOutdatedJvm()) {
|
||||
|
||||
String jvmWarning = "\n" + "============================================================\n"
|
||||
+ " Warning! You're running an outdated version of Java!\n"
|
||||
+ "============================================================\n"
|
||||
+ "* QuickShop will stop being compatible with your current Java version in the future!\n" + "*\n"
|
||||
+ "* You should schedule a Java upgrade on your server,\n"
|
||||
+ "* because we will drop support for any Java versions lower than Java 16.\n" + "*\n"
|
||||
+ "* That means:\n" + "* 1) Future QuickShop builds will no longer work on your server.\n"
|
||||
+ "* 2) No support for QuickShop builds that run on outdated Java versions will be given.\n"
|
||||
+ "* \n" + "* Why:\n" + "* 1) We don't want to keep compatibility with outdated software\n"
|
||||
+ "* and systems. As Paper upgraded, we did too.\n"
|
||||
+ "* 2) Java is downward compatible, so most legacy (Java 8+) Plugins should still work.\n"
|
||||
+ "* 3) Newer Java APIs allow accessing resources and processing them\n"
|
||||
+ "* faster than before, meaning a performance improvement.\n" + "* \n" + "* What should I do?\n"
|
||||
+ "* You should update your server's Java version\n"
|
||||
+ "* as soon as you can to Java 16 or higher.\n" + "*\n"
|
||||
+ "* Most plugins can run on Java 16+ without problems\n"
|
||||
+ "* unless their code is really outdated.\n"
|
||||
+ "* If a Plugin is not compatible with Java 16 and the developer\n"
|
||||
+ "* doesn't update it, then you should replace them.\n" + "*\n" + "* You can get Java 16 here:\n"
|
||||
+ "* https://www.oracle.com/java/technologies/javase-downloads.html\n" + "*\n"
|
||||
+ String.format("* Current Java version: %s", System.getProperty("java.version"));
|
||||
plugin.getLogger().warning(jvmWarning);
|
||||
Thread.sleep(5000);
|
||||
return new ResultContainer(CheckResult.WARNING, "Unsupported outdated JRE version detected.");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Java is up-to-date: " + System.getProperty("java.version"));
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "Spigot Based Server Test", priority = 2)
|
||||
public ResultContainer spigotBasedServer() {
|
||||
|
||||
ResultContainer success = new ResultContainer(CheckResult.PASSED, "Server");
|
||||
ResultContainer failed = new ResultContainer(CheckResult.STOP_WORKING,
|
||||
"Server must be Spigot based, Don't use CraftBukkit!");
|
||||
try {
|
||||
|
||||
// API test
|
||||
try {
|
||||
|
||||
plugin.getServer().spigot();
|
||||
String nmsVersion = ReflectFactory.getNMSVersion();
|
||||
plugin.getLogger().info("Running QuickShop-" + QuickShop.getFork() + " on NMS version " + nmsVersion
|
||||
+ " For Minecraft version " + ReflectFactory.getServerVersion());
|
||||
|
||||
} catch (Throwable e) {
|
||||
|
||||
return failed;
|
||||
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to check Spigot API!" + plugin.getServer().getBukkitVersion()
|
||||
+ " may not be Spigot based.");
|
||||
return failed;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "Old QuickShop Test", priority = 3)
|
||||
public ResultContainer oldQuickShopTest() {
|
||||
|
||||
if (Util.isClassAvailable("org.maxgamer.quickshop.Util.NMS")) {
|
||||
|
||||
return new ResultContainer(CheckResult.STOP_WORKING,
|
||||
"FATAL: Old QuickShop build is installed! You must remove old QuickShop jar from the plugins folder!");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "No old QuickShop jar installled on this server");
|
||||
|
||||
}
|
||||
|
||||
public boolean isForgeBasedServer() {
|
||||
|
||||
// Forge server detect - Arclight
|
||||
if (Util.isClassAvailable("net.minecraftforge.server.ServerMain")) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return Util.isClassAvailable("net.minecraftforge.fml.loading.ModInfo");
|
||||
|
||||
}
|
||||
|
||||
public boolean isFabricBasedServer() {
|
||||
|
||||
// Nobody really make it right!?
|
||||
return Util.isClassAvailable("net.fabricmc.loader.launch.knot.KnotClient"); // OMG
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "ModdedServer Based Test", priority = 4)
|
||||
public ResultContainer moddedBasedTest() {
|
||||
|
||||
boolean trigged = false;
|
||||
if (isForgeBasedServer()) {
|
||||
|
||||
plugin.getLogger().warning("WARN: QuickShop is not designed and tested for Forge!");
|
||||
plugin.getLogger().warning("WARN: Use at you own risk!.");
|
||||
plugin.getLogger().warning("WARN: No support will be given!");
|
||||
trigged = true;
|
||||
|
||||
}
|
||||
|
||||
if (isFabricBasedServer()) {
|
||||
|
||||
plugin.getLogger().warning("WARN: QuickShop is not designed and tested for Fabric!");
|
||||
plugin.getLogger().warning("WARN: Use at you own risk!.");
|
||||
plugin.getLogger().warning("WARN: No support will be given!");
|
||||
trigged = true;
|
||||
|
||||
}
|
||||
|
||||
if (trigged) {
|
||||
|
||||
return new ResultContainer(CheckResult.WARNING, "No support will be given to modded servers.");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Server is unmodified.");
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "CoreSupport Test", priority = 6)
|
||||
public ResultContainer coreSupportTest() {
|
||||
|
||||
String nmsVersion = ReflectFactory.getNMSVersion();
|
||||
GameVersion gameVersion = GameVersion.get(nmsVersion);
|
||||
if (!gameVersion.isCoreSupports()) {
|
||||
|
||||
return new ResultContainer(CheckResult.STOP_WORKING, "Your Minecraft version is no longer supported: "
|
||||
+ ReflectFactory.getServerVersion() + " (" + nmsVersion + ")");
|
||||
|
||||
}
|
||||
|
||||
if (gameVersion == GameVersion.UNKNOWN) {
|
||||
|
||||
return new ResultContainer(CheckResult.WARNING, "QuickShop may not fully support version " + nmsVersion
|
||||
+ "/" + ReflectFactory.getServerVersion() + ", Some features may not work.");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Passed checks");
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "Virtual DisplayItem Support Test", priority = 7)
|
||||
public ResultContainer virtualDisplaySupportTest() {
|
||||
|
||||
String nmsVersion = ReflectFactory.getNMSVersion();
|
||||
GameVersion gameVersion = GameVersion.get(nmsVersion);
|
||||
Throwable throwable;
|
||||
if (!gameVersion.isVirtualDisplaySupports()) {
|
||||
|
||||
throwable = new IllegalStateException(
|
||||
"This game version " + gameVersion + " not supports Virtual DisplayItem.");
|
||||
|
||||
} else {
|
||||
|
||||
if (plugin.getServer().getPluginManager().getPlugin("ProtocolLib") != null) {
|
||||
|
||||
throwable = VirtualDisplayItem.PacketFactory.testFakeItem();
|
||||
|
||||
} else {
|
||||
|
||||
AbstractDisplayItem.setNotSupportVirtualItem(true);
|
||||
return new ResultContainer(CheckResult.WARNING,
|
||||
"ProtocolLib is not installed, virtual DisplayItem seems will not work on your server.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (throwable != null) {
|
||||
|
||||
Util.debugLog(throwable.getMessage());
|
||||
MsgUtil.debugStackTrace(throwable.getStackTrace());
|
||||
AbstractDisplayItem.setNotSupportVirtualItem(true);
|
||||
// do not throw
|
||||
plugin.getLogger().log(Level.SEVERE,
|
||||
"Virtual DisplayItem Support Test: Failed to initialize VirtualDisplayItem", throwable);
|
||||
return new ResultContainer(CheckResult.WARNING,
|
||||
"Virtual DisplayItem seems to not work on this Minecraft server, Make sure QuickShop, ProtocolLib and server builds are up to date.");
|
||||
|
||||
} else {
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Passed checks");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "GameVersion supporting Test", priority = 9)
|
||||
public ResultContainer gamerVersionSupportTest() {
|
||||
|
||||
String nmsVersion = ReflectFactory.getNMSVersion();
|
||||
GameVersion gameVersion = GameVersion.get(nmsVersion);
|
||||
if (gameVersion == GameVersion.UNKNOWN) {
|
||||
|
||||
return new ResultContainer(CheckResult.WARNING,
|
||||
"Your Minecraft server version not tested by developers, QuickShop may ran into issues on this version.");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Passed checks");
|
||||
|
||||
}
|
||||
|
||||
@EnvCheckEntry(name = "PacketListenerAPI Conflict Test", priority = 10)
|
||||
public ResultContainer plapiConflictTest() {
|
||||
|
||||
if (plugin.isDisplayEnabled() && AbstractDisplayItem.getNowUsing() == DisplayType.VIRTUALITEM
|
||||
&& Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")
|
||||
&& Bukkit.getPluginManager().isPluginEnabled("PacketListenerAPI"))
|
||||
{
|
||||
|
||||
return new ResultContainer(CheckResult.WARNING,
|
||||
"Virtual DisplayItem may stop working on your server. We are already aware that [PacketListenerAPI] and [ProtocolLib] are conflicting. (QuickShops requirement to send fake items). If your display is not showing, please uninstall [PacketListenerAPI].");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Passed checks");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* No idea why ghost adding this check, groupmanager should work along with QS
|
||||
*
|
||||
* @EnvCheckEntry(name = "Permission Manager Test", priority = 10, stage =
|
||||
* EnvCheckEntry.Stage.ON_ENABLE) public ResultContainer
|
||||
* permManagerConflictTest() { if
|
||||
* (plugin.getServer().getPluginManager().isPluginEnabled("GroupManager")) {
|
||||
* return new ResultContainer(CheckResult.WARNING,
|
||||
* "WARNING: Unsupported plugin management plugin [GroupManager] installed, the permissions may not working."
|
||||
* ); } return new ResultContainer(CheckResult.PASSED, "Passed checks"); }
|
||||
*/
|
||||
|
||||
@EnvCheckEntry(name = "End of life Test", priority = Integer.MAX_VALUE, stage = EnvCheckEntry.Stage.ON_ENABLE)
|
||||
public ResultContainer eolTest() {
|
||||
|
||||
if (plugin.getGameVersion().isEndOfLife()) {
|
||||
|
||||
return new ResultContainer(CheckResult.WARNING,
|
||||
"End Of Life! This Minecraft version no-longer receive QuickShop future updates! You won't receive any updates from QuickShop, think about upgrading!");
|
||||
|
||||
}
|
||||
|
||||
return new ResultContainer(CheckResult.PASSED, "Passed checks");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is ResultContainer.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.envcheck;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ResultContainer {
|
||||
|
||||
private final CheckResult result;
|
||||
private String resultMessage;
|
||||
|
||||
public ResultContainer(@NotNull CheckResult result, @Nullable String resultMessage) {
|
||||
|
||||
this.result = result;
|
||||
this.resultMessage = resultMessage;
|
||||
if (StringUtils.isEmpty(this.resultMessage)) {
|
||||
|
||||
this.resultMessage = "null";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CheckResult getResult() {
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public String getResultMessage() {
|
||||
|
||||
return resultMessage;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is ResultReport.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.envcheck;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class ResultReport {
|
||||
|
||||
private final CheckResult finalResult;
|
||||
private final Map<EnvCheckEntry, ResultContainer> results;
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package org.maxgamer.quickshop.util.envcheck;
|
||||
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
public class SecurityReport {
|
||||
|
||||
private final StringBuffer buffer = new StringBuffer();
|
||||
|
||||
public void signatureFileMissing(String name) {
|
||||
|
||||
buffer.append("META-INF signature missing: ").append("name=").append(name).append("\n");
|
||||
|
||||
}
|
||||
|
||||
public void signatureVerifyFail(ZipEntry zipEntry) {
|
||||
|
||||
buffer.append("Signature Fail: ").append("name=").append(zipEntry.getName()).append(", ").append("crc=")
|
||||
.append(zipEntry.getCrc()).append(", ").append("time=").append(zipEntry.getTime()).append(", ")
|
||||
.append("method=").append(zipEntry.getMethod()).append("\n");
|
||||
|
||||
}
|
||||
|
||||
public void potentialInfected(ZipEntry zipEntry) {
|
||||
|
||||
buffer.append("Potential Infected: ").append("name=").append(zipEntry.getName()).append(", ").append("crc=")
|
||||
.append(zipEntry.getCrc()).append(", ").append("time=").append(zipEntry.getTime()).append(", ")
|
||||
.append("method=").append(zipEntry.getMethod()).append("\n");
|
||||
|
||||
}
|
||||
|
||||
public void manifestModified(PluginDescriptionFile desc) {
|
||||
|
||||
buffer.append("Invalid Plugin Description: ").append("name=").append(desc.getName()).append(", ")
|
||||
.append("main=").append(desc.getMain()).append(", ").append("libraries=[")
|
||||
.append(Util.list2String(desc.getLibraries())).append("], ").append("provides=[")
|
||||
.append(Util.list2String(desc.getProvides())).append("]\n");
|
||||
|
||||
}
|
||||
|
||||
public String bake() {
|
||||
|
||||
return "=============================\n" + " QuickShop Security Report\n" + "=============================\n"
|
||||
+ "Description:\n" + " QuickShop detected self jar has been modified.\n"
|
||||
+ " Learn more: https://github.com/PotatoCraft-Studio/QuickShop-Reremake/wiki/QuickShop-halt-my-server\n"
|
||||
+ "\n" + "What that mean: \n"
|
||||
+ " It usually mean the jar has been infected by malware and cannot be trusted.\n"
|
||||
+ " Make sure you downloading jar from our SpigotMC and CodeMC pages.\n"
|
||||
+ " Any other sources is untrusted and may provide a infected jar.\n" + "\n"
|
||||
+ "I download QuickShop from SpigotMC, why I still see this:\n"
|
||||
+ " As far as we know, some malware like \"L10\" have ability to infect other jars that installed on your server.\n"
|
||||
+ " So clean jar can be infect when you installed on infected server.\n" + "\n"
|
||||
+ "What should I do:\n"
|
||||
+ " Backup your server immediately, execute virus scan with regular anti-malware software and Spigot Anti-Malware tool.\n"
|
||||
+ " You can download SAMT here: https://www.spigotmc.org/resources/spigot-anti-malware.64982/\n"
|
||||
+ "\n" + "Could this be a false positive:\n" + " Basically not.\n" + "\n"
|
||||
+ "I need some help to handle this issue:\n"
|
||||
+ " Our community and developer can help you and give you action suggestion.\n"
|
||||
+ " Join our discord support server: https://discord.gg/bfefw2E\n" + "\n"
|
||||
+ "Can I disable this noisy check:\n" + " No, you can't.\n" + "\n"
|
||||
+ "----------------------------------\n" + "Important information related to this issue.\n"
|
||||
+ "When you ask for support, please provide this paste to the support staffs:\n" + "\n" + buffer;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
//package org.maxgamer.quickshop.util.hack.packet;
|
||||
//
|
||||
//import com.bergerkiller.bukkit.common.nbt.CommonTagCompound;
|
||||
//import com.bergerkiller.bukkit.common.protocol.CommonPacket;
|
||||
//import com.bergerkiller.bukkit.common.protocol.PacketType;
|
||||
//import com.bergerkiller.bukkit.common.utils.BlockUtil;
|
||||
//import com.bergerkiller.bukkit.common.utils.PacketUtil;
|
||||
//import net.md_5.bungee.chat.ComponentSerializer;
|
||||
//import org.apache.commons.lang3.Validate;
|
||||
//import org.bukkit.Bukkit;
|
||||
//import org.bukkit.block.Sign;
|
||||
//import org.bukkit.entity.Player;
|
||||
//import org.jetbrains.annotations.NotNull;
|
||||
//import org.maxgamer.quickshop.QuickShop;
|
||||
//import org.maxgamer.quickshop.api.chat.ComponentPackage;
|
||||
//
|
||||
//import java.util.List;
|
||||
//
|
||||
///**
|
||||
// * Little treat, we modify the sign component to translatable component if possible...
|
||||
// */
|
||||
//public class SignPacketHack {
|
||||
//
|
||||
// private final QuickShop plugin;
|
||||
//
|
||||
// public SignPacketHack(QuickShop plugin) {
|
||||
// this.plugin = plugin;
|
||||
// Validate.isTrue(Bukkit.getPluginManager().isPluginEnabled("BKCommonLib"), "Require BKCommonLib installed!");
|
||||
// }
|
||||
//
|
||||
// public void sendLines(@NotNull Sign sign, @NotNull List<ComponentPackage> lines, Player player) {
|
||||
// if (player != null) {
|
||||
// CommonPacket updatePacket = BlockUtil.getUpdatePacket(sign);
|
||||
// if (updatePacket != null) {
|
||||
// applyToSign(updatePacket, lines);
|
||||
// PacketUtil.sendPacket(player, updatePacket);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void applyToSign(@NotNull CommonPacket updatePacket, @NotNull List<ComponentPackage> lines) {
|
||||
// if (updatePacket.getType() == PacketType.OUT_TILE_ENTITY_DATA) {
|
||||
// // >= MC 1.10.2
|
||||
//
|
||||
// CommonTagCompound compound = updatePacket.read(PacketType.OUT_TILE_ENTITY_DATA.data);
|
||||
// // ====================================================================
|
||||
//
|
||||
// for (int i = 0; i < lines.size(); i++) {
|
||||
// String key = "Text" + (i + 1);
|
||||
// String text = ComponentSerializer.toString(lines.get(i).getComponents());
|
||||
// compound.putValue(key, text);
|
||||
// }
|
||||
//
|
||||
// // ====================================================================
|
||||
// updatePacket.write(PacketType.OUT_TILE_ENTITY_DATA.data, compound);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
+35
-44
@@ -36,7 +36,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.api.shop.ItemMatcher;
|
||||
import org.maxgamer.quickshop.util.ReflectFactory;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
import org.maxgamer.quickshop.util.reload.ReloadResult;
|
||||
import org.maxgamer.quickshop.util.reload.ReloadStatus;
|
||||
@@ -787,62 +786,54 @@ public class QuickShopItemMatcherImpl implements ItemMatcher, Reloadable {
|
||||
return true;
|
||||
|
||||
}));
|
||||
if (!"v1_13_R1".equals(ReflectFactory.getNMSVersion())
|
||||
&& !"v1_13_R2".equals(ReflectFactory.getNMSVersion()))
|
||||
{
|
||||
|
||||
addIfEnable(itemMatcherConfig, "custommodeldata", ((meta1, meta2) -> {
|
||||
addIfEnable(itemMatcherConfig, "custommodeldata", ((meta1, meta2) -> {
|
||||
|
||||
if (meta1.hasCustomModelData() != meta2.hasCustomModelData()) {
|
||||
if (meta1.hasCustomModelData() != meta2.hasCustomModelData()) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (meta1.hasCustomModelData()) {
|
||||
|
||||
return meta1.getCustomModelData() == meta2.getCustomModelData();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}));
|
||||
|
||||
addIfEnable(itemMatcherConfig, "suspiciousStew", ((meta1, meta2) -> {
|
||||
|
||||
if ((meta1 instanceof SuspiciousStewMeta) != (meta2 instanceof SuspiciousStewMeta)) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (meta1 instanceof SuspiciousStewMeta) {
|
||||
|
||||
SuspiciousStewMeta stewMeta1 = ((SuspiciousStewMeta) meta1);
|
||||
SuspiciousStewMeta stewMeta2 = ((SuspiciousStewMeta) meta2);
|
||||
if (stewMeta1.hasCustomEffects() != stewMeta2.hasCustomEffects()) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (meta1.hasCustomModelData()) {
|
||||
if (stewMeta1.hasCustomEffects()) {
|
||||
|
||||
return meta1.getCustomModelData() == meta2.getCustomModelData();
|
||||
return stewMeta1.getCustomEffects().equals(stewMeta2.getCustomEffects());
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}));
|
||||
if (!"v1_14_R1".equals(ReflectFactory.getNMSVersion())) {
|
||||
|
||||
addIfEnable(itemMatcherConfig, "suspiciousStew", ((meta1, meta2) -> {
|
||||
|
||||
if ((meta1 instanceof SuspiciousStewMeta) != (meta2 instanceof SuspiciousStewMeta)) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (meta1 instanceof SuspiciousStewMeta) {
|
||||
|
||||
SuspiciousStewMeta stewMeta1 = ((SuspiciousStewMeta) meta1);
|
||||
SuspiciousStewMeta stewMeta2 = ((SuspiciousStewMeta) meta2);
|
||||
if (stewMeta1.hasCustomEffects() != stewMeta2.hasCustomEffects()) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (stewMeta1.hasCustomEffects()) {
|
||||
|
||||
return stewMeta1.getCustomEffects().equals(stewMeta2.getCustomEffects());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.maxgamer.quickshop.api.economy.AbstractEconomy;
|
||||
import org.maxgamer.quickshop.api.economy.EconomyCore;
|
||||
import org.maxgamer.quickshop.economy.Economy_Vault;
|
||||
import org.maxgamer.quickshop.util.MsgUtil;
|
||||
import org.maxgamer.quickshop.util.ReflectFactory;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
@@ -124,27 +123,9 @@ public class Paste {
|
||||
finalReport.append("\tName: ").append(plugin.getServer().getName()).append("\n");
|
||||
finalReport.append("\tServer Name: ").append(plugin.getServer().getName()).append("\n");
|
||||
finalReport.append("\tBuild: ").append(plugin.getServer().getVersion()).append("\n");
|
||||
finalReport.append("\tNMSV: ").append(ReflectFactory.getNMSVersion()).append("\n");
|
||||
finalReport.append("\tVersion: ").append(plugin.getServer().getMinecraftVersion()).append("\n");
|
||||
// noinspection deprecation
|
||||
finalReport.append("\tData Version: ").append(plugin.getServer().getUnsafe().getDataVersion()).append("\n");
|
||||
if (plugin.getEnvironmentChecker().isFabricBasedServer()
|
||||
|| plugin.getEnvironmentChecker().isForgeBasedServer())
|
||||
{
|
||||
|
||||
if (plugin.getEnvironmentChecker().isForgeBasedServer()) {
|
||||
|
||||
finalReport.append("\tModded Server: Forge (No support offer on this platform)\n");
|
||||
|
||||
}
|
||||
|
||||
if (plugin.getEnvironmentChecker().isFabricBasedServer()) {
|
||||
|
||||
finalReport.append("\tModded Server: Fabric (No support offer on this platform)\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
finalReport.append("\tJava: ").append(System.getProperty("java.version")).append("\n");
|
||||
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
|
||||
List<String> arguments = runtimeMxBean.getInputArguments();
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is EmptyErrorReporter.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.reporter.error;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EmptyErrorReporter implements IErrorReporter {
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendError(@NotNull Throwable throwable, @NotNull String... context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canReport(@NotNull Throwable throwable) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignoreThrow() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ignoreThrows() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetIgnores() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is IErrorReporter.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.reporter.error;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public interface IErrorReporter {
|
||||
|
||||
void unregister();
|
||||
|
||||
void sendError(@NotNull Throwable throwable, @NotNull String... context);
|
||||
|
||||
boolean canReport(@NotNull Throwable throwable);
|
||||
|
||||
/**
|
||||
* Check a throw is cause by QS
|
||||
*
|
||||
* @param throwable Throws
|
||||
* @return Cause or not
|
||||
*/
|
||||
default RollbarErrorReporter.PossiblyLevel checkWasCauseByQS(@Nullable Throwable throwable) {
|
||||
|
||||
if (throwable == null) {
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.IMPOSSIBLE;
|
||||
|
||||
}
|
||||
|
||||
if (throwable.getMessage() == null) {
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.IMPOSSIBLE;
|
||||
|
||||
}
|
||||
|
||||
if (throwable.getMessage().contains("Could not pass event")) {
|
||||
|
||||
if (throwable.getMessage().contains("QuickShop")) {
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.CONFIRM;
|
||||
|
||||
} else {
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.IMPOSSIBLE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (throwable.getCause() != null) {
|
||||
|
||||
throwable = throwable.getCause();
|
||||
|
||||
}
|
||||
|
||||
StackTraceElement[] stackTraceElements = throwable.getStackTrace();
|
||||
|
||||
if (stackTraceElements.length == 0) {
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.IMPOSSIBLE;
|
||||
|
||||
}
|
||||
|
||||
if (stackTraceElements[0].getClassName().contains("org.maxgamer.quickshop")
|
||||
&& stackTraceElements[1].getClassName().contains("org.maxgamer.quickshop"))
|
||||
{
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.CONFIRM;
|
||||
|
||||
}
|
||||
|
||||
long errorCount = Arrays.stream(stackTraceElements).limit(3)
|
||||
.filter(stackTraceElement -> stackTraceElement.getClassName().contains("org.maxgamer.quickshop"))
|
||||
.count();
|
||||
|
||||
if (errorCount > 0) {
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.MAYBE;
|
||||
|
||||
} else if (throwable.getCause() != null) {
|
||||
|
||||
return checkWasCauseByQS(throwable.getCause());
|
||||
|
||||
}
|
||||
|
||||
return RollbarErrorReporter.PossiblyLevel.IMPOSSIBLE;
|
||||
|
||||
}
|
||||
|
||||
void ignoreThrow();
|
||||
|
||||
void ignoreThrows();
|
||||
|
||||
void resetIgnores();
|
||||
|
||||
boolean isEnabled();
|
||||
|
||||
}
|
||||
@@ -1,537 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is RollbarErrorReporter.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.reporter.error;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.rollbar.notifier.Rollbar;
|
||||
import com.rollbar.notifier.config.Config;
|
||||
import com.rollbar.notifier.config.ConfigBuilder;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.InvalidPluginException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.util.GameVersion;
|
||||
import org.maxgamer.quickshop.util.ReflectFactory;
|
||||
import org.maxgamer.quickshop.util.Util;
|
||||
import org.maxgamer.quickshop.util.paste.Paste;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ProtocolException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
public class RollbarErrorReporter implements IErrorReporter {
|
||||
|
||||
// private volatile static String bootPaste = null;
|
||||
private final Rollbar rollbar;
|
||||
private final List<String> reported = new ArrayList<>(5);
|
||||
private final List<Class<?>> ignoredException = Lists.newArrayList(IOException.class, OutOfMemoryError.class,
|
||||
ProtocolException.class, InvalidPluginException.class, UnsupportedClassVersionError.class,
|
||||
LinkageError.class);
|
||||
private final QuickShop plugin;
|
||||
private final QuickShopExceptionFilter quickShopExceptionFilter;
|
||||
private final GlobalExceptionFilter serverExceptionFilter;
|
||||
private boolean disable;
|
||||
private boolean tempDisable;
|
||||
private String lastPaste = null;
|
||||
// private final GlobalExceptionFilter globalExceptionFilter;
|
||||
@Getter
|
||||
private volatile boolean enabled;
|
||||
|
||||
public RollbarErrorReporter(@NotNull QuickShop plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
Config config = ConfigBuilder.withAccessToken("c386df69d08440d9a3d982cf98b53ed6")
|
||||
.environment(Util.isDevEdition() ? "development" : "production")
|
||||
.platform(plugin.getServer().getVersion()).codeVersion(QuickShop.getVersion())
|
||||
.handleUncaughtErrors(false).build();
|
||||
this.rollbar = Rollbar.init(config);
|
||||
|
||||
quickShopExceptionFilter = new QuickShopExceptionFilter(plugin.getLogger().getFilter());
|
||||
plugin.getLogger().setFilter(quickShopExceptionFilter); // Redirect log request passthrough our error catcher.
|
||||
|
||||
serverExceptionFilter = new GlobalExceptionFilter(plugin.getLogger().getFilter());
|
||||
plugin.getServer().getLogger().setFilter(serverExceptionFilter);
|
||||
|
||||
Util.debugLog("Rollbar error reporter success loaded.");
|
||||
enabled = true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
|
||||
enabled = false;
|
||||
plugin.getLogger().setFilter(quickShopExceptionFilter.preFilter);
|
||||
plugin.getServer().getLogger().setFilter(serverExceptionFilter.preFilter);
|
||||
|
||||
// Logger.getGlobal().setFilter(globalExceptionFilter.preFilter);
|
||||
}
|
||||
|
||||
private Map<String, Object> makeMapping() {
|
||||
|
||||
Map<String, Object> dataMapping = new LinkedHashMap<>();
|
||||
dataMapping.put("paste", this.lastPaste);
|
||||
dataMapping.put("system_os", System.getProperty("os.name"));
|
||||
dataMapping.put("system_arch", System.getProperty("os.arch"));
|
||||
dataMapping.put("system_version", System.getProperty("os.version"));
|
||||
dataMapping.put("system_cores", String.valueOf(Runtime.getRuntime().availableProcessors()));
|
||||
dataMapping.put("server_build", plugin.getServer().getVersion());
|
||||
dataMapping.put("server_java", String.valueOf(System.getProperty("java.version")));
|
||||
dataMapping.put("server_players",
|
||||
plugin.getServer().getOnlinePlayers().size() + "/" + plugin.getServer().getMaxPlayers());
|
||||
dataMapping.put("server_onlinemode", String.valueOf(plugin.getServer().getOnlineMode()));
|
||||
dataMapping.put("server_bukkitversion", plugin.getServer().getVersion());
|
||||
dataMapping.put("user", QuickShop.getInstance().getServerUniqueID().toString());
|
||||
return dataMapping;
|
||||
|
||||
}
|
||||
|
||||
private void sendError0(@NotNull Throwable throwable, @NotNull String... context) {
|
||||
|
||||
try {
|
||||
|
||||
if (plugin.getBootError() != null) {
|
||||
|
||||
return; // Don't report any errors if boot failed.
|
||||
|
||||
}
|
||||
|
||||
if (tempDisable) {
|
||||
|
||||
this.tempDisable = false;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (disable) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!canReport(throwable)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (ignoredException.contains(throwable.getClass())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (throwable.getCause() != null) {
|
||||
|
||||
if (ignoredException.contains(throwable.getCause().getClass())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (lastPaste == null) {
|
||||
|
||||
String pasteURL;
|
||||
try {
|
||||
|
||||
Paste paste = new Paste(plugin);
|
||||
pasteURL = paste.paste(paste.genNewPaste(), Paste.PasteType.UBUNTU);
|
||||
if (pasteURL != null && !pasteURL.isEmpty()) {
|
||||
|
||||
lastPaste = pasteURL;
|
||||
|
||||
} else {
|
||||
|
||||
lastPaste = paste.paste(paste.genNewPaste());
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.rollbar.error(throwable, this.makeMapping(), throwable.getMessage());
|
||||
plugin.getLogger().warning(
|
||||
"A exception was thrown, QuickShop already caught this exception and reported it. This error will only shown once before next restart.");
|
||||
plugin.getLogger().warning("====QuickShop Error Report BEGIN===");
|
||||
plugin.getLogger().warning("Description: " + throwable.getMessage());
|
||||
plugin.getLogger().warning("Server ID: " + plugin.getServerUniqueID());
|
||||
plugin.getLogger().warning("Exception : ");
|
||||
ignoreThrows();
|
||||
throwable.printStackTrace();
|
||||
resetIgnores();
|
||||
plugin.getLogger().warning("====QuickShop Error Report E N D===");
|
||||
Util.debugLog(throwable.getMessage());
|
||||
Arrays.stream(throwable.getStackTrace())
|
||||
.forEach(a -> Util.debugLog(a.getClassName() + "." + a.getMethodName() + ":" + a.getLineNumber()));
|
||||
if (Util.isDevMode()) {
|
||||
|
||||
throwable.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception th) {
|
||||
|
||||
ignoreThrow();
|
||||
plugin.getLogger().log(Level.WARNING,
|
||||
"Something going wrong when automatic report errors, please submit this error on Issue Tracker",
|
||||
th);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a error to Sentry
|
||||
*
|
||||
* @param throwable Throws
|
||||
* @param context BreadCrumb
|
||||
*/
|
||||
@Override
|
||||
public void sendError(@NotNull Throwable throwable, @NotNull String... context) {
|
||||
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
|
||||
Bukkit.getAsyncScheduler().runNow(plugin, task -> sendError0(throwable, context));
|
||||
|
||||
// ignore async response
|
||||
} else {
|
||||
|
||||
sendError0(throwable, context);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Dupe report check
|
||||
*
|
||||
* @param throwable Throws
|
||||
* @return dupecated
|
||||
*/
|
||||
@Override
|
||||
public boolean canReport(@NotNull Throwable throwable) {
|
||||
|
||||
if (!enabled) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (plugin.getUpdateWatcher() == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (!plugin.getUpdateWatcher().getUpdater().isLatest()) { // We only receive latest reports.
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (!plugin.getBuildInfo().getBuildUrl().startsWith("https://ci.codemc.io/job/PotatoCraft-Studio/")) { // Ignored
|
||||
// custom
|
||||
// build
|
||||
// or 3rd
|
||||
// fork
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (!GameVersion.get(ReflectFactory.getServerVersion()).isCoreSupports()) { // Ignore errors if user install
|
||||
// quickshop on unsupported
|
||||
|
||||
// version.
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
PossiblyLevel possiblyLevel = checkWasCauseByQS(throwable);
|
||||
if (possiblyLevel != PossiblyLevel.CONFIRM) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (throwable.getMessage().startsWith("#")) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
StackTraceElement stackTraceElement;
|
||||
if (throwable.getStackTrace().length < 3) {
|
||||
|
||||
stackTraceElement = throwable.getStackTrace()[1];
|
||||
|
||||
} else {
|
||||
|
||||
stackTraceElement = throwable.getStackTrace()[2];
|
||||
|
||||
}
|
||||
|
||||
if (stackTraceElement.getClassName().contains("org.maxgamer.quickshop.util.reporter.error")) {
|
||||
|
||||
ignoreThrows();
|
||||
plugin.getLogger().log(Level.WARNING, "Uncaught exception in ErrorRollbar", throwable);
|
||||
resetIgnores();
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
String text = stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName() + "#"
|
||||
+ stackTraceElement.getLineNumber();
|
||||
if (!reported.contains(text)) {
|
||||
|
||||
reported.add(text);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ignore throw. It will unlocked after accept a throw
|
||||
*/
|
||||
@Override
|
||||
public void ignoreThrow() {
|
||||
|
||||
tempDisable = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set ignore throws. It will unlocked after called method resetIgnores.
|
||||
*/
|
||||
@Override
|
||||
public void ignoreThrows() {
|
||||
|
||||
disable = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset ignore throw(s).
|
||||
*/
|
||||
@Override
|
||||
public void resetIgnores() {
|
||||
|
||||
tempDisable = false;
|
||||
disable = false;
|
||||
|
||||
}
|
||||
|
||||
// private String getPluginInfo() {
|
||||
// StringBuilder buffer = new StringBuilder();
|
||||
// for (Plugin bPlugin : plugin.getServer().getPluginManager().getPlugins()) {
|
||||
// buffer
|
||||
// .append("\t")
|
||||
// .append(bPlugin.getName())
|
||||
// .append("@")
|
||||
// .append(bPlugin.isEnabled() ? "Enabled" : "Disabled")
|
||||
// .append("\n");
|
||||
// }
|
||||
// return buffer.toString();
|
||||
// }
|
||||
|
||||
enum PossiblyLevel {
|
||||
CONFIRM, MAYBE, IMPOSSIBLE
|
||||
}
|
||||
|
||||
class GlobalExceptionFilter implements Filter {
|
||||
|
||||
@Nullable
|
||||
@Getter
|
||||
private final Filter preFilter;
|
||||
|
||||
GlobalExceptionFilter(@Nullable Filter preFilter) {
|
||||
|
||||
this.preFilter = preFilter;
|
||||
|
||||
}
|
||||
|
||||
private boolean defaultValue(LogRecord rec) {
|
||||
|
||||
return preFilter == null || preFilter.isLoggable(rec);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given log record should be published.
|
||||
*
|
||||
* @param rec a LogRecord
|
||||
* @return true if the log record should be published.
|
||||
*/
|
||||
@Override
|
||||
public boolean isLoggable(@NotNull LogRecord rec) {
|
||||
|
||||
if (!enabled) {
|
||||
|
||||
return defaultValue(rec);
|
||||
|
||||
}
|
||||
|
||||
Level level = rec.getLevel();
|
||||
if (level != Level.WARNING && level != Level.SEVERE) {
|
||||
|
||||
return defaultValue(rec);
|
||||
|
||||
}
|
||||
|
||||
if (rec.getThrown() == null) {
|
||||
|
||||
return defaultValue(rec);
|
||||
|
||||
}
|
||||
|
||||
if (Util.isDevMode()) {
|
||||
|
||||
sendError(rec.getThrown(), rec.getMessage());
|
||||
return defaultValue(rec);
|
||||
|
||||
} else {
|
||||
|
||||
sendError(rec.getThrown(), rec.getMessage());
|
||||
PossiblyLevel possiblyLevel = checkWasCauseByQS(rec.getThrown());
|
||||
if (possiblyLevel == PossiblyLevel.IMPOSSIBLE) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (possiblyLevel == PossiblyLevel.MAYBE) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"This seems not a QuickShop error. If you have any question, you should ask QuickShop developer.");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class QuickShopExceptionFilter implements Filter {
|
||||
|
||||
@Nullable
|
||||
@Getter
|
||||
private final Filter preFilter;
|
||||
|
||||
QuickShopExceptionFilter(@Nullable Filter preFilter) {
|
||||
|
||||
this.preFilter = preFilter;
|
||||
|
||||
}
|
||||
|
||||
private boolean defaultValue(LogRecord rec) {
|
||||
|
||||
return preFilter == null || preFilter.isLoggable(rec);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given log record should be published.
|
||||
*
|
||||
* @param rec a LogRecord
|
||||
* @return true if the log record should be published.
|
||||
*/
|
||||
@Override
|
||||
public boolean isLoggable(@NotNull LogRecord rec) {
|
||||
|
||||
if (!enabled) {
|
||||
|
||||
return defaultValue(rec);
|
||||
|
||||
}
|
||||
|
||||
Level level = rec.getLevel();
|
||||
if (level != Level.WARNING && level != Level.SEVERE) {
|
||||
|
||||
return defaultValue(rec);
|
||||
|
||||
}
|
||||
|
||||
if (rec.getThrown() == null) {
|
||||
|
||||
return defaultValue(rec);
|
||||
|
||||
}
|
||||
|
||||
if (Util.isDevMode()) {
|
||||
|
||||
sendError(rec.getThrown(), rec.getMessage());
|
||||
return defaultValue(rec);
|
||||
|
||||
} else {
|
||||
|
||||
sendError(rec.getThrown(), rec.getMessage());
|
||||
PossiblyLevel possiblyLevel = checkWasCauseByQS(rec.getThrown());
|
||||
if (possiblyLevel == PossiblyLevel.IMPOSSIBLE) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (possiblyLevel == PossiblyLevel.MAYBE) {
|
||||
|
||||
plugin.getLogger().warning(
|
||||
"This seems not a QuickShop error. If you have any question, you may can ask QuickShop developer but don't except any solution.");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.security;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Taken from the jarsigner utility.
|
||||
* <p>
|
||||
* see
|
||||
* https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/security/tools/jarsigner/Main.java#l570
|
||||
*
|
||||
* @author Roland Schemers
|
||||
* @author Jan Luehe
|
||||
*/
|
||||
public class JarVerifyTool {
|
||||
|
||||
@NotNull
|
||||
public List<JarEntry> verify(@NotNull JarFile jar) throws IOException {
|
||||
|
||||
List<JarEntry> modified = new ArrayList<>();
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
|
||||
JarEntry entry = entries.nextElement();
|
||||
try (InputStream is = jar.getInputStream(entry)) {
|
||||
|
||||
byte[] buffer = new byte[8192];
|
||||
// noinspection StatementWithEmptyBody
|
||||
while ((is.read(buffer, 0, buffer.length)) != -1) {
|
||||
|
||||
// We just read. This will throw a SecurityException
|
||||
// if a signature/digest check fails.
|
||||
}
|
||||
|
||||
} catch (SecurityException se) {
|
||||
|
||||
modified.add(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return modified;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,6 @@ softdepend:
|
||||
- Reserve
|
||||
- PlaceholderAPI
|
||||
- NoCheatPlus
|
||||
- Spartan
|
||||
- LuckPerms
|
||||
- PermissionEx
|
||||
- GroupManager
|
||||
@@ -63,12 +62,10 @@ softdepend:
|
||||
- Lands
|
||||
- GriefPrevention
|
||||
- JulySafe
|
||||
- FabledSkyblock
|
||||
- OpenInv
|
||||
- WorldEdit
|
||||
- AdvancedRegionMarket
|
||||
- IridiumSkyblock
|
||||
- FabledSkyblock
|
||||
- NBTAPI
|
||||
|
||||
api-version: '${apiVersion}'
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package org.maxgamer.quickshop;
|
||||
|
||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Use for testing related to bukkit api
|
||||
* <p>
|
||||
* If you are writing test which using runtime stuff, just extend it
|
||||
*/
|
||||
public abstract class TestBukkitBase {
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() {
|
||||
|
||||
MockBukkit.getOrCreateMock();
|
||||
System.getProperties().setProperty("org.maxgamer.quickshop.util.envcheck.skip.SIGNATURE_VERIFY", "true");
|
||||
System.getProperties().setProperty(
|
||||
"org.maxgamer.quickshop.util.envcheck.skip.POTENTIAL_INFECTION_CHARACTERISTICS_CHECK", "true");
|
||||
// Prevent network flow to OTA
|
||||
try {
|
||||
|
||||
Field CROWDIN_OTA_HOST = Class
|
||||
.forName("org.maxgamer.quickshop.localization.text.distributions.crowdin.CrowdinOTA")
|
||||
.getDeclaredField("CROWDIN_OTA_HOST");
|
||||
CROWDIN_OTA_HOST.setAccessible(true);
|
||||
CROWDIN_OTA_HOST.set(null, "http://0.0.0.0");
|
||||
|
||||
} catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
}
|
||||
|
||||
MockBukkit.load(QuickShop.class);
|
||||
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown() {
|
||||
|
||||
MockBukkit.unmock();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is EconomyTransactionTest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.economy;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.maxgamer.quickshop.QuickShop;
|
||||
import org.maxgamer.quickshop.TestBukkitBase;
|
||||
import org.maxgamer.quickshop.api.economy.EconomyCore;
|
||||
import org.maxgamer.quickshop.api.economy.EconomyTransaction;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class EconomyTransactionTest extends TestBukkitBase {
|
||||
|
||||
static EconomyCore economy = new TestEconomy();
|
||||
static Trader taxAccount;
|
||||
|
||||
public static Trader getTaxAccount() {
|
||||
|
||||
if (taxAccount == null) {
|
||||
|
||||
taxAccount = Trader.adapt(QuickShop.getInstance().getServer().getOfflinePlayer("Tax"));
|
||||
economy.getBalance(taxAccount, null, null);
|
||||
|
||||
}
|
||||
|
||||
return taxAccount;
|
||||
|
||||
}
|
||||
|
||||
private static EconomyTransaction genTransaction(UUID from, UUID to, double amount, double taxModifier,
|
||||
boolean allowLoan)
|
||||
{
|
||||
|
||||
return EconomyTransaction.builder().core(economy).from(from).to(to).amount(amount).taxAccount(getTaxAccount())
|
||||
.taxModifier(taxModifier).allowLoan(allowLoan).build();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransaction() {
|
||||
|
||||
List<UUID> UUIDList = Stream.generate(UUID::randomUUID).limit(20).collect(Collectors.toList());
|
||||
for (UUID account : UUIDList) {
|
||||
|
||||
genTransaction(null, account, 1000, 0.06, false).commit(new EconomyTransaction.TransactionCallback() {
|
||||
|
||||
@Override
|
||||
public void onTaxFailed(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommit(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
throw new RuntimeException("Deposit Test Failed");
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
assertEquals((Double) (20 * 1000 * 0.06D), (Double) economy.getBalance(taxAccount, null, null));
|
||||
|
||||
assertEquals((Double) (1000 * 0.94D), (Double) economy.getBalance(UUIDList.get(0), null, null));
|
||||
|
||||
genTransaction(UUIDList.get(5), null, 1000, 0.0, true).commit(new EconomyTransaction.TransactionCallback() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
assertEquals(-1000 * 0.06D, economy.getBalance(economyTransaction.getFrom(), null, null));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
throw new RuntimeException("Loan Test Failed");
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
genTransaction(UUIDList.get(4), UUIDList.get(5), 1000, 0.06, true)
|
||||
.commit(new EconomyTransaction.TransactionCallback()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onSuccess(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
assertEquals(-1000 * 0.06D, economy.getBalance(economyTransaction.getFrom(), null, null));
|
||||
assertEquals(-1000 * 0.06D + 1000 * 0.94D,
|
||||
economy.getBalance(economyTransaction.getTo(), null, null));
|
||||
assertEquals(20 * 1000 * 0.06D + (1000 * 0.06D), economy.getBalance(taxAccount, null, null));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(@NotNull EconomyTransaction economyTransaction) {
|
||||
|
||||
throw new RuntimeException("Transfer Test Failed");
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRollback() {
|
||||
|
||||
UUID from = UUID.randomUUID();
|
||||
UUID to = UUID.randomUUID();
|
||||
economy.deposit(from, 99, null, null);
|
||||
assertEquals(99, economy.getBalance(from, null, null));
|
||||
assertEquals(0, economy.getBalance(to, null, null));
|
||||
EconomyTransaction.builder().core(economy).from(from).to(to).amount(100).core(economy).taxAccount(taxAccount)
|
||||
.taxModifier(0.0).build().failSafeCommit();
|
||||
assertEquals(99, economy.getBalance(from, null, null));
|
||||
assertEquals(0, economy.getBalance(to, null, null));
|
||||
EconomyTransaction.builder().core(economy).from(from).to(to).amount(100).core(economy).taxAccount(taxAccount)
|
||||
.taxModifier(0.2).build().failSafeCommit();
|
||||
assertEquals(99, economy.getBalance(from, null, null));
|
||||
assertEquals(0, economy.getBalance(to, null, null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNull() {
|
||||
|
||||
try {
|
||||
|
||||
EconomyTransaction.builder().core(economy).from(null).to(null).amount(100).core(economy)
|
||||
.taxAccount(taxAccount).taxModifier(0.0).build().failSafeCommit();
|
||||
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
throw new RuntimeException("Null Test Failed!");
|
||||
|
||||
}
|
||||
|
||||
static class TestEconomy implements EconomyCore {
|
||||
|
||||
final Map<UUID, Double> playerBalanceMap = new HashMap<>(10);
|
||||
|
||||
private Double getOrCreateAccount(UUID uuid) {
|
||||
|
||||
if (!playerBalanceMap.containsKey(uuid)) {
|
||||
|
||||
playerBalanceMap.put(uuid, 0.0);
|
||||
return 0.0;
|
||||
|
||||
}
|
||||
|
||||
return playerBalanceMap.get(uuid);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(@NotNull UUID name, double amount, @NotNull World world, @Nullable String currency) {
|
||||
|
||||
playerBalanceMap.put(name, amount + getBalance(name, null, null));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(@NotNull OfflinePlayer trader, double amount, @NotNull World world,
|
||||
@Nullable String currency)
|
||||
{
|
||||
|
||||
return deposit(trader.getUniqueId(), amount, null, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(double balance, @NotNull World world, @Nullable String currency) {
|
||||
|
||||
return Double.toString(balance);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBalance(@NotNull UUID name, @NotNull World world, @Nullable String currency) {
|
||||
|
||||
return getOrCreateAccount(name);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBalance(@NotNull OfflinePlayer player, @NotNull World world, @Nullable String currency) {
|
||||
|
||||
return getBalance(player.getUniqueId(), null, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transfer(@NotNull UUID from, @NotNull UUID to, double amount, @NotNull World world,
|
||||
@Nullable String currency)
|
||||
{
|
||||
|
||||
double formBalance = getBalance(from, null, null);
|
||||
playerBalanceMap.put(from, 0.0);
|
||||
playerBalanceMap.put(to, getBalance(from, null, null) + formBalance);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdraw(@NotNull UUID name, double amount, @NotNull World world, @Nullable String currency) {
|
||||
|
||||
playerBalanceMap.put(name, getBalance(name, null, null) - amount);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdraw(@NotNull OfflinePlayer trader, double amount, @NotNull World world,
|
||||
@Nullable String currency)
|
||||
{
|
||||
|
||||
return withdraw(trader.getUniqueId(), amount, null, null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currency does exists
|
||||
*
|
||||
* @param currency Currency name
|
||||
* @return exists
|
||||
*/
|
||||
@Override
|
||||
public boolean hasCurrency(@NotNull World world, @NotNull String currency) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets currency supports status
|
||||
*
|
||||
* @return true if supports
|
||||
*/
|
||||
@Override
|
||||
public boolean supportCurrency() {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getLastError() {
|
||||
|
||||
return "ErrorTracing: Unit Test";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
|
||||
return "TestEconomy";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Plugin getPlugin() {
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is ListenerContainerTest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.eventmanager;
|
||||
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginLoader;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ListenerContainerTest {
|
||||
|
||||
@Test
|
||||
public void testMatches() {
|
||||
|
||||
Plugin testPlugin = new Plugin() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PluginDescriptionFile getDescription() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FileConfiguration getConfig() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FileConfiguration getConfiguration() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public InputStream getResource(@NotNull String s) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConfig() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDefaultConfig() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveResource(@NotNull String s, boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PluginLoader getPluginLoader() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Server getServer() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNaggable() {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNaggable(boolean b) {
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ChunkGenerator getDefaultWorldGenerator(@NotNull String s, @Nullable String s1) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BiomeProvider getDefaultBiomeProvider(@NotNull String s, @Nullable String s1) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
|
||||
return "QuickTest";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull LifecycleEventManager<Plugin> getLifecycleManager() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings)
|
||||
{
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PluginMeta getPluginMeta() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command,
|
||||
@NotNull String s, @NotNull String[] strings)
|
||||
{
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
ListenerContainer listenerContainerA = new ListenerContainer(null, "@QuickTest");
|
||||
ListenerContainer listenerContainerB = new ListenerContainer(null, "@QuickTestBad");
|
||||
Assertions.assertTrue(listenerContainerA.matches(this.getClass(), testPlugin));
|
||||
Assertions.assertFalse(listenerContainerB.matches(this.getClass(), testPlugin));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is ShopTransactionMessageTest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.shop;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.maxgamer.quickshop.TestBukkitBase;
|
||||
import org.maxgamer.quickshop.localization.LocalizedMessagePair;
|
||||
|
||||
public class ShopTransactionMessageTest extends TestBukkitBase {
|
||||
|
||||
@Test
|
||||
public void testV1PlainMessage() {
|
||||
|
||||
ShopTransactionMessageContainer container = ShopTransactionMessageContainer.fromJson("233333");
|
||||
container = ShopTransactionMessageContainer.fromJson(container.toJson());
|
||||
Assertions.assertEquals("233333", container.getMessage(null));
|
||||
Assertions.assertNull(container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testV2PlainMessage() {
|
||||
|
||||
ShopTransactionMessageContainer container = ShopTransactionMessageContainer
|
||||
.fromJson(ShopTransactionMessageContainer.fromJson(
|
||||
"{\"message\":\"233333\",\"hoverItem\":\"item:\\n \\u003d\\u003d: org.bukkit.inventory.ItemStack\\n v: 2730\\n type: JUNGLE_LOG\\n\",\"hoverText\":\"233333\"}")
|
||||
.toJson());
|
||||
Assertions.assertEquals("233333", container.getMessage(null));
|
||||
Assertions.assertEquals(
|
||||
"item:\n \u003d\u003d: org.bukkit.inventory.ItemStack\n v: 2730\n type: JUNGLE_LOG\n",
|
||||
container.getHoverItemStr());
|
||||
Assertions.assertEquals("233333", container.getHoverText(null));
|
||||
container = ShopTransactionMessageContainer.fromJson(ShopTransactionMessageContainer.fromJson(
|
||||
"{\"message\":\"233333\",\"hoverItem\":\"item:\\n \\u003d\\u003d: org.bukkit.inventory.ItemStack\\n v: 2730\\n type: JUNGLE_LOG\\n\"}")
|
||||
.toJson());
|
||||
Assertions.assertEquals("233333", container.getMessage(null));
|
||||
Assertions.assertEquals(
|
||||
"item:\n \u003d\u003d: org.bukkit.inventory.ItemStack\n v: 2730\n type: JUNGLE_LOG\n",
|
||||
container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
container = ShopTransactionMessageContainer
|
||||
.fromJson(ShopTransactionMessageContainer.fromJson("{\"message\":\"233333\"}").toJson());
|
||||
Assertions.assertEquals("233333", container.getMessage(null));
|
||||
Assertions.assertNull(container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModernMessage() {
|
||||
|
||||
// V1
|
||||
ShopTransactionMessageContainer container = ShopTransactionMessageContainer
|
||||
.fromJson(ShopTransactionMessageContainer.ofPlainStr("ghost_chu is an lucky guy").toJson());
|
||||
Assertions.assertEquals("ghost_chu is an lucky guy", container.getMessage(null));
|
||||
Assertions.assertNull(container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
// V2
|
||||
container = ShopTransactionMessageContainer
|
||||
.fromJson(ShopTransactionMessageContainer.ofStrWithItem("ghost_chu", null, null).toJson());
|
||||
Assertions.assertEquals("ghost_chu", container.getMessage(null));
|
||||
Assertions.assertNull(container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
container = ShopTransactionMessageContainer
|
||||
.fromJson(ShopTransactionMessageContainer.ofStrWithItem("ghost_chu", "is", null).toJson());
|
||||
Assertions.assertEquals("ghost_chu", container.getMessage(null));
|
||||
Assertions.assertEquals("is", container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
container = ShopTransactionMessageContainer
|
||||
.fromJson(ShopTransactionMessageContainer.ofStrWithItem("ghost_chu", "is", "an lucky guy").toJson());
|
||||
Assertions.assertEquals("ghost_chu", container.getMessage(null));
|
||||
Assertions.assertEquals("is", container.getHoverItemStr());
|
||||
Assertions.assertEquals("an lucky guy", container.getHoverText(null));
|
||||
// V3
|
||||
container = ShopTransactionMessageContainer.fromJson(ShopTransactionMessageContainer
|
||||
.ofLocalizedMessageWithItem(LocalizedMessagePair.of("nearby-shop-this-way", "ghost_chu"), "is",
|
||||
LocalizedMessagePair.of("nearby-shop-this-way", "ghost_chu"))
|
||||
.toJson());
|
||||
Assertions.assertTrue(container.getMessage(null).contains("ghost_chu"));
|
||||
Assertions.assertEquals("is", container.getHoverItemStr());
|
||||
Assertions.assertTrue(container.getHoverText(null).contains("ghost_chu"));
|
||||
container = ShopTransactionMessageContainer.fromJson(ShopTransactionMessageContainer
|
||||
.ofLocalizedMessageWithItem(LocalizedMessagePair.of("nearby-shop-this-way", "ghost_chu"), "is", null)
|
||||
.toJson());
|
||||
Assertions.assertTrue(container.getMessage(null).contains("ghost_chu"));
|
||||
Assertions.assertEquals("is", container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
container = ShopTransactionMessageContainer.fromJson(ShopTransactionMessageContainer
|
||||
.ofLocalizedMessageWithItem(LocalizedMessagePair.of("nearby-shop-this-way", "ghost_chu"), null, null)
|
||||
.toJson());
|
||||
Assertions.assertTrue(container.getMessage(null).contains("ghost_chu"));
|
||||
Assertions.assertNull(container.getHoverItemStr());
|
||||
Assertions.assertNull(container.getHoverText(null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is InteractUtilTest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.MemoryConfiguration;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class InteractUtilTest {
|
||||
|
||||
private ConfigurationSection genConfig(int mode, boolean allowSneaking) {
|
||||
|
||||
ConfigurationSection configurationSection = new MemoryConfiguration();
|
||||
configurationSection.set("shop.interact.interact-mode", mode);
|
||||
configurationSection.set("shop.interact.sneak-to-create", allowSneaking);
|
||||
return configurationSection.getConfigurationSection("shop.interact");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInteractBoolean() {
|
||||
|
||||
// ONLY
|
||||
InteractUtil.init(genConfig(0, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, true));
|
||||
Assertions.assertFalse(InteractUtil.check(InteractUtil.Action.CREATE, false));
|
||||
InteractUtil.init(genConfig(0, false));
|
||||
Assertions.assertFalse(InteractUtil.check(InteractUtil.Action.CREATE, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, false));
|
||||
// BOTH
|
||||
InteractUtil.init(genConfig(1, false));
|
||||
Assertions.assertFalse(InteractUtil.check(InteractUtil.Action.CREATE, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, false));
|
||||
InteractUtil.init(genConfig(1, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, false));
|
||||
// REVERSED
|
||||
InteractUtil.init(genConfig(2, false));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, false));
|
||||
InteractUtil.init(genConfig(2, true));
|
||||
Assertions.assertFalse(InteractUtil.check(InteractUtil.Action.CREATE, true));
|
||||
Assertions.assertTrue(InteractUtil.check(InteractUtil.Action.CREATE, false));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is UpdaterTest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util;
|
||||
|
||||
public class UpdaterTest {
|
||||
|
||||
// @Test
|
||||
// //TODO: Apply to new updater.
|
||||
// public void TestUpdateVer() {
|
||||
//// Assertions.assertTrue(Updater.hasUpdate("3", "4"));
|
||||
//// Assertions.assertFalse(Updater.hasUpdate("3.2.3", "3.2.3"));
|
||||
//// Assertions.assertTrue(Updater.hasUpdate("3.2.0", "3.2.3"));
|
||||
//// Assertions.assertTrue(Updater.hasUpdate("3.2.3", "3.2.3.1"));
|
||||
//// Assertions.assertTrue(Updater.hasUpdate("3.2.3", "3.2.3.0"));
|
||||
//// Assertions.assertTrue(Updater.hasUpdate("3.2.3.0", "3.2.3.1"));
|
||||
//// Assertions.assertFalse(Updater.hasUpdate("3.2.3.1.3", "3.2.3.1"));
|
||||
// }
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is UtilTest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UtilTest {
|
||||
|
||||
@Test
|
||||
public void array2String() {
|
||||
|
||||
String sample = "A, B, C";
|
||||
Assertions.assertEquals(sample, Util.array2String(new String[] { "A", "B", "C" }));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boolean2Status() {
|
||||
|
||||
Assertions.assertEquals(Util.boolean2Status(true), "Enabled");
|
||||
Assertions.assertEquals(Util.boolean2Status(false), "Disabled");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isClassAvailable() {
|
||||
|
||||
Assertions.assertTrue(Util.isClassAvailable(getClass().getName()));
|
||||
Assertions.assertFalse(Util.isClassAvailable("random.Class"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUUID() {
|
||||
|
||||
Assertions.assertTrue(Util.isUUID("b188beda-8bfb-ed66-65e5-25147a4617cf"));
|
||||
Assertions.assertFalse(Util.isUUID("b188beda8bfbed6665e525147a4617cf"));
|
||||
Assertions.assertFalse(Util.isUUID("?"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void list2String() {
|
||||
|
||||
String sample = "1, 2, 3, 4, 5";
|
||||
Assertions.assertEquals(sample, Util.list2String(Arrays.asList("1", "2", "3", "4", "5")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstUppercase() {
|
||||
|
||||
Assertions.assertEquals("Quickshop", Util.firstUppercase("quickshop"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeArgs() {
|
||||
|
||||
String[] args = new String[3];
|
||||
args[0] = "yaa";
|
||||
args[1] = "hoo";
|
||||
args[2] = "woo";
|
||||
Assertions.assertEquals("yaa hoo woo", Util.mergeArgs(args));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArray2String() {
|
||||
|
||||
String[] array = new String[] { "aaa", "bbb", "ccc", "ddd" };
|
||||
Assertions.assertEquals("aaa, bbb, ccc, ddd", Util.array2String(array));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsClassAvailable() {
|
||||
|
||||
Assertions.assertTrue(Util.isClassAvailable("java.lang.String"));
|
||||
Assertions.assertFalse(Util.isClassAvailable("java.lang.NotExistedClassLoL"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isMethodAvailable() {
|
||||
|
||||
Assertions.assertTrue(Util.isMethodAvailable(String.class.getName(), "toLowerCase"));
|
||||
Assertions.assertFalse(Util.isMethodAvailable(String.class.getName(), "P90 RUSH B"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsUUID() {
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
Assertions.assertTrue(Util.isUUID(uuid.toString()));
|
||||
Assertions.assertTrue(Util.isUUID(Util.getNilUniqueId().toString()));
|
||||
Assertions.assertFalse(Util.isUUID(uuid.toString().replace("-", "")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prettifyText() {
|
||||
|
||||
Assertions.assertEquals("Diamond", Util.prettifyText("DIAMOND"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirstUppercase() {
|
||||
|
||||
Assertions.assertEquals("Foobar", Util.firstUppercase("foobar"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeArgs() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNilUniqueId() {
|
||||
|
||||
Assertions.assertEquals(new UUID(0, 0), Util.getNilUniqueId());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is MojangAPITest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.mojangapi;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.maxgamer.quickshop.TestBukkitBase;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MojangAPITest extends TestBukkitBase {
|
||||
|
||||
@Test
|
||||
public void testMojangMetaApi() {
|
||||
|
||||
MojangAPI api = new MojangAPI(new MojangApiOfficialMirror());
|
||||
Optional<String> metaData = api.getMetaAPI("1.16.5").get();
|
||||
Assertions.assertTrue(metaData.isPresent());
|
||||
Assertions.assertFalse(metaData.get().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMojangAssetsApi() {
|
||||
|
||||
MojangAPI api = new MojangAPI(new MojangApiOfficialMirror());
|
||||
MojangAPI.AssetsAPI assetsAPI = api.getAssetsAPI("1.16.5");
|
||||
Assertions.assertTrue(assetsAPI.isAvailable());
|
||||
Optional<MojangAPI.AssetsFileData> assetsFileData = assetsAPI.getGameAssetsFile();
|
||||
Assertions.assertTrue(assetsFileData.isPresent());
|
||||
Assertions.assertFalse(assetsFileData.get().getContent().isEmpty());
|
||||
Assertions.assertFalse(assetsFileData.get().getId().isEmpty());
|
||||
Assertions.assertFalse(assetsFileData.get().getSha1().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is MojangAPITest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.mojangapi;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.maxgamer.quickshop.TestBukkitBase;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MojangAPITest_BMCLAPI extends TestBukkitBase {
|
||||
|
||||
@Test
|
||||
public void testMojangMetaApi() {
|
||||
|
||||
MojangAPI api = new MojangAPI(new MojangApiBmclApiMirror());
|
||||
Optional<String> metaData = api.getMetaAPI("1.16.5").get();
|
||||
Assertions.assertTrue(metaData.isPresent());
|
||||
Assertions.assertFalse(metaData.get().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMojangAssetsApi() {
|
||||
|
||||
MojangAPI api = new MojangAPI(new MojangApiBmclApiMirror());
|
||||
MojangAPI.AssetsAPI assetsAPI = api.getAssetsAPI("1.16.5");
|
||||
Assertions.assertTrue(assetsAPI.isAvailable());
|
||||
Optional<MojangAPI.AssetsFileData> assetsFileData = assetsAPI.getGameAssetsFile();
|
||||
Assertions.assertTrue(assetsFileData.isPresent());
|
||||
Assertions.assertFalse(assetsFileData.get().getContent().isEmpty());
|
||||
Assertions.assertFalse(assetsFileData.get().getId().isEmpty());
|
||||
Assertions.assertFalse(assetsFileData.get().getSha1().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file is a part of project QuickShop, the name is MojangAPITest.java
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.maxgamer.quickshop.util.mojangapi;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.maxgamer.quickshop.TestBukkitBase;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MojangAPITest_MCBBSAPI extends TestBukkitBase {
|
||||
|
||||
@Test
|
||||
public void testMojangMetaApi() {
|
||||
|
||||
MojangAPI api = new MojangAPI(new MojangApiMcbbsApiMirror());
|
||||
Optional<String> metaData = api.getMetaAPI("1.16.5").get();
|
||||
Assertions.assertTrue(metaData.isPresent());
|
||||
Assertions.assertFalse(metaData.get().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMojangAssetsApi() {
|
||||
|
||||
MojangAPI api = new MojangAPI(new MojangApiMcbbsApiMirror());
|
||||
MojangAPI.AssetsAPI assetsAPI = api.getAssetsAPI("1.16.5");
|
||||
Assertions.assertTrue(assetsAPI.isAvailable());
|
||||
Optional<MojangAPI.AssetsFileData> assetsFileData = assetsAPI.getGameAssetsFile();
|
||||
Assertions.assertTrue(assetsFileData.isPresent());
|
||||
Assertions.assertFalse(assetsFileData.get().getContent().isEmpty());
|
||||
Assertions.assertFalse(assetsFileData.get().getId().isEmpty());
|
||||
Assertions.assertFalse(assetsFileData.get().getSha1().isEmpty());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"username": "Jenkins Webhook",
|
||||
"avatar_url": "https://i.loli.net/2020/07/31/8Z2sEvD137uUlRf.jpg",
|
||||
"content": "New build available!",
|
||||
"embeds": [
|
||||
{
|
||||
"author": {
|
||||
"name": "Jenkins CI",
|
||||
"url": "https://ci.codemc.io",
|
||||
"icon_url": "https://i.loli.net/2020/07/31/8Z2sEvD137uUlRf.jpg"
|
||||
},
|
||||
"title": "New SNAPSHOT #$BUILD_ID available",
|
||||
"url": "$BUILD_URL",
|
||||
"description": "New snapshot of $POM_ARTIFACTID now is available!",
|
||||
"color": 15258703,
|
||||
"fields": [
|
||||
{
|
||||
"name": "Author",
|
||||
"value": "$GIT_AUTHOR_NAME",
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Branch",
|
||||
"value": "$GIT_BRANCH",
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Commit Message",
|
||||
"value": "$GIT_COMMIT_MESSAGE"
|
||||
},
|
||||
{
|
||||
"name": "Download Snapshot",
|
||||
"value": "[Click Here]($BUILD_URL) to download"
|
||||
}
|
||||
],
|
||||
"footer": {
|
||||
"text": "Jenkins CI - Discord Webhook"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user