Compare commits

...

83 Commits
1.7.1 ... 1.8.6

Author SHA1 Message Date
hyperdefined
98ee84ad13 fix handling empty messages 2025-01-18 13:06:38 -05:00
hyperdefined
c68a04851b Update README.md 2024-12-31 13:21:41 -05:00
hyperdefined
06e063a072 Update hangar.yml 2024-12-30 23:29:24 -05:00
hyperdefined
c00c534d49 test complete 2024-12-30 23:28:35 -05:00
hyperdefined
d6f8176ce1 remove deprecated thing 2024-12-30 23:27:11 -05:00
hyperdefined
eb06dff0bc bro 2024-12-30 23:23:36 -05:00
hyperdefined
9a72c509ef hangar API test 2024-12-30 23:22:31 -05:00
hyperdefined
eaca8ac87d Update README.md 2024-12-23 19:24:04 -05:00
hyperdefined
44a2c5cd26 Update README.md 2024-12-23 19:16:29 -05:00
hyperdefined
0957a1c989 Update README.md 2024-12-23 19:07:03 -05:00
hyperdefined
7b12a130a0 1.8.5 2024-12-17 17:47:14 -05:00
hyperdefined
6b263be041 patience wizard 2024-12-15 18:31:38 -05:00
hyperdefined
aeaeee680b revert this since we can now 2024-12-15 18:31:09 -05:00
hyperdefined
d8c7425a5a 1.8.4 2024-12-15 18:29:46 -05:00
hyperdefined
86c92c9706 change these 2024-12-15 17:10:57 -05:00
hyperdefined
cd62f7309e update these 2024-12-14 18:31:14 -05:00
hyperdefined
e2b18cb5f1 Update README.md 2024-12-14 18:06:16 -05:00
hyperdefined
150956b2c9 Update pom.xml 2024-12-14 18:05:01 -05:00
hyperdefined
585e020baf migration to Paper API 2024-12-14 17:28:02 -05:00
hyperdefined
50b5823daf remove debug 2024-10-07 21:19:21 -04:00
hyperdefined
c87d0ca3bf Update pom.xml 2024-10-07 21:18:52 -04:00
hyperdefined
d1a16ff2e6 added missing breaks 2024-10-07 21:18:02 -04:00
hyperdefined
9134da31f4 support for mace #82 2024-10-07 21:16:07 -04:00
hyperdefined
0cf85edda6 support for custom mob names
closes #71
2024-10-07 21:05:46 -04:00
hyperdefined
7fe0234785 fix for older MC versions
fixes #81
2024-10-05 18:37:51 -04:00
hyperdefined
6385814b52 Merge pull request #80 from hyperdefined/dependabot/maven/org.bstats-bstats-bukkit-3.1.0
Bump org.bstats:bstats-bukkit from 3.0.3 to 3.1.0
2024-10-05 18:10:25 -04:00
hyperdefined
603e1ac1fd fix #79 2024-09-25 19:50:26 -04:00
dependabot[bot]
86dc5f421a Bump org.bstats:bstats-bukkit from 3.0.3 to 3.1.0
Bumps [org.bstats:bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.3 to 3.1.0.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.3...v3.1.0)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 11:36:47 +00:00
hyperdefined
7d9be0cfd1 Update README.md 2024-09-10 17:19:15 -04:00
hyperdefined
f7bacec617 Update README.md 2024-09-10 17:17:51 -04:00
hyperdefined
227723fe10 fix #75 2024-09-10 17:08:40 -04:00
hyperdefined
785333e8d1 Update pom.xml 2024-09-10 16:02:04 -04:00
hyperdefined
bc784b8d46 fix elytra flight calculations
fixes #74
2024-09-10 16:01:45 -04:00
hyperdefined
f5ddada892 support for gradient coloring
fixes #72
2024-09-10 16:01:24 -04:00
hyperdefined
a43155b0c5 Fix armor damage + arrows on reset command 2024-09-08 22:57:41 -04:00
hyperdefined
e327d132e2 Update pom.xml 2024-09-08 22:52:55 -04:00
hyperdefined
f09f2d3703 Fix armor damage breaking (#70) 2024-09-08 22:51:49 -04:00
hyperdefined
e9782c2985 bump to 1.8 instead 2024-09-07 15:50:27 -04:00
hyperdefined
b596310bfe redo lore replacement
Instead of partially matching the old lore, build the old lore and match it instead.
2024-09-06 17:47:07 -04:00
hyperdefined
6d1f0fe561 update config from 6 to 7 2024-08-29 00:16:22 -04:00
hyperdefined
fb0d179d37 add flight time (#62) 2024-08-29 00:10:01 -04:00
hyperdefined
e8ab578eef Update pom.xml 2024-08-28 23:23:20 -04:00
hyperdefined
57be2371e1 Merge pull request #67 from hyperdefined/dependabot/maven/net.kyori-adventure-platform-bukkit-4.3.4
Bump net.kyori:adventure-platform-bukkit from 4.3.3 to 4.3.4
2024-08-28 23:20:43 -04:00
hyperdefined
f3732a4eea Merge pull request #69 from hyperdefined/dependabot/maven/org.bstats-bstats-bukkit-3.0.3
Bump org.bstats:bstats-bukkit from 3.0.2 to 3.0.3
2024-08-28 23:20:33 -04:00
hyperdefined
7e13159056 support hex colors in lore (#68) 2024-08-28 23:20:16 -04:00
dependabot[bot]
7cdb8d55b5 Bump org.bstats:bstats-bukkit from 3.0.2 to 3.0.3
Bumps [org.bstats:bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.2...v3.0.3)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-19 11:27:39 +00:00
dependabot[bot]
368e59b1e1 Bump net.kyori:adventure-platform-bukkit from 4.3.3 to 4.3.4
Bumps [net.kyori:adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.3.3 to 4.3.4.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.3.3...v4.3.4)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-platform-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-07 11:04:11 +00:00
hyperdefined
9412dc02d7 Update README.md 2024-07-24 21:32:03 -04:00
hyperdefined
0765c49622 Update pom.xml 2024-07-24 21:29:12 -04:00
hyperdefined
91959c223e new damage cause, fix #64 #65 2024-07-19 20:12:50 -04:00
hyperdefined
a53cebc589 Merge pull request #63 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-clean-plugin-3.4.0
Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0
2024-06-24 21:45:02 -04:00
dependabot[bot]
7f7c1d4656 Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.2 to 3.4.0
Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.3.2 to 3.4.0.
- [Release notes](https://github.com/apache/maven-clean-plugin/releases)
- [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.3.2...maven-clean-plugin-3.4.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-clean-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-20 11:04:51 +00:00
hyperdefined
1e99fa5076 Merge pull request #60 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.6.0
Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.3 to 3.6.0
2024-06-18 12:06:21 -04:00
hyperdefined
d50ee82a98 Merge pull request #61 from hyperdefined/dependabot/maven/net.kyori-adventure-platform-bukkit-4.3.3
Bump net.kyori:adventure-platform-bukkit from 4.3.2 to 4.3.3
2024-06-18 12:04:11 -04:00
dependabot[bot]
2a2c9a7376 Bump net.kyori:adventure-platform-bukkit from 4.3.2 to 4.3.3
Bumps [net.kyori:adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.3.2...v4.3.3)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-platform-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-03 11:19:58 +00:00
dependabot[bot]
813648e330 Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.3 to 3.6.0
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.3 to 3.6.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.3...maven-shade-plugin-3.6.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-31 11:33:03 +00:00
hyperdefined
330001e6de Update README.md 2024-05-25 15:53:34 -04:00
hyperdefined
75b1a95cb5 Merge pull request #56 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.5.3
Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3
2024-05-25 15:52:46 -04:00
hyperdefined
ca37021e5a Merge pull request #57 from hyperdefined/dependabot/maven/net.kyori-adventure-text-minimessage-4.17.0
Bump net.kyori:adventure-text-minimessage from 4.16.0 to 4.17.0
2024-05-25 15:52:39 -04:00
hyperdefined
f72ea3dbfa Update pom.xml 2024-05-25 15:41:49 -04:00
hyperdefined
03077d5e2f possibly fix #59 2024-05-25 15:41:16 -04:00
hyperdefined
608c870667 possibly fix #44 2024-05-25 15:38:44 -04:00
hyperdefined
ea27e4f4ab remove color codes when comparing 2024-05-25 15:37:52 -04:00
dependabot[bot]
8a7c6c720a Bump net.kyori:adventure-text-minimessage from 4.16.0 to 4.17.0
Bumps [net.kyori:adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.16.0 to 4.17.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.16.0...v4.17.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-08 11:41:03 +00:00
dependabot[bot]
12e2758ffd Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.2...maven-shade-plugin-3.5.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-24 11:09:18 +00:00
hyperdefined
5939b8f944 Merge pull request #54 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.13.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.1 to 3.13.0
2024-03-26 18:12:54 -04:00
hyperdefined
021d67e505 Merge pull request #55 from hyperdefined/dependabot/maven/space.arim.morepaperlib-morepaperlib-0.4.4
Bump space.arim.morepaperlib:morepaperlib from 0.4.3 to 0.4.4
2024-03-26 18:10:25 -04:00
dependabot[bot]
c0ee457c4d Bump space.arim.morepaperlib:morepaperlib from 0.4.3 to 0.4.4
Bumps space.arim.morepaperlib:morepaperlib from 0.4.3 to 0.4.4.

---
updated-dependencies:
- dependency-name: space.arim.morepaperlib:morepaperlib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-25 11:28:14 +00:00
dependabot[bot]
4f4e4a961a Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.1 to 3.13.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.1...maven-compiler-plugin-3.13.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-19 11:15:00 +00:00
hyperdefined
3412094f93 Merge pull request #51 from hyperdefined/dependabot/maven/net.kyori-adventure-text-minimessage-4.16.0
Bump net.kyori:adventure-text-minimessage from 4.15.0 to 4.16.0
2024-02-23 17:29:35 -05:00
hyperdefined
cdc46a1f5f Merge pull request #52 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.5.2 2024-02-22 09:33:56 -05:00
dependabot[bot]
d4c7770352 Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.1 to 3.5.2
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.1...maven-shade-plugin-3.5.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-21 11:22:24 +00:00
dependabot[bot]
85db07877d Bump net.kyori:adventure-text-minimessage from 4.15.0 to 4.16.0
Bumps [net.kyori:adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.15.0 to 4.16.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.15.0...v4.16.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-20 11:46:47 +00:00
hyperdefined
1e37fcd3cb Merge pull request #49 from hyperdefined/dependabot/maven/net.kyori-adventure-platform-bukkit-4.3.2
Bump net.kyori:adventure-platform-bukkit from 4.3.1 to 4.3.2
2023-12-26 12:06:21 -05:00
hyperdefined
10f9b9404e Merge pull request #50 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.12.1
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.0 to 3.12.1
2023-12-26 12:05:43 -05:00
dependabot[bot]
c350536ab6 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.0 to 3.12.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.0...maven-compiler-plugin-3.12.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 11:07:40 +00:00
dependabot[bot]
e12a0a80f5 Bump net.kyori:adventure-platform-bukkit from 4.3.1 to 4.3.2
Bumps [net.kyori:adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.3.1...v4.3.2)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-platform-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-22 11:57:41 +00:00
hyperdefined
44a3fc7d63 Merge pull request #46 from hyperdefined/dependabot/maven/net.kyori-adventure-text-minimessage-4.15.0
Bump net.kyori:adventure-text-minimessage from 4.14.0 to 4.15.0
2023-12-19 17:21:21 -05:00
hyperdefined
6a5bb994cc Merge pull request #48 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.12.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.11.0 to 3.12.0
2023-12-19 17:18:53 -05:00
dependabot[bot]
1c52664935 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.12.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.12.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 12:01:49 +00:00
dependabot[bot]
4d18020065 Bump net.kyori:adventure-text-minimessage from 4.14.0 to 4.15.0
Bumps [net.kyori:adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.14.0 to 4.15.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.14.0...v4.15.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 11:40:53 +00:00
hyperdefined
ee5ebff614 Merge pull request #43 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-clean-plugin-3.3.2
Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.1 to 3.3.2
2023-10-27 13:35:41 -04:00
dependabot[bot]
fa7b19e3fc Bump org.apache.maven.plugins:maven-clean-plugin from 3.3.1 to 3.3.2
Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/apache/maven-clean-plugin/releases)
- [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.3.1...maven-clean-plugin-3.3.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-clean-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-27 11:06:37 +00:00
31 changed files with 840 additions and 609 deletions

31
.github/workflows/hangar.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Update Hangar Description
on:
push:
branches: [ master ]
jobs:
update-hangar-page:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Authenticate with Hangar
id: authenticate
run: |
RESPONSE=$(curl -s -X POST "https://hangar.papermc.io/api/v1/authenticate?apiKey=${{ secrets.HANGAR }}" -H 'accept: application/json')
TOKEN=$(echo $RESPONSE | jq -r '.token')
if [[ "$TOKEN" == "null" ]]; then
echo "Error: Unable to fetch JWT token"
exit 1
fi
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> $GITHUB_OUTPUT
- name: Update Project Description
run: |
README_CONTENT=$(cat README.md | jq -Rs .)
curl -s -X PATCH "https://hangar.papermc.io/api/v1/pages/editmain/ToolStats" \
-H "content-type: application/json" \
-H "Authorization: HangarAuth ${{ steps.authenticate.outputs.token }}" \
-d "{\"content\":$README_CONTENT}"

View File

@@ -15,10 +15,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- name: Build with Maven
run: mvn -B package --file pom.xml

View File

@@ -1,3 +1,4 @@
name: Update Modrinth Description
on:
push:
branches: [ master ]
@@ -9,4 +10,4 @@ jobs:
- uses: funnyboy-roks/modrinth-auto-desc@v1.6
with:
auth-token: ${{ secrets.MODRINTH }}
slug: 'oBZj9E15'
slug: 'oBZj9E15'

View File

@@ -1,26 +1,26 @@
<h1 align="center">ToolStats</h1>
<p align="center">
<img src="https://img.shields.io/badge/Minecraft-1.15--1.20.2-orange" alt="Minecraft versions">
<img src="https://img.shields.io/github/v/release/hyperdefined/ToolStats" alt="GitHub release (latest by date)">
<a href="https://github.com/hyperdefined/ToolStats/releases"><img src="https://img.shields.io/github/downloads/hyperdefined/ToolStats/total?logo=github" alt="Downloads"></a>
<img src="https://img.shields.io/badge/made%20with-love%20&%20fluff-red" alt="Made with love & fluff">
<a href="https://ko-fi.com/hyperdefined"><img src="https://img.shields.io/badge/Donate-Ko--fi-red" alt="Donate via Ko-fi"></a>
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://img.shields.io/badge/License-GPLv3-blue.svg" alt="License: GPL v3"></a>
<a href="https://wakatime.com/badge/user/992a7647-176a-477c-8086-e1abfba87ff4/project/0200f07a-f303-4103-a5f2-34b38c9c1fa4"><img src="https://wakatime.com/badge/user/992a7647-176a-477c-8086-e1abfba87ff4/project/0200f07a-f303-4103-a5f2-34b38c9c1fa4.svg" alt="wakatime"></a>
<a href="https://modrinth.com/plugin/ToolStats"><img alt="modrinth" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/available/modrinth_vector.svg"></a>
<a href="https://hangar.papermc.io/hyperdefined/ToolStats"><img alt="hangar" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/available/hangar_vector.svg"></a>
<a href="https://papermc.io"><img alt="paper" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/supported/paper_vector.svg"></a>
<a href="https://github.com/hyperdefined/ToolStats/wiki"><img alt="ghpages" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/documentation/ghpages_vector.svg"></a>
<a href="https://discord.gg/rJuQXVcJz8"><img alt="discord-singular" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/discord-singular_vector.svg"></a>
<a href="https://buymeacoffee.com/hyperdefined"><img alt="buymeacoffee-singular" height="40" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/donate/buymeacoffee-singular_vector.svg"></a>
</p>
ToolStats is a small plugin that display various stats about tools. This plugin is inspired off of [GearStats](https://www.spigotmc.org/resources/gearstats.12960/). You can disable/enable which stats are shown on which tools via the config. Note: stats are tracked regardless of config setting. The config is to disable the lore on the item.
ToolStats is a Paper plugin that display various stats about tools. This plugin is inspired off of [GearStats](https://www.spigotmc.org/resources/gearstats.12960/). You can disable/enable which stats are shown on which tools via the config. Note: stats are tracked regardless of config setting. The config is to disable the lore on the item.
Here is everything it tracks:
* Blocks mined (pickaxes, shovels, axes, hoes, shears)
* Crops mined (hoes)
* Player/mob kills (swords, axes, tridents, bows/crossbows)
* Player/mob kills (swords, axes, tridents, bows/crossbows, mace)
* Ownership of items when crafted, looted (from chests), traded, spawned via creative, and caught from fishing.
* Armor damage taken.
* Fish caught.
* Sheep sheared.
* Arrows shot (bows/crossbows)
* Flight time with elytras.
The best part is, this data is stored on the item itself. You can also change how the lore is displayed on the items!
@@ -43,4 +43,4 @@ If item lore is ever incorrect/missing, you can run `/toolstats reset`. This com
Visit the [wiki](https://github.com/hyperdefined/ToolStats/wiki) for help.
## License
This plugin is released under GNU General Public License v3. See [LICENSE](https://github.com/hyperdefined/ToolStats/blob/master/LICENSE).
This plugin is released under GNU General Public License v3. See [LICENSE](https://github.com/hyperdefined/ToolStats/blob/master/LICENSE).

52
pom.xml
View File

@@ -23,13 +23,13 @@
<groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId>
<version>1.7.1</version>
<version>1.8.6</version>
<packaging>jar</packaging>
<name>ToolStats</name>
<properties>
<java.version>1.8</java.version>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
@@ -37,7 +37,7 @@
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.3.1</version>
<version>3.4.0</version>
<executions>
<execution>
<id>auto-clean</id>
@@ -51,7 +51,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
@@ -60,25 +60,17 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<version>3.6.0</version>
<configuration>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>lol.hyper.toolstats.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.adventure</pattern>
<shadedPattern>lol.hyper.toolstats.adventure</shadedPattern>
</relocation>
<relocation>
<pattern>lol.hyper.githubreleaseapi</pattern>
<shadedPattern>lol.hyper.toolstats.updater</shadedPattern>
</relocation>
<relocation>
<pattern>space.arim.morepaperlib</pattern>
<shadedPattern>lol.hyper.toolstats.morepaperlib</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
@@ -104,26 +96,22 @@
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>arim-mvn-lgpl3</id>
<url>https://mvn-repo.arim.space/lesser-gpl3/</url>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20.2-R0.1-SNAPSHOT</version>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -132,23 +120,5 @@
<version>1.0.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.14.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>space.arim.morepaperlib</groupId>
<artifactId>morepaperlib</artifactId>
<version>0.4.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -27,17 +27,13 @@ import lol.hyper.toolstats.tools.ItemLore;
import lol.hyper.toolstats.tools.NumberFormat;
import lol.hyper.toolstats.tools.config.ConfigTools;
import lol.hyper.toolstats.tools.config.ConfigUpdater;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import space.arim.morepaperlib.MorePaperLib;
import java.io.File;
import java.io.IOException;
@@ -81,10 +77,6 @@ public final class ToolStats extends JavaPlugin {
* Stores how much damage an armor piece has taken.
*/
public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken");
/**
* Stores how much damage an armor piece has taken (as an int).
*/
public final NamespacedKey armorDamageInt = new NamespacedKey(this, "damage-taken-int");
/**
* Key for tracking new elytras that spawn.
*/
@@ -97,6 +89,10 @@ public final class ToolStats extends JavaPlugin {
* Key for arrows shot.
*/
public final NamespacedKey arrowsShot = new NamespacedKey(this, "arrows-shot");
/**
* Key for tracking flight time.
*/
public final NamespacedKey flightTime = new NamespacedKey(this, "flightTime");
/**
* Stores how an item was created.
* 0 = crafted.
@@ -109,7 +105,7 @@ public final class ToolStats extends JavaPlugin {
*/
public final NamespacedKey originType = new NamespacedKey(this, "origin");
public final int CONFIG_VERSION = 6;
public final int CONFIG_VERSION = 8;
public final Logger logger = this.getLogger();
public final File configFile = new File(this.getDataFolder(), "config.yml");
@@ -130,18 +126,15 @@ public final class ToolStats extends JavaPlugin {
public PlayerJoin playerJoin;
public NumberFormat numberFormat;
public YamlConfiguration config;
private BukkitAudiences adventure;
public MorePaperLib morePaperLib;
public HashMaker hashMaker;
public CreativeEvent creativeEvent;
public PlayerMove playerMove;
public ItemChecker itemChecker;
public ShootBow shootBow;
public ConfigTools configTools;
@Override
public void onEnable() {
this.adventure = BukkitAudiences.create(this);
morePaperLib = new MorePaperLib(this);
if (!configFile.exists()) {
this.saveResource("config.yml", true);
logger.info("Copying default config!");
@@ -164,6 +157,7 @@ public final class ToolStats extends JavaPlugin {
inventoryOpen = new InventoryOpen(this);
playerJoin = new PlayerJoin(this);
creativeEvent = new CreativeEvent(this);
playerMove = new PlayerMove(this);
itemChecker = new ItemChecker();
shootBow = new ShootBow(this);
configTools = new ConfigTools(this);
@@ -183,12 +177,12 @@ public final class ToolStats extends JavaPlugin {
Bukkit.getServer().getPluginManager().registerEvents(playerJoin, this);
Bukkit.getServer().getPluginManager().registerEvents(creativeEvent, this);
Bukkit.getServer().getPluginManager().registerEvents(shootBow, this);
Bukkit.getServer().getPluginManager().registerEvents(playerMove, this);
this.getCommand("toolstats").setExecutor(commandToolStats);
new Metrics(this, 14110);
morePaperLib.scheduling().asyncScheduler().run(this::checkForUpdates);
Bukkit.getAsyncScheduler().runNow(this, scheduledTask -> checkForUpdates());
}
public void loadConfig() {
@@ -224,23 +218,4 @@ public final class ToolStats extends JavaPlugin {
logger.warning("A new version is available (" + latest.getTagVersion() + ")! You are running version " + current.getTagVersion() + ". You are " + buildsBehind + " version(s) behind.");
}
}
public BukkitAudiences getAdventure() {
if (this.adventure == null) {
throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!");
}
return this.adventure;
}
public void scheduleEntity(BukkitRunnable runnable, Entity entity, int delay) {
morePaperLib.scheduling().entitySpecificScheduler(entity).runDelayed(runnable, null, delay);
}
public void scheduleGlobal(BukkitRunnable runnable, int delay) {
morePaperLib.scheduling().globalRegionalScheduler().runDelayed(runnable, delay);
}
public void scheduleRegion(BukkitRunnable runnable, World world, Chunk chunk, int delay) {
morePaperLib.scheduling().regionSpecificScheduler(world, chunk.getX(), chunk.getZ()).runDelayed(runnable, delay);
}
}

View File

@@ -19,7 +19,6 @@ package lol.hyper.toolstats.commands;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
@@ -42,65 +41,63 @@ import java.util.*;
public class CommandToolStats implements TabExecutor {
private final ToolStats toolStats;
private final BukkitAudiences audiences;
public CommandToolStats(ToolStats toolStats) {
this.toolStats = toolStats;
this.audiences = toolStats.getAdventure();
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!sender.hasPermission("toolstats.command")) {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return true;
}
if (args.length == 0) {
audiences.sender(sender).sendMessage(Component.text("ToolStats version " + toolStats.getDescription().getVersion() + ". Created by hyperdefined.", NamedTextColor.GREEN));
sender.sendMessage(Component.text("ToolStats version " + toolStats.getPluginMeta().getVersion() + ". Created by hyperdefined.", NamedTextColor.GREEN));
return true;
}
switch (args[0]) {
case "reload": {
if (sender.hasPermission("toolstats.reload")) {
toolStats.loadConfig();
audiences.sender(sender).sendMessage(Component.text("Configuration reloaded!", NamedTextColor.GREEN));
sender.sendMessage(Component.text("Configuration reloaded!", NamedTextColor.GREEN));
} else {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
}
return true;
}
case "reset": {
if (!sender.hasPermission("toolstats.reset")) {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return true;
}
if (sender instanceof ConsoleCommandSender) {
audiences.sender(sender).sendMessage(Component.text("You must be a player for this command.", NamedTextColor.RED));
sender.sendMessage(Component.text("You must be a player for this command.", NamedTextColor.RED));
return true;
}
if (args.length == 2 && args[1].equalsIgnoreCase("confirm")) {
if (!sender.hasPermission("toolstats.reset.confirm")) {
audiences.sender(sender).sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
sender.sendMessage(Component.text("You do not have permission for this command.", NamedTextColor.RED));
return true;
}
Player player = (Player) sender;
ItemStack heldItem = player.getInventory().getItemInMainHand();
if (!toolStats.itemChecker.isValidItem(heldItem.getType())) {
audiences.sender(sender).sendMessage(Component.text("You must hold a valid item.", NamedTextColor.RED));
sender.sendMessage(Component.text("You must hold a valid item.", NamedTextColor.RED));
return true;
}
fixItemLore(heldItem, player);
audiences.sender(sender).sendMessage(Component.text("The lore was reset!", NamedTextColor.GREEN));
sender.sendMessage(Component.text("The lore was reset!", NamedTextColor.GREEN));
return true;
}
audiences.sender(sender).sendMessage(Component.text("This will remove ALL current lore from the held item and replace it with the correct lore.", NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text("If the owner of the item is broken, it will reset to the person holding it.", NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text("Only use this if the tags on the tool are incorrect.", NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text("Type /toolstats reset confirm to confirm this.", NamedTextColor.GREEN));
sender.sendMessage(Component.text("This will remove ALL current lore from the held item and replace it with the correct lore.", NamedTextColor.GREEN));
sender.sendMessage(Component.text("If the owner of the item is broken, it will reset to the person holding it.", NamedTextColor.GREEN));
sender.sendMessage(Component.text("Only use this if the tags on the tool are incorrect.", NamedTextColor.GREEN));
sender.sendMessage(Component.text("Type /toolstats reset confirm to confirm this.", NamedTextColor.GREEN));
return true;
}
default: {
audiences.sender(sender).sendMessage(Component.text("Invalid sub-command.", NamedTextColor.RED));
sender.sendMessage(Component.text("Invalid sub-command.", NamedTextColor.RED));
}
}
return true;
@@ -119,17 +116,7 @@ public class CommandToolStats implements TabExecutor {
return;
}
PersistentDataContainer container = finalMeta.getPersistentDataContainer();
List<String> lore = new ArrayList<>();
String caughtByLore = toolStats.configTools.getLoreFromConfig("fished.caught-by", false);
String lootedByLore = toolStats.configTools.getLoreFromConfig("looted.found-by", false);
String tradedByLore = toolStats.configTools.getLoreFromConfig("traded.traded-by", false);
String spawnedByLore = toolStats.configTools.getLoreFromConfig("spawned-in.spawned-by", false);
// make sure the config messages are not null
if (caughtByLore == null || lootedByLore == null || tradedByLore == null || spawnedByLore == null) {
return;
}
List<Component> lore = new ArrayList<>();
// set how the item was obtained
Integer origin = -1;
@@ -144,20 +131,33 @@ public class CommandToolStats implements TabExecutor {
// hard code elytras
if (finalItem.getType() == Material.ELYTRA) {
if (toolStats.config.getBoolean("enabled.elytra-tag")) {
lore.add(toolStats.configTools.getLoreFromConfig("looted.found-by", true).replace("{player}", player.getName()));
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG);
if (time != null) {
lore.add(toolStats.configTools.getLoreFromConfig("looted.found-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
}
}
finalMeta.setLore(lore);
finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem);
return;
Long flightTime = null;
Long timeCreated = null;
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
timeCreated = container.get(toolStats.timeCreated, PersistentDataType.LONG);
}
if (container.has(toolStats.flightTime, PersistentDataType.LONG)) {
flightTime = container.get(toolStats.flightTime, PersistentDataType.LONG);
}
if (flightTime != null) {
if (toolStats.config.getBoolean("enabled.flight-time")) {
Component line = toolStats.configTools.formatLore("flight-time", "{time}", toolStats.numberFormat.formatDouble((double) flightTime / 1000));
lore.add(line);
}
}
if (timeCreated != null) {
Component timeCreatedLine = toolStats.configTools.formatLore("looted.found-by", "{player}", player.getName());
Component playerOwnerLine = toolStats.configTools.formatLore("looted.found-on", "{date}", toolStats.numberFormat.formatDate(new Date(timeCreated)));
lore.add(timeCreatedLine);
lore.add(playerOwnerLine);
}
finalMeta.lore(lore);
finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem);
}
if (toolStats.configTools.checkConfig(original.getType(), "created-by")) {
@@ -173,7 +173,7 @@ public class CommandToolStats implements TabExecutor {
// if the owner's name is null for whatever reason, set the new owner
// to the current player running the command
if (ownerName == null) {
audiences.player(player).sendMessage(Component.text("The owner of this item is null. Setting to " + player.getName() + ".", NamedTextColor.RED));
player.sendMessage(Component.text("The owner of this item is null. Setting to " + player.getName() + ".", NamedTextColor.RED));
ownerName = player.getName();
container.set(toolStats.genericOwner, new UUIDDataType(), player.getUniqueId());
}
@@ -181,27 +181,27 @@ public class CommandToolStats implements TabExecutor {
// show how the item was created based on the previous lore
switch (origin) {
case 0: {
lore.add(toolStats.configTools.getLoreFromConfig("created.created-by", true).replace("{player}", ownerName));
lore.add(toolStats.configTools.formatLore("created.created-by", "{player}", ownerName));
break;
}
case 2: {
lore.add(toolStats.configTools.getLoreFromConfig("looted.looted-by", true).replace("{player}", ownerName));
lore.add(toolStats.configTools.formatLore("looted.looted-by", "{player}", ownerName));
break;
}
case 3: {
lore.add(toolStats.configTools.getLoreFromConfig("traded.traded-by", true).replace("{player}", ownerName));
lore.add(toolStats.configTools.formatLore("traded.traded-by", "{player}", ownerName));
break;
}
case 4: {
lore.add(toolStats.configTools.getLoreFromConfig("looted.found-by", true).replace("{player}", ownerName));
lore.add(toolStats.configTools.formatLore("looted.found-by", "{player}", ownerName));
break;
}
case 5: {
lore.add(toolStats.configTools.getLoreFromConfig("fished.caught-by", true).replace("{player}", ownerName));
lore.add(toolStats.configTools.formatLore("fished.caught-by", "{player}", ownerName));
break;
}
case 6: {
lore.add(toolStats.configTools.getLoreFromConfig("spawned-in.spawned-by", true).replace("{player}", ownerName));
lore.add(toolStats.configTools.formatLore("spawned-in.spawned-by", "{player}", ownerName));
break;
}
}
@@ -211,30 +211,31 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG);
if (time != null) {
String date = toolStats.numberFormat.formatDate(new Date(time));
// show how when the item was created based on the previous lore
switch (origin) {
case 0: {
lore.add(toolStats.configTools.getLoreFromConfig("created.created-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
lore.add(toolStats.configTools.formatLore("created.created-on", "{date}", date));
break;
}
case 2: {
lore.add(toolStats.configTools.getLoreFromConfig("looted.looted-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
lore.add(toolStats.configTools.formatLore("looted.looted-on", "{date}", date));
break;
}
case 3: {
lore.add(toolStats.configTools.getLoreFromConfig("traded.traded-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
lore.add(toolStats.configTools.formatLore("traded.traded-on", "{date}", date));
break;
}
case 4: {
lore.add(toolStats.configTools.getLoreFromConfig("looted.found-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
lore.add(toolStats.configTools.formatLore("looted.found-on", "{date}", date));
break;
}
case 5: {
lore.add(toolStats.configTools.getLoreFromConfig("fished.caught-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
lore.add(toolStats.configTools.formatLore("fished.caught-on", "{date}", date));
break;
}
case 6: {
lore.add(toolStats.configTools.getLoreFromConfig("spawned-in.spawned-on", true).replace("{date}", toolStats.numberFormat.formatDate(new Date(time))));
lore.add(toolStats.configTools.formatLore("spawned-in.spawned-on", "{date}", date));
break;
}
}
@@ -245,7 +246,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
if (kills != null) {
lore.add(toolStats.configTools.getLoreFromConfig("kills.player", true).replace("{kills}", toolStats.numberFormat.formatInt(kills)));
lore.add(toolStats.configTools.formatLore("kills.player", "{kills}", toolStats.numberFormat.formatInt(kills)));
}
}
}
@@ -253,7 +254,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
if (kills != null) {
lore.add(toolStats.configTools.getLoreFromConfig("kills.mob", true).replace("{kills}", toolStats.numberFormat.formatInt(kills)));
lore.add(toolStats.configTools.formatLore("kills.mob", "{kills}", toolStats.numberFormat.formatInt(kills)));
}
}
}
@@ -262,14 +263,14 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.cropsHarvested, PersistentDataType.INTEGER)) {
Integer crops = container.get(toolStats.cropsHarvested, PersistentDataType.INTEGER);
if (crops != null) {
lore.add(toolStats.configTools.getLoreFromConfig("crops-harvested", true).replace("{crops}", toolStats.numberFormat.formatInt(crops)));
lore.add(toolStats.configTools.formatLore("crops-harvested", "{crops}", toolStats.numberFormat.formatInt(crops)));
}
}
}
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
Integer blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
if (blocksMined != null) {
lore.add(toolStats.configTools.getLoreFromConfig("blocks-mined", true).replace("{blocks}", toolStats.numberFormat.formatInt(blocksMined)));
lore.add(toolStats.configTools.formatLore("blocks-mined", "{blocks}", toolStats.numberFormat.formatInt(blocksMined)));
}
}
}
@@ -277,7 +278,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) {
Integer fish = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER);
if (fish != null) {
lore.add(toolStats.configTools.getLoreFromConfig("fished.fish-caught", true).replace("{fish}", toolStats.numberFormat.formatInt(fish)));
lore.add(toolStats.configTools.formatLore("fished.fish-caught", "{fish}", toolStats.numberFormat.formatInt(fish)));
}
}
}
@@ -285,7 +286,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) {
Integer sheep = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER);
if (sheep != null) {
lore.add(toolStats.configTools.getLoreFromConfig("sheep-sheared", true).replace("{sheep}", toolStats.numberFormat.formatInt(sheep)));
lore.add(toolStats.configTools.formatLore("sheep-sheared", "{sheep}", toolStats.numberFormat.formatInt(sheep)));
}
}
}
@@ -293,7 +294,7 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.armorDamage, PersistentDataType.DOUBLE)) {
Double damage = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE);
if (damage != null) {
lore.add(toolStats.configTools.getLoreFromConfig("damage-taken", true).replace("{damage}", toolStats.numberFormat.formatDouble(damage)));
lore.add(toolStats.configTools.formatLore("damage-taken", "{damage}", toolStats.numberFormat.formatDouble(damage)));
}
}
}
@@ -301,11 +302,11 @@ public class CommandToolStats implements TabExecutor {
if (container.has(toolStats.arrowsShot, PersistentDataType.INTEGER)) {
Integer arrows = container.get(toolStats.arrowsShot, PersistentDataType.INTEGER);
if (arrows != null) {
lore.add(toolStats.configTools.getLoreFromConfig("arrows-shot", true).replace("{arrows}", toolStats.numberFormat.formatInt(arrows)));
lore.add(toolStats.configTools.formatLore("arrows-shot", "{arrows}", toolStats.numberFormat.formatInt(arrows)));
}
}
}
finalMeta.setLore(lore);
finalMeta.lore(lore);
finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem);

View File

@@ -17,7 +17,10 @@
package lol.hyper.toolstats.events;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -36,6 +39,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
public class BlocksMined implements Listener {
@@ -60,13 +64,7 @@ public class BlocksMined implements Listener {
if (block.getType() == Material.CHEST) {
toolStats.playerInteract.openedChests.put(block, player);
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
toolStats.playerInteract.openedChests.remove(block);
}
};
toolStats.scheduleGlobal(runnable, 20);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> toolStats.playerInteract.openedChests.remove(block), 20);
}
// only check certain items
@@ -104,14 +102,19 @@ public class BlocksMined implements Listener {
toolStats.logger.warning(playerTool + " does not have valid generic-mined set! Resting to zero. This should NEVER happen.");
}
blocksMined++;
container.set(toolStats.genericMined, PersistentDataType.INTEGER, blocksMined);
container.set(toolStats.genericMined, PersistentDataType.INTEGER, blocksMined + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) {
String blocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{blocks}", blocksMinedFormatted, "blocks-mined");
meta.setLore(newLore);
String oldBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined);
String newBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined + 1);
Component oldLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", oldBlocksMinedFormatted);
Component newLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", newBlocksMinedFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
playerTool.setItemMeta(meta);
}
@@ -140,14 +143,19 @@ public class BlocksMined implements Listener {
toolStats.logger.warning(playerTool + " does not have valid crops-mined set! Resting to zero. This should NEVER happen.");
}
cropsMined++;
container.set(toolStats.cropsHarvested, PersistentDataType.INTEGER, cropsMined);
container.set(toolStats.cropsHarvested, PersistentDataType.INTEGER, cropsMined + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) {
String cropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{crops}", cropsMinedFormatted, "crops-harvested");
meta.setLore(newLore);
String oldCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined);
String newCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined + 1);
Component oldLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", oldCropsMinedFormatted);
Component newLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", newCropsMinedFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
playerTool.setItemMeta(meta);
}

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
@@ -31,7 +32,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
public class ChunkPopulate implements Listener {
@@ -49,34 +49,30 @@ public class ChunkPopulate implements Listener {
if (event.getChunk().getWorld().getEnvironment() != World.Environment.THE_END) {
return;
}
World world = event.getChunk().getWorld();
// this is delayed because entities are not loaded instantly
// we just check 1 second later
Chunk chunk = event.getChunk();
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
for (Entity entity : chunk.getEntities()) {
// if there is a new item frame
if (!(entity instanceof ItemFrame)) {
Bukkit.getRegionScheduler().runDelayed(toolStats, world, chunk.getX(), chunk.getZ(), scheduledTask -> {
for (Entity entity : chunk.getEntities()) {
// if there is a new item frame
if (!(entity instanceof ItemFrame itemFrame)) {
continue;
}
// if the item frame has an elytra
if (itemFrame.getItem().getType() == Material.ELYTRA) {
ItemStack elytraCopy = itemFrame.getItem();
ItemMeta meta = elytraCopy.getItemMeta();
if (meta == null) {
continue;
}
ItemFrame itemFrame = (ItemFrame) entity;
// if the item frame has an elytra
if (itemFrame.getItem().getType() == Material.ELYTRA) {
ItemStack elytraCopy = itemFrame.getItem();
ItemMeta meta = elytraCopy.getItemMeta();
if (meta == null) {
continue;
}
// add the new tag so we know it's new
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1);
elytraCopy.setItemMeta(meta);
itemFrame.setItem(elytraCopy);
}
// add the new tag so we know it's new
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1);
elytraCopy.setItemMeta(meta);
itemFrame.setItem(elytraCopy);
}
}
};
toolStats.scheduleRegion(runnable, chunk.getWorld(), chunk, 20);
}, 20);
}
}

View File

@@ -19,7 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.ChatColor;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -32,7 +32,9 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class CraftItem implements Listener {
@@ -62,13 +64,12 @@ public class CraftItem implements Listener {
// if the player shift clicks, send them this warning
if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.crafting");
if (configMessage != null) {
if (configMessage.length() != 0) {
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
}
Component component = toolStats.configTools.formatLore("shift-click-warning.crafting", null, null);
if (component != null) {
event.getWhoClicked().sendMessage(component);
}
}
// test the item before setting it
ItemStack newItem = addLore(itemStack, player);
if (newItem != null) {
@@ -113,31 +114,30 @@ public class CraftItem implements Listener {
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
container.set(toolStats.originType, PersistentDataType.INTEGER, 0);
List<String> lore;
List<Component> lore;
// get the current lore the item
if (meta.hasLore()) {
lore = meta.getLore();
lore = meta.lore();
} else {
lore = new ArrayList<>();
}
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(itemStack.getType(), "created-date")) {
String createdOnRaw = toolStats.configTools.getLoreFromConfig("created.created-on", true);
if (createdOnRaw == null) {
toolStats.logger.warning("There is no lore message for messages.created.created-on!");
String date = toolStats.numberFormat.formatDate(finalDate);
Component newLine = toolStats.configTools.formatLore("created.created-on", "{date}", date);
if (newLine == null) {
return null;
}
lore.add(createdOnRaw.replace("{date}", toolStats.numberFormat.formatDate(finalDate)));
meta.setLore(lore);
lore.add(newLine);
meta.lore(lore);
}
if (toolStats.configTools.checkConfig(itemStack.getType(), "created-by")) {
String createdByRaw = toolStats.configTools.getLoreFromConfig("created.created-by", true);
if (createdByRaw == null) {
toolStats.logger.warning("There is no lore message for messages.created.created-by!");
Component newLine = toolStats.configTools.formatLore("created.created-by", "{player}", owner.getName());
if (newLine == null) {
return null;
}
lore.add(createdByRaw.replace("{player}", owner.getName()));
meta.setLore(lore);
lore.add(newLine);
meta.lore(lore);
}
newItem.setItemMeta(meta);
return newItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -87,6 +88,11 @@ public class CreativeEvent implements Listener {
Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer();
// if the item already has an origin set, don't add it again
if (container.has(toolStats.originType, PersistentDataType.INTEGER)) {
return null;
}
// only make the hash if it's enabled
if (toolStats.config.getBoolean("generate-hash-for-items")) {
String hash = toolStats.hashMaker.makeHash(spawnedItem.getType(), owner.getUniqueId(), timeCreated);
@@ -99,8 +105,8 @@ public class CreativeEvent implements Listener {
if (toolStats.configTools.checkConfig(newSpawnedItem.getType(), "spawned-in")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore);
List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.lore(newLore);
}
newSpawnedItem.setItemMeta(meta);

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.*;
@@ -39,7 +40,7 @@ public class EntityDamage implements Listener {
private final ToolStats toolStats;
public final Set<UUID> trackedMobs = new HashSet<>();
private final List<EntityDamageEvent.DamageCause> ignoredCauses = Arrays.asList(EntityDamageEvent.DamageCause.SUICIDE, EntityDamageEvent.DamageCause.VOID, EntityDamageEvent.DamageCause.CUSTOM);
private final List<EntityDamageEvent.DamageCause> ignoredCauses = Arrays.asList(EntityDamageEvent.DamageCause.SUICIDE, EntityDamageEvent.DamageCause.VOID, EntityDamageEvent.DamageCause.CUSTOM, EntityDamageEvent.DamageCause.KILL);
public EntityDamage(ToolStats toolStats) {
this.toolStats = toolStats;
@@ -51,10 +52,9 @@ public class EntityDamage implements Listener {
return;
}
if (!(event.getEntity() instanceof LivingEntity)) {
if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) {
return;
}
LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// ignore void and /kill damage
EntityDamageEvent.DamageCause cause = event.getCause();
@@ -65,8 +65,7 @@ public class EntityDamage implements Listener {
// mob is going to die
if (mobBeingAttacked.getHealth() - event.getFinalDamage() <= 0) {
// a player is killing something
if (event.getDamager() instanceof Player) {
Player attackingPlayer = (Player) event.getDamager();
if (event.getDamager() instanceof Player attackingPlayer) {
if (attackingPlayer.getGameMode() == GameMode.CREATIVE || attackingPlayer.getGameMode() == GameMode.SPECTATOR) {
return;
}
@@ -86,27 +85,24 @@ public class EntityDamage implements Listener {
trackedMobs.add(mobBeingAttacked.getUniqueId());
}
// trident is being thrown at something
if (event.getDamager() instanceof Trident) {
Trident trident = (Trident) event.getDamager();
if (event.getDamager() instanceof Trident trident) {
ItemStack newTrident;
// trident is killing player
if (mobBeingAttacked instanceof Player) {
newTrident = tridentPlayerKills(trident.getItem());
newTrident = tridentPlayerKills(trident.getItemStack());
} else {
// trident is killing a mob
newTrident = tridentMobKills(trident.getItem());
newTrident = tridentMobKills(trident.getItemStack());
trackedMobs.add(mobBeingAttacked.getUniqueId());
}
if (newTrident != null) {
trident.setItem(newTrident);
trident.setItemStack(newTrident);
}
}
// arrow is being shot
if (event.getDamager() instanceof Arrow) {
Arrow arrow = (Arrow) event.getDamager();
if (event.getDamager() instanceof Arrow arrow) {
// if the shooter is a player
if (arrow.getShooter() instanceof Player) {
Player shootingPlayer = (Player) arrow.getShooter();
if (arrow.getShooter() instanceof Player shootingPlayer) {
if (shootingPlayer.getGameMode() == GameMode.CREATIVE || shootingPlayer.getGameMode() == GameMode.SPECTATOR) {
return;
}
@@ -143,8 +139,7 @@ public class EntityDamage implements Listener {
}
}
// player is taken damage but not being killed
if (mobBeingAttacked instanceof Player) {
Player playerTakingDamage = (Player) mobBeingAttacked;
if (mobBeingAttacked instanceof Player playerTakingDamage) {
if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return;
}
@@ -161,7 +156,7 @@ public class EntityDamage implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) {
if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) {
return;
}
@@ -171,10 +166,8 @@ public class EntityDamage implements Listener {
return;
}
LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// player is taken damage but not being killed
if (mobBeingAttacked instanceof Player) {
Player playerTakingDamage = (Player) mobBeingAttacked;
if (mobBeingAttacked instanceof Player playerTakingDamage) {
if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return;
}
@@ -191,7 +184,7 @@ public class EntityDamage implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onDamage(EntityDamageByBlockEvent event) {
if (!(event.getEntity() instanceof LivingEntity)) {
if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) {
return;
}
@@ -201,10 +194,8 @@ public class EntityDamage implements Listener {
return;
}
LivingEntity mobBeingAttacked = (LivingEntity) event.getEntity();
// player is taken damage but not being killed
if (mobBeingAttacked instanceof Player) {
Player playerTakingDamage = (Player) mobBeingAttacked;
if (mobBeingAttacked instanceof Player playerTakingDamage) {
if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) {
return;
}
@@ -241,14 +232,19 @@ public class EntityDamage implements Listener {
toolStats.logger.warning(itemStack + " does not have valid player-kills set! Resting to zero. This should NEVER happen.");
}
playerKills++;
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills);
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(itemStack.getType(), "player-kills")) {
String playerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", playerKillsFormatted, "kills.player");
meta.setLore(newLore);
String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
itemStack.setItemMeta(meta);
}
@@ -275,14 +271,19 @@ public class EntityDamage implements Listener {
toolStats.logger.warning(itemStack + " does not have valid mob-kills set! Resting to zero. This should NEVER happen.");
}
mobKills++;
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills);
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(itemStack.getType(), "mob-kills")) {
String mobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", mobKillsFormatted, "kills.mob");
meta.setLore(newLore);
String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
itemStack.setItemMeta(meta);
}
@@ -294,6 +295,10 @@ public class EntityDamage implements Listener {
* @param damage How much damage is being added.
*/
private void updateDamage(ItemStack itemStack, double damage) {
// ignore if the damage is zero or negative
if (damage < 0) {
return;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
@@ -310,14 +315,18 @@ public class EntityDamage implements Listener {
toolStats.logger.warning(itemStack + " does not have valid damage-taken set! Resting to zero. This should NEVER happen.");
}
damageTaken = damageTaken + damage;
container.set(toolStats.armorDamage, PersistentDataType.DOUBLE, damageTaken);
container.set(toolStats.armorDamageInt, PersistentDataType.INTEGER, damageTaken.intValue());
container.set(toolStats.armorDamage, PersistentDataType.DOUBLE, damageTaken + damage);
if (toolStats.config.getBoolean("enabled.armor-damage")) {
String damageTakenFormatted = toolStats.numberFormat.formatDouble(damageTaken);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{damage}", damageTakenFormatted, "damage-taken");
meta.setLore(newLore);
String oldDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken);
String newDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken + damage);
Component oldLine = toolStats.configTools.formatLore("damage-taken", "{damage}", oldDamageFormatted);
Component newLine = toolStats.configTools.formatLore("damage-taken", "{damage}", newDamageFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
itemStack.setItemMeta(meta);
}
@@ -345,14 +354,19 @@ public class EntityDamage implements Listener {
toolStats.logger.warning(newTrident + " does not have valid mob-kills set! Resting to zero. This should NEVER happen.");
}
mobKills++;
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills);
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(newTrident.getType(), "mob-kills")) {
String mobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", mobKillsFormatted, "kills.mob");
meta.setLore(newLore);
String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted);
if (oldLine == null || newLine == null) {
return null;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
newTrident.setItemMeta(meta);
return newTrident;
@@ -381,14 +395,19 @@ public class EntityDamage implements Listener {
toolStats.logger.warning(newTrident + " does not have valid player-kills set! Resting to zero. This should NEVER happen.");
}
playerKills++;
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills);
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(newTrident.getType(), "player-kills")) {
String playerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{kills}", playerKillsFormatted, "kills.player");
meta.setLore(newLore);
String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted);
if (oldLine == null || newLine == null) {
return null;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
newTrident.setItemMeta(meta);
return newTrident;

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -29,7 +30,8 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.*;
import java.util.List;
import java.util.UUID;
public class EntityDeath implements Listener {
@@ -53,13 +55,13 @@ public class EntityDeath implements Listener {
ItemMeta droppedItemMeta = droppedItem.getItemMeta();
if (droppedItemMeta != null) {
PersistentDataContainer container = droppedItemMeta.getPersistentDataContainer();
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
if (container.has(toolStats.originType, PersistentDataType.INTEGER)) {
continue; // ignore any items that have our tags
}
}
if (toolStats.itemChecker.isValidItem(droppedItem.getType())) {
ItemStack newItem = addLore(droppedItem, livingEntity.getName());
ItemStack newItem = addLore(droppedItem, livingEntity);
if (newItem != null) {
event.getDrops().set(i, newItem);
}
@@ -73,9 +75,9 @@ public class EntityDeath implements Listener {
* Adds "drop by" tag to item.
*
* @param oldItem The item to add lore to.
* @param mob The mob or player name.
* @param entity The mob dying.
*/
private ItemStack addLore(ItemStack oldItem, String mob) {
private ItemStack addLore(ItemStack oldItem, LivingEntity entity) {
ItemStack newItem = oldItem.clone();
ItemMeta meta = newItem.getItemMeta();
if (meta == null) {
@@ -86,8 +88,13 @@ public class EntityDeath implements Listener {
container.set(toolStats.originType, PersistentDataType.INTEGER, 1);
if (toolStats.config.getBoolean("enabled.dropped-by")) {
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{name}", mob, "dropped-by");
meta.setLore(newLore);
String mobName = toolStats.config.getString("messages.mob." + entity.getType());
if (mobName == null) {
mobName = entity.getName();
}
Component newLine = toolStats.configTools.formatLore("dropped-by", "{name}", mobName);
List<Component> newLore = toolStats.itemLore.addItemLore(meta, newLine);
meta.lore(newLore);
}
newItem.setItemMeta(meta);
return newItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -76,8 +77,7 @@ public class GenerateLoot implements Listener {
Player player = toolStats.playerInteract.openedChests.get(openedChest);
setLoot(event.getLoot(), player);
}
if (inventoryHolder instanceof StorageMinecart) {
StorageMinecart mineCart = (StorageMinecart) inventoryHolder;
if (inventoryHolder instanceof StorageMinecart mineCart) {
if (toolStats.playerInteract.openedMineCarts.containsKey(mineCart)) {
Player player = toolStats.playerInteract.openedMineCarts.get(mineCart);
setLoot(event.getLoot(), player);
@@ -118,8 +118,8 @@ public class GenerateLoot implements Listener {
if (toolStats.configTools.checkConfig(newItem.getType(), "looted-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore);
List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.lore(newLore);
}
newItem.setItemMeta(meta);
return newItem;

View File

@@ -17,10 +17,11 @@
package lol.hyper.toolstats.events;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryOpenEvent;
@@ -32,6 +33,7 @@ import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID;
import java.util.function.Consumer;
public class InventoryOpen implements Listener {
@@ -83,23 +85,9 @@ public class InventoryOpen implements Listener {
container.set(toolStats.hash, PersistentDataType.STRING, hash);
}
}
// add origin tag
if (!container.has(toolStats.originType, PersistentDataType.INTEGER)) {
itemMeta = toolStats.itemLore.getOrigin(itemMeta, itemStack.getType() == Material.ELYTRA);
if (itemMeta == null) {
continue;
}
}
ItemMeta clone = itemMeta.clone();
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
itemStack.setItemMeta(clone);
}
};
if (location != null) {
toolStats.scheduleRegion(runnable, location.getWorld(), location.getChunk(), 1);
Bukkit.getRegionScheduler().runDelayed(toolStats, location, scheduledTask -> itemStack.setItemMeta(clone), 1);
}
}
}

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.*;
@@ -48,13 +49,12 @@ public class PickupItem implements Listener {
return;
}
Entity entity = event.getEntity();
if (entity instanceof Player) {
Player player = (Player) entity;
if (entity instanceof Player player) {
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
Item item = event.getItem();
if (item.getType() == EntityType.DROPPED_ITEM) {
if (item.getType() == EntityType.ITEM) {
ItemStack itemStack = event.getItem().getItemStack();
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
@@ -103,8 +103,8 @@ public class PickupItem implements Listener {
if (toolStats.config.getBoolean("enabled.elytra-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore);
List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.lore(newLore);
}
finalItem.setItemMeta(meta);
return finalItem;

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Item;
@@ -32,6 +33,7 @@ import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.util.Date;
import java.util.List;
@@ -58,25 +60,8 @@ public class PlayerFish implements Listener {
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
// make sure the player is holding a fishing rod
// player can fish with their offhand
PlayerInventory inventory = player.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.FISHING_ROD;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.FISHING_ROD;
ItemStack fishingRod = null;
if (isMainHand) {
fishingRod = inventory.getItemInMainHand();
}
if (isOffHand) {
fishingRod = inventory.getItemInOffHand();
}
// if the player is hold fishing rods in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
fishingRod = inventory.getItemInMainHand();
}
ItemStack fishingRod = getItemStack(player);
// player swapped items?
if (fishingRod == null) {
return;
@@ -99,6 +84,26 @@ public class PlayerFish implements Listener {
}
}
private static @Nullable ItemStack getItemStack(Player player) {
PlayerInventory inventory = player.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.FISHING_ROD;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.FISHING_ROD;
ItemStack fishingRod = null;
if (isMainHand) {
fishingRod = inventory.getItemInMainHand();
}
if (isOffHand) {
fishingRod = inventory.getItemInOffHand();
}
// if the player is hold fishing rods in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
fishingRod = inventory.getItemInMainHand();
}
return fishingRod;
}
/**
* Update a fishing rod's fish count.
*
@@ -121,13 +126,18 @@ public class PlayerFish implements Listener {
toolStats.logger.warning(fishingRod + " does not have valid fish-caught set! Resting to zero. This should NEVER happen.");
}
fishCaught++;
container.set(toolStats.fishingRodCaught, PersistentDataType.INTEGER, fishCaught);
container.set(toolStats.fishingRodCaught, PersistentDataType.INTEGER, fishCaught + 1);
if (toolStats.config.getBoolean("enabled.fish-caught")) {
String fishCaughtFormatted = toolStats.numberFormat.formatInt(fishCaught);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{fish}", fishCaughtFormatted, "fished.fish-caught");
meta.setLore(newLore);
String oldFishFormatted = toolStats.numberFormat.formatInt(fishCaught);
String newFishFormatted = toolStats.numberFormat.formatInt(fishCaught + 1);
Component oldLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", oldFishFormatted);
Component newLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", newFishFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
fishingRod.setItemMeta(meta);
}
@@ -162,8 +172,8 @@ public class PlayerFish implements Listener {
if (toolStats.configTools.checkConfig(newItem.getType(), "fished-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore);
List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.lore(newLore);
}
newItem.setItemMeta(meta);
return newItem;

View File

@@ -17,7 +17,9 @@
package lol.hyper.toolstats.events;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -34,6 +36,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class PlayerInteract implements Listener {
@@ -64,13 +67,7 @@ public class PlayerInteract implements Listener {
// store when a player opens a chest
if (block.getType() != Material.AIR && block.getType() == Material.CHEST) {
openedChests.put(block, player);
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
openedChests.remove(block);
}
};
toolStats.scheduleGlobal(runnable, 20);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedChests.remove(block), 20);
}
}
@@ -82,16 +79,10 @@ public class PlayerInteract implements Listener {
return;
}
// store when a player opens a minecart
if (clicked.getType() == EntityType.MINECART_CHEST) {
if (clicked.getType() == EntityType.CHEST_MINECART) {
StorageMinecart storageMinecart = (StorageMinecart) clicked;
openedMineCarts.put(storageMinecart, player);
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
openedMineCarts.remove(storageMinecart);
}
};
toolStats.scheduleGlobal(runnable, 20);
Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> openedMineCarts.remove(storageMinecart), 20);
}
}
}

View File

@@ -17,9 +17,9 @@
package lol.hyper.toolstats.events;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -32,6 +32,7 @@ import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID;
import java.util.function.Consumer;
public class PlayerJoin implements Listener {
@@ -77,22 +78,8 @@ public class PlayerJoin implements Listener {
String hash = toolStats.hashMaker.makeHash(itemStack.getType(), owner, timestamp);
container.set(toolStats.hash, PersistentDataType.STRING, hash);
}
// add origin tag
if (!container.has(toolStats.originType, PersistentDataType.INTEGER)) {
itemMeta = toolStats.itemLore.getOrigin(itemMeta, itemStack.getType() == Material.ELYTRA);
if (itemMeta == null) {
continue;
}
}
ItemMeta clone = itemMeta.clone();
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
itemStack.setItemMeta(clone);
}
};
toolStats.scheduleEntity(runnable, player, 1);
player.getScheduler().runDelayed(toolStats, scheduledTask -> itemStack.setItemMeta(clone), null, 1);
}
}
}

View File

@@ -0,0 +1,108 @@
/*
* This file is part of ToolStats.
*
* ToolStats 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.
*
* ToolStats 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 ToolStats. If not, see <https://www.gnu.org/licenses/>.
*/
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PlayerMove implements Listener {
private final ToolStats toolStats;
private final Map<Player, Long> playerStartFlight = new HashMap<>();
public PlayerMove(ToolStats toolStats) {
this.toolStats = toolStats;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onCraft(PlayerMoveEvent event) {
Player player = event.getPlayer();
// player starts to fly
if (player.isGliding()) {
// if they are flying, and we don't have them tracked, add them
if (!playerStartFlight.containsKey(player)) {
playerStartFlight.put(player, System.currentTimeMillis());
}
} else {
// player is not flying
if (playerStartFlight.containsKey(player)) {
trackFlight(player, playerStartFlight.get(player));
playerStartFlight.remove(player);
}
}
}
private void trackFlight(Player player, long startTime) {
ItemStack chest = player.getInventory().getChestplate();
// make sure their chest piece is an elytra
if (chest == null || chest.getType() != Material.ELYTRA) {
return;
}
ItemMeta meta = chest.getItemMeta();
if (meta == null) {
toolStats.logger.warning(chest + " does NOT have any meta! Unable to update stats.");
return;
}
// read the current stats from the item
// if they don't exist, then start from 0
Long flightTime = 0L;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.flightTime, PersistentDataType.LONG)) {
flightTime = container.get(toolStats.flightTime, PersistentDataType.LONG);
}
if (flightTime == null) {
flightTime = 0L;
toolStats.logger.warning(flightTime + " does not have valid flight-time set! Resting to zero. This should NEVER happen.");
}
// get the duration of the flight
long duration = (System.currentTimeMillis() - startTime);
double newDuration = flightTime + duration;
container.set(toolStats.flightTime, PersistentDataType.LONG, flightTime + duration);
// do we add the lore based on the config?
if (toolStats.config.getBoolean("enabled.flight-time")) {
String oldFlightFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
String newFlightFormatted = toolStats.numberFormat.formatDouble(newDuration / 1000);
Component oldLine = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightFormatted);
Component newLine = toolStats.configTools.formatLore("flight-time", "{time}", newFlightFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
chest.setItemMeta(meta);
}
}

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
@@ -32,6 +33,7 @@ import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -53,12 +55,26 @@ public class SheepShear implements Listener {
return;
}
Entity entity = event.getRightClicked();
if (!(entity instanceof Sheep)) {
if (!(entity instanceof Sheep sheep)) {
return;
}
// make sure the player is holding shears
// player can shear with their offhand
ItemStack shears = getShears(player);
// player swapped items?
if (shears == null) {
return;
}
// make sure the sheep is not sheared
if (sheep.isSheared()) {
return;
}
// update the stats
addLore(shears);
}
private static @Nullable ItemStack getShears(Player player) {
PlayerInventory inventory = player.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.SHEARS;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.SHEARS;
@@ -70,26 +86,12 @@ public class SheepShear implements Listener {
shears = inventory.getItemInOffHand();
}
// if the player is hold fishing rods in both hands
// if the player is hold shears in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
shears = inventory.getItemInMainHand();
}
// player swapped items?
if (shears == null) {
return;
}
Sheep sheep = (Sheep) entity;
// make sure the sheep is not sheared
if (sheep.isSheared()) {
return;
}
// update the stats
ItemStack finalShears = shears;
addLore(finalShears);
return shears;
}
/**
@@ -114,13 +116,18 @@ public class SheepShear implements Listener {
toolStats.logger.warning(newShears + " does not have valid sheared set! Resting to zero. This should NEVER happen.");
}
sheepSheared++;
container.set(toolStats.shearsSheared, PersistentDataType.INTEGER, sheepSheared);
container.set(toolStats.shearsSheared, PersistentDataType.INTEGER, sheepSheared + 1);
if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
String sheepShearedFormatted = toolStats.numberFormat.formatInt(sheepSheared);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{sheep}", sheepShearedFormatted, "sheep-sheared");
meta.setLore(newLore);
String oldSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared);
String newSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared + 1);
Component oldLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", oldSheepFormatted);
Component newLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", newSheepFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
newShears.setItemMeta(meta);
}

View File

@@ -18,6 +18,7 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
@@ -31,6 +32,7 @@ import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -46,16 +48,26 @@ public class ShootBow implements Listener {
public void onShoot(EntityShootBowEvent event) {
Entity shooter = event.getEntity();
// only listen for players
if (!(shooter instanceof Player)) {
if (!(shooter instanceof Player player)) {
return;
}
Player player = (Player) shooter;
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.ADVENTURE) {
return;
}
PlayerInventory inventory = player.getInventory();
ItemStack heldBow = getBow(inventory);
// player swapped
if (heldBow == null) {
return;
}
updateArrowsShot(heldBow);
}
private static @Nullable ItemStack getBow(PlayerInventory inventory) {
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW;
ItemStack heldBow = null;
@@ -71,13 +83,7 @@ public class ShootBow implements Listener {
if (isMainHand && isOffHand) {
heldBow = inventory.getItemInMainHand();
}
// player swapped
if (heldBow == null) {
return;
}
updateArrowsShot(heldBow);
return heldBow;
}
private void updateArrowsShot(ItemStack bow) {
@@ -99,14 +105,19 @@ public class ShootBow implements Listener {
toolStats.logger.warning(arrowsShot + " does not have valid arrows-shot set! Resting to zero. This should NEVER happen.");
}
arrowsShot++;
container.set(toolStats.arrowsShot, PersistentDataType.INTEGER, arrowsShot);
container.set(toolStats.arrowsShot, PersistentDataType.INTEGER, arrowsShot + 1);
// do we add the lore based on the config?
if (toolStats.config.getBoolean("enabled.arrows-shot")) {
String arrowsShotFormatted = toolStats.numberFormat.formatInt(arrowsShot);
List<String> newLore = toolStats.itemLore.addItemLore(meta, "{arrows}", arrowsShotFormatted, "arrows-shot");
meta.setLore(newLore);
String oldArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot);
String newArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot + 1);
Component oldLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", oldArrowsFormatted);
Component newLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", newArrowsFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
bow.setItemMeta(meta);
}

View File

@@ -19,6 +19,7 @@ package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
@@ -51,10 +52,9 @@ public class VillagerTrade implements Listener {
return;
}
Inventory inventory = event.getClickedInventory();
if (!(event.getWhoClicked() instanceof Player)) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}
Player player = (Player) event.getWhoClicked();
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
@@ -69,9 +69,9 @@ public class VillagerTrade implements Listener {
}
// if the player shift clicks, show the warning
if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.trading");
if (configMessage != null) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
Component component = toolStats.configTools.formatLore("shift-click-warning.trading", null, null);
if (component != null) {
event.getWhoClicked().sendMessage(component);
}
}
ItemStack newItem = addLore(item, player);
@@ -117,8 +117,8 @@ public class VillagerTrade implements Listener {
if (toolStats.configTools.checkConfig(newItem.getType(), "traded-tag")) {
String formattedDate = toolStats.numberFormat.formatDate(finalDate);
List<String> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.setLore(newLore);
List<Component> newLore = toolStats.itemLore.addNewOwner(meta, owner.getName(), formattedDate);
meta.lore(newLore);
}
newItem.setItemMeta(meta);
return newItem;

View File

@@ -47,6 +47,9 @@ public class ItemChecker {
if (lowerCase.contains("_helmet") || lowerCase.contains("_chestplate") || lowerCase.contains("_leggings") || lowerCase.contains("_boots")) {
armorItems.add(material);
}
if (lowerCase.equalsIgnoreCase("mace")) {
meleeItems.add(material);
}
}
// hardcode these
@@ -55,6 +58,7 @@ public class ItemChecker {
validItems.add(Material.BOW);
validItems.add(Material.FISHING_ROD);
validItems.add(Material.CROSSBOW);
validItems.add(Material.ELYTRA);
// combine the lists
validItems.addAll(armorItems);

View File

@@ -18,6 +18,8 @@
package lol.hyper.toolstats.tools;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
@@ -34,49 +36,48 @@ public class ItemLore {
}
/**
* Adds/updates lore for an item.
* Updates existing lore on an item.
*
* @param placeholder The placeholder from the config. ex: {kills}
* @param placeholderValue The value to replace the placeholder.
* @param configLorePath The path to the config message.
* @param itemMeta The item's meta.
* @param oldLine The old line to replace.
* @param newLine The new line to replace oldLine.
* @return The item's new lore.
*/
public List<String> addItemLore(ItemMeta itemMeta, String placeholder, String placeholderValue, String configLorePath) {
String configLore = toolStats.configTools.getLoreFromConfig(configLorePath, false);
String configLoreRaw = toolStats.configTools.getLoreFromConfig(configLorePath, true);
if (configLore == null || configLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages." + configLorePath + "!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
}
List<String> newLore;
// replace the placeholder with the value
// ex: {kills} -> a number
String newLine = configLoreRaw.replace(placeholder, placeholderValue);
public List<Component> updateItemLore(ItemMeta itemMeta, Component oldLine, Component newLine) {
List<Component> itemLore;
if (itemMeta.hasLore()) {
newLore = itemMeta.getLore();
itemLore = itemMeta.lore();
// keep track of line index
// this doesn't mess the lore of existing items
for (int x = 0; x < newLore.size(); x++) {
// check to see if the line matches the config value
for (int x = 0; x < itemLore.size(); x++) {
Component line = itemLore.get(x);
// find the old line to update, keeping index
// this means we update this line only!
String line = newLore.get(x);
if (line.contains(configLore)) {
newLore.set(x, newLine);
return newLore;
if (line.equals(oldLine)) {
itemLore.set(x, newLine);
return itemLore;
}
}
// if the item has lore, but we didn't find the line
newLore.add(newLine);
itemLore.add(newLine);
} else {
// if the item has no lore, create a new list and add the line
newLore = new ArrayList<>();
newLore.add(newLine);
itemLore = new ArrayList<>();
itemLore.add(newLine);
}
return newLore;
return itemLore;
}
public List<Component> addItemLore(ItemMeta itemMeta, Component newLine) {
List<Component> itemLore;
if (itemMeta.hasLore()) {
itemLore = itemMeta.lore();
itemLore.add(newLine);
} else {
itemLore = new ArrayList<>();
itemLore.add(newLine);
}
return itemLore;
}
/**
@@ -87,9 +88,9 @@ public class ItemLore {
* @param formattedDate The date of the ownership.
* @return The item's new lore.
*/
public List<String> addNewOwner(ItemMeta itemMeta, String playerName, String formattedDate) {
String dateCreatedLore;
String itemOwnerLore;
public List<Component> addNewOwner(ItemMeta itemMeta, String playerName, String formattedDate) {
Component dateCreatedLore;
Component itemOwnerLore;
Integer origin = null;
PersistentDataContainer container = itemMeta.getPersistentDataContainer();
if (container.has(toolStats.originType, PersistentDataType.INTEGER)) {
@@ -100,166 +101,107 @@ public class ItemLore {
if (origin == null) {
toolStats.logger.info("Unable to determine origin for item " + itemMeta.getAsString());
toolStats.logger.info("This IS a bug, please report this to the GitHub.");
return itemMeta.getLore();
return itemMeta.lore();
}
// set the lore based on the origin
switch (origin) {
case 2: {
dateCreatedLore = toolStats.configTools.getLoreFromConfig("looted.looted-on", true);
itemOwnerLore = toolStats.configTools.getLoreFromConfig("looted.looted-by", true);
dateCreatedLore = toolStats.configTools.formatLore("looted.looted-on", "{date}", formattedDate);
itemOwnerLore = toolStats.configTools.formatLore("looted.looted-by", "{player}", playerName);
if (dateCreatedLore == null) {
toolStats.logger.warning("messages.looted.looted-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
if (itemOwnerLore == null) {
toolStats.logger.warning("messages.looted.looted-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
break;
}
case 3: {
dateCreatedLore = toolStats.configTools.getLoreFromConfig("traded.traded-on", true);
itemOwnerLore = toolStats.configTools.getLoreFromConfig("traded.traded-by", true);
dateCreatedLore = toolStats.configTools.formatLore("traded.traded-on", "{date}", formattedDate);
itemOwnerLore = toolStats.configTools.formatLore("traded.traded-by", "{player}", playerName);
if (dateCreatedLore == null) {
toolStats.logger.warning("messages.traded.traded-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
if (itemOwnerLore == null) {
toolStats.logger.warning("messages.traded.traded-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
break;
}
case 4: {
dateCreatedLore = toolStats.configTools.getLoreFromConfig("looted.found-on", true);
itemOwnerLore = toolStats.configTools.getLoreFromConfig("looted.found-by", true);
dateCreatedLore = toolStats.configTools.formatLore("looted.found-on", "{date}", formattedDate);
itemOwnerLore = toolStats.configTools.formatLore("looted.found-by", "{player}", playerName);
if (dateCreatedLore == null) {
toolStats.logger.warning("messages.looted.found-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
if (itemOwnerLore == null) {
toolStats.logger.warning("messages.looted.found-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
break;
}
case 5: {
dateCreatedLore = toolStats.configTools.getLoreFromConfig("fished.caught-on", true);
itemOwnerLore = toolStats.configTools.getLoreFromConfig("fished.caught-by", true);
dateCreatedLore = toolStats.configTools.formatLore("fished.caught-on", "{date}", formattedDate);
itemOwnerLore = toolStats.configTools.formatLore("fished.caught-by", "{player}", playerName);
if (dateCreatedLore == null) {
toolStats.logger.warning("messages.fished.caught-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
if (itemOwnerLore == null) {
toolStats.logger.warning("messages.fished.caught-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
break;
}
case 6: {
dateCreatedLore = toolStats.configTools.getLoreFromConfig("spawned-in.spawned-on", true);
itemOwnerLore = toolStats.configTools.getLoreFromConfig("spawned-in.spawned-by", true);
dateCreatedLore = toolStats.configTools.formatLore("spawned-in.spawned-on", "{date}", formattedDate);
itemOwnerLore = toolStats.configTools.formatLore("spawned-in.spawned-by", "{player}", playerName);
if (dateCreatedLore == null) {
toolStats.logger.warning("messages.spawned-in.spawned-on is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
if (itemOwnerLore == null) {
toolStats.logger.warning("messages.spawned-in.spawned-by is not set in your config!");
toolStats.logger.warning("Unable to update lore for item.");
return itemMeta.getLore();
return itemMeta.lore();
}
break;
}
default: {
toolStats.logger.warning("Origin " + origin + " was found. Data was modified OR something REALLY broke.");
toolStats.logger.warning(itemMeta.getAsString());
return itemMeta.getLore();
return itemMeta.lore();
}
}
List<String> newLore;
List<Component> newLore;
if (itemMeta.hasLore()) {
newLore = itemMeta.getLore();
newLore = itemMeta.lore();
} else {
newLore = new ArrayList<>();
}
newLore.add(dateCreatedLore.replace("{date}", formattedDate));
newLore.add(itemOwnerLore.replace("{player}", playerName));
newLore.add(dateCreatedLore);
newLore.add(itemOwnerLore);
return newLore;
}
/**
* Determine an item's origin based on lore.
*
* @param itemMeta The item's meta.
* @param elytra If they item is an elytra.
* @return The new item meta with the new origin tag. Returns null if origin cannot be determined.
*/
public ItemMeta getOrigin(ItemMeta itemMeta, boolean elytra) {
List<String> lore;
if (!itemMeta.hasLore()) {
return null;
}
lore = itemMeta.getLore();
Integer origin = null;
String createdBy = toolStats.configTools.getLoreFromConfig("created.created-by", false);
String createdOn = toolStats.configTools.getLoreFromConfig("created.created-on", false);
String caughtBy = toolStats.configTools.getLoreFromConfig("fished.caught-by", false);
String lootedBy = toolStats.configTools.getLoreFromConfig("looted.looted-by", false);
String foundBy = toolStats.configTools.getLoreFromConfig("looted.found-by", false);
String tradedBy = toolStats.configTools.getLoreFromConfig("traded.traded-by", false);
for (String line : lore) {
// this is the worst code I have ever written
if (createdBy != null && line.contains(createdBy)) {
origin = 0;
}
if (createdOn != null && line.contains(createdOn)) {
origin = 0;
}
if (caughtBy != null && line.contains(caughtBy)) {
origin = 5;
}
if (lootedBy != null && line.contains(lootedBy)) {
origin = 2;
}
// because the config changed, "found-by" was being used for ALL looted items
// this includes elytras, so we have to check for this mistake
if (foundBy != null && line.contains(foundBy)) {
if (elytra) {
origin = 4;
} else {
origin = 5;
}
}
if (tradedBy != null && line.contains(tradedBy)) {
origin = 3;
}
}
if (origin == null) {
return null;
}
PersistentDataContainer container = itemMeta.getPersistentDataContainer();
container.set(toolStats.originType, PersistentDataType.INTEGER, origin);
return itemMeta;
}
}

View File

@@ -18,15 +18,20 @@
package lol.hyper.toolstats.tools.config;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.ChatColor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Material;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ConfigTools {
private final ToolStats toolStats;
private final Pattern COLOR_CODES = Pattern.compile("(?i)&[0-9A-FK-ORX]");
public static final Pattern COLOR_CODES = Pattern.compile("[&§]([0-9a-fk-or])");
public static final Pattern CONFIG_HEX_PATTERN = Pattern.compile("[&§]#([A-Fa-f0-9]{6})");
public static final Pattern MINECRAFT_HEX_PATTERN = Pattern.compile("§x(?:§[a-fA-F0-9]){6}|§[a-fA-F0-9]");
public ConfigTools(ToolStats toolStats) {
this.toolStats = toolStats;
@@ -67,96 +72,74 @@ public class ConfigTools {
itemType = itemName.substring(itemName.indexOf('_') + 1);
}
switch (itemType) {
case "pickaxe": {
return toolStats.config.getBoolean("enabled." + configName + ".pickaxe");
}
case "sword": {
return toolStats.config.getBoolean("enabled." + configName + ".sword");
}
case "shovel": {
return toolStats.config.getBoolean("enabled." + configName + ".shovel");
}
case "axe": {
return toolStats.config.getBoolean("enabled." + configName + ".axe");
}
case "hoe": {
return toolStats.config.getBoolean("enabled." + configName + ".hoe");
}
case "shears": {
return toolStats.config.getBoolean("enabled." + configName + ".shears");
}
case "crossbow":
case "bow": {
return toolStats.config.getBoolean("enabled." + configName + ".bow");
}
case "trident": {
return toolStats.config.getBoolean("enabled." + configName + ".trident");
}
case "fishing-rod": {
return toolStats.config.getBoolean("enabled." + configName + ".fishing-rod");
}
case "helmet":
case "chestplate":
case "leggings":
case "boots": {
return toolStats.config.getBoolean("enabled." + configName + ".armor");
}
}
return false;
return switch (itemType) {
case "pickaxe" -> toolStats.config.getBoolean("enabled." + configName + ".pickaxe");
case "sword" -> toolStats.config.getBoolean("enabled." + configName + ".sword");
case "shovel" -> toolStats.config.getBoolean("enabled." + configName + ".shovel");
case "axe" -> toolStats.config.getBoolean("enabled." + configName + ".axe");
case "hoe" -> toolStats.config.getBoolean("enabled." + configName + ".hoe");
case "shears" -> toolStats.config.getBoolean("enabled." + configName + ".shears");
case "crossbow", "bow" -> toolStats.config.getBoolean("enabled." + configName + ".bow");
case "trident" -> toolStats.config.getBoolean("enabled." + configName + ".trident");
case "fishing-rod" -> toolStats.config.getBoolean("enabled." + configName + ".fishing-rod");
case "mace" -> toolStats.config.getBoolean("enabled." + configName + ".mace");
case "helmet", "chestplate", "leggings", "boots" ->
toolStats.config.getBoolean("enabled." + configName + ".armor");
default -> false;
};
}
/**
* Gets the lore message from the config.
* Format a string to be ready for lore usage.
*
* @param configName The config name, "messages." is already in front.
* @param raw If you want the raw message with the formatting codes and placeholders.
* @return The lore message.
* @param configName The message to use.
* @param placeHolder The placeholder text in the message.
* @param value The value to set the placeholder.
* @return Formatted string, null if the configName doesn't exist.
*/
public String getLoreFromConfig(String configName, boolean raw) {
public Component formatLore(String configName, String placeHolder, Object value) {
String lore = toolStats.config.getString("messages." + configName);
if (lore == null) {
toolStats.logger.warning("Unable to find config message for: messages." + configName);
return null;
}
if (raw) {
return ChatColor.translateAlternateColorCodes('&', lore);
} else {
// remove all color codes
// this is used to compare the current lore on the item
// Example: [§7Arrows shot: §8] is on the lore
// this will return [Arrows shot: ] so we can match it
lore = COLOR_CODES.matcher(lore).replaceAll("");
if (lore.contains("{player}")) {
lore = lore.replace("{player}", "");
}
if (lore.contains("{date}")) {
lore = lore.replace("{date}", "");
}
if (lore.contains("{name}")) {
lore = lore.replace("{name}", "");
}
if (lore.contains("{kills}")) {
lore = lore.replace("{kills}", "");
}
if (lore.contains("{blocks}")) {
lore = lore.replace("{blocks}", "");
}
if (lore.contains("{sheep}")) {
lore = lore.replace("{sheep}", "");
}
if (lore.contains("{damage}")) {
lore = lore.replace("{damage}", "");
}
if (lore.contains("{fish}")) {
lore = lore.replace("{fish}", "");
}
if (lore.contains("{crops}")) {
lore = lore.replace("{crops}", "");
}
if (lore.contains("{arrows}")) {
lore = lore.replace("{arrows}", "");
}
// if the config message is empty, don't send it
if (lore.isEmpty()) {
return null;
}
return lore;
// the final component for this lore
Component component;
// set the placeholder to the value
if (placeHolder != null && value != null) {
lore = lore.replace(placeHolder, String.valueOf(value));
}
// if we match the old color codes, then format them as so
Matcher hexMatcher = CONFIG_HEX_PATTERN.matcher(lore);
Matcher colorMatcher = COLOR_CODES.matcher(lore);
if (hexMatcher.find() || colorMatcher.find()) {
component = LegacyComponentSerializer.legacyAmpersand().deserialize(lore);
} else {
// otherwise format them normally
component = Component.text(lore);
}
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
}
/**
* Remove all color codes from a message.
*
* @param message The message.
* @return The message without color codes.
*/
public String removeColor(String message) {
message = MINECRAFT_HEX_PATTERN.matcher(message).replaceAll("");
message = COLOR_CODES.matcher(message).replaceAll("");
message = CONFIG_HEX_PATTERN.matcher(message).replaceAll("");
return message;
}
}

View File

@@ -36,6 +36,8 @@ package lol.hyper.toolstats.tools.config;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.config.versions.Version6;
import lol.hyper.toolstats.tools.config.versions.Version7;
import lol.hyper.toolstats.tools.config.versions.Version8;
public class ConfigUpdater {
@@ -48,10 +50,25 @@ public class ConfigUpdater {
public void updateConfig() {
int version = toolStats.config.getInt("config-version");
// this will be a switch in the future
if (version == 5) {
Version6 version6 = new Version6(toolStats);
version6.update();
switch(version) {
case 5: {
// Version 5 to 6
Version6 version6 = new Version6(toolStats);
version6.update();
break;
}
case 6: {
// Version 6 to 7
Version7 version7 = new Version7(toolStats);
version7.update();
break;
}
case 7: {
// Version 7 to 8
Version8 version8 = new Version8(toolStats);
version8.update();
break;
}
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of ToolStats.
*
* ToolStats 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.
*
* ToolStats 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 ToolStats. If not, see <https://www.gnu.org/licenses/>.
*/
package lol.hyper.toolstats.tools.config.versions;
import lol.hyper.toolstats.ToolStats;
import java.io.File;
import java.io.IOException;
public class Version7 {
private final ToolStats toolStats;
/**
* Used for updating from version 6 to 7.
*
* @param toolStats ToolStats instance.
*/
public Version7(ToolStats toolStats) {
this.toolStats = toolStats;
}
/**
* Perform the config update.
*/
public void update() {
// save the old config first
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config-6.yml");
} catch (IOException exception) {
toolStats.logger.severe("Unable to save config-6.yml!");
throw new RuntimeException(exception);
}
// we make this super verbose so that admins can see what's being added
toolStats.logger.info("Updating config.yml to version 7.");
toolStats.config.set("config-version", 7);
toolStats.logger.info("Adding messages.flight-time to config.yml.");
toolStats.config.set("messages.flight-time", "&7Flight time: &8{time}");
toolStats.logger.info("Adding enabled.flight-time to config.yml.");
toolStats.config.set("enabled.flight-time", true);
// save the config and reload it
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
} catch (IOException exception) {
toolStats.logger.severe("Unable to save config.yml!");
throw new RuntimeException(exception);
}
toolStats.loadConfig();
toolStats.logger.info("Config has been updated to version 7. A copy of version 6 has been saved as config-6.yml");
}
}

View File

@@ -0,0 +1,87 @@
/*
* This file is part of ToolStats.
*
* ToolStats 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.
*
* ToolStats 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 ToolStats. If not, see <https://www.gnu.org/licenses/>.
*/
package lol.hyper.toolstats.tools.config.versions;
import lol.hyper.toolstats.ToolStats;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Version8 {
private final ToolStats toolStats;
/**
* Used for updating from version 7 to 8.
*
* @param toolStats ToolStats instance.
*/
public Version8(ToolStats toolStats) {
this.toolStats = toolStats;
}
/**
* Perform the config update.
*/
public void update() {
// save the old config first
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config-7.yml");
} catch (IOException exception) {
toolStats.logger.severe("Unable to save config-7.yml!");
throw new RuntimeException(exception);
}
// we make this super verbose so that admins can see what's being added
toolStats.logger.info("Updating config.yml to version 8.");
toolStats.config.set("config-version", 8);
// Add example to setting mob names
toolStats.logger.info("Adding example for messages.mob.ZOMBIE");
toolStats.config.set("messages.mob.ZOMBIE", "Zombie");
// Add mace to enabled sections
toolStats.logger.info("Adding entry for enabled.created-by.mace");
toolStats.config.set("enabled.created-by.mace", true);
toolStats.logger.info("Adding entry for enabled.created-date.mace");
toolStats.config.set("enabled.created-date.mace", true);
toolStats.logger.info("Adding entry for enabled.player-kills.mace");
toolStats.config.set("enabled.player-kills.mace", true);
toolStats.logger.info("Adding entry for enabled.mob-kills.mace");
toolStats.config.set("enabled.mob-kills.mace", true);
List<String> mobComments = new ArrayList<>();
mobComments.add("Set display name for mobs. See: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html");
toolStats.config.setComments("messages.mob", mobComments);
// save the config and reload it
try {
toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml");
} catch (IOException exception) {
toolStats.logger.severe("Unable to save config.yml!");
throw new RuntimeException(exception);
}
toolStats.loadConfig();
toolStats.logger.info("Config has been updated to version 8. A copy of version 7 has been saved as config-7.yml");
}
}

View File

@@ -9,6 +9,7 @@ enabled:
shears: true
bow: true
armor: true
mace: true
# Will show time the item is created
created-date:
pickaxe: true
@@ -19,6 +20,7 @@ enabled:
shears: true
bow: true
armor: true
mace: true
# Will show "Fished by <player>"
fished-tag:
pickaxe: true
@@ -54,11 +56,13 @@ enabled:
axe: true
trident: true
bow: true
mace: true
mob-kills:
sword: true
axe: true
trident: true
bow: true
mace: true
blocks-mined:
pickaxe: true
shovel: true
@@ -75,12 +79,14 @@ enabled:
shears: true
bow: true
armor: true
mace: true
fish-caught: true
sheep-sheared: true
armor-damage: true
dropped-by: true
elytra-tag: true
arrows-shot: true
flight-time: true
messages:
created:
@@ -110,11 +116,15 @@ messages:
dropped-by: "&7Dropped by: &8{name}" # name will be player/mob name
damage-taken: "&7Damage taken: &8{damage}"
arrows-shot: "&7Arrows shot: &8{arrows}"
flight-time: "&7Flight time: &8{time}"
# Display this message if the player shift click trades/crafts items. It's not really easy to get every single item
# that is crafted. The tag will only be added to the first item. If you don't want this message, simply replace them both with ""
shift-click-warning:
crafting: "&cCrafting items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
trading: "&cTrading items via shift clicking does not fully apply tags to each item. This is a limitation with the Bukkit API."
# Set display name for mobs. See: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html
mobs:
ZOMBIE: "Zombie"
# Change the default formatting for dates.
# See: https://www.digitalocean.com/community/tutorials/java-simpledateformat-java-date-format
@@ -134,4 +144,4 @@ number-formats:
# This has no use currently, but can be used for future features for dupe detection.
generate-hash-for-items: true
config-version: 6
config-version: 7

View File

@@ -1,9 +1,10 @@
name: ToolStats
version: '${project.version}'
main: lol.hyper.toolstats.ToolStats
api-version: 1.15
api-version: 1.21
author: hyperdefined
description: Track various tool stats!
website: https://github.com/hyperdefined/ToolStats
folia-supported: true
commands:
toolstats: