From 0b27d2406951e3ea749435d35522c905deaf00ad Mon Sep 17 00:00:00 2001 From: sandtechnology <20417547+sandtechnology@users.noreply.github.com> Date: Fri, 17 Mar 2023 15:04:17 +0800 Subject: [PATCH] 5.1.2.0 (#326) * PlayerFinder:Disable offline search when offline stash is enabled * Bump to 5.1.1.3 * Add progress report and try-catch block for offline player caching * Add error counting for caching offline player * Create crowdin ota workflow * Let workflow runs when translation PR merged * Use crowdin ids in secrets * Add okhttp shutdown logic on plugin disabling * Say hello to CrowdinOTA again Change crowdin requesting behavior to use timestamp querying files and not caching when querying manifest * New Crowdin translations by Github Action (#288) Co-authored-by: Crowdin Bot * Fix test * Fix test again * Fix messed okhttp cache folder * Temporary disable custom_languages field for wrong format See https://github.com/Ghost-chu/CrowdinCopyDeploy/pull/1 * Fix enderchest shop not working * Refactor PlayerFinder and solve lag issue for real * Fix unwanted change to registerCustomCommands * PlayerFinder: use toLowerCase(Locale.ROOT) when updating * PlayerFinder: fix a bug which returning null for name2uuid * Disable the support of reloading DatabaseManager * Fix bug for bypassing item stacking option * Add user agent to http query * Fix a bug for got NPE when eco plugin not installed * Update LandsAPI ABI * Add include-offlineplayer-for-command option * Fix unit test for mojang api * Fix the bug about using static language * Update the doc in config.yml for this fix * #299 Set connectTimeout to 10 seconds * update mcbbs link (#310) * fix wrong update link * update link * update link * Update MCBBS Link * [ShopPurger] Add timeout to prevent crash server * SubCommand_Find: Add finding enchantments on enchanted books (#306) * SubCommand_Find: Add finding enchants on books * Reduce nested if's into singular if statement using && * Combine getBooksEnchantments and listContainsString into single function * Add missed imports --------- Co-authored-by: sandtechnology <20417547+sandtechnology@users.noreply.github.com> * Add manual trigger for crowdin workflow * New Crowdin translations by Github Action (#292) Co-authored-by: Crowdin Bot * #305 Fix wrong potionEffect level showing * Bump skyblock from 2.3.30 to 2.5.0 (#312) Bumps skyblock from 2.3.30 to 2.5.0. --- updated-dependencies: - dependency-name: com.songoda:skyblock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add listener to handle Spartan compatibility * Add missed soft depends for Spartan * #316 Delete wrong depends on ArmShopBridge * New Crowdin translations by Github Action (#313) Co-authored-by: Crowdin Bot * Refactor PriceLimiter Improve code readability Fix free shop price checking Fix digit checking not working other than shop creation Send detail message to player after price check failed * Fix wrong price in price error message * Add missed comment * Remove GroupManager check No idea why ghost adding this check, groupmanager should work along with QS * Fix maximumDigitsInPrice not working It should have extra # in formatting * Fix broken maximumDigitsInPrice config option and config version * Fix broken coloring * Fix javadoc for isBookEnchantmentsMatched method * Revert "Fix broken coloring" This reverts commit df9307768942cf298609f31f3250a1250e285990. * Use modified MineDown to fix color issue * Fix price limit message not correct * Fix not calc the real tax in message when selling item (permission) * Add PlayerShopClickEvent and Deprecated ShopClickEvent * Add 1.19.4 support * New Crowdin translations by Github Action (#320) Co-authored-by: Crowdin Bot * Bump GriefPrevention from 16.18 to 16.18.1 (#324) Bumps [GriefPrevention](https://github.com/TechFortress/GriefPrevention) from 16.18 to 16.18.1. - [Release notes](https://github.com/TechFortress/GriefPrevention/releases) - [Commits](https://github.com/TechFortress/GriefPrevention/compare/16.18...16.18.1) --- updated-dependencies: - dependency-name: com.github.TechFortress:GriefPrevention dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump SongodaCore from 2.6.16 to 2.6.18 (#303) Bumps SongodaCore from 2.6.16 to 2.6.18. --- updated-dependencies: - dependency-name: com.songoda:SongodaCore dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump LandsAPI from 6.26.18 to 6.28.11 (#314) Bumps [LandsAPI](https://github.com/Angeschossen/LandsAPI) from 6.26.18 to 6.28.11. - [Release notes](https://github.com/Angeschossen/LandsAPI/releases) - [Commits](https://github.com/Angeschossen/LandsAPI/compare/6.26.18...6.28.11) --- updated-dependencies: - dependency-name: com.github.angeschossen:LandsAPI dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump spigot-api from 1.19.3-R0.1-SNAPSHOT to 1.19.4-R0.1-SNAPSHOT (#325) Bumps spigot-api from 1.19.3-R0.1-SNAPSHOT to 1.19.4-R0.1-SNAPSHOT. --- updated-dependencies: - dependency-name: org.spigotmc:spigot-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump PlotSquared-Core from 6.10.5 to 6.11.1 (#321) Bumps [PlotSquared-Core](https://github.com/IntellectualSites/PlotSquared) from 6.10.5 to 6.11.1. - [Release notes](https://github.com/IntellectualSites/PlotSquared/releases) - [Commits](https://github.com/IntellectualSites/PlotSquared/compare/6.10.5...6.11.1) --- updated-dependencies: - dependency-name: com.plotsquared:PlotSquared-Core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump to 5.1.2.0 * Fix price change log recording wrong new price --------- Signed-off-by: dependabot[bot] Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Crowdin Bot Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: YuanYuanOwO <81153017+YuanYuanOwO@users.noreply.github.com> Co-authored-by: Efe Kurban Co-authored-by: Smudge <68658429+smuddgge@users.noreply.github.com> Co-authored-by: Sarah --- .github/workflows/crowdin.yml | 1 + .github/workflows/sync-crowdinota.yml | 44 +++++ README.md | 2 +- crowdin/lang/af-ZA/messages.json | 4 +- crowdin/lang/ar-SA/messages.json | 6 +- crowdin/lang/bg-BG/messages.json | 4 +- crowdin/lang/ca-ES/messages.json | 4 +- crowdin/lang/cs-CZ/messages.json | 4 +- crowdin/lang/da-DK/messages.json | 4 +- crowdin/lang/de-DE/messages.json | 4 +- crowdin/lang/el-GR/messages.json | 4 +- crowdin/lang/en-US/messages.json | 4 +- crowdin/lang/es-ES/messages.json | 12 +- crowdin/lang/fi-FI/messages.json | 4 +- crowdin/lang/fr-FR/messages.json | 28 +-- crowdin/lang/he-IL/messages.json | 4 +- crowdin/lang/hi-IN/messages.json | 4 +- crowdin/lang/hu-HU/messages.json | 4 +- crowdin/lang/it-IT/messages.json | 4 +- crowdin/lang/ja-JP/messages.json | 4 +- crowdin/lang/ko-KR/messages.json | 4 +- crowdin/lang/lt-LT/messages.json | 4 +- crowdin/lang/nl-NL/messages.json | 4 +- crowdin/lang/no-NO/messages.json | 4 +- crowdin/lang/pl-PL/messages.json | 4 +- crowdin/lang/pt-BR/messages.json | 4 +- crowdin/lang/pt-PT/messages.json | 4 +- crowdin/lang/ro-RO/messages.json | 6 +- crowdin/lang/ru-RU/messages.json | 4 +- crowdin/lang/sr-SP/messages.json | 4 +- crowdin/lang/sv-SE/messages.json | 4 +- crowdin/lang/th-TH/messages.json | 4 +- crowdin/lang/tr-TR/messages.json | 18 +- crowdin/lang/uk-UA/messages.json | 28 +-- crowdin/lang/vi-VN/messages.json | 4 +- crowdin/lang/zh-CN/messages.json | 24 +-- crowdin/lang/zh-HK/messages.json | 4 +- crowdin/lang/zh-TW/messages.json | 126 ++++++------ pom.xml | 20 +- .../org/maxgamer/quickshop/QuickShop.java | 23 ++- .../compatibility/CompatibilityModule.java | 14 ++ .../api/event/PlayerShopClickEvent.java | 48 +++++ .../quickshop/api/event/ShopClickEvent.java | 3 + .../api/shop/PriceLimiterCheckResult.java | 59 ++++++ .../api/shop/PriceLimiterStatus.java | 3 +- .../command/subcommand/SubCommand_Find.java | 10 +- .../command/subcommand/SubCommand_Item.java | 12 +- .../command/subcommand/SubCommand_Price.java | 32 +--- .../subcommand/SubCommand_RemoveAll.java | 13 +- .../subcommand/SubCommand_SetOwner.java | 9 +- .../command/subcommand/SubCommand_Size.java | 10 +- .../command/subcommand/SubCommand_Staff.java | 17 +- .../subcommand/SubCommand_TaxAccount.java | 7 +- .../subcommand/SubCommand_Transfer.java | 25 ++- .../quickshop/database/DatabaseManager.java | 8 +- .../quickshop/economy/Economy_TNE.java | 8 +- .../quickshop/economy/Economy_Vault.java | 7 +- .../maxgamer/quickshop/economy/Trader.java | 11 +- .../integration/lands/LandsIntegration.java | 2 +- .../quickshop/listener/InternalListener.java | 19 +- .../quickshop/listener/PlayerListener.java | 10 +- .../localization/text/SimpleTextManager.java | 11 +- .../distributions/crowdin/CrowdinOTA.java | 10 +- .../distributions/crowdin/bean/Manifest.java | 2 +- .../quickshop/shop/ContainerShop.java | 124 ++++++------ .../maxgamer/quickshop/shop/ShopLoader.java | 2 +- .../maxgamer/quickshop/shop/ShopPurger.java | 53 +++-- .../quickshop/shop/SimplePriceLimiter.java | 84 ++++++-- .../shop/SimplePriceLimiterCheckResult.java | 22 +++ .../quickshop/shop/SimpleShopManager.java | 72 ++----- .../maxgamer/quickshop/util/GameVersion.java | 2 + .../org/maxgamer/quickshop/util/HttpUtil.java | 60 ++++-- .../org/maxgamer/quickshop/util/MsgUtil.java | 6 +- .../maxgamer/quickshop/util/PlayerFinder.java | 181 ++++++++++++++---- .../org/maxgamer/quickshop/util/Util.java | 35 +++- .../SimpleCompatibilityManager.java | 7 +- .../SpartanCompatibilityModule.java | 33 +++- .../economyformatter/EconomyFormatter.java | 6 +- .../util/envcheck/EnvironmentChecker.java | 20 +- .../quickshop/watcher/OngoingFeeWatcher.java | 4 +- src/main/resources/config.yml | 14 +- src/main/resources/lang/messages.json | 4 +- src/main/resources/plugin.yml | 2 +- .../maxgamer/quickshop/TestBukkitBase.java | 2 +- .../util/mojangapi/MojangAPITest.java | 3 +- .../util/mojangapi/MojangAPITest_BMCLAPI.java | 3 +- .../mojangapi/MojangAPITest_MCBBSAPI.java | 3 +- 87 files changed, 1013 insertions(+), 525 deletions(-) create mode 100644 .github/workflows/sync-crowdinota.yml create mode 100644 src/main/java/org/maxgamer/quickshop/api/event/PlayerShopClickEvent.java diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index fa70473fb4..4e21be1240 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -1,6 +1,7 @@ name: Crowdin Action on: + workflow_dispatch: schedule: # * is a special character in YAML so you have to quote this string - cron: '0 */6 * * *' diff --git a/.github/workflows/sync-crowdinota.yml b/.github/workflows/sync-crowdinota.yml new file mode 100644 index 0000000000..8bb316b7ce --- /dev/null +++ b/.github/workflows/sync-crowdinota.yml @@ -0,0 +1,44 @@ +name: ota-distribution + +on: + workflow_dispatch: + pull_request: + types: + - closed + branches: + - master + paths: + - 'crowdin/lang/**' + +jobs: + build: + if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: +# - uses: actions/checkout@v3 +# - name: Set up JDK 17 +# uses: actions/setup-java@v3 +# with: +# java-version: '17' +# distribution: 'temurin' + - name: Build Translations + uses: Ghost-chu/CrowdinCopyDeploy-action@master + with: + args: uploads3 + env: + CROWDIN_ACCESS_TOKEN: ${{ secrets.CROWDIN_ACCESS_TOKEN }} + CROWDIN_PROJECT_BRANCH_ID: ${{ secrets.CROWDIN_BRANCH_ID }} + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + #DEPLOY_PATH: './deploy-prod' + AWS_S3_ENDPOINT: ${{ secrets.AWS_S3_ENDPOINT }} + AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: auto + - name: Purge CloudFlare cache + uses: jakejarvis/cloudflare-purge-action@master + env: + # Zone is required by both authentication methods + CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }} + CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} + CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }} diff --git a/README.md b/README.md index b8492f01c6..3a71827944 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ from [KaiKikuchi's QuickShop upstream repository](https://github.com/KaiKikuchi/ ## Downloads -| | | | +| | | | | :---: | :---: | :---: | :---: | | **Spigot** | **BukkitDev** | **MCBBS** | **Jenkins** | diff --git a/crowdin/lang/af-ZA/messages.json b/crowdin/lang/af-ZA/messages.json index ab8edfa270..728d2daec2 100644 --- a/crowdin/lang/af-ZA/messages.json +++ b/crowdin/lang/af-ZA/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/ar-SA/messages.json b/crowdin/lang/ar-SA/messages.json index e9073fcb4a..833a5ce810 100644 --- a/crowdin/lang/ar-SA/messages.json +++ b/crowdin/lang/ar-SA/messages.json @@ -1,11 +1,11 @@ { - "_comment": "Hi translator! If you editing this from Github or from code sources, you should go https://crowdin.com/project/quickshop-reremake", + "_comment": "أهلاً أيها المترجم! إذا كنت تترجم بإستخدام GitHub أو عن طريق الكود الأساسي من الأفضل أن تذهب إلى https://crowdin.com/project/quickshop-reremake", "file-test": "This is a test textfile. We use it to test if the messages.json is broken. You can fill it with any easter eggs you like here :)", "translation-author": "المترجم: Ghost_chu, Andre_601, MoroccanTea", "translation-version": "إصدار الدعم: إعادة التشكيل", "translation-contributors": "المساهمون: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken و Andre_601", "translation-country": "منطقة اللغة: العربية (ar_AR)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cلا يمكن العثور على QuickShop. تحتاج إلى النظر إلى واحد.", "no-anythings-in-your-hand": "&cلا يوجد شيء في يديك.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/bg-BG/messages.json b/crowdin/lang/bg-BG/messages.json index ab8edfa270..728d2daec2 100644 --- a/crowdin/lang/bg-BG/messages.json +++ b/crowdin/lang/bg-BG/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/ca-ES/messages.json b/crowdin/lang/ca-ES/messages.json index a6e8b402d9..2c31fbab95 100644 --- a/crowdin/lang/ca-ES/messages.json +++ b/crowdin/lang/ca-ES/messages.json @@ -5,7 +5,7 @@ "translation-version": "Versió suportada: Reremake", "translation-contributors": "Contributors: Hoswolf, Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Zona de l'idioma: Català (ca_ES)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "No s'ha trobat cap QuickShop. N'has d'estar mirant una.", "no-anythings-in-your-hand": "No tens res a la mà.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cEl preu de la botiga és massa alt! No en pots crear amb un preu més alt que {0}.", "you-cant-create-shop-in-there": "&cNo tens permís per crear una botiga aquí.", - "unknown-player": "&cEl jugador no existeix, assegura't que ho has escrit correctament.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aS'han eliminat tots els moderadors de la teva botiga.", "shop-staff-added": "&aS'ha afegit {0} com a moderador de la teva botiga.", "shop-staff-deleted": "&aS'ha eliminat {0} com a moderador de la teva botiga.", diff --git a/crowdin/lang/cs-CZ/messages.json b/crowdin/lang/cs-CZ/messages.json index 646919c9d3..070a7cda8a 100644 --- a/crowdin/lang/cs-CZ/messages.json +++ b/crowdin/lang/cs-CZ/messages.json @@ -5,7 +5,7 @@ "translation-version": "Podpora verze: Reremake", "translation-contributors": "Přispěli: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Jazyková Zóna: Czech (cs_CZ)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cNelze najít blok pro vytvoření obchodu. Musíte se na něj dívat.", "not-looking-at-shop": "&cNelze najít QuickShop. Musíš se na něj podívat.", "no-anythings-in-your-hand": "&cNemáš v ruce žádný předmět.", @@ -34,7 +34,7 @@ "shop-purchase-cancelled": "&cNákup v obchodě byl zrušen.", "shop-stock-too-low": "&cV obchodě zbývá pouze {0} {1}!", "you-cant-afford-to-buy": "&cToto stojí {0}, ale ty máš jen {1}", - "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", + "select-shop-type-or-cancel": "&aJaký typ obchodu chcete použít? \n {0} {1} {2}", "select-shop-type-or-cancel-selling-button": "&d[Selling]", "select-shop-type-or-cancel-buying-button": "&b[Buying]", "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", diff --git a/crowdin/lang/da-DK/messages.json b/crowdin/lang/da-DK/messages.json index 6fe8a31d4c..63408c60ef 100644 --- a/crowdin/lang/da-DK/messages.json +++ b/crowdin/lang/da-DK/messages.json @@ -5,7 +5,7 @@ "translation-version": "Supportversion: Reremake", "translation-contributors": "Bidragydere: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken og Andre_601", "translation-country": "Sprogzone: dansk (da_DA)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cKunne ikke finde en QuickShop. Du skal kigge på en.", "no-anythings-in-your-hand": "&cDer er intet i din hånd.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/de-DE/messages.json b/crowdin/lang/de-DE/messages.json index 91568756b6..fb5c4e7413 100644 --- a/crowdin/lang/de-DE/messages.json +++ b/crowdin/lang/de-DE/messages.json @@ -5,7 +5,7 @@ "translation-version": "Unterstütze Version: Reremake", "translation-contributors": "Mitwirkende: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken und Andre_601", "translation-country": "Sprache: Deutsch (de_DE)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cKonnte keinen Block zum erstellen eines Shops finden. Stelle sicher dass du einen ansiehst.", "not-looking-at-shop": "&cKonnte keinen QuickShop finden. Du musst auf einen schauen.", "no-anythings-in-your-hand": "&cEs befindet sich nichts in deiner Hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eSammelt Daten und lädt diese anschließend auf Pastebin hoch, dies kann eine Weile dauern. &c&lAchtung&c: Die hochgeladenen Daten werden dort eine Woche lang gespeichert. Die Daten können möglicherweise Konfigurationseinstellungen oder andere sensitive Daten enthalten. Stelle sicher diese nur Teammitgliedern und Entwicklern zu Verfügung zu stellen, denen du &lvertraust.", "price-too-high": "&cDer Shoppreis ist zu hoch! Du kannst keinen Shop mit einem Preis über {0} erstellen.", "you-cant-create-shop-in-there": "&cDu bist nicht berechtigt an diesem Ort ein Shop zu erstellen.", - "unknown-player": "&cDieser Spieler existiert nicht. Bitte überprüfe, ob der Name korrekt geschrieben wurde.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aAlle Shopmitarbeiter erfolgreich von deinem Shop entfernt.", "shop-staff-added": "&a{0} erfolgreich als Shopmitarbeiter für deinen Shop hinzugefügt.", "shop-staff-deleted": "&a{0} erfolgreich von deinem Shop als Shopmitarbeiter entfernt.", diff --git a/crowdin/lang/el-GR/messages.json b/crowdin/lang/el-GR/messages.json index ab8edfa270..728d2daec2 100644 --- a/crowdin/lang/el-GR/messages.json +++ b/crowdin/lang/el-GR/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/en-US/messages.json b/crowdin/lang/en-US/messages.json index 71a59d97cc..5f91ebc78c 100644 --- a/crowdin/lang/en-US/messages.json +++ b/crowdin/lang/en-US/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not create a shop. Please look at a supported block type and try again.", "not-looking-at-shop": "&cCouldn't find a QuickShop. Make sure you look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading to Pastebin, this may take a while. &c&lWarning: &cThe data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create a shop with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permissions to create a shop at this location.", - "unknown-player": "&cThe target player doesn't exist. Please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member to your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member from your shop.", diff --git a/crowdin/lang/es-ES/messages.json b/crowdin/lang/es-ES/messages.json index f8ab33cca0..e29713ec4c 100644 --- a/crowdin/lang/es-ES/messages.json +++ b/crowdin/lang/es-ES/messages.json @@ -5,7 +5,7 @@ "translation-version": "&c&lVersión Soportada: &b&lReremake", "translation-contributors": "Contribuidores: Randall_Rut, Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken y Andre_601", "translation-country": "&c&lIdioma: &b&lEspañol (es_ES)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cNo se pudo encontrar un bloque para crear una tienda. Tienes que mirar uno.", "not-looking-at-shop": "&cNo se pudo encontrar ninguna tienda. Tienes que mirar hacia una.", "no-anythings-in-your-hand": "&cNo hay nada en tu mano.", @@ -34,11 +34,11 @@ "shop-purchase-cancelled": "&cCompra cancelada.", "shop-stock-too-low": "&cSólo queda {0} {1} en la tienda!", "you-cant-afford-to-buy": "&cCuesta {0} pero sólo tienes {1}", - "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", - "select-shop-type-or-cancel-selling-button": "&d[Selling]", + "select-shop-type-or-cancel": "&a¿Qué tipo de tienda desea utilizar? \n {0} {1} {2}", + "select-shop-type-or-cancel-selling-button": "&d[Vendiendo]", "select-shop-type-or-cancel-buying-button": "&b[Buying]", "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", - "not-a-valid-shop-type": "&cYou can only input Buy/Sell/Cancel, your input was {0}.", + "not-a-valid-shop-type": "&cSolo puede ingresar Comprar / Vender / Cancelar, su entrada fue {0}.", "negative-amount": "&cNo puedes comerciar con dinero negativo", "not-a-number": "&cSolo puedes introducir un número, tu entrada era {0}.", "exceeded-maximum": "&cEl valor excedió el valor máximo en Java.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eRecopilando datos y subiendo a Pastebin, esto puede llevar un tiempo. &c&lAviso:&c ¡Los datos serán públicos durante una semana! Esto puede revelar la configuración de tu servidor y otra información sensible. Asegúrate de enviarlo solamente a &lpersonal/desarrolladores de confianza.", "price-too-high": "&c¡El precio establecido es demasiado alto! No puedes crear una tienda con un precio superior a {0}.", "you-cant-create-shop-in-there": "&cNo tienes permiso para crear una tienda en este lugar.", - "unknown-player": "&cDicho jugador no existe, por favor revisa el nombre de usuario que escribiste.", + "unknown-player": "&cEl jugador objetivo no existe, comprueba el nombre de usuario que escribió.", "shop-staff-cleared": "&aTodo el personal de tu tienda ha sido eliminado con éxito.", "shop-staff-added": "&aAgregado a {0} como personal de tu tienda con éxito.", "shop-staff-deleted": "&aEliminado a {0} como personal de tu tienda con éxito.", @@ -247,7 +247,7 @@ "freeze-hover": "&eCambiar estado de congelación de la tienda.,", "toggledisplay": "&eMostrar Item: &b{0} &e[&d&lCambiar&e]", "toggledisplay-hover": "&eAlternar el estado del mostrar item de la tienda", - "staff": "&aStaff amount: &b{0} &e[&d&lModify&e]" + "staff": "&aCantidad de modificación: &b{0} &e[&d&lModify&e]" }, "tableformat": { "full_line": "+---------------------------------------------------+", diff --git a/crowdin/lang/fi-FI/messages.json b/crowdin/lang/fi-FI/messages.json index 532ed3f8cd..b1feab3ff9 100644 --- a/crowdin/lang/fi-FI/messages.json +++ b/crowdin/lang/fi-FI/messages.json @@ -5,7 +5,7 @@ "translation-version": "Tuettu versio: Reremake", "translation-contributors": "Avustajat: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Kielialue: Suomi (fi_FI)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cQuickShoppia ei löytynyt. Sinun täytyy katsoa yhtä.", "no-anythings-in-your-hand": "&cKädessäsi ei ole mitään.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eKerätään tietoja ja ladataan ne Pastebiniin, tässä saattaa mennä hetki. &c&lVaroitus:&c Tietoja pidetään julkisena vain yhden viikon! Se voi vuotaa palvelimesi asetuksia tai muuta arkoluontoista tietoa. Varmista, että lähetät sen vain &lluotettaville ylläpidon jäsenille ja kehittäjille.", "price-too-high": "&cKaupan hinta on liian korkea! Et voi luoda kauppaan, jonka hinta on korkeampi kuin {0}.", "you-cant-create-shop-in-there": "&cSinulla ei ole oikeutta luoda kauppaa tälle alueelle.", - "unknown-player": "&cKohde pelaajaa ei ole olemassa, tarkista käyttäjätunnus jonka kirjoitit.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aKauppasi henkilökunta poistettiin onnistuneesti.", "shop-staff-added": "&aOnnistuneesti lisätty {0} kauppasi henkilökuntaan.", "shop-staff-deleted": "&aOnnistuneesti poistettu {0} kauppasi henkilökunnasta.", diff --git a/crowdin/lang/fr-FR/messages.json b/crowdin/lang/fr-FR/messages.json index e3ccb33300..2a0f717464 100644 --- a/crowdin/lang/fr-FR/messages.json +++ b/crowdin/lang/fr-FR/messages.json @@ -1,19 +1,19 @@ { - "_comment": "Bonjour traducteur! Si vous éditez ceci à partir de Github ou à partir du code source, vous devriez aller sur https://crowdin.com/project/quickshop-reremake", + "_comment": "Bonjour traducteur ! Si vous éditez ceci à partir de Github ou à partir du code source, vous devriez aller sur https://crowdin.com/project/quickshop-reremake", "file-test": "Ceci est un fichier texte de test. Nous l'utilisons pour tester si les messages sont cassés. Vous pouvez le remplir avec n'importe quel \"easter eggs\" que vous aimez ici :)", "translation-author": "&cYou only have room for {0} more", "translation-version": "Version suportée: Reremake", "translation-contributors": "Contributeurs : Timtower, Netherfoam, KaiNoMood, Mgazul, JackThePicken, Andre_601, brunopaiva15, HiiRaZ, WAXIE", - "translation-country": "Langue: Français (fr_FR)", - "language-version": "65", + "translation-country": "Langue : Français (fr_FR)", + "language-version": "66", "not-looking-at-valid-shop-block": "&cImpossible de trouver un bloc pour créer une boutique. Vous devez en regarder un.", "not-looking-at-shop": "&cImpossible de trouver un QuickShop. Vous devez en regarder un.", "no-anythings-in-your-hand": "&cVous n'avez aucun objet dans votre main.", "no-permission": "&cVous n'avez pas la permission de faire ceci.", "integrations-check-failed-create": "&cIntégration {0} à refusé la création de la boutique", "integrations-check-failed-trade": "&cIntégration {0} à refusé la création de la boutique", - "3rd-plugin-build-check-failed": "&c3rd party plugin &l{0}&r&c denied the protection checks (build protection), did you have build permission of this 3rd plugin? If is not expected, please contact admin.", - "3rd-plugin-build-check-failed-admin": "&7(AdminOnly) &d{0} &8denied the protection checks (build protection), If this not excepted, try add &d{1} &7to listener blacklist. &7Configure Guide: https://github.com/PotatoCraft-Studio/QuickShop-Reremake/wiki/Use-protection-listener-filter", + "3rd-plugin-build-check-failed": "&cPlug-in tiers &l{0}&r&c a refusé les vérifications de protection (protection contre la compilation), aviez-vous l'autorisation de compiler ce troisième plugin ? Si ce n'est pas prévu, veuillez contacter un administrateur.", + "3rd-plugin-build-check-failed-admin": "&7(AdminOnly) &d{0} &8a refusé les contrôles de protection (build protection). Si cela n'est pas exclu, essayez d'ajouter &d{1} &7à la liste noire. &7Guide de configuration : https://github.com/PotatoCraft-Studio/QuickShop-Reremake/wiki/Use-protection-listener-filter", "no-creative-break": "&cVous ne pouvez pas détruire les boutiques des autres joueurs en mode créatif, basculez en mode survie ou essayez d'utiliser le super-outil {0} à la place.", "trading-in-creative-mode-is-disabled": "&cVous ne pouvez pas utiliser une boutique en mode créatif.", "supertool-is-disabled": "&cLe super-outil est désactivé, impossible de détruire une boutique avec.", @@ -34,11 +34,11 @@ "shop-purchase-cancelled": "&cAchat de la boutique annulé.", "shop-stock-too-low": "&cIl ne reste que {0} {1} dans cette boutique!", "you-cant-afford-to-buy": "&cCette transaction coûte {0}, mais vous ne disposez que de {1}", - "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", - "select-shop-type-or-cancel-selling-button": "&d[Selling]", - "select-shop-type-or-cancel-buying-button": "&b[Buying]", - "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", - "not-a-valid-shop-type": "&cYou can only input Buy/Sell/Cancel, your input was {0}.", + "select-shop-type-or-cancel": "&aQuel type de boutique souhaitez-vous utiliser ?\n {0} {1} {2}", + "select-shop-type-or-cancel-selling-button": "&d[Selling] Vente", + "select-shop-type-or-cancel-buying-button": "&b[Buying] Achat", + "select-shop-type-or-cancel-cancel-button": "&c[Cancel] Annuler", + "not-a-valid-shop-type": "&cVous ne pouvez saisir que Acheter/Vendre/Annuler, votre saisie était {0}.\nDemande De Contexte.", "negative-amount": "&cVous ne pouvez pas échanger une quantité négative", "not-a-number": "&cVous ne pouvez saisir qu'un nombre, votre entrée était {0}.", "exceeded-maximum": "&cLa valeur maximal à ne pas dépasser en Java.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eAssemblage de données et upload vers PasteBin, cela peut prendre un moment. &c&lAttention :&c Les données sont gardées publiques pendant UNE semaine, cela peut faire fuiter la config de votre serveur, assurez vous de la partager à des gens de confiances.", "price-too-high": "&cLe prix est trop haut! Tu ne peux pas mettre un prix supérieur à {0}.", "you-cant-create-shop-in-there": "&cTu n'as pas la permission de créer une boutique à cet emplacement!", - "unknown-player": "&cLe joueur cible n'existe pas, merci de vérifier le pseudo que tu as entré.", + "unknown-player": "&cLe joueur ciblé n'existe pas ou n'est pas en ligne, veuillez vérifier le nom d'utilisateur que vous avez saisi.", "shop-staff-cleared": "&aTous les gérants de ta boutique ont été supprimés avec succès.", "shop-staff-added": "&a {0} a été ajouté avec succès comme membre du personnel pour votre boutique.", "shop-staff-deleted": "&a {0} a été ajouté avec succès comme membre du personnel pour votre boutique.", @@ -134,7 +134,7 @@ "counting": "&aLa boutique compte désormais toujours le conteneur, même illimité", "not-counting": "&aLe shop est maintenant respecté si le shop est illimitée" }, - "transfer-success": "&aTransferred &e{0} &a selling shop(s) to &e{1}", + "transfer-success": "&aTransfert &e{0} &a boutique(s) de vente à &e{1}", "transfer-success-other": "&aTransfert du shop &e{0} &aà &e{1}", "some-shops-removed": "&e{0} &ashop(s) supprimé(s)", "no-owner-given": "&cAucun propriétaire indiqué", @@ -184,7 +184,7 @@ "supercreate": "&eCréer une boutique en contournant tous les contrôles de protection", "language": "Modifier la langue actuelle", "removeall": "&eSupprimer toutes les boutiques d'un joueur spécifié", - "transfer": "&eTransfer someone's ALL selling shops to other", + "transfer": "&e Transférez TOUS les magasins de vente de quelqu'un à une autre personne", "removeworld": "&eSupprime TOUTES les boutiques dans un monde spécifié", "currency": "&eDéfinir ou supprimer les paramètres de devise de la boutique", "ban": "&eBanni un joueur de la boutique", @@ -247,7 +247,7 @@ "freeze-hover": "&eActiver/désactiver le statut de blocage de la boutique.", "toggledisplay": "&eVisibilité des items: &b{0} &e[&d&lActiver/Désactiver&r&e]", "toggledisplay-hover": "&eActiver/désactiver l'affichage de l'item de la boutique", - "staff": "&aStaff amount: &b{0} &e[&d&lModify&e]" + "staff": "&aMontant Administrateur : &b{0} &e[&d&lModifier&e]" }, "tableformat": { "full_line": "+---------------------------------------------------+", diff --git a/crowdin/lang/he-IL/messages.json b/crowdin/lang/he-IL/messages.json index e616c8bc98..8fe0ffbb29 100644 --- a/crowdin/lang/he-IL/messages.json +++ b/crowdin/lang/he-IL/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/hi-IN/messages.json b/crowdin/lang/hi-IN/messages.json index ab8edfa270..728d2daec2 100644 --- a/crowdin/lang/hi-IN/messages.json +++ b/crowdin/lang/hi-IN/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/hu-HU/messages.json b/crowdin/lang/hu-HU/messages.json index aad3ce2503..5e60799778 100644 --- a/crowdin/lang/hu-HU/messages.json +++ b/crowdin/lang/hu-HU/messages.json @@ -5,7 +5,7 @@ "translation-version": "Támogatott Verzió: Reremake", "translation-contributors": "Közreműködők: Timtower, Netherfoam, KaiNoMood and Mgazul", "translation-country": "Nyelv Zóna: Magyar (hu_HU)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cNem tudtuk létrehozni a boltot, mert nem találtunk blokkot. Nézz egy blokkra.", "not-looking-at-shop": "&cEz nem egy bolt amire nézel.", "no-anythings-in-your-hand": "&cNincs semmi a kezedben.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eAdatok összegyűjtése és feltöltése a Pastebinbe. Ez el fog tartani egy kis ideig. &c&lFigyelem&c, Az adaz csak egy hétig lesz publikus! Kiszivároghat a szerver konfiguréciója és egyébb dolgok is! Győzödjön meg róla, hogy csak azoknak az embereknek küldi el akikben megbízik!", "price-too-high": "&c A bolt ára túl magas! Nem tudsz olyan boltot létrehozni, amelynek magasabb az ára, mint {0}.", "you-cant-create-shop-in-there": "&cNincsen jogosultságod boltot készíteni ezen a helyen!", - "unknown-player": "&cNincs ilyen játékos a szerveren! Győzödj meg róla, hogy jól írtad be a játékos nevet!", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSikeresen eltávolítottál mindent a boltodból!", "shop-staff-added": "&aSikeresen hozzá adtad a {0}t a boltodhoz!", "shop-staff-deleted": "&aSikeresen eltávolítottad a {0}t a boltodból!", diff --git a/crowdin/lang/it-IT/messages.json b/crowdin/lang/it-IT/messages.json index 4e681bb6dd..97b787f5c0 100644 --- a/crowdin/lang/it-IT/messages.json +++ b/crowdin/lang/it-IT/messages.json @@ -5,7 +5,7 @@ "translation-version": "Versione di Supporto: Reremake", "translation-contributors": "Collaboratori: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601, sandtechnology, MiniMoro", "translation-country": "Lingua zona: Italian (it_IT)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "Impossibile trovare un blocco per la creazione del negozio. Devi guardarne uno.", "not-looking-at-shop": "&cImpossibile trovare un negozio. È necessario guardarne uno.", "no-anythings-in-your-hand": "&cNon hai nulla in mano.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eRaccogliere i dati e caricarli su Pastebin, potrebbe richiedere un po' di tempo. &c&lWarning:&c I dati sono tenuti pubblici per una settimana! Potrebbe mostrare la configurazione del server e altre informazioni sensibili. Assicurati di inviarlo solo allo &lstaff/sviluppatori fidati.", "price-too-high": "&cIl prezzo del negozio è troppo alto! Non puoi crearne uno con un prezzo superiore a {0}.", "you-cant-create-shop-in-there": "&cNon hai il permesso di creare un negozio in questa posizione.", - "unknown-player": "&cIl giocatore di destinazione non esiste, per favore controlla il nome utente digitato.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aRimossi con successo tutti i membri dello staff dal tuo negozio.", "shop-staff-added": "&aAggiunto con successo {0} come membro dello staff per il tuo negozio.", "shop-staff-deleted": "&aRimosso {0} come membro dello staff per il tuo negozio.", diff --git a/crowdin/lang/ja-JP/messages.json b/crowdin/lang/ja-JP/messages.json index 7872f7df10..43e6979c43 100644 --- a/crowdin/lang/ja-JP/messages.json +++ b/crowdin/lang/ja-JP/messages.json @@ -5,7 +5,7 @@ "translation-version": "&c&lサポートバージョン: &b&lReremake", "translation-contributors": "貢献者: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken, Andre_601 and Namiu", "translation-country": "&c&l言語圏: &b&l日本語 (ja_JP)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cショップを作成するためのブロックが見つかりませんでした。確認する必要があります。", "not-looking-at-shop": "&cQuickShopが見つかりませんでした。確認する必要があります。", "no-anythings-in-your-hand": "&cあなたは手に何も持っていません。", @@ -79,7 +79,7 @@ "warn-to-paste": "&eデータを収集してPastebinにアップロードするには、しばらく時間がかかる場合があります。&c&l警告:&c データは1週間公開されます。サーバーの設定やその他の機密情報が漏洩する可能性があります。&l信頼できるスタッフや開発者にのみ送信するようにしてください。", "price-too-high": "&cショップの価格が高すぎます! {0} より高い価格のショップは作成できません。", "you-cant-create-shop-in-there": "&cこの場所にショップを作成する権限がありません。", - "unknown-player": "&c指定したプレーヤーが存在しません。入力したユーザー名を確認してください。", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aショップのスタッフを全員削除しました。", "shop-staff-added": "&aあなたのショップスタッフに {0} を追加しました。", "shop-staff-deleted": "&aあなたのショップスタッフの {0} を削除しました。", diff --git a/crowdin/lang/ko-KR/messages.json b/crowdin/lang/ko-KR/messages.json index 7a747822bd..d995b0058b 100644 --- a/crowdin/lang/ko-KR/messages.json +++ b/crowdin/lang/ko-KR/messages.json @@ -5,7 +5,7 @@ "translation-version": "지원 버전: Reremake", "translation-contributors": "기여자: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "언어 지역: 한국어 (ko_KR)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&c상점을 만들수 잇는 블럭을 찾을수 없습니다. 상점으로 만들 블럭을 봐야합니다.", "not-looking-at-shop": "&c상점을 찾을수 없습니다. 상점을 보고있어야만 합니다.", "no-anythings-in-your-hand": "&c당신의 손에 아무것도 없습니다.", @@ -79,7 +79,7 @@ "warn-to-paste": "&e데이터를 수집하고 Pastebin에 업로드하는 데 시간이 걸릴 수 있습니다. &c&l주의!&c. 데이터는 일주일 동안 공개되며 서버 구성이 유출될 수 있으므로 신뢰할 수 있는 운영자/관리자 에게만 전송해야 합니다.", "price-too-high": "&c상점의 가격이 너무 높습니다! 당신은 {0} 원 이상의 상점을 만들수 없습니다!", "you-cant-create-shop-in-there": "&c당신은 이 위치에 상점을 설치할 수 있는 권한이 없습니다.", - "unknown-player": "&c대상 플레이어가 없습니다. 유저이름을 확인해주세요.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&a성공적으로 당신 상점의 모든 관리자를 해고하였습니다.", "shop-staff-added": "&a{0} 님을(를) 상점 관리자로 추가했습니다.", "shop-staff-deleted": "&a{0} 님을(를) 상점 관리자에서 삭제했습니다.", diff --git a/crowdin/lang/lt-LT/messages.json b/crowdin/lang/lt-LT/messages.json index ab8edfa270..728d2daec2 100644 --- a/crowdin/lang/lt-LT/messages.json +++ b/crowdin/lang/lt-LT/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/nl-NL/messages.json b/crowdin/lang/nl-NL/messages.json index e9a8e10496..9e356f4ad0 100644 --- a/crowdin/lang/nl-NL/messages.json +++ b/crowdin/lang/nl-NL/messages.json @@ -5,7 +5,7 @@ "translation-version": "ondersteunende versie: Reremake", "translation-contributors": "Medewerkers", "translation-country": "Taal Zone: Engels (nl_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cKan geen blok vinden om een winkel mee te maken. Je moet naar één kijken om een winkel te maken.", "not-looking-at-shop": "&cGeen QuickShop gevonden, je moet naar een QuickShop kijken.", "no-anythings-in-your-hand": "&cJe hebt niks in je hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&Het verzamelen van gegevens en het uploaden naar de Pastebin, dit kan enige tijd duren. &c&lWaarschuwing:&c De gegevens worden één week openbaar gemaakt! Het kan uw serverconfiguratie en andere gevoelige informatie lekken. Zorg ervoor dat je het alleen doorstuurt naar &vertrouwde medewerkers/ontwikkelaars.", "price-too-high": "&cDe prijs van de winkel is te hoog! U kunt er niet een maken met een prijs hoger dan {0}.", "you-cant-create-shop-in-there": "&cJe hebt geen toestemming om een winkel te maken op deze locatie.", - "unknown-player": "&cTarget player bestaat niet, controleer de gebruikersnaam die u heeft ingevoerd.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccesvol alle medewerkers verwijderd uit uw winkel.", "shop-staff-added": "&aSuccesvol toegevoegd {0} als staflid in uw winkel.", "shop-staff-deleted": "&aSuccesvol {0} verwijderd als staflid van uw winkel.", diff --git a/crowdin/lang/no-NO/messages.json b/crowdin/lang/no-NO/messages.json index 10b6ee0d2b..0b0e867770 100644 --- a/crowdin/lang/no-NO/messages.json +++ b/crowdin/lang/no-NO/messages.json @@ -5,7 +5,7 @@ "translation-version": "Støttet versjon: Reremake", "translation-contributors": "Bidragsytere: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Språksone: Norsk (no_NO)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cKunne ikke finne en blokk for å opprette butikk. Du må se på en gyldig blokk.", "not-looking-at-shop": "&cKunne ikke finne en QuickShop. Du må se på en butikk.", "no-anythings-in-your-hand": "&cDet er ingenting i hånden din.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eSamler inn data for å laste den opp til Pastebin, dette kan ta en stund. &c&lAdvarsel:&c Dataene oppbevares offentlig i en uke! Det kan lekke serverkonfigurasjonen og annen sensitiv informasjon. Sørg for at du bare sender den til &lstab/utviklere du stoler på.", "price-too-high": "&cButikkprisen er for høy! Du kan ikke sette en pris høyere enn {0}.", "you-cant-create-shop-in-there": "&cDu har ikke tillatelse til å opprette en butikk på denne plasseringen.", - "unknown-player": "&cSpilleren eksisterer ikke, sjekk om du har skrevet riktig spillernavn.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aAlle ansatte ble fjernet fra din butikk.", "shop-staff-added": "&cDu ansatte {0} som medarbeider i din butikk.", "shop-staff-deleted": "&aSpiller {0} ble fjernet som medarbeider i din butikk.", diff --git a/crowdin/lang/pl-PL/messages.json b/crowdin/lang/pl-PL/messages.json index 2400eaa6b5..9395ebefdd 100644 --- a/crowdin/lang/pl-PL/messages.json +++ b/crowdin/lang/pl-PL/messages.json @@ -5,7 +5,7 @@ "translation-version": "Wspierana wersja: Reremake", "translation-contributors": "Współtwórcy: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken i Andre_601", "translation-country": "Język: Polski (pl_PL)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cNie można znaleźć bloku do tworzenia sklepu. Musisz patrzeć się na jeden z nich.", "not-looking-at-shop": "&cNie można znaleźć QuickShop. Musisz na niego patrzeć.", "no-anythings-in-your-hand": "&cW twojej ręce nic nie ma.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eGromadzenie danych i przesyłanie ich do Pastebin może trochę potrwać. &c&lOstrzeżenie:&c dane są upublicznione przez tydzień! Może to spowodować wyciek z konfiguracji serwera i innych poufnych informacji. Upewnij się, że wysyłasz je tylko do &lzaufanego personelu/programistów.", "price-too-high": "&cZbyt wysoka cena sklepu! Nie można utworzyć takiego, którego cena jest wyższa niż {0}.", "you-cant-create-shop-in-there": "&cNie masz uprawnień do utworzenia sklepu w tej lokalizacji.", - "unknown-player": "&cDocelowy gracz nie istnieje, sprawdź wpisaną nazwę użytkownika.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aPomyślnie usunięto wszystkich graczy z twojego sklepu.", "shop-staff-added": "&aPomyślnie dodano {0} jako członka personelu twojego sklepu.", "shop-staff-deleted": "&aPomyślnie usunięto {0} jako członka personelu twojego sklepu.", diff --git a/crowdin/lang/pt-BR/messages.json b/crowdin/lang/pt-BR/messages.json index 2b4e85135c..d0f0a52d17 100644 --- a/crowdin/lang/pt-BR/messages.json +++ b/crowdin/lang/pt-BR/messages.json @@ -5,7 +5,7 @@ "translation-version": "Versão de suporte: Remake", "translation-contributors": "Contribuidores: Torre de Timor, Netherfoam, KaiNoMood, Mgazul, JackTheChicken e Andre_601", "translation-country": "Zona do idioma: Português Brasileiro (pt_BR)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cNão conseguimos achar um bloco para criar a loja. Você precisa olhar para um.", "not-looking-at-shop": "Não conseguimos encontrar uma QuickShop. Você precisa estar olhando para uma.", "no-anythings-in-your-hand": "&cNão há nada na sua mão.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eColetando dados e enviando-os para Pastebin, isso pode demorar um pouco. &c&lCuidado: &cOs dados são mantidos públicos por uma semana! Pode vazar a configuração do servidor e outras informações confidenciais. Envie-o apenas para equipe/desenvolvedores confiáveis.", "price-too-high": "&cO preço da loja é muito alto! Você não pode criar uma que tenha o preço superior a {0}.", "you-cant-create-shop-in-there": "&cVocê não tem permissão para criar uma loja neste local.", - "unknown-player": "&cEsse jogador não existe, verifique o nick que você digitou.", + "unknown-player": "&cO jogador alvo não existe ou não está online, por favor, verifique o nome de usuário que você digitou.", "shop-staff-cleared": "&aTodos os membros da equipe de sua loja foram removidos.", "shop-staff-added": "&aAdicionado com sucesso {0} como membro da equipe da sua loja.", "shop-staff-deleted": "&aRemovido com sucesso {0} como membro da equipe da sua loja.", diff --git a/crowdin/lang/pt-PT/messages.json b/crowdin/lang/pt-PT/messages.json index 9985ea1578..3e5f2860c6 100644 --- a/crowdin/lang/pt-PT/messages.json +++ b/crowdin/lang/pt-PT/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&Não tens nada na mão.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/ro-RO/messages.json b/crowdin/lang/ro-RO/messages.json index 6adceafb61..8c8a7aecdf 100644 --- a/crowdin/lang/ro-RO/messages.json +++ b/crowdin/lang/ro-RO/messages.json @@ -5,7 +5,7 @@ "translation-version": "Versiune suport: Reproducere", "translation-contributors": "Contribuitori: Turnul, Netherfoam, KaiNoMood, Mgazul, JackTheChicken și Andre_601", "translation-country": "Zona de Limbă: Engleză (ro_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cNu am putut gasi un magazin. Trebuie sa te uiti la unul.", "no-anythings-in-your-hand": "&cNu este nimic in mana.", @@ -35,7 +35,7 @@ "shop-stock-too-low": "&cMagazinul mai are {0} {1}!", "you-cant-afford-to-buy": "&cCosta {0}, dar ai doar {1}", "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", - "select-shop-type-or-cancel-selling-button": "&d[Selling]", + "select-shop-type-or-cancel-selling-button": "&d[Vanzare]", "select-shop-type-or-cancel-buying-button": "&b[Buying]", "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", "not-a-valid-shop-type": "&cYou can only input Buy/Sell/Cancel, your input was {0}.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/ru-RU/messages.json b/crowdin/lang/ru-RU/messages.json index 20e14b56c5..4d155b45fa 100644 --- a/crowdin/lang/ru-RU/messages.json +++ b/crowdin/lang/ru-RU/messages.json @@ -5,7 +5,7 @@ "translation-version": "Поддерживаемая версия: Reremake", "translation-contributors": "Участники: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken и Andre_601", "translation-country": "Языковой регион: Русский (ru_RU)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cНе удалось найти блок для создания магазина. Вы должны смотреть на него.", "not-looking-at-shop": "&cНе удалось найти магазин. Вы должны смотреть на него.", "no-anythings-in-your-hand": "&cУ вас нет ничего в руках.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eСбор данных и загрузка их в Pastebin, это может занять некоторое время. &c&lПредупреждение:&c Данные хранятся в течение одной недели! Это может привести к утечке конфигурации вашего сервера и другой конфиденциальной информации. Убедитесь, что вы отправляете его только доверенным персоналу/разработчикам.", "price-too-high": "&cЦена слишком высокая! Вы не можете установить ее выше {0}.", "you-cant-create-shop-in-there": "&cУ вас нет прав на создание магазина в данном месте.", - "unknown-player": "&cТакой игрок не существует, пожалуйста, проверьте имя, которое вы ввели.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aВсе сотрудники успешно удалены из вашего магазина.", "shop-staff-added": "&aУспешно добавлен {0} в качестве сотрудника вашего магазина.", "shop-staff-deleted": "&aСотрудник {0} успешно удален из вашего магазина.", diff --git a/crowdin/lang/sr-SP/messages.json b/crowdin/lang/sr-SP/messages.json index ab8edfa270..728d2daec2 100644 --- a/crowdin/lang/sr-SP/messages.json +++ b/crowdin/lang/sr-SP/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/sv-SE/messages.json b/crowdin/lang/sv-SE/messages.json index 239e9d5de3..99d4e691a1 100644 --- a/crowdin/lang/sv-SE/messages.json +++ b/crowdin/lang/sv-SE/messages.json @@ -5,7 +5,7 @@ "translation-version": "Supportversion: Reremake", "translation-contributors": "Medhjälpare: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken och Andre_601", "translation-country": "Språkområde: Svenska (sv_SE)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cKunde inte hitta ett block för att skapa butik. Du måste titta på ett.", "not-looking-at-shop": "&cKunde inte hitta en QuickShop. Du måste titta på en.", "no-anythings-in-your-hand": "&cDet finns inget i din hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eSamlar in data och laddar upp det till Pastebin, det kan ta ett tag. &c&lVarning:&c Datan hålls offentlig i en vecka! Det kan läcka din serverkonfiguration och annan känslig information. Se till att du bara skickar den till &lbetrodd personal/utvecklas.", "price-too-high": "&cButikspriset är för högt! Du kan inte skapa ett med ett pris högre än {0}.", "you-cant-create-shop-in-there": "&cDu har inte behörighet att skapa en butik på den här platsen.", - "unknown-player": "&cAngiven spelare finns inte, kontrollera användarnamnet du angav.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aLyckades ta bort all personal från din butik.", "shop-staff-added": "&aFramgångsrikt lagt till {0} som personal för din butik.", "shop-staff-deleted": "&aFramgångsrikt tagit bort {0} som personal för din butik.", diff --git a/crowdin/lang/th-TH/messages.json b/crowdin/lang/th-TH/messages.json index beeebf5fea..c92ffdef06 100644 --- a/crowdin/lang/th-TH/messages.json +++ b/crowdin/lang/th-TH/messages.json @@ -5,7 +5,7 @@ "translation-version": "เวอร์ชั่นที่รองรับ: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "โซนภาษา: ไทย (th_TH)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "ไม่พบบล็อกสำหรับสร้างร้านค้า คุณต้องมองดูที่ป้ายหีบ", "not-looking-at-shop": "ไม่พบหีบสำหรับสร้างร้านค้า คุณต้องมองดูที่ป้ายหีบ", "no-anythings-in-your-hand": "&cไม่มีอะไรอยู่ในมือของคุณ", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/tr-TR/messages.json b/crowdin/lang/tr-TR/messages.json index c52bf5089b..0055260a22 100644 --- a/crowdin/lang/tr-TR/messages.json +++ b/crowdin/lang/tr-TR/messages.json @@ -5,8 +5,8 @@ "translation-version": "Destek Versiyonu: Reremake", "translation-contributors": "Katkıda Bulunanlar: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken Andre_601 and ZOYTRK#4529", "translation-country": "Dil Bölgesi: Türkçe (tr_TR)", - "language-version": "65", - "not-looking-at-valid-shop-block": "&cHiç Mağaza bulunamadı. Birine bakman lazım.", + "language-version": "66", + "not-looking-at-valid-shop-block": "&cBaktığın blokta bir mağaza mevcut değil.", "not-looking-at-shop": "&sHiç Mağaza bulunamadı. Birine bakman lazım.", "no-anythings-in-your-hand": "&cElinde hiçbir şey yok.", "no-permission": "&cBunu yapmaya iznin yok.", @@ -34,10 +34,10 @@ "shop-purchase-cancelled": "&cMarket alımı iptal edildi.", "shop-stock-too-low": "&cMarkette sadece {0} tane {1} kalmış!", "you-cant-afford-to-buy": "&cBu {0} ediyor, ama sende sadece {1} var", - "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", - "select-shop-type-or-cancel-selling-button": "&d[Selling]", - "select-shop-type-or-cancel-buying-button": "&b[Buying]", - "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", + "select-shop-type-or-cancel": "&aHangi mağaza türünü kullanmak istiyorsunuz? \n {0} {1} {2}", + "select-shop-type-or-cancel-selling-button": "[Satıyor]", + "select-shop-type-or-cancel-buying-button": "[Alıyor]", + "select-shop-type-or-cancel-cancel-button": "[İptal]", "not-a-valid-shop-type": "&cYou can only input Buy/Sell/Cancel, your input was {0}.", "negative-amount": "&cNegatif miktarlarda işlem yapamazsın", "not-a-number": "&cGirdi sadece sayı olabilir, senin girdin {0} idi.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eVeriler toplanıyor ve Pastebin'e yükleniyor, bu biraz zaman alabilir. &c&lUyarı&c, Veriler bir hafta boyunca herkese açık tutulur, sunucu konfigürasyonunuzu ve diğer hassas bilgilerinizi sızdırabilir, sadece &lgüvendiğiniz personele/geliştiriciye &c göderdiğinizden emin olun.", "price-too-high": "&cMarket fiyatı çok yüksek! {0} fiyatından yüksek bir tane oluşturamazsınız.", "you-cant-create-shop-in-there": "&cBurada bir market oluşturma izniniz yok.", - "unknown-player": "&cHedef oyuncu mevcut değil, lütfen yazdığınız kullanıcı adını kontrol ediniz.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aBaşarıyla marketinizin bütün personelleri kadırıldı.", "shop-staff-added": "&a{0} başarıyla market personellerinize eklendi.", "shop-staff-deleted": "&a{0} başarıyla market personellerinizden kaldırıldı.", @@ -118,7 +118,7 @@ }, "bypassing-lock": "&cBir QuickShop kilidi atlanıyor!", "that-is-locked": "&cBu market kilitli.", - "how-many-buy": "&aSohbete kaç tane &bSatın almak&a istediğinizi yazın. &e{0}&a tane alabilirsiniz. Hepsini satın almak için &b{1}&a yazın.", + "how-many-buy": "&7Ne kadar &eSATIN ALMAK&a istediğini sohbete yaz. &e{0}&7 tane satın alabilirsiniz. Hepsini satın almak için &eall&7 yaz.", "how-many-sell": "&aSohbete kaç tane &bSATMAK&a istediğinizi yazın. &e{0}&a tane satabilirsiniz. Hepsini satmak için &b{1}&a yazın.", "not-allowed-to-create": "&cBurada bir market oluşturamazsın.", "blacklisted-item": "&cBu öğeyi satamazsın çünkü kara listede", @@ -219,7 +219,7 @@ "alwayscounting": "&aHer zaman sayıyor: {0} &e[&d&lDeğiştir&e]", "alwayscounting-hover": "Dükkan her zaman konteyner sayıyorsa geçiş yapmak için &etıklayın.", "setowner": "&aSahibi: &b{0} &e[&d&lDeğiştir&e]", - "infomation": "&aMarket Kontrol paneli:", + "infomation": "&bMarket Kontrol paneli:", "setowner-hover": "&eSahibi değiştirmek için tıkla.", "unlimited": "&aSınırsız: {0} &e[&d&lDeğiştir&e]", "unlimited-hover": "&eMağaza sınırsızsa geçiş yapmak için tıkla.", diff --git a/crowdin/lang/uk-UA/messages.json b/crowdin/lang/uk-UA/messages.json index ab8edfa270..6e7925b19c 100644 --- a/crowdin/lang/uk-UA/messages.json +++ b/crowdin/lang/uk-UA/messages.json @@ -1,17 +1,17 @@ { - "_comment": "Hi translator! If you editing this from Github or from code sources, you should go https://crowdin.com/project/quickshop-reremake", - "file-test": "This is a test textfile. We use it to test if the messages.json is broken. You can fill it with any easter eggs you like here :)", - "translation-author": "Translator: Ghost_chu, Andre_601", - "translation-version": "Support Version: Reremake", - "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", - "translation-country": "Language Zone: English (en_US)", - "language-version": "65", - "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", - "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", - "no-anythings-in-your-hand": "&cThere is nothing in your hand.", - "no-permission": "&cYou do not have permission to do that.", - "integrations-check-failed-create": "&cIntegration {0} denied the shop-creation", - "integrations-check-failed-trade": "&cIntegration {0} denied the Shop trading", + "_comment": "Привіт, перекладачу! Якщо ви редагуєте це з Github або з джерел коду, вам слід перейти за посиланням https://crowdin.com/project/quickshop-reremake", + "file-test": "Це тестовий текстовий файл. Ми використовуємо його, щоб перевірити, чи не зламано файл messages.json. Ви можете наповнити його пасхальними яйцями, які вам подобаються :)", + "translation-author": "Перекладач: random9", + "translation-version": "Версія Підтримки: Reremake", + "translation-contributors": "Учасники: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken та Andre_601", + "translation-country": "Мова: Українська(uk_UA)", + "language-version": "66", + "not-looking-at-valid-shop-block": "&cНе вдалося знайти блок для створення магазину. Слід на нього глянути.", + "not-looking-at-shop": "&cНе вдалося знайти QuickShop. Слід глянути на нього.", + "no-anythings-in-your-hand": "&cУ вашій руці нічого немає.", + "no-permission": "&cУ вас недостатньо повноважень, аби зробити це.", + "integrations-check-failed-create": "&cІнтеграція {0} відхилила спробу створення магазину", + "integrations-check-failed-trade": "&cІнтеграція {0} відхилила Магазинну торгівлю", "3rd-plugin-build-check-failed": "&c3rd party plugin &l{0}&r&c denied the protection checks (build protection), did you have build permission of this 3rd plugin? If is not expected, please contact admin.", "3rd-plugin-build-check-failed-admin": "&7(AdminOnly) &d{0} &8denied the protection checks (build protection), If this not excepted, try add &d{1} &7to listener blacklist. &7Configure Guide: https://github.com/PotatoCraft-Studio/QuickShop-Reremake/wiki/Use-protection-listener-filter", "no-creative-break": "&cYou cannot break other players shops in creative mode, switch to survival mode or try to use the supertool {0} instead.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/vi-VN/messages.json b/crowdin/lang/vi-VN/messages.json index 7efd9e647c..0a45f2fc24 100644 --- a/crowdin/lang/vi-VN/messages.json +++ b/crowdin/lang/vi-VN/messages.json @@ -5,7 +5,7 @@ "translation-version": "Phiên bản hỗ trợ: Reremake", "translation-contributors": "Người đóng góp: huyhhuy", "translation-country": "Vùng ngôn ngữ: Tiếng Việt (vi_VN)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cKhông thể tìm ra block để tạo Shop. Bạn cần phải nhìn vào block trước.", "not-looking-at-shop": "&cKhông thể tìm ra QuickShop. Bạn cần phải nhìn vào nó trước.", "no-anythings-in-your-hand": "&cChẳng có gì trong tay bạn cả.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eThu thập dữ liệu và tải nó lên Pastebin, quá trình này có thể mất một lúc. &c&lCảnh báo: &cDữ liệu được giữ công khai trong một tuần! Nó có thể làm rò rỉ cấu hình máy chủ của bạn và các thông tin nhạy cảm khác. Đảm bảo rằng bạn chỉ gửi nó cho & nhân viên/nhà phát triển.", "price-too-high": "&cGiá shop cao quá! Bạn không thể tạo một cái có giá cao hơn {0}.", "you-cant-create-shop-in-there": "&cBạn không được phép tạo cửa hàng tại vị trí này.", - "unknown-player": "&cNgười chơi không tồn tại, vui lòng kiểm tra lại tên người chơi bạn đã nhập.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aĐã xóa thành công tất cả nhân viên khỏi cửa hàng của bạn.", "shop-staff-added": "&aĐã thêm thành công {0} làm nhân viên cho cửa hàng của bạn.", "shop-staff-deleted": "&aĐã xóa thành công nhân viên {0} cửa hàng của bạn.", diff --git a/crowdin/lang/zh-CN/messages.json b/crowdin/lang/zh-CN/messages.json index cfa9cd4fef..a3b8bc5a33 100644 --- a/crowdin/lang/zh-CN/messages.json +++ b/crowdin/lang/zh-CN/messages.json @@ -5,7 +5,7 @@ "translation-version": "支持版本:Reremake", "translation-contributors": "开发贡献者:Timtower, Netherfoam, KaiNoMood JackTheChicken 和 Andre_601", "translation-country": "本地化语言:简体中文 (zh_CN)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&c无法找到创建商店的方块,您需要注视着一个商店方块", "not-looking-at-shop": "&c无法找到商店,您需要注视着你想要操作的商店。", "no-anythings-in-your-hand": "&c你的手里没有任何物品。", @@ -25,7 +25,7 @@ "price-too-cheap": "&c价格必须大于&e${0}", "no-price-change": "&c这不会导致价格变动!", "you-cant-afford-a-new-shop": "&c你需要 {0} 才能创建一个商店。", - "player-bought-from-your-store-tax": "&c{0} 从你的商店里购买了 {1} {2} &r&c,你因此赚得了 {3} ( 扣税 {4} )", + "player-bought-from-your-store-tax": "&c{0} 从你的商店里购买了 {1} {2} &r&c,你因此赚得了 {3} (扣税 {4} )", "you-cant-afford-to-change-price": "&c你需要 {0} 才能修改商店的价格。", "success-created-shop": "&c商店已创建", "success-removed-shop": "&a商店已删除!", @@ -34,11 +34,11 @@ "shop-purchase-cancelled": "&c您取消了交易操作。", "shop-stock-too-low": "&c这个商店只有 {0} 个 {1} 了。", "you-cant-afford-to-buy": "&c余额不足!购买该商店物品需要 {0},但是你只有 {1}。", - "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", - "select-shop-type-or-cancel-selling-button": "&d[Selling]", - "select-shop-type-or-cancel-buying-button": "&b[Buying]", - "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", - "not-a-valid-shop-type": "&cYou can only input Buy/Sell/Cancel, your input was {0}.", + "select-shop-type-or-cancel": "&a您想要使用哪种商店类型? \n {0} {1} {2}", + "select-shop-type-or-cancel-selling-button": "&d[出售]", + "select-shop-type-or-cancel-buying-button": "&b[收购]", + "select-shop-type-or-cancel-cancel-button": "&c[取消]", + "not-a-valid-shop-type": "&c您只能输入Buy/Sell/Cancel,但是您的输入是 {0}。", "negative-amount": "&c你输入的数字是负数。", "not-a-number": "&c您只能输入一个数字,但您的输入是 {0}。", "exceeded-maximum": "&c该值超过了Java 中的最大值。", @@ -79,10 +79,10 @@ "warn-to-paste": "&e收集并上传数据到Pastebin,这会花费点时间。&c&l警告&c,数据将会在一周内对外可见,可能会导致你泄露服务器的配置和其他敏感信息,确保只向&l你信任的人/开发者&c发送链接。", "price-too-high": "&c商品的价格太高了!你不能创建价格高于 {0} 的商店。", "you-cant-create-shop-in-there": "&c你没有在这个位置创建商店的权限。", - "unknown-player": "&c目标玩家不存在,请检查你输入的玩家名字。", + "unknown-player": "&c目标玩家不存在或不在线,请检查你输入的玩家名字。", "shop-staff-cleared": "&a成功删除了该商店的所有助手。", "shop-staff-added": "&a成功将 {0} 添加到你的商店助手列表中。", - "shop-staff-deleted": "&a成功移除 {0} 的商店助手权限", + "shop-staff-deleted": "&a成功移除了 {0} 的商店助手权限", "no-permission-build": "&c你不能在这里建立商店。", "success-change-owner-to-server": "&a成功设置商店所有者为 服务器", "flush-finished": "&a成功获取所有商店记录", @@ -134,7 +134,7 @@ "counting": "&a商店现在总会计算容器物品(即使是无限商店)", "not-counting": "&a商店现在会视情况计算容器物品(无限商店无视容器物品)" }, - "transfer-success": "&a已将&e {0} &a个商店转移到玩家&e {1}", + "transfer-success": "&a已将&e {0} &a个出售商店转移到玩家&e {1}", "transfer-success-other": "&a已将玩家&e {1} 的&a {0} 个商店转移到玩家&e {2}", "some-shops-removed": "&e{0} &a个商店已被移除", "no-owner-given": "&c未指定新的商店所有者", @@ -184,7 +184,7 @@ "supercreate": "&e越过所有区域保护检查创建商店", "language": "&e切换正在使用的语言", "removeall": "&e删除指定玩家的&b所有&r&e商店", - "transfer": "&e将某人的所有商店转移给其他人", + "transfer": "&e将某人的所有出售商店转移给其他人", "removeworld": "&e删除指定世界中的所有商店", "currency": "&e设置或移除该商店的货币类型设置", "ban": "&e封禁商店中的玩家", @@ -247,7 +247,7 @@ "freeze-hover": "&e切换商店冻结状态。", "toggledisplay": "&e悬浮物显示: &b{0} &e[&d&l切换&e]", "toggledisplay-hover": "&e切换商店是否显示悬浮物", - "staff": "&aStaff amount: &b{0} &e[&d&lModify&e]" + "staff": "&a助手数量: &b{0} &e[&d&l修改&e]" }, "tableformat": { "full_line": "+---------------------------------------------------+", diff --git a/crowdin/lang/zh-HK/messages.json b/crowdin/lang/zh-HK/messages.json index 38ab19d244..5610c9ddc1 100644 --- a/crowdin/lang/zh-HK/messages.json +++ b/crowdin/lang/zh-HK/messages.json @@ -5,7 +5,7 @@ "translation-version": "支援版本: Reremake", "translation-contributors": "貢獻者: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken 同埋 Andre_601", "translation-country": "語言區域: 中文(zh_HK)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&c找不到用來創建商店的箱子,你需正視著一個。", "not-looking-at-shop": "&c我搵唔到一個箱子商店, 唔該望住個箱, 如果唔係我辨認唔到", "no-anythings-in-your-hand": "&c 你隻手都冇嘢", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/crowdin/lang/zh-TW/messages.json b/crowdin/lang/zh-TW/messages.json index f248bddc28..6f87903f11 100644 --- a/crowdin/lang/zh-TW/messages.json +++ b/crowdin/lang/zh-TW/messages.json @@ -5,7 +5,7 @@ "translation-version": "支援版本:Reremake(重製版)", "translation-contributors": "貢獻人員:Timtower、Netherfoam、KaiNoMood、Mgazul、JackTheChicken 和 Andre_601", "translation-country": "語言:&b&l繁體中文 Chinese Traditional(zh_TW)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&c無法找到建立商店的方塊,你需要先注視著商店方塊。", "not-looking-at-shop": "&c無法找到儲物箱商店,你需要先注視著儲物箱。", "no-anythings-in-your-hand": "&c手上沒有任何東西。", @@ -24,38 +24,38 @@ "chest-was-removed": "&c儲物箱已被移除。", "price-too-cheap": "&c價格必須大於 &e${0}", "no-price-change": "&c這不會導致價格變動!", - "you-cant-afford-a-new-shop": "&c需要花費 {0} 元才能建立商店。", - "player-bought-from-your-store-tax": "&c{0} &r&c從你的商店購買了 {1} 個 {2},你總共賺了 {3} 元 ({4} 元的稅) 。", - "you-cant-afford-to-change-price": "&c你需要花費 {0} 元來修改商品價格。", + "you-cant-afford-a-new-shop": "&c需要花費 {0} 才能建立商店。", + "player-bought-from-your-store-tax": "&c{0} &r&c從你的商店購買了 {1} 個 {2},你總共賺了 {3} ({4} 的稅) 。", + "you-cant-afford-to-change-price": "&c你需要花費 {0} 來修改商品價格。", "success-created-shop": "&c已建立商店。", - "success-removed-shop": "&a已刪除商店。", + "success-removed-shop": "&a已移除商店。", "shops-arent-locked": "&c請注意,商店無法防盜!如果你想要防盜功能,請使用 LWC、Lockette 等插件鎖住商店。", "shop-creation-cancelled": "&c已取消建立商店。", "shop-purchase-cancelled": "&c已取消購買。", "shop-stock-too-low": "&c該商店只剩 {0} 個 {1}!", - "you-cant-afford-to-buy": "&c商品價格 {0} 元,但是你只有 {1} 元。", - "select-shop-type-or-cancel": "&aWhich shop type you want to use? \n {0} {1} {2}", - "select-shop-type-or-cancel-selling-button": "&d[Selling]", - "select-shop-type-or-cancel-buying-button": "&b[Buying]", - "select-shop-type-or-cancel-cancel-button": "&c[Cancel]", - "not-a-valid-shop-type": "&cYou can only input Buy/Sell/Cancel, your input was {0}.", + "you-cant-afford-to-buy": "&c商品價格 {0} ,但是你只有 {1}。", + "select-shop-type-or-cancel": "&a您想要使用哪種商店類型? \n {0} {1} {2}", + "select-shop-type-or-cancel-selling-button": "&d[出售]", + "select-shop-type-or-cancel-buying-button": "&b[收購]", + "select-shop-type-or-cancel-cancel-button": "&c[取消]", + "not-a-valid-shop-type": "&c您只能輸入 收購/出售/取消,但你輸入的是 {0}.", "negative-amount": "&c我的天啊,沒想到居然有人想要交易負數的數量。", "not-a-number": "&c輸入內容只能是數字,但你輸入了 {0}。", "exceeded-maximum": "&c該值超出了 Java 中的最大值。 ", "not-a-integer": "&c輸入一定是數字,但你輸入了 {0}。", "player-bought-from-your-store": "&c{0} &r&c從你的商店購買了 {1} {2},你總共賺了 {3}。", - "shop-out-of-stock": "&5你在 XYZ: {0} / {1} / {2} 出售 {3} 的商店已售罄一空!", + "shop-out-of-stock": "&5你在 {0}, {1}, {2} 出售 {3} 的商店已售罄一空!", "shop-has-no-space": "&c該商店只能再裝下 {0} 個 {1} 了。", "you-dont-have-that-many-items": "&c你的身上只有 {0} 個 {1}!", - "the-owner-cant-afford-to-buy-from-you": "&c該商品價格 {0} 元,但店主只剩 {1} 元了。", + "the-owner-cant-afford-to-buy-from-you": "&c該商品價格 {0},但店主只剩 {1} 了。", "player-sold-to-your-store": "&a{0} 在你的商店賣出了 {1} 個 {2}。", "shop-out-of-space": "&5你在 XYZ:{0} / {1} / {2} 的商店已滿了。", - "fee-charged-for-price-change": "&a你付了 &c{0}&a 元修改商店定價。", - "price-is-now": "&a現在你的商店定價是 &e{0} 元。", + "fee-charged-for-price-change": "&a你花費了 &c{0}&a 修改商店定價。", + "price-is-now": "&a現在你的商店定價是 &e{0}。", "thats-not-a-number": "&c無效的數字", "forbidden-vanilla-behavior": "&c該操作不符合原版行為,因此被禁止。", "no-price-given": "&c請輸入有效的價格。", - "average-price-nearby": "&a附近的平均價格:&e{0} 元。", + "average-price-nearby": "&a附近的平均價格:&e{0}", "shop-has-changed": "&c你嘗試交易的商店在點擊後已有變動!", "shop-not-exist": "&c商店不存在。", "nearby-shop-this-way": "&a商店距離你 {0} 個方塊。", @@ -70,32 +70,32 @@ "unknown-owner": "未知", "owner-bypass-check": "&e繞過所有檢查並交易成功!(因為你是商店擁有者!)", "reached-maximum-can-create": "&c你建立的商店數量已達到上限(你已建立 {0} 個,最多 {1} 個!)", - "restricted-prices": "&c{0} 元是無效的價格:最高 {1} 元,最低 {2} 元。", - "no-enough-money-to-keep-shops": "&c你的金錢不夠繳稅,所以你所有的商店已被刪除……", + "restricted-prices": "&c{0} 是無效的價格:最高 {1},最低 {2}。", + "no-enough-money-to-keep-shops": "&c你沒有足夠的金錢維持你的商店經營!所以你所有的商店已被移除……", "nothing-to-flush": "&a沒有關於商店的新訊息。", "break-shop-use-supertool": "&e你可以使用超級工具破壞商店。", "failed-to-put-sign": "&c你的商店周圍沒有足夠的空間放置商店的資訊告示牌。", "failed-to-paste": "&c無法將資料上傳至 Pastebin,請檢查你的連線後再重試。(請查看控制台以獲得詳細資訊)", "warn-to-paste": "&e正在收集資料並上傳到 Pastebin,這可能需要一點時間。&c&l警告:&c資料上傳後,該連結會公開一週!所以可能會洩漏伺服器中的設定或其他資料。請確保傳送該連結的人是 &l伺服器員工或開發者&c。", - "price-too-high": "&c商店價格太高了!請設定在 {0} 元以內。", + "price-too-high": "&c商店價格太高了!請設定在 {0} 以內。", "you-cant-create-shop-in-there": "&c你沒有在這個地方建立商店的權限。", - "unknown-player": "&c找不到相對應的玩家,請檢查你輸入的玩家名稱是否正確。", - "shop-staff-cleared": "&a成功從你的商店刪除所有員工。", - "shop-staff-added": "&a成功新增員工 {0} 到你的商店。", - "shop-staff-deleted": "&a成功從你的商店刪除員工 {0} 。", + "unknown-player": "&c目標玩家不存在或不在線,請檢查你所輸入的使用者名稱。", + "shop-staff-cleared": "&a成功地將所有員工從你的商店移除。", + "shop-staff-added": "&a成功地新增員工 {0} 到你的商店。", + "shop-staff-deleted": "&a成功地將員工 {0} 從你的商店移除。", "no-permission-build": "&c你沒有建立商店的權限。", - "success-change-owner-to-server": "&a成功轉交商店擁有者給伺服器。", - "flush-finished": "&a成功獲得所有的商店記錄。", + "success-change-owner-to-server": "&a成功地將商店店主轉交給伺服器。", + "flush-finished": "&a成功地清除所有最近的商店記錄。", "purchase-failed": "&c交易失敗:發生錯誤,請聯繫伺服器管理員。", "no-pending-action": "&c你沒有待處理的操作", - "permission-denied-3rd-party": "&c權限被拒絕:第三方插件 [{0}]。", + "permission-denied-3rd-party": "&c權限被第三方插件 [{0}] 拒絕。", "shops-removed-in-world": "&e世界 &b{1} &e總共有 &b{0} &e個商店被刪除。", "world-not-exists": "&c世界 &e{0}&c 不存在", "menu": { - "successful-purchase": "&a成功購買:", - "successfully-sold": "&a成功出售:", - "item-name-and-price": "&a共 &e{2} &a元的 &e{0} &a個 &e{1}", - "sell-tax": "&a你付了 &e{0} &a元的稅。", + "successful-purchase": "&a成功地購買:", + "successfully-sold": "&a成功地出售:", + "item-name-and-price": "&a共 &e{2} &a的 &e{0} &a個 &e{1}", + "sell-tax": "&a你付了 &e{0} &a的稅。", "sell-tax-self": "&a因為你是商店主人,所以不需要繳稅。", "enchants": "&5附魔", "stored-enchants": "&5附魔", @@ -107,12 +107,12 @@ "preview": "&b[物品預覽介面]", "space": "&a空間:&e{0}", "stock": "&a庫存 : &e{0} 個", - "price-per": "&a價格 : &e1 個 {0} {1} 元", - "price-per-stack": "&a價格 : &e{2} 個 {0} {1} 元", - "total-value-of-chest": "&a儲物箱中的物品價值:&e{0} 元", - "damage-percent-remaining": "&a耐久度 : &e剩餘 {0}%。", - "this-shop-is-buying": "&a此商店是 &d收購物品&a 的商店。", - "this-shop-is-selling": "&a此商店正在&b出售&a物品。", + "price-per": "&a每個 &e{0} &a價格&e {1}", + "price-per-stack": "&a每 &e{2} &a個 &e{0} &a組價格&e {1}", + "total-value-of-chest": "&a儲物箱中的物品價值:&e{0}", + "damage-percent-remaining": "&a剩餘 &e{0}% &a點耐久度。", + "this-shop-is-buying": "&a該商店正在 &d出售&a 物品。", + "this-shop-is-selling": "&a該商店正在 &b出售&a 物品。", "shop-stack": "&a每份物品的數量:&e{0}", "effects": "&a藥水效果" }, @@ -121,7 +121,7 @@ "how-many-buy": "&a在聊天室中輸入你想要「&b購買&a」的數量,你最多可以購買 &e{0} &a個。輸入「&b{1}&a」購買全部。", "how-many-sell": "&a在聊天室中輸入你想要「&d出售&a」的數量,你最多可以出售 &e{0} &a個。輸入「&b{1}&a」出售全部。", "not-allowed-to-create": "&c你無法在此建立商店。", - "blacklisted-item": "&c由於這是黑名單的物品,所以你不能賣。", + "blacklisted-item": "&c由於這是黑名單的物品,所以你不能賣", "how-much-to-trade-for": "&a請在聊天室中輸入你想買賣 &e{1} 個 {0} &a的價格。", "command": { "format": "&a/{0} {1} &e- {2}", @@ -136,14 +136,14 @@ }, "transfer-success": "&a轉讓 &e{0} &a 正在出售中的商店給 &e{1}", "transfer-success-other": "&a將&e {0} {1}&a的商店轉移到&e {2}", - "some-shops-removed": "&e{0} &a的商店已刪除", + "some-shops-removed": "&e{0} &a的商店已移除", "no-owner-given": "&c未指定新的擁有者", "new-owner": "&a新擁有者:&e{0}", "now-buying": "&a商店正在 &d收購 &e{0}", "now-selling": "&a商店現在 &b出售 &e{0}", "cleaning": "&a正在刪除沒有任何物品的商店……", "reloading": "&a配置檔案已經重新載入。&e某些更改可能需要重新啟動才能生效。 \n&7(注意:版本 4.0.9.10 後的重新載入發生了變化,我們現在只重新載入配置檔案而不是整個插件以確保伺服器不會崩潰。)", - "cleaned": "&a已刪除 &e{0} &a個商店。", + "cleaned": "&a已移除 &e{0} &a個商店。", "no-type-given": "&c用法:/qs find <物品>", "no-world-given": "&c請指定世界名稱", "bulk-size-not-set": "&c用法:/qs size <數量>", @@ -152,20 +152,20 @@ "no-trade-item": "&a請在主手持有要修改的交易商品", "trade-item-now": "&a現在開始交易 &e{0} 個 {1}", "no-amount-given": "&c沒有指定數量,請使用:&a/qs refill <數量>&c", - "now-debuging": "&a成功啟用開發者模式,正在重新載入 QuickShop 中……", - "now-nolonger-debuging": "&a成功停用開發者模式,正在重新載入 QuickShop 中……", + "now-debuging": "&a成功地啟用開發者模式,正在重新載入 QuickShop……", + "now-nolonger-debuging": "&a成功地停用開發者模式,正在重新載入 QuickShop……", "wrong-args": "&c無效的參數。請使用 &l/qs help &c查看指令列表。", "description": { "alwayscounting": "&e設定商店是否會持續計數容器物品(即使是無限商店)", "title": "&aQuickShop 說明", "unlimited": "&e設定商店為無限庫存", - "setowner": "&e設定新的商店擁有者。", - "owner": "&e設定新的商店擁有者。", + "setowner": "&e修改新的商店擁有者。", + "owner": "&e修改新的商店擁有者。", "buy": "&e修改成 &d收購 &e模式", "sell": "&e修改成 &d出售 &e模式", "price": "&e修改 收購/出售 的價格", - "clean": "&e刪除所有(已載入)沒有商品的商店", - "find": "&e搜尋附近指定物品類型的商店", + "clean": "&e移除所有(已載入)沒有商品的商店", + "find": "&e搜尋附近指定物品類型的商店。", "reload": "&e重新載入 QuickShop", "refill": "&e新增指定數量的商品到商店", "empty": "&e清空商店空間", @@ -175,7 +175,7 @@ "info": "&e顯示 QuickShop 統計資料", "paste": "&e自動將伺服器資料傳送到 Pastebin 上", "staff": "&e管理你的商店員工", - "remove": "&e刪除你注視的商店", + "remove": "&e移除你注視的商店", "amount": "&e設定物品數量(聊天室發生問題時很實用)", "about": "&e顯示關於 QuickShop 資訊", "help": "&e顯示 QuickShop 說明", @@ -183,9 +183,9 @@ "size": "&e修改每份物品的數量", "supercreate": "&e繞過所有保護檢查並建立商店", "language": "&e修改正在使用的語言", - "removeall": "&e刪除指定玩家的所有商店", + "removeall": "&e移除指定玩家的所有商店", "transfer": "&e將某人所有出售中的商店轉讓給其他人", - "removeworld": "&e刪除指定世界的商店", + "removeworld": "&e移除指定世界的商店", "currency": "&e設定或移除目前商店的貨幣設定", "ban": "&e解除封禁商店中的玩家", "unban": "&e解除封禁商店中的玩家", @@ -196,7 +196,7 @@ "purge": "&e在背景啟動商店清理任務" }, "disabled": "&c該指令已被停用:&e{0}", - "feature-not-enabled": "該功能沒有在配置檔案中啟用" + "feature-not-enabled": "該功能沒有在配置檔案中啟用。" }, "signs": { "selling": "出售 {0} 個", @@ -206,8 +206,8 @@ "stack-buying": "收購 {0}", "item-left": "", "item-right": "", - "price": "每個 {0} 元", - "stack-price": "{0} {1} 個 {2} 元", + "price": "每個 {0}", + "stack-price": "{0} {1} 個 {2}", "unlimited": "無限", "status-available": "&a", "status-unavailable": "&c", @@ -231,23 +231,23 @@ "price-hover": "&e點擊修改商品價格。", "refill": "&a補貨:重新填充商品 &e[&d&l確定&e]", "refill-hover": "&e點擊重新填充商品。", - "empty": "&a清空:刪除所有商品 &e[&d&l確定&e]", + "empty": "&a清空:移除所有商品 &e[&d&l確定&e]", "empty-hover": "&e點擊清除商店內庫存。", - "remove": "&c&l[刪除商店]", - "remove-hover": "&e點擊刪除商店。", + "remove": "&c&l[移除商店]", + "remove-hover": "&e點擊移除該商店。", "stack": "&a每份數量:&b{0} &e[&d&l修改&e]", - "stack-hover": "&e點擊設置每份的物品數量。設定為 1 以恢復為普通單物品商店。", + "stack-hover": "&e點擊設定每份的物品數量。設定為 1 以恢復為普通單物品商店。", "item": "&a商店物品:{0} &e[&d&l修改&e]", "item-hover": "&e點擊修改商店物品", "currency": "&a目前:&b{0} &e[&d&l設定&e]", "currency-hover": "&e點擊設定或移除目前正在使用的商店貨幣", "lock": "&e商店鎖:&b{0} &e[&d&l切換&e]", - "lock-hover": "&e啟用或停用商店鎖保護。", + "lock-hover": "&e啟用/停用商店鎖保護。", "freeze": "&e凍結模式:&b{0} &e[&d&l切換&e]", "freeze-hover": "&e切換商店凍結狀態。", "toggledisplay": "&e懸浮物顯示:&b{0} &e[&d&l切換&e]", "toggledisplay-hover": "&e切換商店是否顯示懸浮物", - "staff": "&aStaff amount: &b{0} &e[&d&lModify&e]" + "staff": "&a員工數量:&b{0}&e [&d&l修改&e]" }, "tableformat": { "full_line": "+---------------------------------------------------+", @@ -302,7 +302,7 @@ "master": "[主要分支 Master]" } }, - "shop-removed-cause-ongoing-fee": "&c你在 {0} 的商店已被刪除,因為你沒有足夠的資金去維護它!", + "shop-removed-cause-ongoing-fee": "&c你在 {0} 的商店已被移除,因為你沒有足夠的資金去維護它!", "digits-reach-the-limit": "&c你的價格超過小數點後位數上限。", "complete": "&a完成!", "quickshop-gui-preview": "QuickShop 物品預覽介面", @@ -335,8 +335,8 @@ "help-us": "&a[幫助我們提升翻譯品質]" }, "currency-not-exists": "&c找不到你想要設定的貨幣,可能是拼寫錯誤或該貨幣在這個世界無法使用。", - "currency-set": "&a成功設定商店貨幣為 {0}。", - "currency-unset": "&a成功刪除商店貨幣。現在使用預設設定。", + "currency-set": "&a成功地設定商店貨幣為 {0}。", + "currency-unset": "&a已成功地移除商店貨幣。現在使用預設設定。", "currency-not-support": "&c該經濟插件不支援多重經濟(multi-economy)功能。", "item-not-exist": "&c物品&e {0}&c不存在,請檢查你的拼寫。 ", "backup-success": "&a備份成功。", @@ -354,15 +354,15 @@ "success": "&a重新載入且沒有發生任何錯誤。", "require-restart": "&a重新載入完成。&e(一些更改需要重新啟動伺服器後作用)", "failed": "&c無法重新載入,請檢查伺服器控制台", - "scheduled": "&a重新載入完成。&e(一些更改需要一段時間後作用)" + "scheduled": "&a重新載入完成。&7(一些更改需要一段時間後作用)" }, "client-language-changed": "&aQuickShop 偵測到你的客戶端語言已切換,我們現在為你切換為 {0}。", "client-language-unsupported": "&eQuickShop 不支援你的客戶端語言,我們現在將它還原為 {0}。", "taxaccount-set": "&a已經設定 &e{0} &a為該商店的稅金帳戶", "taxaccount-unset": "&a該商店的稅金帳戶現在按照伺服器全域設定。", "taxaccount-invalid": "&c無效的目標帳戶,請輸入有效的玩家名稱或 uuid(須加破折號)。", - "display-turn-on": "&a成功開啟商店懸浮物顯示", - "display-turn-off": "&a成功關閉商店懸浮物顯示", + "display-turn-on": "&a成功地啟用商店懸浮物顯示。", + "display-turn-off": "&a成功地關閉商店懸浮物顯示。", "shop-purged-start": "&a已開始商店清理,請查看控制台以獲得詳細資訊。", "purchase-out-of-stock": "&c該商店已缺貨,請聯繫商店擁有者或商店員工補充庫存。", "purchase-out-of-space": "&c該商店空間不足,請聯繫商店擁有者或商店員工清空商店。", diff --git a/pom.xml b/pom.xml index c4425f7c97..17d4145295 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ QuickShop - 5.1.1.2 + 5.1.2.0 org.maxgamer.quickshop Ghost-chu UTF-8 @@ -464,7 +464,7 @@ com.github.TechFortress GriefPrevention - 16.18 + 16.18.1 provided @@ -577,7 +577,7 @@ com.github.angeschossen LandsAPI - 6.25.5 + 6.28.11 provided @@ -627,7 +627,7 @@ org.spigotmc spigot-api - 1.19.3-R0.1-SNAPSHOT + 1.19.4-R0.1-SNAPSHOT provided @@ -712,7 +712,7 @@ com.plotsquared PlotSquared-Core - 6.10.5 + 6.11.1 provided @@ -754,9 +754,9 @@ rollbar-java - de.themoep - minedown - 1.7.1-SNAPSHOT + com.github.PotatoCraft-Studio + MineDown + 1.7.1-modified compile @@ -776,7 +776,7 @@ com.songoda skyblock - 2.3.30 + 2.5.0 provided @@ -788,7 +788,7 @@ com.songoda SongodaCore - 2.6.16 + 2.6.18 provided diff --git a/src/main/java/org/maxgamer/quickshop/QuickShop.java b/src/main/java/org/maxgamer/quickshop/QuickShop.java index 7338a31e58..cd50364dd5 100644 --- a/src/main/java/org/maxgamer/quickshop/QuickShop.java +++ b/src/main/java/org/maxgamer/quickshop/QuickShop.java @@ -101,6 +101,7 @@ import org.maxgamer.quickshop.shop.SimpleShopManager; import org.maxgamer.quickshop.shop.VirtualDisplayItem; import org.maxgamer.quickshop.util.GameVersion; +import org.maxgamer.quickshop.util.HttpUtil; import org.maxgamer.quickshop.util.JsonUtil; import org.maxgamer.quickshop.util.MsgUtil; import org.maxgamer.quickshop.util.PermissionChecker; @@ -228,6 +229,7 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI { * The economy we hook into for transactions */ @Getter + @Nullable private AbstractEconomy economy; /** * Whether or not to limit players shop amounts @@ -294,6 +296,8 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI { @Getter private boolean allowStack; @Getter + private boolean includeOfflinePlayer; + @Getter private EnvironmentChecker environmentChecker; @Getter @Nullable @@ -567,7 +571,7 @@ public boolean loadEcon() { if (Util.isUUID(taxAccount)) { tax = PlayerFinder.findOfflinePlayerByUUID(UUID.fromString(taxAccount)); } else { - tax = PlayerFinder.findOfflinePlayerByName((Objects.requireNonNull(taxAccount))); + tax = PlayerFinder.findOfflinePlayerByUUID(PlayerFinder.findUUIDByName(Objects.requireNonNull(taxAccount), true, true)); } Economy_Vault vault = (Economy_Vault) economy; if (vault.isValid()) { @@ -670,6 +674,7 @@ public void reloadConfiguration() { this.priceChangeRequiresFee = this.getConfig().getBoolean("shop.price-change-requires-fee"); this.displayItemCheckTicks = this.getConfig().getInt("shop.display-items-check-ticks"); this.allowStack = this.getConfig().getBoolean("shop.allow-stacks"); + this.includeOfflinePlayer = this.getConfig().getBoolean("include-offlineplayer-for-command"); this.currency = this.getConfig().getString("currency"); this.loggingLocation = this.getConfig().getInt("logging.location"); if (StringUtils.isEmpty(this.currency)) { @@ -792,10 +797,11 @@ public final void onDisable() { } Util.debugLog("Cleanup listeners..."); - HandlerList.unregisterAll(this); Util.debugLog("Unregistering plugin services..."); getServer().getServicesManager().unregisterAll(this); + Util.debugLog("Shutdown okhttp client..."); + HttpUtil.shutdown(); Util.debugLog("Cleanup..."); Util.debugLog("All shutdown work is finished."); @@ -2217,6 +2223,19 @@ private void updateConfig(int selectedVersion) throws IOException { getConfig().set("database.mysql-connect-options", new ArrayList<>(Arrays.asList("autoReconnect=true", "useUnicode=true", "characterEncoding=utf8"))); getConfig().set("config-version", ++selectedVersion); } + if (selectedVersion == 162) { + getConfig().set("include-offlineplayer-for-command", false); + getConfig().set("config-version", ++selectedVersion); + } + //Fix broken maximum-digits-in-price option + if (getConfig().isSet("maximum-digits-in-price")) { + int maximumDigitsInPrice = getConfig().getInt("maximum-digits-in-price", -1); + int maximumDigitsInPriceNew = getConfig().getInt("shop.maximum-digits-in-price", -1); + if (maximumDigitsInPrice != -1 && maximumDigitsInPriceNew == -1) { + getConfig().set("shop.maximum-digits-in-price", maximumDigitsInPrice); + } + getConfig().set("maximum-digits-in-price", null); + } if (getConfig().isSet("shop.shop")) { getConfig().set("shop.shop", null); } diff --git a/src/main/java/org/maxgamer/quickshop/api/compatibility/CompatibilityModule.java b/src/main/java/org/maxgamer/quickshop/api/compatibility/CompatibilityModule.java index 86795d0b93..7027b68697 100644 --- a/src/main/java/org/maxgamer/quickshop/api/compatibility/CompatibilityModule.java +++ b/src/main/java/org/maxgamer/quickshop/api/compatibility/CompatibilityModule.java @@ -31,6 +31,20 @@ public interface CompatibilityModule { */ @NotNull String getName(); + /*** + * Call on registering module + */ + default void register() { + + } + + /** + * Call on unregister module + */ + default void unregister() { + + } + /** * Gets the CompatibilityModule provider plugin instance * diff --git a/src/main/java/org/maxgamer/quickshop/api/event/PlayerShopClickEvent.java b/src/main/java/org/maxgamer/quickshop/api/event/PlayerShopClickEvent.java new file mode 100644 index 0000000000..8da4c5c5d3 --- /dev/null +++ b/src/main/java/org/maxgamer/quickshop/api/event/PlayerShopClickEvent.java @@ -0,0 +1,48 @@ +/* + * This file is a part of project QuickShop, the name is PlayerShopClickEvent.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 . + * + */ + +package org.maxgamer.quickshop.api.event; + +import lombok.Getter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.maxgamer.quickshop.api.shop.Shop; + +/** + * A click event which have player variable + *

+ * Since 5.1.2.0 + */ +public class PlayerShopClickEvent extends ShopClickEvent { + + + @Getter + private final Player player; + + /** + * Call when shop was clicked. + * + * @param shop The shop bought from + * @param player the player clicking shop + */ + public PlayerShopClickEvent(@NotNull Shop shop, Player player) { + super(shop); + this.player = player; + } +} diff --git a/src/main/java/org/maxgamer/quickshop/api/event/ShopClickEvent.java b/src/main/java/org/maxgamer/quickshop/api/event/ShopClickEvent.java index 5244428f32..e45be1edaa 100644 --- a/src/main/java/org/maxgamer/quickshop/api/event/ShopClickEvent.java +++ b/src/main/java/org/maxgamer/quickshop/api/event/ShopClickEvent.java @@ -25,7 +25,10 @@ /** * Calling when shop clicked + *

+ * Deprecated, use PlayerShopClickEvent instead */ +@Deprecated public class ShopClickEvent extends AbstractQSEvent implements Cancellable { @NotNull diff --git a/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterCheckResult.java b/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterCheckResult.java index 2dba40c045..a248f38b61 100644 --- a/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterCheckResult.java +++ b/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterCheckResult.java @@ -19,6 +19,10 @@ package org.maxgamer.quickshop.api.shop; +import org.bukkit.command.CommandSender; +import org.maxgamer.quickshop.QuickShop; +import org.maxgamer.quickshop.util.MsgUtil; + /** * Result of PriceLimiter check */ @@ -43,4 +47,59 @@ public interface PriceLimiterCheckResult { * @return Max price */ double getMax(); + + /** + * Get the price max digit should be + * + * @return the max digit limit + */ + default int getMaxDigit() { + return -1; + } + + /** + * Get the price should be in this limitation + * + * @return the price after adjusted + */ + default double getPriceShouldBe() { + return getMin(); + } + + default void sendErrorMsg(QuickShop plugin, CommandSender sender, String input, String itemName) { + boolean decFormat = plugin.getConfig().getBoolean("use-decimal-format"); + String maxPriceStr; + String minPriceStr; + if (decFormat) { + maxPriceStr = MsgUtil.decimalFormat(getMax()); + minPriceStr = MsgUtil.decimalFormat(getMin()); + } else { + maxPriceStr = Double.toString(getMax()); + minPriceStr = Double.toString(getMin()); + } + switch (getStatus()) { + case REACHED_PRICE_MIN_LIMIT: + plugin.text().of(sender, "price-too-cheap", + minPriceStr).send(); + break; + case REACHED_PRICE_MAX_LIMIT: + plugin.text().of(sender, "price-too-high", + maxPriceStr).send(); + break; + case NOT_VALID: + plugin.text().of(sender, "not-a-number", input).send(); + break; + case NOT_A_WHOLE_NUMBER: + plugin.text().of(sender, "not-a-integer", input).send(); + break; + case REACH_DIGITS_LIMIT: + plugin.text().of(sender, "digits-reach-the-limit", String.valueOf(getMaxDigit())).send(); + break; + default: + plugin.text().of(sender, "restricted-prices", + itemName, + minPriceStr, + maxPriceStr).send(); + } + } } diff --git a/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterStatus.java b/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterStatus.java index 0b14dd9214..65c54c50e4 100644 --- a/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterStatus.java +++ b/src/main/java/org/maxgamer/quickshop/api/shop/PriceLimiterStatus.java @@ -6,5 +6,6 @@ public enum PriceLimiterStatus { REACHED_PRICE_MIN_LIMIT, PRICE_RESTRICTED, NOT_A_WHOLE_NUMBER, - NOT_VALID + NOT_VALID, + REACH_DIGITS_LIMIT, } diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Find.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Find.java index 461958e7ae..796976d82b 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Find.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Find.java @@ -89,11 +89,11 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not double distance = shopVector.distance(playerVector); //Check distance if (distance <= maxDistance) { - //Collect valid shop that trading items we want - if (!Util.getItemStackName(shop.getItem()).toLowerCase().contains(lookFor)) { - if (!shop.getItem().getType().name().toLowerCase().contains(lookFor)) { - continue; - } + // Collect valid shop that trading items we want + if (!Util.getItemStackName(shop.getItem()).toLowerCase().contains(lookFor) + && !shop.getItem().getType().name().toLowerCase().contains(lookFor) + && !Util.isBookEnchantmentsMatched(shop.getItem(), lookFor)) { + continue; } if (excludeOutOfStock) { if ((shop.isSelling() && shop.getRemainingStock() == 0) || (shop.isBuying() && shop.getRemainingSpace() == 0)) { diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Item.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Item.java index a4b7de628c..b341a40e86 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Item.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Item.java @@ -61,19 +61,13 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not plugin.text().of(sender, "blacklisted-item").send(); return; } - if (!plugin.isAllowStack() && !QuickShop.getPermissionManager().hasPermission(sender, "quickshop.create.stacks")) { + if (!plugin.isAllowStack() || !QuickShop.getPermissionManager().hasPermission(sender, "quickshop.create.stacks")) { itemStack.setAmount(1); } - SimplePriceLimiter limiter = new SimplePriceLimiter( - plugin.getConfig().getDouble("shop.minimum-price"), - plugin.getConfig().getInt("shop.maximum-price"), - plugin.getConfig().getBoolean("shop.allow-free-shop"), - plugin.getConfig().getBoolean("whole-number-prices-only")); + SimplePriceLimiter limiter = new SimplePriceLimiter(plugin); PriceLimiterCheckResult checkResult = limiter.check(itemStack, shop.getPrice()); if (checkResult.getStatus() != PriceLimiterStatus.PASS) { - plugin.text().of(sender, "restricted-prices", MsgUtil.getTranslateText(shop.getItem()), - String.valueOf(checkResult.getMin()), - String.valueOf(checkResult.getMax())).send(); + checkResult.sendErrorMsg(plugin, sender, "", MsgUtil.getTranslateText(shop.getItem())); return; } shop.setItem(itemStack); diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Price.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Price.java index 173c9d73d4..f8b8415cfe 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Price.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Price.java @@ -62,13 +62,6 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not plugin.text().of(sender, "not-a-number", cmdArg[0]).send(); return; } - // No number input - if (Double.isInfinite(price) || Double.isNaN(price)) { - plugin.text().of(sender, "not-a-number", cmdArg[0]).send(); - return; - } - - final boolean format = plugin.getConfig().getBoolean("use-decimal-format"); double fee = 0; @@ -83,11 +76,7 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not return; } - SimplePriceLimiter limiter = new SimplePriceLimiter( - plugin.getConfig().getDouble("shop.minimum-price"), - plugin.getConfig().getInt("shop.maximum-price"), - plugin.getConfig().getBoolean("shop.allow-free-shop"), - plugin.getConfig().getBoolean("whole-number-prices-only")); + SimplePriceLimiter limiter = new SimplePriceLimiter(plugin); while (bIt.hasNext()) { final Block b = bIt.next(); @@ -107,23 +96,8 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not } PriceLimiterCheckResult checkResult = limiter.check(shop.getItem(), price); - if (checkResult.getStatus() == PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT) { - plugin.text().of(sender, "price-too-cheap", (format) ? MsgUtil.decimalFormat(checkResult.getMin()) : Double.toString(checkResult.getMin())).send(); - return; - } - if (checkResult.getStatus() == PriceLimiterStatus.REACHED_PRICE_MAX_LIMIT) { - plugin.text().of(sender, "price-too-high", (format) ? MsgUtil.decimalFormat(checkResult.getMax()) : Double.toString(checkResult.getMax())).send(); - return; - } - if (checkResult.getStatus() == PriceLimiterStatus.PRICE_RESTRICTED) { - plugin.text().of(sender, "restricted-prices", MsgUtil.getTranslateText(shop.getItem()), - String.valueOf(checkResult.getMin()), - String.valueOf(checkResult.getMax())).send(); - return; - } - - if (checkResult.getStatus() == PriceLimiterStatus.NOT_A_WHOLE_NUMBER) { - plugin.text().of(sender, "not-a-integer", price).send(); + if (checkResult.getStatus() != PriceLimiterStatus.PASS) { + checkResult.sendErrorMsg(plugin, sender, cmdArg[0], MsgUtil.getTranslateText(shop.getItem())); return; } diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_RemoveAll.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_RemoveAll.java index 6da22a68ce..37abd67970 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_RemoveAll.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_RemoveAll.java @@ -28,6 +28,7 @@ import org.maxgamer.quickshop.QuickShop; import org.maxgamer.quickshop.api.command.CommandHandler; import org.maxgamer.quickshop.api.shop.Shop; +import org.maxgamer.quickshop.util.PlayerFinder; import org.maxgamer.quickshop.util.Util; import org.maxgamer.quickshop.util.logging.container.ShopRemoveLog; @@ -47,26 +48,20 @@ public void onCommand(@NotNull CommandSender sender, @NotNull String commandLabe if (cmdArg.length == 1) { //copy it first List tempList = new ArrayList<>(plugin.getShopManager().getAllShops()); - OfflinePlayer shopOwner = null; - for (OfflinePlayer player : plugin.getServer().getOfflinePlayers()) { - if (player.getName() != null && player.getName().equalsIgnoreCase(cmdArg[0])) { - shopOwner = player; - break; - } - } + PlayerFinder.PlayerProfile shopOwner = PlayerFinder.findPlayerProfileByName(cmdArg[0], false, plugin.isIncludeOfflinePlayer()); if (shopOwner == null) { plugin.text().of(sender, "unknown-player").send(); return; } int i = 0; - if (!shopOwner.equals(sender)) { //Non-self shop + if (sender instanceof OfflinePlayer && !shopOwner.getUuid().equals(((OfflinePlayer) sender).getUniqueId())) { //Non-self shop if (!sender.hasPermission("quickshop.removeall.other")) { plugin.text().of(sender, "no-permission").send(); return; } for (Shop shop : tempList) { - if (shop.getOwner().equals(shopOwner.getUniqueId())) { + if (shop.getOwner().equals(shopOwner.getUuid())) { plugin.logEvent(new ShopRemoveLog(Util.getSenderUniqueId(sender), "Deleting shop " + shop + " as requested by the /qs removeall command.", shop.saveToInfoStorage())); shop.delete(); i++; diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_SetOwner.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_SetOwner.java index a868a0032d..e9c5d87901 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_SetOwner.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_SetOwner.java @@ -20,7 +20,6 @@ package org.maxgamer.quickshop.command.subcommand; import lombok.AllArgsConstructor; -import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.BlockIterator; @@ -58,13 +57,13 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not continue; } - final OfflinePlayer newShopOwner = PlayerFinder.findOfflinePlayerByName(cmdArg[0]); - if (newShopOwner.getName() == null) { + final PlayerFinder.PlayerProfile newShopOwnerProfile = PlayerFinder.findPlayerProfileByName(cmdArg[0], false, plugin.isIncludeOfflinePlayer()); + if (newShopOwnerProfile == null) { plugin.text().of(sender, "unknown-player").send(); return; } - shop.setOwner(newShopOwner.getUniqueId()); - plugin.text().of(sender, "command.new-owner", newShopOwner.getName()).send(); + shop.setOwner(newShopOwnerProfile.getUuid()); + plugin.text().of(sender, "command.new-owner", newShopOwnerProfile.getName()).send(); return; } diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Size.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Size.java index f43c6b0e8a..f2405ff0ce 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Size.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Size.java @@ -68,16 +68,10 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not } ItemStack pendingItemStack = shop.getItem().clone(); pendingItemStack.setAmount(amount); - SimplePriceLimiter limiter = new SimplePriceLimiter( - plugin.getConfig().getDouble("shop.minimum-price"), - plugin.getConfig().getInt("shop.maximum-price"), - plugin.getConfig().getBoolean("shop.allow-free-shop"), - plugin.getConfig().getBoolean("whole-number-prices-only")); + SimplePriceLimiter limiter = new SimplePriceLimiter(plugin); PriceLimiterCheckResult checkResult = limiter.check(pendingItemStack, shop.getPrice()); if (checkResult.getStatus() != PriceLimiterStatus.PASS) { - plugin.text().of(sender, "restricted-prices", MsgUtil.getTranslateText(shop.getItem()), - String.valueOf(checkResult.getMin()), - String.valueOf(checkResult.getMax())).send(); + checkResult.sendErrorMsg(plugin, sender, cmdArg[0], MsgUtil.getTranslateText(shop.getItem())); return; } shop.setItem(pendingItemStack); diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Staff.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Staff.java index 970dc59d36..010123fa28 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Staff.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Staff.java @@ -20,9 +20,7 @@ package org.maxgamer.quickshop.command.subcommand; import lombok.AllArgsConstructor; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.BlockIterator; @@ -76,7 +74,7 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not MsgUtil.sendDirectMessage(sender, ChatColor.GREEN + plugin.text().of(sender, "tableformat.left_begin").forLocale() - + Bukkit.getOfflinePlayer(uuid).getName()); + + PlayerFinder.findNameByUUID(uuid)); } return; case "add": @@ -86,19 +84,22 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not return; } case 2: - final OfflinePlayer offlinePlayer = PlayerFinder.findOfflinePlayerByName(cmdArg[1]); - String offlinePlayerName = offlinePlayer.getName(); - + final PlayerFinder.PlayerProfile profile = PlayerFinder.findPlayerProfileByName(cmdArg[1], false, plugin.isIncludeOfflinePlayer()); + if (profile == null) { + plugin.text().of(sender, "unknown-player").send(); + return; + } + String offlinePlayerName = profile.getName(); if (offlinePlayerName == null) { offlinePlayerName = "null"; } switch (cmdArg[0]) { case "add": - shop.addStaff(offlinePlayer.getUniqueId()); + shop.addStaff(profile.getUuid()); plugin.text().of(sender, "shop-staff-added", offlinePlayerName).send(); return; case "del": - shop.delStaff(offlinePlayer.getUniqueId()); + shop.delStaff(profile.getUuid()); plugin.text().of(sender, "shop-staff-deleted", offlinePlayerName).send(); return; diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_TaxAccount.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_TaxAccount.java index 91014911b3..b8c3bf9f7e 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_TaxAccount.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_TaxAccount.java @@ -54,7 +54,12 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not if (Util.isUUID(cmdArg[0])) { shop.setTaxAccount(UUID.fromString(cmdArg[0])); } else { - shop.setTaxAccount(PlayerFinder.findUUIDByName(cmdArg[0])); + UUID uuid = PlayerFinder.findUUIDByName(cmdArg[0], false, plugin.isIncludeOfflinePlayer()); + if (uuid == null) { + plugin.text().of(sender, "unknown-player").send(); + return; + } + shop.setTaxAccount(uuid); } plugin.text().of(sender, "taxaccount-set", cmdArg[0]).send(); return; diff --git a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Transfer.java b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Transfer.java index 49d3a278d3..325589a704 100644 --- a/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Transfer.java +++ b/src/main/java/org/maxgamer/quickshop/command/subcommand/SubCommand_Transfer.java @@ -19,7 +19,6 @@ package org.maxgamer.quickshop.command.subcommand; -import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,12 +44,16 @@ public SubCommand_Transfer(QuickShop plugin) { @Override public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { if (cmdArg.length == 1) { - final OfflinePlayer targetPlayer = PlayerFinder.findOfflinePlayerByName(cmdArg[0]); + final PlayerFinder.PlayerProfile targetPlayer = PlayerFinder.findPlayerProfileByName(cmdArg[0], false, plugin.isIncludeOfflinePlayer()); + if (targetPlayer == null) { + plugin.text().of(sender, "unknown-player").send(); + return; + } String targetPlayerName = targetPlayer.getName(); if (targetPlayerName == null) { targetPlayerName = "null"; } - final UUID targetPlayerUUID = targetPlayer.getUniqueId(); + final UUID targetPlayerUUID = targetPlayer.getUuid(); List shopList = plugin.getShopManager().getPlayerAllShops(sender.getUniqueId()); for (Shop shop : shopList) { if (!shop.isBuying()) { @@ -64,19 +67,27 @@ public void onCommand(@NotNull Player sender, @NotNull String commandLabel, @Not return; } - final OfflinePlayer fromPlayer = PlayerFinder.findOfflinePlayerByName(cmdArg[0]); + final PlayerFinder.PlayerProfile fromPlayer = PlayerFinder.findPlayerProfileByName(cmdArg[0], false, plugin.isIncludeOfflinePlayer()); + if (fromPlayer == null) { + plugin.text().of(sender, "unknown-player").send(); + return; + } String fromPlayerName = fromPlayer.getName(); if (fromPlayerName == null) { fromPlayerName = "null"; } //FIXME: Update this when drop 1.15 supports - final OfflinePlayer targetPlayer = PlayerFinder.findOfflinePlayerByName(cmdArg[1]); + final PlayerFinder.PlayerProfile targetPlayer = PlayerFinder.findPlayerProfileByName(cmdArg[1], false, plugin.isIncludeOfflinePlayer()); + if (targetPlayer == null) { + plugin.text().of(sender, "unknown-player").send(); + return; + } String targetPlayerName = targetPlayer.getName(); if (targetPlayerName == null) { targetPlayerName = "null"; } - final UUID targetPlayerUUID = targetPlayer.getUniqueId(); - List shopList = plugin.getShopManager().getPlayerAllShops(fromPlayer.getUniqueId()); + final UUID targetPlayerUUID = targetPlayer.getUuid(); + List shopList = plugin.getShopManager().getPlayerAllShops(fromPlayer.getUuid()); for (Shop shop : shopList) { shop.setOwner(targetPlayerUUID); } diff --git a/src/main/java/org/maxgamer/quickshop/database/DatabaseManager.java b/src/main/java/org/maxgamer/quickshop/database/DatabaseManager.java index bfd20b7260..8281b0cea9 100644 --- a/src/main/java/org/maxgamer/quickshop/database/DatabaseManager.java +++ b/src/main/java/org/maxgamer/quickshop/database/DatabaseManager.java @@ -32,7 +32,11 @@ import org.maxgamer.quickshop.util.reload.ReloadStatus; import org.maxgamer.quickshop.util.reload.Reloadable; -import java.sql.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import java.util.logging.Level; @@ -265,7 +269,7 @@ public synchronized void unInit() { */ @Override public ReloadResult reloadModule() throws Exception { - init(); + //init(); return ReloadResult.builder().status(ReloadStatus.SUCCESS).build(); } diff --git a/src/main/java/org/maxgamer/quickshop/economy/Economy_TNE.java b/src/main/java/org/maxgamer/quickshop/economy/Economy_TNE.java index d327196435..e338dcd71c 100644 --- a/src/main/java/org/maxgamer/quickshop/economy/Economy_TNE.java +++ b/src/main/java/org/maxgamer/quickshop/economy/Economy_TNE.java @@ -25,7 +25,6 @@ import net.tnemc.core.TNE; import net.tnemc.core.common.api.TNEAPI; import net.tnemc.core.common.currency.TNECurrency; -import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.plugin.Plugin; @@ -33,6 +32,7 @@ import org.jetbrains.annotations.Nullable; import org.maxgamer.quickshop.QuickShop; import org.maxgamer.quickshop.api.economy.AbstractEconomy; +import org.maxgamer.quickshop.util.PlayerFinder; import org.maxgamer.quickshop.util.reload.ReloadResult; import org.maxgamer.quickshop.util.reload.ReloadStatus; @@ -90,7 +90,7 @@ private TNECurrency getCurrency(@NotNull World world, @Nullable String currency) */ @Override public boolean deposit(@NotNull UUID name, double amount, @NotNull World world, @Nullable String currency) { - deposit(Bukkit.getOfflinePlayer(name), amount, world, currency); + deposit(PlayerFinder.findOfflinePlayerByUUID(name), amount, world, currency); return false; } @@ -141,7 +141,7 @@ public String format(double balance, @NotNull World world, @Nullable String curr */ @Override public double getBalance(@NotNull UUID name, @NotNull World world, @Nullable String currency) { - return getBalance(Bukkit.getOfflinePlayer(name), world, currency); + return getBalance(PlayerFinder.findOfflinePlayerByUUID(name), world, currency); } /** @@ -173,7 +173,7 @@ public double getBalance(@NotNull OfflinePlayer player, @NotNull World world, @N */ @Override public boolean withdraw(@NotNull UUID name, double amount, @NotNull World world, @Nullable String currency) { - return withdraw(Bukkit.getOfflinePlayer(name), amount, world, currency); + return withdraw(PlayerFinder.findOfflinePlayerByUUID(name), amount, world, currency); } /** diff --git a/src/main/java/org/maxgamer/quickshop/economy/Economy_Vault.java b/src/main/java/org/maxgamer/quickshop/economy/Economy_Vault.java index f75a35e9fc..09e5db748d 100644 --- a/src/main/java/org/maxgamer/quickshop/economy/Economy_Vault.java +++ b/src/main/java/org/maxgamer/quickshop/economy/Economy_Vault.java @@ -36,6 +36,7 @@ import org.jetbrains.annotations.Nullable; import org.maxgamer.quickshop.QuickShop; import org.maxgamer.quickshop.api.economy.AbstractEconomy; +import org.maxgamer.quickshop.util.PlayerFinder; import org.maxgamer.quickshop.util.Util; import org.maxgamer.quickshop.util.economyformatter.BuiltInEconomyFormatter; import org.maxgamer.quickshop.util.reload.ReloadResult; @@ -132,7 +133,7 @@ public boolean deposit(@NotNull UUID name, double amount, @NotNull World world, if (!isValid()) { return false; } - return deposit(plugin.getServer().getOfflinePlayer(name), amount, world, currency); + return deposit(PlayerFinder.findOfflinePlayerByUUID(name), amount, world, currency); } @@ -190,7 +191,7 @@ public double getBalance(@NotNull UUID name, @NotNull World world, @Nullable Str return 0.0; } - return getBalance(plugin.getServer().getOfflinePlayer(name), world, currency); + return getBalance(PlayerFinder.findOfflinePlayerByUUID(name), world, currency); } @@ -216,7 +217,7 @@ public boolean withdraw(@NotNull UUID name, double amount, @NotNull World world, if (!isValid()) { return false; } - return withdraw(plugin.getServer().getOfflinePlayer(name), amount, world, currency); + return withdraw(PlayerFinder.findOfflinePlayerByUUID(name), amount, world, currency); } @Override diff --git a/src/main/java/org/maxgamer/quickshop/economy/Trader.java b/src/main/java/org/maxgamer/quickshop/economy/Trader.java index 6dd13d5366..afe5c2f109 100644 --- a/src/main/java/org/maxgamer/quickshop/economy/Trader.java +++ b/src/main/java/org/maxgamer/quickshop/economy/Trader.java @@ -20,6 +20,7 @@ package org.maxgamer.quickshop.economy; import lombok.AllArgsConstructor; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -29,6 +30,7 @@ import org.bukkit.profile.PlayerProfile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.maxgamer.quickshop.util.PlayerFinder; import java.util.Map; import java.util.UUID; @@ -36,8 +38,9 @@ @AllArgsConstructor public class Trader implements OfflinePlayer { + @Nullable - private final String name; + private String lastKnownName; @NotNull private final OfflinePlayer offlinePlayer; @@ -45,6 +48,10 @@ public static Trader adapt(OfflinePlayer offlinePlayer) { return new Trader(offlinePlayer.getName(), offlinePlayer); } + public static Trader adapt(PlayerFinder.PlayerProfile profile) { + return new Trader(profile.getName(), Bukkit.getOfflinePlayer(profile.getUuid())); + } + @Override public boolean isOnline() { return offlinePlayer.isOnline(); @@ -52,7 +59,7 @@ public boolean isOnline() { @Override public @Nullable String getName() { - return name == null ? offlinePlayer.getName() : name; + return lastKnownName == null && offlinePlayer.isOnline() ? lastKnownName = offlinePlayer.getName() : lastKnownName; } @Override diff --git a/src/main/java/org/maxgamer/quickshop/integration/lands/LandsIntegration.java b/src/main/java/org/maxgamer/quickshop/integration/lands/LandsIntegration.java index a40b506b1a..9134f7ec87 100644 --- a/src/main/java/org/maxgamer/quickshop/integration/lands/LandsIntegration.java +++ b/src/main/java/org/maxgamer/quickshop/integration/lands/LandsIntegration.java @@ -125,7 +125,7 @@ public void onLandsPermissionChanges(LandUntrustPlayerEvent event) { if (!deleteWhenLosePermission) { return; } - deleteShopInLand(event.getLand(), event.getTarget(), Reason.UNTRUSTED); + deleteShopInLand(event.getLand(), event.getTargetUID(), Reason.UNTRUSTED); } private void deleteShopInLand(Land land, UUID target, Reason reason) { diff --git a/src/main/java/org/maxgamer/quickshop/listener/InternalListener.java b/src/main/java/org/maxgamer/quickshop/listener/InternalListener.java index a78420e299..f4c56cd805 100644 --- a/src/main/java/org/maxgamer/quickshop/listener/InternalListener.java +++ b/src/main/java/org/maxgamer/quickshop/listener/InternalListener.java @@ -27,15 +27,24 @@ import org.bukkit.event.EventPriority; import org.jetbrains.annotations.NotNull; import org.maxgamer.quickshop.QuickShop; -import org.maxgamer.quickshop.api.event.*; +import org.maxgamer.quickshop.api.event.ShopCreateEvent; +import org.maxgamer.quickshop.api.event.ShopDeleteEvent; +import org.maxgamer.quickshop.api.event.ShopInventoryCalculateEvent; +import org.maxgamer.quickshop.api.event.ShopModeratorChangedEvent; +import org.maxgamer.quickshop.api.event.ShopPriceChangeEvent; +import org.maxgamer.quickshop.api.event.ShopPurchaseEvent; +import org.maxgamer.quickshop.api.event.ShopSuccessPurchaseEvent; import org.maxgamer.quickshop.shop.SimpleShopModerator; import org.maxgamer.quickshop.util.Util; -import org.maxgamer.quickshop.util.logging.container.*; +import org.maxgamer.quickshop.util.logging.container.PlayerEconomyPreCheckLog; +import org.maxgamer.quickshop.util.logging.container.ShopCreationLog; +import org.maxgamer.quickshop.util.logging.container.ShopModeratorChangedLog; +import org.maxgamer.quickshop.util.logging.container.ShopPriceChangedLog; +import org.maxgamer.quickshop.util.logging.container.ShopPurchaseLog; +import org.maxgamer.quickshop.util.logging.container.ShopRemoveLog; import org.maxgamer.quickshop.util.reload.ReloadResult; import org.maxgamer.quickshop.util.reload.ReloadStatus; -import java.util.Objects; - public class InternalListener extends AbstractQSListener { private final QuickShop plugin; @@ -94,7 +103,7 @@ public void shopModeratorChanges(ShopModeratorChangedEvent event) { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void shopPriceChanges(ShopPriceChangeEvent event) { if (loggingAction) { - plugin.logEvent(new ShopPriceChangedLog(event.getShop().saveToInfoStorage(), event.getOldPrice(), event.getOldPrice())); + plugin.logEvent(new ShopPriceChangedLog(event.getShop().saveToInfoStorage(), event.getOldPrice(), event.getNewPrice())); } } diff --git a/src/main/java/org/maxgamer/quickshop/listener/PlayerListener.java b/src/main/java/org/maxgamer/quickshop/listener/PlayerListener.java index 7e33ec0ffd..279f2d2bfc 100644 --- a/src/main/java/org/maxgamer/quickshop/listener/PlayerListener.java +++ b/src/main/java/org/maxgamer/quickshop/listener/PlayerListener.java @@ -48,6 +48,7 @@ import org.jetbrains.annotations.Nullable; import org.maxgamer.quickshop.QuickShop; import org.maxgamer.quickshop.api.economy.AbstractEconomy; +import org.maxgamer.quickshop.api.event.PlayerShopClickEvent; import org.maxgamer.quickshop.api.shop.Info; import org.maxgamer.quickshop.api.shop.Shop; import org.maxgamer.quickshop.api.shop.ShopAction; @@ -213,6 +214,11 @@ private void postTrade(PlayerInteractEvent e) { } //Prevent use item by ancient e.setUseItemInHand(Event.Result.DENY); + PlayerShopClickEvent event = new PlayerShopClickEvent(shop, p); + if (Util.fireCancellableEvent(event)) { + Util.debugLog("Ignore shop click, because some plugin cancel it."); + return; + } shop.onClick(); this.playClickSound(e.getPlayer()); // Text menu @@ -390,12 +396,12 @@ public void onInventoryClose(InventoryCloseEvent e) { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onJoin(PlayerJoinEvent e) { Util.debugLog("Player " + e.getPlayer().getName() + " using locale " + e.getPlayer().getLocale() + ": " + plugin.text().of(e.getPlayer(), "file-test").forLocale()); - PlayerFinder.updateStashIfNeeded(e.getPlayer()); + PlayerFinder.updateIfNeeded(e.getPlayer()); // Notify the player any messages they were sent if (plugin.getConfig().getBoolean("shop.auto-fetch-shop-messages")) { //Run Task later to make sure locale is correct plugin.getServer().getScheduler().runTaskLater(plugin, () -> - MsgUtil.flush(plugin.getServer().getOfflinePlayer(e.getPlayer().getUniqueId())) + MsgUtil.flush(PlayerFinder.findOfflinePlayerByUUID(e.getPlayer().getUniqueId())) , 50); } } diff --git a/src/main/java/org/maxgamer/quickshop/localization/text/SimpleTextManager.java b/src/main/java/org/maxgamer/quickshop/localization/text/SimpleTextManager.java index ac184bb172..3098a785b8 100644 --- a/src/main/java/org/maxgamer/quickshop/localization/text/SimpleTextManager.java +++ b/src/main/java/org/maxgamer/quickshop/localization/text/SimpleTextManager.java @@ -53,7 +53,12 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -291,7 +296,9 @@ private String findRelativeLanguages(String langCode) { String result = languagesCache.getIfPresent(langCode); if (result == null) { result = "en_us"; - if (availableLanguages.contains(langCode)) { + if (availableLanguages.size() == 1) { + result = availableLanguages.get(0); + } else if (availableLanguages.contains(langCode)) { result = langCode; } else { String[] splits = langCode.split("_", 2); diff --git a/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/CrowdinOTA.java b/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/CrowdinOTA.java index 5ee6fdb0ef..d796600826 100644 --- a/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/CrowdinOTA.java +++ b/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/CrowdinOTA.java @@ -48,7 +48,7 @@ public class CrowdinOTA implements Distribution { private static final String localManifest = "{\"files\":[\"\\/master\\/crowdin\\/lang\\/%locale%\\/messages.json\"],\"languages\":[\"af\",\"ar\",\"bg\",\"ca\",\"zh-CN\",\"zh-TW\",\"zh-HK\",\"cs\",\"da\",\"nl\",\"en\",\"fi\",\"fr\",\"de\",\"el\",\"he\",\"hi\",\"hu\",\"it\",\"ja\",\"ko\",\"lt\",\"no\",\"pl\",\"pt-PT\",\"pt-BR\",\"ro\",\"ru\",\"sr\",\"es-ES\",\"sv-SE\",\"th\",\"tr\",\"uk\",\"vi\"],\"language_mapping\":{\"ro\":{\"locale\":\"ro-RO\"},\"fr\":{\"locale\":\"fr-FR\"},\"es-ES\":{\"locale\":\"es-ES\"},\"af\":{\"locale\":\"af-ZA\"},\"ar\":{\"locale\":\"ar-SA\"},\"bg\":{\"locale\":\"bg-BG\"},\"ca\":{\"locale\":\"ca-ES\"},\"cs\":{\"locale\":\"cs-CZ\"},\"da\":{\"locale\":\"da-DK\"},\"de\":{\"locale\":\"de-DE\"},\"el\":{\"locale\":\"el-GR\"},\"fi\":{\"locale\":\"fi-FI\"},\"he\":{\"locale\":\"he-IL\"},\"hu\":{\"locale\":\"hu-HU\"},\"it\":{\"locale\":\"it-IT\"},\"ja\":{\"locale\":\"ja-JP\"},\"ko\":{\"locale\":\"ko-KR\"},\"lt\":{\"locale\":\"lt-LT\"},\"nl\":{\"locale\":\"nl-NL\"},\"no\":{\"locale\":\"no-NO\"},\"pl\":{\"locale\":\"pl-PL\"},\"pt-PT\":{\"locale\":\"pt-PT\"},\"ru\":{\"locale\":\"ru-RU\"},\"sr\":{\"locale\":\"sr-SP\"},\"sv-SE\":{\"locale\":\"sv-SE\"},\"tr\":{\"locale\":\"tr-TR\"},\"uk\":{\"locale\":\"uk-UA\"},\"zh-CN\":{\"locale\":\"zh-CN\"},\"zh-TW\":{\"locale\":\"zh-TW\"},\"en\":{\"locale\":\"en-US\"},\"vi\":{\"locale\":\"vi-VN\"},\"pt-BR\":{\"locale\":\"pt-BR\"},\"th\":{\"locale\":\"th-TH\"},\"hi\":{\"locale\":\"hi-IN\"},\"zh-HK\":{\"locale\":\"zh-HK\"}},\"custom_languages\":[],\"timestamp\":1671608400,\"content\":{\"af\":[\"\\/content\\/master\\/crowdin\\/lang\\/af-ZA\\/messages.json\"],\"ar\":[\"\\/content\\/master\\/crowdin\\/lang\\/ar-SA\\/messages.json\"],\"bg\":[\"\\/content\\/master\\/crowdin\\/lang\\/bg-BG\\/messages.json\"],\"ca\":[\"\\/content\\/master\\/crowdin\\/lang\\/ca-ES\\/messages.json\"],\"zh-CN\":[\"\\/content\\/master\\/crowdin\\/lang\\/zh-CN\\/messages.json\"],\"zh-TW\":[\"\\/content\\/master\\/crowdin\\/lang\\/zh-TW\\/messages.json\"],\"zh-HK\":[\"\\/content\\/master\\/crowdin\\/lang\\/zh-HK\\/messages.json\"],\"cs\":[\"\\/content\\/master\\/crowdin\\/lang\\/cs-CZ\\/messages.json\"],\"da\":[\"\\/content\\/master\\/crowdin\\/lang\\/da-DK\\/messages.json\"],\"nl\":[\"\\/content\\/master\\/crowdin\\/lang\\/nl-NL\\/messages.json\"],\"en\":[\"\\/content\\/master\\/crowdin\\/lang\\/en-US\\/messages.json\"],\"fi\":[\"\\/content\\/master\\/crowdin\\/lang\\/fi-FI\\/messages.json\"],\"fr\":[\"\\/content\\/master\\/crowdin\\/lang\\/fr-FR\\/messages.json\"],\"de\":[\"\\/content\\/master\\/crowdin\\/lang\\/de-DE\\/messages.json\"],\"el\":[\"\\/content\\/master\\/crowdin\\/lang\\/el-GR\\/messages.json\"],\"he\":[\"\\/content\\/master\\/crowdin\\/lang\\/he-IL\\/messages.json\"],\"hi\":[\"\\/content\\/master\\/crowdin\\/lang\\/hi-IN\\/messages.json\"],\"hu\":[\"\\/content\\/master\\/crowdin\\/lang\\/hu-HU\\/messages.json\"],\"it\":[\"\\/content\\/master\\/crowdin\\/lang\\/it-IT\\/messages.json\"],\"ja\":[\"\\/content\\/master\\/crowdin\\/lang\\/ja-JP\\/messages.json\"],\"ko\":[\"\\/content\\/master\\/crowdin\\/lang\\/ko-KR\\/messages.json\"],\"lt\":[\"\\/content\\/master\\/crowdin\\/lang\\/lt-LT\\/messages.json\"],\"no\":[\"\\/content\\/master\\/crowdin\\/lang\\/no-NO\\/messages.json\"],\"pl\":[\"\\/content\\/master\\/crowdin\\/lang\\/pl-PL\\/messages.json\"],\"pt-PT\":[\"\\/content\\/master\\/crowdin\\/lang\\/pt-PT\\/messages.json\"],\"pt-BR\":[\"\\/content\\/master\\/crowdin\\/lang\\/pt-BR\\/messages.json\"],\"ro\":[\"\\/content\\/master\\/crowdin\\/lang\\/ro-RO\\/messages.json\"],\"ru\":[\"\\/content\\/master\\/crowdin\\/lang\\/ru-RU\\/messages.json\"],\"sr\":[\"\\/content\\/master\\/crowdin\\/lang\\/sr-SP\\/messages.json\"],\"es-ES\":[\"\\/content\\/master\\/crowdin\\/lang\\/es-ES\\/messages.json\"],\"sv-SE\":[\"\\/content\\/master\\/crowdin\\/lang\\/sv-SE\\/messages.json\"],\"th\":[\"\\/content\\/master\\/crowdin\\/lang\\/th-TH\\/messages.json\"],\"tr\":[\"\\/content\\/master\\/crowdin\\/lang\\/tr-TR\\/messages.json\"],\"uk\":[\"\\/content\\/master\\/crowdin\\/lang\\/uk-UA\\/messages.json\"],\"vi\":[\"\\/content\\/master\\/crowdin\\/lang\\/vi-VN\\/messages.json\"]},\"mapping\":[\"\\/mapping\\/master\\/crowdin\\/lang\\/en-US\\/messages.json\"],\"local\":true}"; //DO NOT final it! Unit-test needs to change it to prevent network flow - protected static String CROWDIN_OTA_HOST = ""; + protected static String CROWDIN_OTA_HOST = "https://crowdinota.reremake.r2.quickshop-powered.top/"; private final QuickShop plugin; private final OTACacheControl otaCacheControl = new OTACacheControl(); @@ -76,10 +76,8 @@ public Manifest getManifest() { */ @NotNull public String getManifestJson() { - //Comment for disable OTA - //String url = CROWDIN_OTA_HOST + "manifest.json"; - //HttpUtil.createGet(url, localManifest); - return localManifest; + String url = CROWDIN_OTA_HOST + "manifest.json"; + return HttpUtil.createGet(url, localManifest, false); } /** @@ -173,7 +171,7 @@ public String getFile(String fileCrowdinPath, String crowdinLocale, boolean forc Util.debugLog("Manifest timestamp check failed " + postProcessingPath + " excepted:" + otaCacheControl.readManifestTimestamp() + " actual: " + getManifest().getTimestamp() + " forceUpdate: " + forceFlush); } // Out of the cache - String url = CROWDIN_OTA_HOST + "content" + fileCrowdinPath.replace("%locale%", crowdinLocale); + String url = CROWDIN_OTA_HOST + "content" + fileCrowdinPath.replace("%locale%", crowdinLocale) + "?timestamp=" + manifestTimestamp; plugin.getLogger().info("Updating translation " + crowdinLocale + " from: " + url); String data = HttpUtil.createGet(url, forceFlush); if (data == null) { diff --git a/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/bean/Manifest.java b/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/bean/Manifest.java index c80bed00e8..a47852e028 100644 --- a/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/bean/Manifest.java +++ b/src/main/java/org/maxgamer/quickshop/localization/text/distributions/crowdin/bean/Manifest.java @@ -32,7 +32,7 @@ public class Manifest { private List files; private List languages; - private List custom_languages; + //private List custom_languages; private long timestamp; private boolean local; } diff --git a/src/main/java/org/maxgamer/quickshop/shop/ContainerShop.java b/src/main/java/org/maxgamer/quickshop/shop/ContainerShop.java index 916aa61d6d..a094c8f6ca 100644 --- a/src/main/java/org/maxgamer/quickshop/shop/ContainerShop.java +++ b/src/main/java/org/maxgamer/quickshop/shop/ContainerShop.java @@ -25,7 +25,11 @@ import lombok.EqualsAndHashCode; import me.lucko.helper.serialize.BlockPosition; import net.md_5.bungee.api.chat.BaseComponent; -import org.bukkit.*; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; @@ -46,15 +50,40 @@ import org.maxgamer.quickshop.QuickShop; import org.maxgamer.quickshop.api.chat.ComponentPackage; import org.maxgamer.quickshop.api.economy.EconomyCore; -import org.maxgamer.quickshop.api.event.*; -import org.maxgamer.quickshop.api.shop.*; +import org.maxgamer.quickshop.api.event.ShopDeleteEvent; +import org.maxgamer.quickshop.api.event.ShopInventoryCalculateEvent; +import org.maxgamer.quickshop.api.event.ShopInventoryEvent; +import org.maxgamer.quickshop.api.event.ShopItemChangeEvent; +import org.maxgamer.quickshop.api.event.ShopLoadEvent; +import org.maxgamer.quickshop.api.event.ShopModeratorChangedEvent; +import org.maxgamer.quickshop.api.event.ShopOwnerNameGettingEvent; +import org.maxgamer.quickshop.api.event.ShopPriceChangeEvent; +import org.maxgamer.quickshop.api.event.ShopSignUpdateEvent; +import org.maxgamer.quickshop.api.event.ShopTaxAccountGettingEvent; +import org.maxgamer.quickshop.api.event.ShopTypeChangeEvent; +import org.maxgamer.quickshop.api.event.ShopUnloadEvent; +import org.maxgamer.quickshop.api.event.ShopUpdateEvent; +import org.maxgamer.quickshop.api.shop.AbstractDisplayItem; +import org.maxgamer.quickshop.api.shop.PriceLimiterCheckResult; +import org.maxgamer.quickshop.api.shop.PriceLimiterStatus; +import org.maxgamer.quickshop.api.shop.Shop; +import org.maxgamer.quickshop.api.shop.ShopInfoStorage; +import org.maxgamer.quickshop.api.shop.ShopModerator; +import org.maxgamer.quickshop.api.shop.ShopType; import org.maxgamer.quickshop.chat.platform.minedown.BungeeQuickChat; import org.maxgamer.quickshop.economy.Trader; import org.maxgamer.quickshop.util.MsgUtil; +import org.maxgamer.quickshop.util.PlayerFinder; import org.maxgamer.quickshop.util.Util; import org.maxgamer.quickshop.util.logging.container.ShopRemoveLog; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; import java.util.logging.Level; import static org.maxgamer.quickshop.chat.platform.minedown.BungeeQuickChat.fromLegacyText; @@ -548,11 +577,6 @@ public boolean matches(@Nullable ItemStack item) { @Override public void onClick() { Util.ensureThread(false); - ShopClickEvent event = new ShopClickEvent(this); - if (Util.fireCancellableEvent(event)) { - Util.debugLog("Ignore shop click, because some plugin cancel it."); - return; - } refresh(); setSignText(); } @@ -589,8 +613,7 @@ public void onUnload() { @Override public @NotNull String ownerName(boolean forceUsername) { - OfflinePlayer player = plugin.getServer().getOfflinePlayer(this.getOwner()); - String name = player.getName(); + String name = PlayerFinder.findNameByUUID(this.getOwner()); if (name == null || name.isEmpty()) { name = plugin.text().of("unknown-owner").forLocale(); } @@ -1003,27 +1026,9 @@ public void onLoad() { // check price restriction PriceLimiterCheckResult priceRestriction = plugin.getShopManager().getPriceLimiter().check(item, price); - boolean markUpdate = false; if (priceRestriction.getStatus() != PriceLimiterStatus.PASS) { - if (priceRestriction.getStatus() == PriceLimiterStatus.NOT_A_WHOLE_NUMBER) { - setDirty(); - price = Math.floor(price); - markUpdate = true; - } else if (priceRestriction.getStatus() == PriceLimiterStatus.NOT_VALID) { - setDirty(); - price = priceRestriction.getMin(); - markUpdate = true; - } - if (price < priceRestriction.getMin()) { - setDirty(); - price = priceRestriction.getMin(); - markUpdate = true; - } else if (price > priceRestriction.getMax()) { - setDirty(); - price = priceRestriction.getMax(); - markUpdate = true; - } - if (markUpdate) { + if (price != priceRestriction.getPriceShouldBe()) { + price = priceRestriction.getPriceShouldBe(); update(); } } @@ -1335,41 +1340,40 @@ public AbstractDisplayItem getDisplayItem() { public @Nullable Inventory getInventory() { Util.ensureThread(false); BlockState state = PaperLib.getBlockState(location.getBlock(), false).getState(); - Inventory inv; - try { - if (state.getType() == Material.ENDER_CHEST - && plugin.getOpenInvPlugin() != null) { //FIXME: Need better impl + Inventory inv = null; + if (state.getType() == Material.ENDER_CHEST && plugin.getOpenInvPlugin() != null) { + try {//FIXME: Need better impl + OfflinePlayer offlinePlayer = PlayerFinder.findOfflinePlayerByUUID(this.getOwner()); IOpenInv openInv = ((IOpenInv) plugin.getOpenInvPlugin()); - inv = openInv.getSpecialEnderChest( - Objects.requireNonNull( - openInv.loadPlayer( - plugin.getServer().getOfflinePlayer(this.moderator.getOwner()))), - plugin.getServer().getOfflinePlayer((this.moderator.getOwner())).isOnline()) - .getBukkitInventory(); + Player player = openInv.loadPlayer(offlinePlayer); + if (player != null) { + inv = openInv.getSpecialEnderChest(player, offlinePlayer.isOnline()).getBukkitInventory(); + } + } catch (Exception e) { + Util.debugLog(e.getMessage()); + return null; } - } catch (Exception e) { - Util.debugLog(e.getMessage()); - return null; } - InventoryHolder container; - try { - container = (InventoryHolder) state; - inv = container.getInventory(); - } catch (Exception e) { - if (!createBackup) { - createBackup = Util.backupDatabase(); - if (createBackup) { - this.delete(false); + if (inv == null) { + InventoryHolder container; + try { + container = (InventoryHolder) state; + inv = container.getInventory(); + } catch (Exception e) { + if (!createBackup) { + createBackup = Util.backupDatabase(); + if (createBackup) { + this.delete(false); + } + } else { + this.delete(true); } - } else { - this.delete(true); + plugin.logEvent(new ShopRemoveLog(Util.getNilUniqueId(), "Inventory Invalid", this.saveToInfoStorage())); + Util.debugLog( + "Inventory doesn't exist anymore: " + this + " shop was removed."); + return null; } - plugin.logEvent(new ShopRemoveLog(Util.getNilUniqueId(), "Inventory Invalid", this.saveToInfoStorage())); - Util.debugLog( - "Inventory doesn't exist anymore: " + this + " shop was removed."); - return null; } - ShopInventoryEvent event = new ShopInventoryEvent(this, inv); event.callEvent(); return event.getInventory(); diff --git a/src/main/java/org/maxgamer/quickshop/shop/ShopLoader.java b/src/main/java/org/maxgamer/quickshop/shop/ShopLoader.java index 043a0c2736..8814b9ca06 100644 --- a/src/main/java/org/maxgamer/quickshop/shop/ShopLoader.java +++ b/src/main/java/org/maxgamer/quickshop/shop/ShopLoader.java @@ -491,7 +491,7 @@ public class ShopDatabaseInfo { shopModerator = SimpleShopModerator.deserialize(moderatorJson); } catch (JsonSyntaxException ex) { Util.debugLog("Updating old shop data... for " + moderatorJson); - moderatorJson = PlayerFinder.findUUIDByName(moderatorJson).toString(); + moderatorJson = PlayerFinder.findUUIDByName(moderatorJson, true, true).toString(); shopModerator = new SimpleShopModerator(UUID.fromString(moderatorJson)); // New one needUpdate.set(true); } diff --git a/src/main/java/org/maxgamer/quickshop/shop/ShopPurger.java b/src/main/java/org/maxgamer/quickshop/shop/ShopPurger.java index 66e130ef01..fd7bf0a567 100644 --- a/src/main/java/org/maxgamer/quickshop/shop/ShopPurger.java +++ b/src/main/java/org/maxgamer/quickshop/shop/ShopPurger.java @@ -19,15 +19,17 @@ package org.maxgamer.quickshop.shop; -import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.scheduler.BukkitRunnable; import org.maxgamer.quickshop.QuickShop; import org.maxgamer.quickshop.api.economy.EconomyTransaction; import org.maxgamer.quickshop.api.shop.Shop; +import org.maxgamer.quickshop.util.PlayerFinder; import org.maxgamer.quickshop.util.Util; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.UUID; @@ -67,7 +69,7 @@ private void run() { boolean skipOp = plugin.getConfig().getBoolean("purge.skip-op"); boolean returnCreationFee = plugin.getConfig().getBoolean("purge.return-create-fee"); for (Shop shop : plugin.getShopManager().getAllShops()) { - OfflinePlayer player = Bukkit.getOfflinePlayer(shop.getOwner()); + OfflinePlayer player = PlayerFinder.findOfflinePlayerByUUID(shop.getOwner()); if (!player.hasPlayedBefore()) { Util.debugLog("Shop " + shop + " detection skipped: Owner never played before."); continue; @@ -95,26 +97,37 @@ private void run() { } if (pendingRemovalShops.size() > 0) { plugin.getLogger().info("[Shop Purger] Found " + pendingRemovalShops.size() + " need to removed, will remove in the next tick."); - plugin.getServer().getScheduler().runTaskLater(plugin, () -> { - for (Shop shop : pendingRemovalShops) { - shop.delete(false); - if (returnCreationFee) { - EconomyTransaction transaction = - EconomyTransaction.builder() - .amount(plugin.getConfig().getDouble("shop.cost")) - .allowLoan(false) - .core(QuickShop.getInstance().getEconomy()) - .currency(shop.getCurrency()) - .world(shop.getLocation().getWorld()) - .to(shop.getOwner()) - .build(); - transaction.failSafeCommit(); + new BukkitRunnable() { + @Override + public void run() { + Iterator shopIterator = pendingRemovalShops.iterator(); + long startTimeMs = System.currentTimeMillis(); + while (shopIterator.hasNext()) { + if (startTimeMs - System.currentTimeMillis() > 130) { + plugin.getLogger().info("[Shop Purger] it seems taking long time to purge shop (>130ms), do it in the next tick..."); + } + Shop shop = shopIterator.next(); + shop.delete(false); + if (returnCreationFee) { + EconomyTransaction transaction = + EconomyTransaction.builder() + .amount(plugin.getConfig().getDouble("shop.cost")) + .allowLoan(false) + .core(QuickShop.getInstance().getEconomy()) + .currency(shop.getCurrency()) + .world(shop.getLocation().getWorld()) + .to(shop.getOwner()) + .build(); + transaction.failSafeCommit(); + } + shopIterator.remove(); + plugin.getLogger().info("[Shop Purger] Shop " + shop + " has been purged."); } - plugin.getLogger().info("[Shop Purger] Shop " + shop + " has been purged."); + plugin.getLogger().info("[Shop Purger] Task completed, " + pendingRemovalShops.size() + " shops was purged"); + this.cancel(); + executing = false; } - plugin.getLogger().info("[Shop Purger] Task completed, " + pendingRemovalShops.size() + " shops was purged"); - executing = false; - }, 1L); + }.runTaskTimer(plugin, 1L, 1L); } else { plugin.getLogger().info("[Shop Purger] Task completed, No shops need to purge."); executing = false; diff --git a/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiter.java b/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiter.java index cec0252c28..71944b8f87 100644 --- a/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiter.java +++ b/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiter.java @@ -19,8 +19,8 @@ package org.maxgamer.quickshop.shop; -import lombok.AllArgsConstructor; import lombok.Data; +import lombok.EqualsAndHashCode; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.maxgamer.quickshop.QuickShop; @@ -32,41 +32,84 @@ import java.math.BigDecimal; import java.math.RoundingMode; +import java.text.DecimalFormat; import java.util.Map; -@AllArgsConstructor @Data public class SimplePriceLimiter implements PriceLimiter { + private double minPrice; private double maxPrice; private boolean allowFreeShop; private boolean wholeNumberOnly; + private int maximumDigitsInPrice; + @EqualsAndHashCode.Exclude + private DecimalFormat decimalFormat; + + public SimplePriceLimiter(double minPrice, double maxPrice, boolean allowFreeShop, boolean wholeNumberOnly, int maximumDigitsInPrice) { + this.minPrice = minPrice; + this.maxPrice = maxPrice; + this.allowFreeShop = allowFreeShop; + this.wholeNumberOnly = wholeNumberOnly; + this.maximumDigitsInPrice = maximumDigitsInPrice; + } + + public SimplePriceLimiter(QuickShop plugin) { + this(plugin.getConfig().getDouble("shop.minimum-price"), + plugin.getConfig().getInt("shop.maximum-price"), + plugin.getConfig().getBoolean("shop.allow-free-shop"), + plugin.getConfig().getBoolean("whole-number-prices-only"), + plugin.getConfig().getInt("shop.maximum-digits-in-price", -1)); + } + + private DecimalFormat getDecimalFormat() { + if (decimalFormat == null) { + StringBuilder builder = new StringBuilder("#."); + for (int i = 0; i <= (maximumDigitsInPrice + 1); i++) { + builder.append("#"); + } + decimalFormat = new DecimalFormat(builder.toString()); + } + return decimalFormat; + } @Override @NotNull public PriceLimiterCheckResult check(@NotNull ItemStack stack, double price) { + SimplePriceLimiterCheckResult result = new SimplePriceLimiterCheckResult(PriceLimiterStatus.PASS, minPrice, maxPrice, price, maximumDigitsInPrice); + if (Double.isInfinite(price) || Double.isNaN(price)) { - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.NOT_VALID, minPrice, maxPrice); + return result.status(PriceLimiterStatus.NOT_VALID) + .priceShouldBe(minPrice); } - if (allowFreeShop) { - if (price != 0 && price < minPrice) { - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT, minPrice, maxPrice); + if (maximumDigitsInPrice != -1) { + String strFormat = getDecimalFormat().format(Math.abs(price)).replace(",", "."); + String[] processedDouble = strFormat.split("\\."); + if (processedDouble.length > 1) { + if (processedDouble[1].length() > maximumDigitsInPrice) { + return result.status(PriceLimiterStatus.REACH_DIGITS_LIMIT) + .priceShouldBe(Double.parseDouble(processedDouble[0] + "." + processedDouble[1].substring(0, maximumDigitsInPrice))); + } } } if (wholeNumberOnly) { try { + //noinspection ResultOfMethodCallIgnored BigDecimal.valueOf(price).setScale(0, RoundingMode.UNNECESSARY); } catch (ArithmeticException exception) { Util.debugLog(exception.getMessage()); - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.NOT_A_WHOLE_NUMBER, minPrice, maxPrice); + return result.status(PriceLimiterStatus.NOT_A_WHOLE_NUMBER) + .priceShouldBe(Math.floor(price)); } } - if (price < minPrice) { - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT, minPrice, maxPrice); - } - if (maxPrice != -1) { - if (price > maxPrice) { - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.REACHED_PRICE_MAX_LIMIT, minPrice, maxPrice); + if (!allowFreeShop || price != 0) { + if (price < minPrice) { + return result.status(PriceLimiterStatus.REACHED_PRICE_MIN_LIMIT) + .priceShouldBe(minPrice); + } + if (maxPrice != -1 && price > maxPrice) { + return result.status(PriceLimiterStatus.REACHED_PRICE_MAX_LIMIT) + .priceShouldBe(maxPrice); } } double perItemPrice; @@ -77,11 +120,18 @@ public PriceLimiterCheckResult check(@NotNull ItemStack stack, double price) { } Map.Entry materialLimit = Util.getPriceRestriction(stack.getType()); if (materialLimit != null) { - if (perItemPrice < materialLimit.getKey() || perItemPrice > materialLimit.getValue()) { - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.PRICE_RESTRICTED, materialLimit.getKey(), materialLimit.getValue()); + //Updating the max and min price + result.max(materialLimit.getKey()).min(materialLimit.getValue()); + if (!allowFreeShop || price != 0) { + if (perItemPrice < materialLimit.getKey()) { + return result.status(PriceLimiterStatus.PRICE_RESTRICTED) + .priceShouldBe(materialLimit.getKey()); + } else if (perItemPrice > materialLimit.getValue()) { + return result.status(PriceLimiterStatus.PRICE_RESTRICTED) + .priceShouldBe(materialLimit.getValue()); + } } - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.PASS, materialLimit.getKey(), materialLimit.getValue()); } - return new SimplePriceLimiterCheckResult(PriceLimiterStatus.PASS, minPrice, maxPrice); + return result; } } diff --git a/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiterCheckResult.java b/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiterCheckResult.java index c8016b0957..892e4e4247 100644 --- a/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiterCheckResult.java +++ b/src/main/java/org/maxgamer/quickshop/shop/SimplePriceLimiterCheckResult.java @@ -30,4 +30,26 @@ public class SimplePriceLimiterCheckResult implements PriceLimiterCheckResult { PriceLimiterStatus status; double min; double max; + double priceShouldBe; + int maxDigit; + + public SimplePriceLimiterCheckResult min(double min) { + this.min = min; + return this; + } + + public SimplePriceLimiterCheckResult max(double max) { + this.max = max; + return this; + } + + public SimplePriceLimiterCheckResult priceShouldBe(double priceShouldBe) { + this.priceShouldBe = priceShouldBe; + return this; + } + + public SimplePriceLimiterCheckResult status(PriceLimiterStatus status) { + this.status = status; + return this; + } } diff --git a/src/main/java/org/maxgamer/quickshop/shop/SimpleShopManager.java b/src/main/java/org/maxgamer/quickshop/shop/SimpleShopManager.java index 2336bf6532..7b4472a1e7 100644 --- a/src/main/java/org/maxgamer/quickshop/shop/SimpleShopManager.java +++ b/src/main/java/org/maxgamer/quickshop/shop/SimpleShopManager.java @@ -63,6 +63,7 @@ import org.maxgamer.quickshop.api.shop.Info; import org.maxgamer.quickshop.api.shop.PriceLimiter; import org.maxgamer.quickshop.api.shop.PriceLimiterCheckResult; +import org.maxgamer.quickshop.api.shop.PriceLimiterStatus; import org.maxgamer.quickshop.api.shop.Shop; import org.maxgamer.quickshop.api.shop.ShopAction; import org.maxgamer.quickshop.api.shop.ShopChunk; @@ -83,7 +84,6 @@ import org.maxgamer.quickshop.util.reload.ReloadStatus; import org.maxgamer.quickshop.util.reload.Reloadable; -import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -140,11 +140,9 @@ private void init() { String taxAccount = plugin.getConfig().getString("tax-account", "tax"); if (!taxAccount.isEmpty()) { if (Util.isUUID(taxAccount)) { - this.cacheTaxAccount = new Trader(taxAccount, - plugin.getServer().getOfflinePlayer(UUID.fromString(taxAccount))); + this.cacheTaxAccount = new Trader(taxAccount, PlayerFinder.findOfflinePlayerByUUID(UUID.fromString(taxAccount))); } else { - this.cacheTaxAccount = new Trader(taxAccount, - PlayerFinder.findOfflinePlayerByName(taxAccount)); + this.cacheTaxAccount = PlayerFinder.findPlayerProfileByName(taxAccount, true, true).getTrader(); } } else { // disable tax account @@ -157,16 +155,12 @@ private void init() { plugin.getLogger().log(Level.WARNING, "unlimited-shop-owner-change-account is empty, default to \"quickshop\""); } if (Util.isUUID(uAccount)) { - cacheUnlimitedShopAccount = new Trader(uAccount, Bukkit.getOfflinePlayer(UUID.fromString(uAccount))); + cacheUnlimitedShopAccount = new Trader(uAccount, PlayerFinder.findOfflinePlayerByUUID(UUID.fromString(uAccount))); } else { - cacheUnlimitedShopAccount = new Trader(uAccount, PlayerFinder.findOfflinePlayerByName(uAccount)); + cacheUnlimitedShopAccount = PlayerFinder.findPlayerProfileByName(uAccount, true, true).getTrader(); } } - this.priceLimiter = new SimplePriceLimiter( - plugin.getConfig().getDouble("shop.minimum-price"), - plugin.getConfig().getInt("shop.maximum-price"), - plugin.getConfig().getBoolean("shop.allow-free-shop"), - plugin.getConfig().getBoolean("whole-number-prices-only")); + this.priceLimiter = new SimplePriceLimiter(plugin); this.useOldCanBuildAlgorithm = plugin.getConfig().getBoolean("limits.old-algorithm"); this.autoSign = plugin.getConfig().getBoolean("shop.auto-sign"); } @@ -754,7 +748,7 @@ public void actionBuy( } Trader taxAccount; if (shop.getTaxAccount() != null) { - taxAccount = Trader.adapt(Bukkit.getOfflinePlayer(shop.getTaxAccount())); + taxAccount = Trader.adapt(PlayerFinder.findOfflinePlayerByUUID(shop.getTaxAccount())); } else { taxAccount = this.cacheTaxAccount; } @@ -944,22 +938,6 @@ public void actionCreate(@NotNull Player p, Info info, @NotNull String message) double price; try { price = Double.parseDouble(message); - if (Double.isInfinite(price)) { - plugin.text().of(p, "exceeded-maximum", message).send(); - return; - } - String strFormat = new DecimalFormat("#.#########").format(Math.abs(price)) - .replace(",", "."); - String[] processedDouble = strFormat.split("\\."); - if (processedDouble.length > 1) { - int maximumDigitsLimit = plugin.getConfig() - .getInt("maximum-digits-in-price", -1); - if (processedDouble[1].length() > maximumDigitsLimit - && maximumDigitsLimit != -1) { - plugin.text().of(p, "digits-reach-the-limit", String.valueOf(maximumDigitsLimit)).send(); - return; - } - } } catch (NumberFormatException ex) { Util.debugLog(ex.getMessage()); plugin.text().of(p, "not-a-number", message).send(); @@ -967,33 +945,11 @@ public void actionCreate(@NotNull Player p, Info info, @NotNull String message) } // Price limit checking - boolean decFormat = plugin.getConfig().getBoolean("use-decimal-format"); - PriceLimiterCheckResult priceCheckResult = this.priceLimiter.check(info.getItem(), price); - switch (priceCheckResult.getStatus()) { - case REACHED_PRICE_MIN_LIMIT: - plugin.text().of(p, "price-too-cheap", - (decFormat) ? MsgUtil.decimalFormat(this.priceLimiter.getMaxPrice()) - : Double.toString(this.priceLimiter.getMinPrice())).send(); - return; - case REACHED_PRICE_MAX_LIMIT: - plugin.text().of(p, "price-too-high", - (decFormat) ? MsgUtil.decimalFormat(this.priceLimiter.getMaxPrice()) - : Double.toString(this.priceLimiter.getMinPrice())).send(); - return; - case PRICE_RESTRICTED: - plugin.text().of(p, "restricted-prices", - MsgUtil.getTranslateText(info.getItem()), - String.valueOf(priceCheckResult.getMin()), - String.valueOf(priceCheckResult.getMax())).send(); - return; - case NOT_VALID: - plugin.text().of(p, "not-a-number", message).send(); - return; - case NOT_A_WHOLE_NUMBER: - plugin.text().of(p, "not-a-integer", message).send(); - return; + if (priceCheckResult.getStatus() != PriceLimiterStatus.PASS) { + priceCheckResult.sendErrorMsg(plugin, p, message, MsgUtil.getTranslateText(info.getItem())); + return; } // Set to 1 when disabled stacking shop @@ -1155,7 +1111,7 @@ public void actionSell( EconomyTransaction transaction; Trader taxAccount; if (shop.getTaxAccount() != null) { - taxAccount = Trader.adapt(Bukkit.getOfflinePlayer(shop.getTaxAccount())); + taxAccount = Trader.adapt(PlayerFinder.findOfflinePlayerByUUID(shop.getTaxAccount())); } else { taxAccount = this.cacheTaxAccount; } @@ -1285,7 +1241,7 @@ public void sendSellSuccess(@NotNull UUID seller, @NotNull Shop shop, int amount MsgUtil.getTranslateText(shop.getItem()), format(total, shop)).forLocale()); if (plugin.getConfig().getBoolean("show-tax")) { - double tax = plugin.getConfig().getDouble("tax"); + double tax = getTax(shop, seller); if (tax != 0) { if (!seller.equals(shop.getOwner())) { chatSheetPrinter.printLine( @@ -1358,7 +1314,9 @@ public void sendShopInfo(@NotNull Player p, @NotNull Shop shop) { } if (potionMeta.hasCustomEffects()) { for (PotionEffect potionEffect : potionMeta.getCustomEffects()) { - int level = potionEffect.getAmplifier(); + // https://hub.spigotmc.org/jira/browse/SPIGOT-1697 + // 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)); } } diff --git a/src/main/java/org/maxgamer/quickshop/util/GameVersion.java b/src/main/java/org/maxgamer/quickshop/util/GameVersion.java index 365a8c3cc3..47addd7750 100644 --- a/src/main/java/org/maxgamer/quickshop/util/GameVersion.java +++ b/src/main/java/org/maxgamer/quickshop/util/GameVersion.java @@ -65,6 +65,8 @@ public enum GameVersion { v1_18_R2(true, false, true, true, true, true), 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), + UNKNOWN(true, false, false, true, true, true); /** * CoreSupports - Check does QuickShop most features supports this server version diff --git a/src/main/java/org/maxgamer/quickshop/util/HttpUtil.java b/src/main/java/org/maxgamer/quickshop/util/HttpUtil.java index e5b217ba66..e881101a49 100644 --- a/src/main/java/org/maxgamer/quickshop/util/HttpUtil.java +++ b/src/main/java/org/maxgamer/quickshop/util/HttpUtil.java @@ -28,6 +28,7 @@ import okhttp3.Response; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.maxgamer.quickshop.QuickShop; import java.io.File; import java.io.IOException; @@ -37,9 +38,17 @@ public class HttpUtil { protected static final com.google.common.cache.Cache requestCachePool = CacheBuilder.newBuilder() .expireAfterWrite(7, TimeUnit.DAYS) .build(); - private static final OkHttpClient client = new OkHttpClient.Builder() - .cache(new Cache(getCacheFolder(), 50L * 1024L * 1024L)).build(); + private static final File cacheFolder = getCacheFolder(); + private static OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).cache(new Cache(cacheFolder, 50L * 1024L * 1024L)).build(); + private static volatile boolean shutdown = false; + + @NotNull + private static File getCacheFolder() { + File file = new File(Util.getCacheFolder(), "okhttp_tmp"); + file.mkdirs(); + return file; + } @Deprecated public static HttpUtil create() { @@ -47,19 +56,27 @@ public static HttpUtil create() { } public static Response makeGet(@NotNull String url) throws IOException { + checkIfNeedToRecreateClient(); return client.newCall(new Request.Builder().get().url(url).build()).execute(); } @NotNull - public static String createGet(@NotNull String url, String def) { + public static String createGet(@NotNull String url, String def, boolean caching) { String result = createGet(url, false); if (result == null) { result = def; } - requestCachePool.put(url, result); + if (caching) { + requestCachePool.put(url, result); + } return result; } + @NotNull + public static String createGet(@NotNull String url, String def) { + return createGet(url, def, true); + } + @Nullable public static String createGet(@NotNull String url) { return createGet(url, false); @@ -67,6 +84,7 @@ public static String createGet(@NotNull String url) { @Nullable public static String createGet(@NotNull String url, boolean flushCache) { + checkIfNeedToRecreateClient(); String cache; if (!flushCache) { cache = requestCachePool.getIfPresent(url); @@ -74,7 +92,7 @@ public static String createGet(@NotNull String url, boolean flushCache) { return cache; } } - try (Response response = client.newCall(new Request.Builder().get().url(url).build()).execute()) { + try (Response response = client.newCall(new Request.Builder().get().url(url).header("User-Agent", "Java QuickShop-" + QuickShop.getFork() + " " + QuickShop.getVersion()).build()).execute()) { val body = response.body(); if (body == null) { return null; @@ -92,23 +110,43 @@ public static String createGet(@NotNull String url, boolean flushCache) { @NotNull public static Response makePost(@NotNull String url, @NotNull RequestBody body) throws IOException { + checkIfNeedToRecreateClient(); return client.newCall(new Request.Builder().post(body).url(url).build()).execute(); } - @NotNull - private static File getCacheFolder() { - File file = new File(Util.getCacheFolder(), "okhttp_tmp"); - file.mkdirs(); - return file; - } public static OkHttpClient getClientInstance() { + checkIfNeedToRecreateClient(); return client; } + private static void checkIfNeedToRecreateClient() { + if (shutdown) { + shutdown = false; + client = new OkHttpClient.Builder().cache(new Cache(cacheFolder, 50L * 1024L * 1024L)).build(); + new RuntimeException("Quickshop HTTPUtil: OkHttpClient is rebuilding, it should not happened outside the testing!").printStackTrace(); + } + } + + public static void shutdown() { + try { + if (!shutdown) { + shutdown = true; + client.dispatcher().executorService().shutdown(); + client.connectionPool().evictAll(); + okhttp3.Cache cache = client.cache(); + if (cache != null) { + cache.close(); + } + } + } catch (Throwable ignored) { + } + } + @Deprecated @NotNull public OkHttpClient getClient() { + checkIfNeedToRecreateClient(); return client; } } diff --git a/src/main/java/org/maxgamer/quickshop/util/MsgUtil.java b/src/main/java/org/maxgamer/quickshop/util/MsgUtil.java index a41f0ab359..5ee2c02b6c 100644 --- a/src/main/java/org/maxgamer/quickshop/util/MsgUtil.java +++ b/src/main/java/org/maxgamer/quickshop/util/MsgUtil.java @@ -365,7 +365,7 @@ public static void loadTransactionMessages() { if (Util.isUUID(owner)) { ownerUUID = UUID.fromString(owner); } else { - ownerUUID = PlayerFinder.findUUIDByName(owner); + ownerUUID = PlayerFinder.findUUIDByName(owner, true, true); } String message = rs.getString("message"); List msgs = OUTGOING_MESSAGES.computeIfAbsent(ownerUUID, k -> new LinkedList<>()); @@ -390,7 +390,7 @@ public static void send(@NotNull UUID uuid, @NotNull ShopTransactionMessageConta return; // Ignore unlimited shops messages. } Util.debugLog(shopTransactionMessage.getMessage(null)); - OfflinePlayer p = Bukkit.getOfflinePlayer(uuid); + OfflinePlayer p = PlayerFinder.findOfflinePlayerByUUID(uuid); if (!p.isOnline()) { List msgs = OUTGOING_MESSAGES.getOrDefault(uuid, new LinkedList<>()); msgs.add(shopTransactionMessage); @@ -427,7 +427,7 @@ public static void send(@NotNull Shop shop, @NotNull UUID uuid, @NotNull ShopTra if (shop.isUnlimited() && plugin.getConfig().getBoolean("shop.ignore-unlimited-shop-messages")) { return; // Ignore unlimited shops messages. } - OfflinePlayer p = Bukkit.getOfflinePlayer(uuid); + OfflinePlayer p = PlayerFinder.findOfflinePlayerByUUID(uuid); if (!p.isOnline()) { List msgs = OUTGOING_MESSAGES.getOrDefault(uuid, new LinkedList<>()); msgs.add(shopTransactionMessageContainer); diff --git a/src/main/java/org/maxgamer/quickshop/util/PlayerFinder.java b/src/main/java/org/maxgamer/quickshop/util/PlayerFinder.java index 46d22507ff..65f915120b 100644 --- a/src/main/java/org/maxgamer/quickshop/util/PlayerFinder.java +++ b/src/main/java/org/maxgamer/quickshop/util/PlayerFinder.java @@ -21,18 +21,24 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; +import lombok.AllArgsConstructor; +import lombok.Data; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.Server; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.maxgamer.quickshop.QuickShop; +import org.maxgamer.quickshop.economy.Trader; import java.util.Arrays; +import java.util.Collections; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -45,79 +51,188 @@ public final class PlayerFinder { //Hold store for large server - private static final Map string2UUIDStash = new java.util.concurrent.ConcurrentHashMap<>(); - private static final Cache string2UUIDCache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.MINUTES).build(); + private static final Map name2UUIDStash = new java.util.concurrent.ConcurrentHashMap<>(); + private static final Cache name2UUIDCache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.MINUTES).build(); + private static final Cache uuid2StringCache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.MINUTES).build(); - private static volatile boolean isStashNeeded; + private static final Set emptyNameUUIDSet = new ConcurrentSkipListSet<>(); - private PlayerFinder() { - } - - public static UUID findUUIDByName(String name) { - return findOfflinePlayerByName(name).getUniqueId(); - } + private static volatile boolean useOfflineStash; @Nullable - private static OfflinePlayer findPlayerByName(String name, java.util.Collection players, boolean isOfflinePlayer) { + private static PlayerProfile findProfileByName(String name, java.util.Collection players, boolean isOfflinePlayer) { for (OfflinePlayer player : players) { + UUID uuid = player.getUniqueId(); + if (isOfflinePlayer && emptyNameUUIDSet.contains(uuid)) { + continue; + } String playerName = player.getName(); if (playerName != null) { if (playerName.equalsIgnoreCase(name)) { - return player; + return new PlayerProfile(playerName, player.getUniqueId()); } + } else { + emptyNameUUIDSet.add(uuid); } } return null; } + private PlayerFinder() { + } + + /** + * Get the unmodified list of cached offline player names + * will return empty when useOfflineStash is false + */ public static Set getCachedOfflinePlayerNames() { - return string2UUIDStash.keySet(); + return Collections.unmodifiableSet(name2UUIDStash.keySet()); } - public static void updateStashIfNeeded(Player player) { - if (isStashNeeded) { - string2UUIDStash.put(player.getName().toLowerCase(Locale.ROOT), player.getUniqueId()); + /** + * Update the cache when needed + * + * @param player player instance needed to be updated + */ + public static void updateIfNeeded(Player player) { + UUID uuid = player.getUniqueId(); + emptyNameUUIDSet.remove(uuid); + if (useOfflineStash) { + name2UUIDStash.put(player.getName().toLowerCase(Locale.ROOT), uuid); } } public static void doLargeOfflineCachingWork(QuickShop quickShop, OfflinePlayer[] offlinePlayers) { quickShop.getLogger().log(Level.INFO, "Large server detected (offline player > 2000), start offline player caching..."); - isStashNeeded = true; + useOfflineStash = true; + int amount = 0; + int errorAmount = 0; + int doneAmount = 0; for (OfflinePlayer offlinePlayer : quickShop.getServer().getOfflinePlayers()) { - String name = offlinePlayer.getName(); - if (name != null) { - string2UUIDStash.put(name, offlinePlayer.getUniqueId()); + try { + String name = offlinePlayer.getName(); + if (name != null) { + name2UUIDStash.put(name.toLowerCase(Locale.ROOT), offlinePlayer.getUniqueId()); + } else { + emptyNameUUIDSet.add(offlinePlayer.getUniqueId()); + } + } catch (Throwable ignored) { + errorAmount++; + } + amount++; + if (amount == 1000) { + doneAmount += 1000; + amount = 0; + quickShop.getLogger().log(Level.INFO, "Caching Offline player...cached " + doneAmount + "/" + offlinePlayers.length + " players, " + errorAmount + " errors got when caching players."); } } - quickShop.getLogger().log(Level.INFO, "Done! cached " + offlinePlayers.length + " players."); + quickShop.getLogger().log(Level.INFO, "Done! cached " + offlinePlayers.length + " players, " + errorAmount + " errors got when caching players."); } - public static OfflinePlayer findOfflinePlayerByName(String name) { - OfflinePlayer result; - UUID uuid; + /** + * Getting built-in PlayerProfile from PlayerFinder by name + * + * @param name the player name, case ignored + * @param forceWebRequest whether to use web request, may result blocking server thread + * @return the uuid of this player name, null when [forceWebRequest] is false + */ + public static PlayerProfile findPlayerProfileByName(String name, boolean forceWebRequest, boolean checkOfflinePlayer) { + UUID uuid = findUUIDByName(name, forceWebRequest, checkOfflinePlayer); + if (uuid != null) { + return new PlayerProfile(findNameByUUID(uuid), uuid); + } else { + return null; + } + } - uuid = string2UUIDCache.getIfPresent(name.toLowerCase(Locale.ROOT)); + private static void puttingToCache(String realPlayerName, UUID uuid) { + if (realPlayerName == null) { + emptyNameUUIDSet.add(uuid); + } else { + uuid2StringCache.put(uuid, realPlayerName); + name2UUIDCache.put(realPlayerName.toLowerCase(Locale.ROOT), uuid); + } + } - if (uuid == null && !string2UUIDStash.isEmpty()) { - uuid = string2UUIDStash.get(name.toLowerCase(Locale.ROOT)); + /** + * Get player uuid from its name + * + * @param name the player name, case ignored + * @param includingBlockingWebReq whether to use web request, may result blocking server thread + * @param checkOfflinePlayer whether to check offline player, beware that should be a large cost for some times + * @return the uuid of this player name, null when [includingBlockingWebReq] is false + */ + @Nullable + public static UUID findUUIDByName(String name, boolean includingBlockingWebReq, boolean checkOfflinePlayer) { + + UUID uuid = name2UUIDCache.getIfPresent(name.toLowerCase(Locale.ROOT)); + + if (uuid == null && useOfflineStash) { + uuid = name2UUIDStash.get(name.toLowerCase(Locale.ROOT)); } if (uuid != null) { - return Bukkit.getOfflinePlayer(uuid); + return uuid; } else { Server server = Bukkit.getServer(); - result = findPlayerByName(name, server.getOnlinePlayers(), false); - if (result == null) { - result = findPlayerByName(name, Arrays.asList(server.getOfflinePlayers()), true); + //Online + PlayerProfile profile = findProfileByName(name, server.getOnlinePlayers(), false); + //Offline + if (!useOfflineStash && checkOfflinePlayer && profile == null) { + profile = findProfileByName(name, Arrays.asList(server.getOfflinePlayers()), true); } - if (result == null) { - result = Bukkit.getServer().getOfflinePlayer(name); + //Blocking web request/querying user cache + //TODO:Adding timeout + if (profile == null && includingBlockingWebReq) { + OfflinePlayer player = Bukkit.getServer().getOfflinePlayer(name); + profile = new PlayerProfile(player.getName(), player.getUniqueId()); + } + + if (profile == null) { + return null; } - string2UUIDCache.put(name.toLowerCase(Locale.ROOT), result.getUniqueId()); + puttingToCache(profile.getName(), profile.getUuid()); + return profile.getUuid(); + } + } + + /** + * Get player name from its uuid + * + * @param uuid the player uuid + * @return the player name, null when it does not exist in local + */ + @Nullable + public static String findNameByUUID(UUID uuid) { + if (emptyNameUUIDSet.contains(uuid)) { + return null; + } + String result = uuid2StringCache.getIfPresent(uuid); + if (result == null) { + OfflinePlayer player = findOfflinePlayerByUUID(uuid); + result = player.getName(); + puttingToCache(result, uuid); } return result; } + @Data + @AllArgsConstructor + public static class PlayerProfile { + @Nullable + private String name; + @NotNull + private UUID uuid; + + public Trader getTrader() { + return Trader.adapt(this); + } + + public OfflinePlayer getOfflinePlayer() { + return Bukkit.getOfflinePlayer(uuid); + } + } + public static OfflinePlayer findOfflinePlayerByUUID(UUID uuid) { return Bukkit.getOfflinePlayer(uuid); } diff --git a/src/main/java/org/maxgamer/quickshop/util/Util.java b/src/main/java/org/maxgamer/quickshop/util/Util.java index b13788bdfc..65173994f0 100644 --- a/src/main/java/org/maxgamer/quickshop/util/Util.java +++ b/src/main/java/org/maxgamer/quickshop/util/Util.java @@ -94,6 +94,7 @@ import java.util.EnumSet; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; @@ -551,7 +552,9 @@ public static String getItemCustomName(@NotNull ItemStack itemStack) { } else if (potionMeta.hasCustomEffects()) { PotionEffect potionEffect = potionMeta.getCustomEffects().get(0); if (potionEffect != null) { - int level = potionEffect.getAmplifier(); + // https://hub.spigotmc.org/jira/browse/SPIGOT-1697 + // Internal api notes: amplifier starts from zero, so plus one to get the correct result + int level = potionEffect.getAmplifier() + 1; return MsgUtil.getPotioni18n(potionEffect.getType()) + " " + (level <= 10 ? RomanNumber.toRoman(potionEffect.getAmplifier()) : level); } } @@ -576,6 +579,34 @@ public static String getItemStackName(@NotNull ItemStack itemStack) { return result == null ? MsgUtil.getItemi18n(itemStack.getType().name()) : result; } + /** + * Check all enchantments on a book and return true if they contain the + * nameToMatch + * + * @param itemStack The enchanted book itemstack + * @param nameToMatch The name of the enchant to check the book for + * @return The names of enchants contained on the enchanted book + */ + @NotNull + public static boolean isBookEnchantmentsMatched(@NotNull ItemStack itemStack, @NotNull String nameToMatch) { + if (itemStack.getType() == Material.ENCHANTED_BOOK) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (!(itemMeta instanceof EnchantmentStorageMeta)) + return false; + EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) itemStack.getItemMeta(); + if (enchantmentStorageMeta.hasStoredEnchants()) { + for (Enchantment enchantment : enchantmentStorageMeta.getStoredEnchants().keySet()) { + nameToMatch = nameToMatch.toUpperCase(Locale.ROOT); + if (enchantment.getKey().getKey().toUpperCase(Locale.ROOT).contains(nameToMatch) + || MsgUtil.getEnchi18n(enchantment).toUpperCase(Locale.ROOT).contains(nameToMatch)) { + return true; + } + } + } + } + return false; + } + @NotNull public static String getFirstEnchantmentName(@NotNull EnchantmentStorageMeta meta) { if (!meta.hasStoredEnchants()) { @@ -1165,7 +1196,7 @@ public static String parseColours(@Nullable String text) { parser.reset(); //A hack for saving reset character text = text.replace("&r", "&l&r").replace("§r", "§l§r"); - return toLegacyText(parser.enable(MineDownParser.Option.LEGACY_COLORS).backwardsCompatibility(true).parse(text).create()); + return toLegacyText(parser.enable(MineDownParser.Option.LEGACY_COLORS).enable(MineDownParser.Option.APPEND_COLORS_TO_EMPTY_STRING).backwardsCompatibility(true).parse(text).create()); } /** diff --git a/src/main/java/org/maxgamer/quickshop/util/compatibility/SimpleCompatibilityManager.java b/src/main/java/org/maxgamer/quickshop/util/compatibility/SimpleCompatibilityManager.java index ccb3851d90..a43892281d 100644 --- a/src/main/java/org/maxgamer/quickshop/util/compatibility/SimpleCompatibilityManager.java +++ b/src/main/java/org/maxgamer/quickshop/util/compatibility/SimpleCompatibilityManager.java @@ -102,6 +102,7 @@ public void unregisterAll() { public void register(@NotNull CompatibilityModule module) { if (!registeredModules.containsKey(module.getName())) { plugin.getLogger().info("Registering " + module.getName() + " Compatibility Module"); + module.register(); registeredModules.put(module.getName(), module); } } @@ -128,12 +129,16 @@ public void register(@NotNull Class compatibility @Override public void unregister(@NotNull String moduleName) { plugin.getLogger().info("Unregistering " + moduleName + " compatibility module"); - registeredModules.remove(moduleName); + CompatibilityModule module = registeredModules.remove(moduleName); + if (module != null) { + module.unregister(); + } } @Override public void unregister(@NotNull CompatibilityModule module) { plugin.getLogger().info("Unregistering " + module.getName() + " compatibility module"); registeredModules.remove(module.getName()); + module.unregister(); } } diff --git a/src/main/java/org/maxgamer/quickshop/util/compatibility/SpartanCompatibilityModule.java b/src/main/java/org/maxgamer/quickshop/util/compatibility/SpartanCompatibilityModule.java index efdea4cb82..767eb601f6 100644 --- a/src/main/java/org/maxgamer/quickshop/util/compatibility/SpartanCompatibilityModule.java +++ b/src/main/java/org/maxgamer/quickshop/util/compatibility/SpartanCompatibilityModule.java @@ -21,34 +21,63 @@ 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; -public class SpartanCompatibilityModule extends AbstractQSCompatibilityModule { +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 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() diff --git a/src/main/java/org/maxgamer/quickshop/util/economyformatter/EconomyFormatter.java b/src/main/java/org/maxgamer/quickshop/util/economyformatter/EconomyFormatter.java index 5ac1ea16e5..a198b36c66 100644 --- a/src/main/java/org/maxgamer/quickshop/util/economyformatter/EconomyFormatter.java +++ b/src/main/java/org/maxgamer/quickshop/util/economyformatter/EconomyFormatter.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.maxgamer.quickshop.QuickShop; +import org.maxgamer.quickshop.api.economy.AbstractEconomy; import org.maxgamer.quickshop.api.shop.Shop; import org.maxgamer.quickshop.util.MsgUtil; import org.maxgamer.quickshop.util.Util; @@ -99,11 +100,12 @@ public String format(double n, boolean internalFormat, @NotNull World world, @Nu @NotNull public String format(double n, boolean internalFormat, @NotNull World world, @Nullable String currency) { - if (internalFormat) { + AbstractEconomy economy = QuickShop.getInstance().getEconomy(); + if (internalFormat || economy == null) { return getInternalFormat(n, currency); } try { - String formatted = QuickShop.getInstance().getEconomy().format(n, world, currency); + String formatted = economy.format(n, world, currency); if (StringUtils.isEmpty(formatted)) { Util.debugLog( "Use alternate-currency-symbol to formatting, Cause economy plugin returned null"); diff --git a/src/main/java/org/maxgamer/quickshop/util/envcheck/EnvironmentChecker.java b/src/main/java/org/maxgamer/quickshop/util/envcheck/EnvironmentChecker.java index 053c4f3c1c..2341b91767 100644 --- a/src/main/java/org/maxgamer/quickshop/util/envcheck/EnvironmentChecker.java +++ b/src/main/java/org/maxgamer/quickshop/util/envcheck/EnvironmentChecker.java @@ -27,14 +27,25 @@ 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.*; +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.*; +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; @@ -411,7 +422,7 @@ public ResultContainer virtualDisplaySupportTest() { GameVersion gameVersion = GameVersion.get(nmsVersion); Throwable throwable; if (!gameVersion.isVirtualDisplaySupports()) { - throwable = new IllegalStateException("Version not supports Virtual DisplayItem."); + throwable = new IllegalStateException("This game version " + gameVersion + " not supports Virtual DisplayItem."); } else { if (plugin.getServer().getPluginManager().getPlugin("ProtocolLib") != null) { throwable = VirtualDisplayItem.PacketFactory.testFakeItem(); @@ -451,13 +462,14 @@ public ResultContainer plapiConflictTest() { 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() { diff --git a/src/main/java/org/maxgamer/quickshop/watcher/OngoingFeeWatcher.java b/src/main/java/org/maxgamer/quickshop/watcher/OngoingFeeWatcher.java index 4bb0d2cac3..74e992c64d 100644 --- a/src/main/java/org/maxgamer/quickshop/watcher/OngoingFeeWatcher.java +++ b/src/main/java/org/maxgamer/quickshop/watcher/OngoingFeeWatcher.java @@ -19,7 +19,6 @@ package org.maxgamer.quickshop.watcher; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.scheduler.BukkitRunnable; @@ -33,6 +32,7 @@ import org.maxgamer.quickshop.shop.ShopTransactionMessageContainer; import org.maxgamer.quickshop.shop.SimpleShopManager; import org.maxgamer.quickshop.util.MsgUtil; +import org.maxgamer.quickshop.util.PlayerFinder; import org.maxgamer.quickshop.util.Util; import org.maxgamer.quickshop.util.WarningSender; @@ -77,7 +77,7 @@ public void run() { if (allowLoan || plugin.getEconomy().getBalance(shopOwner, Objects.requireNonNull(world), shop.getCurrency()) >= cost) { Trader taxAccount; if (shop.getTaxAccount() != null) { - taxAccount = Trader.adapt(Bukkit.getOfflinePlayer(shop.getTaxAccount())); + taxAccount = Trader.adapt(PlayerFinder.findOfflinePlayerByUUID(shop.getTaxAccount())); } else { taxAccount = ((SimpleShopManager) plugin.getShopManager()).getCacheTaxAccount(); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 25156a8d56..5bf4b80bdd 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ # QuickShop-Reremake Plugin Configuration #Do not touch this if you don't know what you're doing! -config-version: 162 +config-version: 163 #Set the default language code the plugin should use, it will apply to: #Item Name @@ -14,7 +14,11 @@ config-version: 162 game-language: default #Choose which languages should be enabled -#Any client connect to server that using disabled language, will fallback to game-language option there +#All clients connect to server that using disabled language using following fallback logic: +# 1. if just one language was enabled, then it will use this language (Static language) +# 2. if not, it will use the value of game-language option there +# 3. if still could not find a valid language, it will use built-in en_us language +# #Set to - '*' to enable all available languages #The language files will automatically update thorough Crowdin OTA system, you can translate it there: #https://crowdin.com/project/quickshop-reremake @@ -96,6 +100,12 @@ updater: true #It will also create a paste for data-recovery or debug when the server boots up. auto-report-errors: true +#Should QS including offline player for the command which needed the specified player? +#This might improve player experience, but can cause lag for large amount of offline player +#false = Only include OnlinePlayer +#true = Include all players that have ever joined your server. +include-offlineplayer-for-command: false + #Should QS use OfflinePlayer list for TabComplete? #This might improve player experience, but may cause lag due to searching what can be a long list. #false = Only use the OnlinePlayer list. diff --git a/src/main/resources/lang/messages.json b/src/main/resources/lang/messages.json index ab8edfa270..728d2daec2 100644 --- a/src/main/resources/lang/messages.json +++ b/src/main/resources/lang/messages.json @@ -5,7 +5,7 @@ "translation-version": "Support Version: Reremake", "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood, Mgazul, JackTheChicken and Andre_601", "translation-country": "Language Zone: English (en_US)", - "language-version": "65", + "language-version": "66", "not-looking-at-valid-shop-block": "&cCould not find a block for creating shop. You need to look at one.", "not-looking-at-shop": "&cCould not find a QuickShop. You need to look at one.", "no-anythings-in-your-hand": "&cThere is nothing in your hand.", @@ -79,7 +79,7 @@ "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning:&c The data is kept public for one week! It may leak your server configuration and other sensitive information. Make sure you only send it to <rusted staff/developers.", "price-too-high": "&cThe shop price is too high! You cannot create one with a price higher than {0}.", "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", - "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "unknown-player": "&cTarget player doesn't existed or not online, please check the username you typed.", "shop-staff-cleared": "&aSuccessfully removed all staff members from your shop.", "shop-staff-added": "&aSuccessfully added {0} as a staff member for your shop.", "shop-staff-deleted": "&aSuccessfully removed {0} as a staff member for your shop.", diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1406cf065a..b9ac546046 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -45,6 +45,7 @@ softdepend: - Reserve - PlaceholderAPI - NoCheatPlus + - Spartan - LuckPerms - PermissionEx - GroupManager @@ -66,7 +67,6 @@ softdepend: - OpenInv - WorldEdit - AdvancedRegionMarket - - ArmShopBridge - IridiumSkyblock - FabledSkyblock - NBTAPI diff --git a/src/test/java/org/maxgamer/quickshop/TestBukkitBase.java b/src/test/java/org/maxgamer/quickshop/TestBukkitBase.java index cbd366c701..aa55a287fe 100644 --- a/src/test/java/org/maxgamer/quickshop/TestBukkitBase.java +++ b/src/test/java/org/maxgamer/quickshop/TestBukkitBase.java @@ -21,7 +21,7 @@ public static void setUp() { 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, ""); + CROWDIN_OTA_HOST.set(null, "http://0.0.0.0"); } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } diff --git a/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest.java b/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest.java index 204b068a9f..4a25492603 100644 --- a/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest.java +++ b/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest.java @@ -21,10 +21,11 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.maxgamer.quickshop.TestBukkitBase; import java.util.Optional; -public class MojangAPITest { +public class MojangAPITest extends TestBukkitBase { @Test public void testMojangMetaApi() { MojangAPI api = new MojangAPI(new MojangApiOfficialMirror()); diff --git a/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_BMCLAPI.java b/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_BMCLAPI.java index 3893921394..cd2fb795b9 100644 --- a/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_BMCLAPI.java +++ b/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_BMCLAPI.java @@ -21,10 +21,11 @@ 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 { +public class MojangAPITest_BMCLAPI extends TestBukkitBase { @Test public void testMojangMetaApi() { MojangAPI api = new MojangAPI(new MojangApiBmclApiMirror()); diff --git a/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_MCBBSAPI.java b/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_MCBBSAPI.java index feac04cc7a..48f6426b49 100644 --- a/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_MCBBSAPI.java +++ b/src/test/java/org/maxgamer/quickshop/util/mojangapi/MojangAPITest_MCBBSAPI.java @@ -21,10 +21,11 @@ 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 { +public class MojangAPITest_MCBBSAPI extends TestBukkitBase { @Test public void testMojangMetaApi() { MojangAPI api = new MojangAPI(new MojangApiMcbbsApiMirror());