diff --git a/.gradle/9.6.1/checksums/checksums.lock b/.gradle/9.6.1/checksums/checksums.lock new file mode 100644 index 0000000..65aff3f Binary files /dev/null and b/.gradle/9.6.1/checksums/checksums.lock differ diff --git a/.gradle/9.6.1/checksums/md5-checksums.bin b/.gradle/9.6.1/checksums/md5-checksums.bin new file mode 100644 index 0000000..7c299e7 Binary files /dev/null and b/.gradle/9.6.1/checksums/md5-checksums.bin differ diff --git a/.gradle/9.6.1/checksums/sha1-checksums.bin b/.gradle/9.6.1/checksums/sha1-checksums.bin new file mode 100644 index 0000000..c387a39 Binary files /dev/null and b/.gradle/9.6.1/checksums/sha1-checksums.bin differ diff --git a/.gradle/9.6.1/executionHistory/executionHistory.bin b/.gradle/9.6.1/executionHistory/executionHistory.bin new file mode 100644 index 0000000..04941a5 Binary files /dev/null and b/.gradle/9.6.1/executionHistory/executionHistory.bin differ diff --git a/.gradle/9.6.1/executionHistory/executionHistory.lock b/.gradle/9.6.1/executionHistory/executionHistory.lock new file mode 100644 index 0000000..beb0bb8 Binary files /dev/null and b/.gradle/9.6.1/executionHistory/executionHistory.lock differ diff --git a/.gradle/9.6.1/fileChanges/last-build.bin b/.gradle/9.6.1/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/9.6.1/fileChanges/last-build.bin differ diff --git a/.gradle/9.6.1/fileHashes/fileHashes.bin b/.gradle/9.6.1/fileHashes/fileHashes.bin new file mode 100644 index 0000000..8831819 Binary files /dev/null and b/.gradle/9.6.1/fileHashes/fileHashes.bin differ diff --git a/.gradle/9.6.1/fileHashes/fileHashes.lock b/.gradle/9.6.1/fileHashes/fileHashes.lock new file mode 100644 index 0000000..25c9e21 Binary files /dev/null and b/.gradle/9.6.1/fileHashes/fileHashes.lock differ diff --git a/.gradle/9.6.1/fileHashes/resourceHashesCache.bin b/.gradle/9.6.1/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000..480b0de Binary files /dev/null and b/.gradle/9.6.1/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/9.6.1/gc.properties b/.gradle/9.6.1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/9.6.1/kotlin-dsl-plugin-entries/kotlin-dsl-plugin-entries.lock b/.gradle/9.6.1/kotlin-dsl-plugin-entries/kotlin-dsl-plugin-entries.lock new file mode 100644 index 0000000..d682852 Binary files /dev/null and b/.gradle/9.6.1/kotlin-dsl-plugin-entries/kotlin-dsl-plugin-entries.lock differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000..3312b10 Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..3d76b0d --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Fri Sep 04 09:55:07 CEST 2026 +gradle.version=9.6.1 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000..28da4bf Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/.globals.work.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/.globals.work.bin new file mode 100644 index 0000000..fb8246c --- /dev/null +++ b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/.globals.work.bin @@ -0,0 +1 @@ + µøD©×OX"�ñs鿚 \ No newline at end of file diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/.strings.work.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/.strings.work.bin new file mode 100644 index 0000000..a829d91 Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/.strings.work.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/_.work.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/_.work.bin new file mode 100644 index 0000000..c57505f Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/_.work.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/buildfingerprint.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/buildfingerprint.bin new file mode 100644 index 0000000..eb41021 Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/buildfingerprint.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/classloaderscopes.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/classloaderscopes.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/classloaderscopes.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/entry.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/entry.bin new file mode 100644 index 0000000..51a99dd Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/entry.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/projectfingerprint.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/projectfingerprint.bin new file mode 100644 index 0000000..de8cae4 Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/projectfingerprint.bin differ diff --git a/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/work.bin b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/work.bin new file mode 100644 index 0000000..976414d Binary files /dev/null and b/.gradle/configuration-cache/04874f85-d75a-4b9f-91ec-9f227f2a0929/work.bin differ diff --git a/.gradle/configuration-cache/0a6fcc7f-203b-41cd-9bee-4149060db226/classloaderscopes13361634749120215098.tmp b/.gradle/configuration-cache/0a6fcc7f-203b-41cd-9bee-4149060db226/classloaderscopes13361634749120215098.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/0a6fcc7f-203b-41cd-9bee-4149060db226/classloaderscopes13361634749120215098.tmp differ diff --git a/.gradle/configuration-cache/1dae3fb7-7c9b-4252-9987-7d0bf4c8a39c/classloaderscopes11303081905500863799.tmp b/.gradle/configuration-cache/1dae3fb7-7c9b-4252-9987-7d0bf4c8a39c/classloaderscopes11303081905500863799.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/1dae3fb7-7c9b-4252-9987-7d0bf4c8a39c/classloaderscopes11303081905500863799.tmp differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/.globals.work.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/.globals.work.bin new file mode 100644 index 0000000..bee2f5f --- /dev/null +++ b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/.globals.work.bin @@ -0,0 +1 @@ +ÑuWiPº¢Ïnì7a¶—àut \ No newline at end of file diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/.strings.work.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/.strings.work.bin new file mode 100644 index 0000000..37e7c85 Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/.strings.work.bin differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/_.work.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/_.work.bin new file mode 100644 index 0000000..30c7309 Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/_.work.bin differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/build.work.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/build.work.bin new file mode 100644 index 0000000..ff3988c --- /dev/null +++ b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/build.work.bin @@ -0,0 +1 @@ +X&¿IÞä�±@áî¦gKŸÁÙÅQ©L% \ No newline at end of file diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/buildfingerprint.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/buildfingerprint.bin new file mode 100644 index 0000000..2abcb27 Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/buildfingerprint.bin differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/classloaderscopes.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/classloaderscopes.bin new file mode 100644 index 0000000..ba9450a Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/classloaderscopes.bin differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/entry.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/entry.bin new file mode 100644 index 0000000..580a410 Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/entry.bin differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/projectfingerprint.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/projectfingerprint.bin new file mode 100644 index 0000000..434380a Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/projectfingerprint.bin differ diff --git a/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/work.bin b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/work.bin new file mode 100644 index 0000000..6642e13 Binary files /dev/null and b/.gradle/configuration-cache/341fbea8-17c8-4ff9-abb1-8cf0a8d07b36/work.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/.globals.work.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/.globals.work.bin new file mode 100644 index 0000000..fdafe58 --- /dev/null +++ b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/.globals.work.bin @@ -0,0 +1 @@ +®=Ãps_ïćì²;m«KRáò \ No newline at end of file diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/.strings.work.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/.strings.work.bin new file mode 100644 index 0000000..115b2b3 Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/.strings.work.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/_.work.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/_.work.bin new file mode 100644 index 0000000..afeda6a Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/_.work.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/buildfingerprint.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/buildfingerprint.bin new file mode 100644 index 0000000..875a32d Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/buildfingerprint.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/classloaderscopes.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/classloaderscopes.bin new file mode 100644 index 0000000..ba9450a Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/classloaderscopes.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/entry.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/entry.bin new file mode 100644 index 0000000..df96cfa Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/entry.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/projectfingerprint.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/projectfingerprint.bin new file mode 100644 index 0000000..25a6e4c Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/projectfingerprint.bin differ diff --git a/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/work.bin b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/work.bin new file mode 100644 index 0000000..a203861 Binary files /dev/null and b/.gradle/configuration-cache/4ad0b03c-7d47-4056-990b-3a93c3db11fa/work.bin differ diff --git a/.gradle/configuration-cache/7014d45d-1419-4a4c-8a3a-ef9442bc9fb4/classloaderscopes16220690481779945732.tmp b/.gradle/configuration-cache/7014d45d-1419-4a4c-8a3a-ef9442bc9fb4/classloaderscopes16220690481779945732.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/7014d45d-1419-4a4c-8a3a-ef9442bc9fb4/classloaderscopes16220690481779945732.tmp differ diff --git a/.gradle/configuration-cache/9291a06f-3306-48d6-9bf2-f3df3a9ed90d/classloaderscopes17273679322066117525.tmp b/.gradle/configuration-cache/9291a06f-3306-48d6-9bf2-f3df3a9ed90d/classloaderscopes17273679322066117525.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/9291a06f-3306-48d6-9bf2-f3df3a9ed90d/classloaderscopes17273679322066117525.tmp differ diff --git a/.gradle/configuration-cache/ai52j6yn7dodllvdf53pkfm4n/candidates.bin b/.gradle/configuration-cache/ai52j6yn7dodllvdf53pkfm4n/candidates.bin new file mode 100644 index 0000000..9c96d90 --- /dev/null +++ b/.gradle/configuration-cache/ai52j6yn7dodllvdf53pkfm4n/candidates.bin @@ -0,0 +1 @@ +04874f85-d75a-4b9f-91ec-9f227f2a092¹ \ No newline at end of file diff --git a/.gradle/configuration-cache/ar1d6jr1dzfkx6v3l38d47pb9/candidates.bin b/.gradle/configuration-cache/ar1d6jr1dzfkx6v3l38d47pb9/candidates.bin new file mode 100644 index 0000000..c62b9bb --- /dev/null +++ b/.gradle/configuration-cache/ar1d6jr1dzfkx6v3l38d47pb9/candidates.bin @@ -0,0 +1 @@ +341fbea8-17c8-4ff9-abb1-8cf0a8d07b3¶ \ No newline at end of file diff --git a/.gradle/configuration-cache/bd41d510-ed22-45ce-940f-f06d19f20a88/classloaderscopes16335041072390187000.tmp b/.gradle/configuration-cache/bd41d510-ed22-45ce-940f-f06d19f20a88/classloaderscopes16335041072390187000.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/bd41d510-ed22-45ce-940f-f06d19f20a88/classloaderscopes16335041072390187000.tmp differ diff --git a/.gradle/configuration-cache/c98bcd8d-0cc5-4259-9c8e-1d8f73264445/classloaderscopes16498410897654978536.tmp b/.gradle/configuration-cache/c98bcd8d-0cc5-4259-9c8e-1d8f73264445/classloaderscopes16498410897654978536.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/c98bcd8d-0cc5-4259-9c8e-1d8f73264445/classloaderscopes16498410897654978536.tmp differ diff --git a/.gradle/configuration-cache/configuration-cache.lock b/.gradle/configuration-cache/configuration-cache.lock new file mode 100644 index 0000000..7d34d4f Binary files /dev/null and b/.gradle/configuration-cache/configuration-cache.lock differ diff --git a/.gradle/configuration-cache/dm175kxwzsruj0sogx306vr1b/candidates.bin b/.gradle/configuration-cache/dm175kxwzsruj0sogx306vr1b/candidates.bin new file mode 100644 index 0000000..03c6cb1 --- /dev/null +++ b/.gradle/configuration-cache/dm175kxwzsruj0sogx306vr1b/candidates.bin @@ -0,0 +1 @@ +4ad0b03c-7d47-4056-990b-3a93c3db11fá \ No newline at end of file diff --git a/.gradle/configuration-cache/fd7352ca-cea3-478e-947e-acba6f17b48b/classloaderscopes13362262299681345635.tmp b/.gradle/configuration-cache/fd7352ca-cea3-478e-947e-acba6f17b48b/classloaderscopes13362262299681345635.tmp new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/configuration-cache/fd7352ca-cea3-478e-947e-acba6f17b48b/classloaderscopes13362262299681345635.tmp differ diff --git a/.gradle/configuration-cache/gc.properties b/.gradle/configuration-cache/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe new file mode 100644 index 0000000..462509e Binary files /dev/null and b/.gradle/file-system.probe differ diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f3f4f83 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index dece6c5..3c73da5 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A quality-of-life SMP plugin for Paper/Folia. - **Join messages** — friendly welcome messages, including a first-join message that lists the server's plugins, and a special announcement when the owner logs in. - **`/nopvp`** — toggle no-PvP mode. While active you cannot damage other players and other players cannot damage you (direct hits and projectiles). While enabled you also glow so everyone can see you're protected. Turning no-PvP *off* starts a **1-hour cooldown** before you can enable it again, and the state persists across restarts so relogging can't bypass it. +- **Anti-combat-logging** — whenever you hit another player or get hit by one, you're tagged as being in combat for **15 seconds** with a chat warning. Logging off while tagged kills you on the spot and announces it to the server. ## Commands @@ -27,9 +28,11 @@ Player no-PvP state and cooldown timestamps are stored in `plugins/qol-tweaks/no ## Building ```bash -./gradlew build +./build.sh ``` +This just runs `./gradlew build`, but if the pinned Java toolchain isn't installed it will automatically fall back to whatever JDK you do have (keeping the jar's bytecode compatible). You can also pass extra Gradle args, e.g. `./build.sh clean build`. + The plugin jar is output to `build/libs/`. ## License diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..ac51b7e --- /dev/null +++ b/build.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# Builds the qol-tweaks plugin jar. +# +# The build pins a Java toolchain version in build.gradle.kts. This script +# finds that version on your machine, and if it isn't installed it transparently +# falls back to the highest JDK that is (so `./build.sh` just works). +# +# Usage: ./build.sh [extra gradle args...] +set -euo pipefail + +cd "$(dirname "$0")" + +# --- 1. which Java version does the build pin? -------------------------------- +pinned="$(grep -oE 'JavaLanguageVersion\.of\([0-9]+\)' build.gradle.kts | grep -oE '[0-9]+' | head -1 || true)" +pinned="${pinned:-25}" + +# --- 2. find an installed JDK for a given version ------------------------------ +java_major() { # $1 = path to java binary; echoes its major version (e.g. 26) + "$1" -version 2>&1 | grep -oE '"([0-9]+)' | head -1 | tr -d '"' +} + +find_java_home() { # $1 = version (e.g. 25); echoes a home whose java matches, or fails + local -a candidates=() + if [[ -x /usr/libexec/java_home ]]; then + local mac_home + if mac_home="$(/usr/libexec/java_home -v "$1" 2>/dev/null)"; then + candidates+=("$mac_home") + fi + fi + [[ -n "${JAVA_HOME:-}" ]] && candidates+=("$JAVA_HOME") + + local home bin ver + for home in "${candidates[@]}"; do + bin="$home/bin/java" + [[ -x "$bin" ]] || continue + ver="$(java_major "$bin")" + if [[ -n "$ver" && "$ver" == "$1" ]]; then + echo "$home" + return 0 + fi + done + return 1 +} + +# --- 3. pick the JDK to build with -------------------------------------------- +selected="" +selected_home="" +for v in "$pinned" 26 25 24 23 22 21 20 17; do + if h="$(find_java_home "$v")"; then + selected="$v" + selected_home="$h" + break + fi +done + +if [[ -z "$selected" ]]; then + echo "error: no JDK found. Install any JDK 17+ (e.g. Java 25) and try again." >&2 + exit 1 +fi + +export JAVA_HOME="$selected_home" +export PATH="$JAVA_HOME/bin:$PATH" + +gradle_args=() +override_init="" + +if [[ "$selected" != "$pinned" ]]; then + echo "note: pinned JDK $pinned not found; building with installed JDK $selected." + override_init="${TMPDIR:-/tmp}/qol-tweaks-toolchain-$pinned-$selected.gradle" + cat > "$override_init" < + if (p.plugins.hasPlugin('java')) { + p.extensions.findByName('java').toolchain.languageVersion.set(JavaLanguageVersion.of($selected)) + p.tasks.withType(JavaCompile).configureEach { + options.release.set($pinned) + } + } +} +EOF + gradle_args+=(-I "$override_init") + # the init script is external input, so a cached configuration would be stale + gradle_args+=(--no-configuration-cache) +fi + +trap '[[ -n "$override_init" ]] && rm -f "$override_init"' EXIT + +if [[ $# -eq 0 ]]; then + gradle_args+=(build) +else + gradle_args+=("$@") +fi + +echo "Using JDK $selected at $JAVA_HOME" +./gradlew "${gradle_args[@]}" + +jar="$(ls -1 build/libs/*.jar 2>/dev/null | grep -Ev '(-sources|-javadoc)\.jar$' | head -1 || true)" +if [[ -n "$jar" ]]; then + echo + echo "Done. Plugin jar: $(pwd)/$jar" +fi diff --git a/src/main/java/com/dvorakmortonxd/qoltweaks/QoLtweaks.java b/src/main/java/com/dvorakmortonxd/qoltweaks/QoLtweaks.java index bc3c3e6..0209929 100644 --- a/src/main/java/com/dvorakmortonxd/qoltweaks/QoLtweaks.java +++ b/src/main/java/com/dvorakmortonxd/qoltweaks/QoLtweaks.java @@ -1,5 +1,7 @@ package com.dvorakmortonxd.qoltweaks; +import com.dvorakmortonxd.qoltweaks.combatlog.CombatLogListener; +import com.dvorakmortonxd.qoltweaks.combatlog.CombatLogManager; import com.dvorakmortonxd.qoltweaks.listeners.JoinListener; import com.dvorakmortonxd.qoltweaks.nopvp.NoPvPCommand; import com.dvorakmortonxd.qoltweaks.nopvp.NoPvPListener; @@ -10,14 +12,17 @@ import org.bukkit.plugin.java.JavaPlugin; public final class QoLtweaks extends JavaPlugin { private NoPvPManager noPvPManager; + private CombatLogManager combatLogManager; @Override public void onEnable() { // Plugin startup logic noPvPManager = new NoPvPManager(this); + combatLogManager = new CombatLogManager(this); getServer().getPluginManager().registerEvents(new JoinListener(), this); getServer().getPluginManager().registerEvents(new NoPvPListener(noPvPManager), this); + getServer().getPluginManager().registerEvents(new CombatLogListener(this, combatLogManager), this); PluginCommand noPvPCommand = getCommand("nopvp"); if (noPvPCommand != null) { @@ -31,5 +36,8 @@ public final class QoLtweaks extends JavaPlugin { if (noPvPManager != null) { noPvPManager.save(); } + if (combatLogManager != null) { + combatLogManager.cancelNotices(); + } } } diff --git a/src/main/java/com/dvorakmortonxd/qoltweaks/combatlog/CombatLogListener.java b/src/main/java/com/dvorakmortonxd/qoltweaks/combatlog/CombatLogListener.java new file mode 100644 index 0000000..347cb7b --- /dev/null +++ b/src/main/java/com/dvorakmortonxd/qoltweaks/combatlog/CombatLogListener.java @@ -0,0 +1,63 @@ +package com.dvorakmortonxd.qoltweaks.combatlog; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +public final class CombatLogListener implements Listener { + + private final JavaPlugin plugin; + private final CombatLogManager manager; + + public CombatLogListener(JavaPlugin plugin, CombatLogManager manager) { + this.plugin = plugin; + this.manager = manager; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof Player victim)) { + return; + } + + Player attacker = resolveAttacker(event.getDamager()); + if (attacker == null) { + return; + } + + if (attacker.getUniqueId().equals(victim.getUniqueId())) { + return; + } + + manager.tag(victim, true); + manager.tag(attacker, false); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + if (!plugin.isEnabled() || player.isDead() || !manager.isTagged(player)) { + return; + } + + player.setHealth(0.0); + plugin.getServer().getOnlinePlayers().forEach(other -> + other.sendMessage("§c" + player.getName() + " combat-logged and died!")); + } + + private Player resolveAttacker(Entity damager) { + if (damager instanceof Player player) { + return player; + } + if (damager instanceof Projectile projectile && projectile.getShooter() instanceof Player player) { + return player; + } + return null; + } +} diff --git a/src/main/java/com/dvorakmortonxd/qoltweaks/combatlog/CombatLogManager.java b/src/main/java/com/dvorakmortonxd/qoltweaks/combatlog/CombatLogManager.java new file mode 100644 index 0000000..79710ea --- /dev/null +++ b/src/main/java/com/dvorakmortonxd/qoltweaks/combatlog/CombatLogManager.java @@ -0,0 +1,70 @@ +package com.dvorakmortonxd.qoltweaks.combatlog; + +import io.papermc.paper.threadedregions.scheduler.ScheduledTask; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public final class CombatLogManager { + + public static final long TAG_MILLIS = 15 * 1000L; // 15 seconds + + private static final String VICTIM_MESSAGE = "§cYou got hit! Don't log off for 15 seconds or you'll insta-die."; + private static final String ATTACKER_MESSAGE = "§cYou hit a player! Don't log off for 15 seconds or you'll insta-die."; + private static final String SAFE_MESSAGE = "§aYou are no longer in combat."; + + private final JavaPlugin plugin; + private final Map taggedUntil = new ConcurrentHashMap<>(); + private final Map notices = new ConcurrentHashMap<>(); + + public CombatLogManager(JavaPlugin plugin) { + this.plugin = plugin; + } + + public void tag(Player player, boolean victim) { + UUID uuid = player.getUniqueId(); + boolean firstTag = !isTagged(player); + taggedUntil.put(uuid, System.currentTimeMillis() + TAG_MILLIS); + + if (firstTag) { + player.sendMessage(victim ? VICTIM_MESSAGE : ATTACKER_MESSAGE); + } + scheduleNotice(player); + } + + public boolean isTagged(Player player) { + return getRemainingMillis(player) > 0; + } + + public long getRemainingMillis(Player player) { + long until = taggedUntil.getOrDefault(player.getUniqueId(), 0L); + return Math.max(0L, until - System.currentTimeMillis()); + } + + private void scheduleNotice(Player player) { + UUID uuid = player.getUniqueId(); + ScheduledTask previous = notices.remove(uuid); + if (previous != null) { + previous.cancel(); + } + long delayTicks = (TAG_MILLIS / 1000L) * 20L; + ScheduledTask task = plugin.getServer().getGlobalRegionScheduler() + .runDelayed(plugin, scheduled -> { + notices.remove(uuid); + if (player.isOnline() && !isTagged(player)) { + player.sendMessage(SAFE_MESSAGE); + } + }, delayTicks); + notices.put(uuid, task); + } + + public void cancelNotices() { + for (ScheduledTask task : notices.values()) { + task.cancel(); + } + notices.clear(); + } +} diff --git a/src/main/java/com/dvorakmortonxd/qoltweaks/listeners/JoinListener.java b/src/main/java/com/dvorakmortonxd/qoltweaks/listeners/JoinListener.java index 4e60057..21b140a 100644 --- a/src/main/java/com/dvorakmortonxd/qoltweaks/listeners/JoinListener.java +++ b/src/main/java/com/dvorakmortonxd/qoltweaks/listeners/JoinListener.java @@ -10,8 +10,20 @@ public class JoinListener implements Listener { public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); + player.sendTitle("§aWelcome to the SMP", "§7on a new world since 4th September 2026", 10, 70, 20); + if (!player.hasPlayedBefore()) { - player.sendMessage("§aWelcome to the SMP, " + player.getName() + "!\nThis is your first time here, so let me tell you whats on here, theres a 3d map of the server at https://bluemap.dvorakmortonxd.dev , theres a voicechat you can optionally install as a mod (Simple Voice Chat), theres a tree chopper plugin you can toggle with /atc, theres veinminer which you can also toggle with /veinminer toggle, theres tradecycle plugin which allows you to cycle thru villagers trades by clicking [F] in any inventory slot while trading and there is ClickVillagers which allows you to pick up villagers into your inventory when shifting and right clicking,\n thats about it, enjoy your game! :3"); + player.sendMessage("§aWelcome to the SMP, " + player.getName() + "!"); + player.sendMessage("This is your first time here, so let me tell you whats on here:"); + player.sendMessage("§7- a 3d map of the server at https://bluemap.dvorakmortonxd.dev"); + player.sendMessage("§7- a voicechat you can optionally install as a mod (Simple Voice Chat)"); + player.sendMessage("§7- a tree chopper plugin you can toggle with /atc"); + player.sendMessage("§7- veinminer, which you can also toggle with /veinminer toggle"); + player.sendMessage("§7- tradecycle, which lets you cycle thru villagers trades by pressing [F] in any inventory slot while trading"); + player.sendMessage("§7- ClickVillagers, which lets you pick up villagers into your inventory by shift-right-clicking"); + player.sendMessage("§7- a /nopvp command to toggle no-pvp mode if you want to build in peace"); + player.sendMessage("§cAbuse of /nopvp is bannable. Also, combat logging is NOT a good idea."); + player.sendMessage("§aThats about it, enjoy your game! :3"); event.setJoinMessage("§e" + player.getName() + " has joined the SMP for the first time!"); } else { if (player.getName().equals("dvorakmortonxd")) {