From 3684e32ac028164e083c7b92d9dadfdf936ccb3d Mon Sep 17 00:00:00 2001 From: Andre_601 Date: Wed, 4 Dec 2024 15:00:51 +0100 Subject: [PATCH 1/9] Update Common Issues page link in issue-template --- .github/ISSUE_TEMPLATE/bug_report.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 77f7217..3f2f845 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -18,13 +18,13 @@ body: label: Confirmation description: Please make sure to have followed the following checks. options: - - label: My issue isn't already found on the Issue tracker. + - label: "My issue isn't already found on the Issue tracker." required: true - - label: My issue is about **PlaceholderAPI** and not any expansion or external plugin + - label: "My issue is about **PlaceholderAPI** and not any expansion or external plugin." required: true - - label: The issue isn't already fixed in a Spigot Release or Development Build. + - label: "The issue isn't already fixed in a Spigot Release or Development Build." required: true - - label: The [Common Issues](https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Common-Issues) page doesn't mention this issue. + - label: "The [Common Issues](https://wiki.placeholderapi.com/common-issues/) page doesn't mention this issue." required: true - type: dropdown attributes: @@ -85,6 +85,8 @@ body: description: |- Get the latest content of your `latest.log` file an upload it to https://paste.helpch.at Take the generated URL and paste it into this field. + + **Always provide the full `latest.log` and not just parts of it or just the error (if any)!** placeholder: "https://paste.helpch.at/latest.log" - type: input id: "error" @@ -99,5 +101,5 @@ body: description: |- Add any extra info you think is nessesary for this Bug report. - If you selected `API Bug` will you need to include code-examples here to reproduce the issue. - - If you selected `Plugin/Server Incompatability` should you include extra Server info such as a Timings or Spark-Report or info about the plugin in question. + - If you selected `Plugin/Server Incompatability` should you include extra Server info such as Spark-Report or info about the plugin in question. placeholder: "Put any extra info you like into this field..." From 6c5f19b61d2ae14279bfeb6cb98a110d055b8690 Mon Sep 17 00:00:00 2001 From: PiggyPiglet Date: Sun, 8 Feb 2026 20:02:02 +0800 Subject: [PATCH 2/9] Fix #1167 --- .../me/clip/placeholderapi/updatechecker/UpdateChecker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java index 694afcf..a9f70a6 100644 --- a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java @@ -26,8 +26,8 @@ import java.net.URL; import java.util.Arrays; import javax.net.ssl.HttpsURLConnection; +import com.google.gson.Gson; import com.google.gson.JsonElement; -import com.google.gson.JsonParser; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.scheduler.scheduling.schedulers.TaskScheduler; import me.clip.placeholderapi.util.Msg; @@ -66,7 +66,7 @@ public class UpdateChecker implements Listener { try { HttpsURLConnection con = (HttpsURLConnection) new URL(MODRINTH_URL).openConnection(); con.setRequestMethod("GET"); - final JsonElement json = JsonParser.parseReader(new BufferedReader(new InputStreamReader(con.getInputStream()))); + final JsonElement json = new Gson().fromJson(new BufferedReader(new InputStreamReader(con.getInputStream())), JsonElement.class); modrinthVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("version_number").getAsString(); } catch (Exception ex) { plugin.getLogger().info("Failed to check for updates on modrinth."); From 0a53559ae1c6df2a65cec035e3b69bffb599d9ef Mon Sep 17 00:00:00 2001 From: PiggyPiglet Date: Sun, 8 Feb 2026 20:09:01 +0800 Subject: [PATCH 3/9] 2.12.2 release --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index c5cf45b..34e7816 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "me.clip" -version = "2.12.2-DEV-${System.getProperty("BUILD_NUMBER")}" +version = "2.12.2" description = "An awesome placeholder provider!" From 0d1a356e0ff47bf1af213d1c86303a5074e86862 Mon Sep 17 00:00:00 2001 From: PiggyPiglet Date: Mon, 9 Feb 2026 01:02:32 +0800 Subject: [PATCH 4/9] ExpansionSafety: Fix NPE & Only check files not directories --- .../placeholderapi/util/ExpansionSafetyCheck.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/clip/placeholderapi/util/ExpansionSafetyCheck.java b/src/main/java/me/clip/placeholderapi/util/ExpansionSafetyCheck.java index 365fb36..5b7e810 100644 --- a/src/main/java/me/clip/placeholderapi/util/ExpansionSafetyCheck.java +++ b/src/main/java/me/clip/placeholderapi/util/ExpansionSafetyCheck.java @@ -55,9 +55,18 @@ public final class ExpansionSafetyCheck { } final Set maliciousPaths = new HashSet<>(); + final File[] files = expansionsFolder.listFiles(); - for (File file : expansionsFolder.listFiles()) { + if (files == null) { + return false; + } + + for (File file : files) { try { + if (!file.isFile()) { + continue; + } + final String hash = Hashing.sha256().hashBytes(Files.asByteSource(file).read()).toString(); if (knownMaliciousExpansions.contains(hash)) { From e187eb640231c6a72f3c6e3f80e975b4223f6db1 Mon Sep 17 00:00:00 2001 From: PiggyPiglet Date: Mon, 9 Feb 2026 01:05:57 +0800 Subject: [PATCH 5/9] 2.12.3-dev --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 34e7816..36c1891 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { } group = "me.clip" -version = "2.12.2" +version = "2.12.3-DEV-${System.getProperty("BUILD_NUMBER")}" description = "An awesome placeholder provider!" From f267887b5e3728cb5cc1a62983b6fa8cebf40821 Mon Sep 17 00:00:00 2001 From: Andre_601 <11576465+Andre601@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:20:59 +0100 Subject: [PATCH 6/9] Use wiki PR validation on main branch. --- .github/workflows/pr_wiki_validation.yml | 58 ++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/pr_wiki_validation.yml diff --git a/.github/workflows/pr_wiki_validation.yml b/.github/workflows/pr_wiki_validation.yml new file mode 100644 index 0000000..4453259 --- /dev/null +++ b/.github/workflows/pr_wiki_validation.yml @@ -0,0 +1,58 @@ +# +# Validates Pull requests targeting the wiki branch +# to ensure that the site can be build successfully +# without broken links, navigation, etc. +# +name: "Validate Wiki Build" + +on: + pull_request_target: + types: + - opened + - reopened + - synchronize + paths-ignore: + - "README.md" + branches: + - wiki + workflow_dispatch: + +permissions: + contents: read + issues: write + +env: + RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}" + +jobs: + buildWiki: + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v6 + with: + fetch-depth: 0 + ref: "${{ github.event.pull_request.head.sha }}" + - name: "Setup Python 3.x" + uses: actions/setup-python@v6 + with: + python-version: 3.x + - name: "Install dependencies" + run: "pip install -r requirements.txt" + - name: "Build Site" + run: "mkdocs build --strict" + commentOnFail: + runs-on: ubuntu-latest + if: ${{ failure() }} + steps: + - name: "Create Comment" + uses: peter-evans/create-or-update-comment@v5 + with: + body: |- + ## Wiki Build failure + + Something went wrong while creating a test-build of the Wiki for this Pull request. + Please check the [Workflow Logs](${{ env.RUN_URL }}) for any errors. + issue-number: "${{ github.event.pull_request.number }}" + token: "${{ secrets.GITHUB_TOKEN }}" + edit-mode: replace From 7b8550c3f1fa8ba2e21c6dd19a5f7bf9315e507d Mon Sep 17 00:00:00 2001 From: Andre_601 <11576465+Andre601@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:28:11 +0100 Subject: [PATCH 7/9] Fix wrong install command and move comment step --- .github/workflows/pr_wiki_validation.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr_wiki_validation.yml b/.github/workflows/pr_wiki_validation.yml index 4453259..f247eed 100644 --- a/.github/workflows/pr_wiki_validation.yml +++ b/.github/workflows/pr_wiki_validation.yml @@ -38,15 +38,12 @@ jobs: with: python-version: 3.x - name: "Install dependencies" - run: "pip install -r requirements.txt" + run: "python -m pip install mkdocs-material" - name: "Build Site" run: "mkdocs build --strict" - commentOnFail: - runs-on: ubuntu-latest - if: ${{ failure() }} - steps: - name: "Create Comment" uses: peter-evans/create-or-update-comment@v5 + if: ${{ failure() }} with: body: |- ## Wiki Build failure From 64b3d6fa680cb08c6540d4e10681d7bbc02c8593 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:05:20 +0200 Subject: [PATCH 8/9] Make setPlaceholders behavior consistent with setRelationalPlaceholders --- .../clip/placeholderapi/replacer/CharsReplacer.java | 12 +++++++----- src/test/java/me/clip/placeholderapi/Values.java | 5 +++++ .../placeholderapi/replacer/ReplacerUnitTester.java | 13 +++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java index 8f0af63..fc6fa4a 100644 --- a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java +++ b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java @@ -2,7 +2,7 @@ * This file is part of PlaceholderAPI * * PlaceholderAPI - * Copyright (c) 2015 - 2026 PlaceholderAPI Team + * Copyright (c) 2015 - 2024 PlaceholderAPI Team * * PlaceholderAPI free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,9 +22,7 @@ package me.clip.placeholderapi.replacer; import java.util.Locale; import java.util.function.Function; - import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -68,10 +66,14 @@ public final class CharsReplacer implements Replacer { hadSpace = true; break; } - if (p == closure.tail) { + if (p == closure.tail && identified) { invalid = false; break; } + if (p == closure.tail) { + identifier.append(p); + break; + } if (p == '_' && !identified) { identified = true; @@ -135,4 +137,4 @@ public final class CharsReplacer implements Replacer { return builder.toString(); } -} +} \ No newline at end of file diff --git a/src/test/java/me/clip/placeholderapi/Values.java b/src/test/java/me/clip/placeholderapi/Values.java index 11e0459..55c01a9 100644 --- a/src/test/java/me/clip/placeholderapi/Values.java +++ b/src/test/java/me/clip/placeholderapi/Values.java @@ -30,6 +30,8 @@ import org.jetbrains.annotations.Nullable; public interface Values { + String NO_ARGUMENTS_PLACEHOLDER = "%player%"; + String EMPTY_ARGUMENT_PLACEHOLDER = "%player_%"; String SMALL_TEXT = "My name is %player_name%"; String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%"; @@ -43,6 +45,7 @@ public interface Values { final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion { + public static final String EMPTY_ARGUMENT = "Empty Argument"; public static final String PLAYER_X = "10"; public static final String PLAYER_Y = "20"; public static final String PLAYER_Z = "30"; @@ -83,6 +86,8 @@ public interface Values { return PLAYER_Y; case "z": return PLAYER_Z; + case "": + return EMPTY_ARGUMENT; } return null; diff --git a/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java b/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java index fcc886d..5529a47 100644 --- a/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java +++ b/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java @@ -24,6 +24,7 @@ import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYE import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_X; import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_Y; import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_Z; +import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.EMPTY_ARGUMENT; import static org.junit.jupiter.api.Assertions.assertEquals; import me.clip.placeholderapi.Values; @@ -37,6 +38,18 @@ public final class ReplacerUnitTester { Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get)); } + @Test + void charsReplacersDoesNotParsePlaceholdersWithNoArguments() { + assertEquals(Values.NO_ARGUMENTS_PLACEHOLDER, + Values.CHARS_REPLACER.apply(Values.NO_ARGUMENTS_PLACEHOLDER, null, Values.PLACEHOLDERS::get)); + } + + @Test + void charsReplacersParsesPlaceholdersWithOneArgumentThatIsEmpty() { + assertEquals(EMPTY_ARGUMENT, + Values.CHARS_REPLACER.apply(Values.EMPTY_ARGUMENT_PLACEHOLDER, null, Values.PLACEHOLDERS::get)); + } + @Test void testCharsReplacerProducesExpectedSentence() { assertEquals(String.format( From 566beb48c53345ac0017665598049e335be9d681 Mon Sep 17 00:00:00 2001 From: BlitzOffline <52609756+BlitzOffline@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:06:35 +0200 Subject: [PATCH 9/9] Fix copyright --- .../java/me/clip/placeholderapi/replacer/CharsReplacer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java index fc6fa4a..a0fe4dc 100644 --- a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java +++ b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java @@ -2,7 +2,7 @@ * This file is part of PlaceholderAPI * * PlaceholderAPI - * Copyright (c) 2015 - 2024 PlaceholderAPI Team + * Copyright (c) 2015 - 2026 PlaceholderAPI Team * * PlaceholderAPI free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -137,4 +137,4 @@ public final class CharsReplacer implements Replacer { return builder.toString(); } -} \ No newline at end of file +}