mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
Compare commits
190 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8447233b1e | |||
| eb2e7b3abb | |||
| 7f7f049b7b | |||
| 37e8ca7da9 | |||
| 95d3cf3228 | |||
| 178b372255 | |||
| 106cd53b02 | |||
| 950bad2168 | |||
| bc9cbe0b44 | |||
| 9d616d2fd0 | |||
| f82ccfa07e | |||
| cff94a2c5a | |||
| 4b5133c872 | |||
| 98d359f59f | |||
| 96754fd260 | |||
| b92b762551 | |||
| c064e4b1e1 | |||
| fc33b6fbd5 | |||
| 29e08fe29b | |||
| 151666fd21 | |||
| 593527241a | |||
| 3578322686 | |||
| 12ec4e1f54 | |||
| b0f32fdba2 | |||
| d82bd9b22c | |||
| 380b0de92f | |||
| d91576b0de | |||
| 2f9d25bfe9 | |||
| 49b0054eca | |||
| 2efb6e55e2 | |||
| d679cd73f9 | |||
| 9f06f708f5 | |||
| 31fa3d38b7 | |||
| bf4395ba3f | |||
| 2768c0a0dc | |||
| f0d53a6ffa | |||
| d0078e528d | |||
| edceba879f | |||
| 106bc724a1 | |||
| e6293be1c6 | |||
| 7a705f3bfc | |||
| df92b4bf91 | |||
| bf8144ad06 | |||
| 2d31a7f5a8 | |||
| 3992ce1662 | |||
| 7aac325c70 | |||
| 171a8cad6d | |||
| fb27ad2e55 | |||
| 1b3447d041 | |||
| ac9f492125 | |||
| 1660250ee1 | |||
| 856c1e08bd | |||
| 2c3e43cb84 | |||
| d67380da1a | |||
| b18cf1fd59 | |||
| bf926fb159 | |||
| 21087b89e0 | |||
| a392702df2 | |||
| 5265d81176 | |||
| 91d2cce8cc | |||
| 31f9e7e281 | |||
| 05951d0ace | |||
| 65bf82a239 | |||
| 90cc758e88 | |||
| d926b5001e | |||
| 809dc3488b | |||
| 3594cf72af | |||
| 2070f8fd68 | |||
| 68f63a8ec7 | |||
| c703dc68f9 | |||
| 36030c598b | |||
| a6cdd79750 | |||
| 440b2b2741 | |||
| 41a62d810a | |||
| 459e3351fd | |||
| e00c5e8b47 | |||
| 638df714fd | |||
| 190f334656 | |||
| 8141232c46 | |||
| a1984ad5b9 | |||
| f5343440e4 | |||
| 55f6b94ba9 | |||
| 24db259435 | |||
| d867ca6c85 | |||
| 1b86996317 | |||
| bce43649bc | |||
| 12bfcb75ce | |||
| e30f09120d | |||
| b42fb42d83 | |||
| daa1c6171f | |||
| d4e94872d8 | |||
| 7612eac765 | |||
|
|
1a71086327 | ||
| 45fe037a92 | |||
| d061bfc6f4 | |||
| 889d452466 | |||
| 7fbf68dff3 | |||
| f520d5e3db | |||
| e5167971f4 | |||
| 3d50e0ec82 | |||
| 60ebdbf107 | |||
| f3c6526967 | |||
| 8ded2ae9c6 | |||
| f0d2f07703 | |||
| 26469982b2 | |||
| 882e50e449 | |||
| c96dd7d308 | |||
| f59071f504 | |||
| 6afe51acca | |||
| 6a4c861eab | |||
| ab3e4a32ba | |||
| b532ce7dc6 | |||
| e08a02a84a | |||
| 9b8a2d0f32 | |||
| 7bb0c1523d | |||
| 5caa56be59 | |||
| 77c8494166 | |||
| 0440835013 | |||
| bc7ed5af85 | |||
| 2dd48a8041 | |||
| 621222fc01 | |||
| 7044860267 | |||
| 48f0cab15d | |||
| 3e68af06ea | |||
| d037263e3f | |||
| 5ff096190f | |||
| 39db70d7ad | |||
| ec2384bc7f | |||
| 4e15aab024 | |||
| a66206a52c | |||
| 2cff7bd83c | |||
| 33a86cd3bc | |||
| fbc862a5a3 | |||
| 20509faed4 | |||
| 63f2f16b9f | |||
| 63353c6205 | |||
| 5f707c7397 | |||
| 3eb07a8c09 | |||
| 196392e206 | |||
| f13503f873 | |||
| 49abca2ccf | |||
| d801d85242 | |||
| 9cf06fbb93 | |||
| c57de03442 | |||
| ae8167faec | |||
| 7aeb776ce0 | |||
| 2c30446bc1 | |||
| 9ed43f3def | |||
| 8e3f190bb3 | |||
| c8f1aa65a2 | |||
| 4dd7d6361b | |||
| 58b2910350 | |||
| 76e5059632 | |||
| b7e19355a8 | |||
| 377bc4c1d8 | |||
| ea6c5724fa | |||
| f14fe20faf | |||
| 675a16c9b4 | |||
| 18a0f58e68 | |||
| dc7f3f5e20 | |||
| 73fd79b9da | |||
| 5c32e819fd | |||
| 4a2a9c5b3a | |||
| 203713385a | |||
| 35c67e4207 | |||
| e1c794403c | |||
| 69f0e2936e | |||
| be3a98078f | |||
| 5fe65799c8 | |||
| 9e0e546367 | |||
| d4165df61a | |||
| 4ed9de3d3c | |||
| 474ad0f1b2 | |||
| a373cd76f7 | |||
| a350b7fa69 | |||
| fe2196626a | |||
| 161ef6ba91 | |||
| a6cee2d591 | |||
| be7f4d0bcb | |||
| 89eec84a66 | |||
| 59d3c9a85c | |||
| 6975f29d9d | |||
| 1544cd315b | |||
| 01d7d91d4f | |||
| 87f7ed6538 | |||
| 87c9971626 | |||
| fc94dbe169 | |||
| f5a89fea7c | |||
| ee4936ecf5 | |||
| c166d2a78a |
161 changed files with 5266 additions and 1883 deletions
92
.github/workflows/gradle.yml
vendored
92
.github/workflows/gradle.yml
vendored
|
|
@ -12,9 +12,11 @@ on:
|
||||||
branches: [ "v1.x.x", "v2.x.x" ]
|
branches: [ "v1.x.x", "v2.x.x" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "v1.x.x", "v2.x.x" ]
|
branches: [ "v1.x.x", "v2.x.x" ]
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
@ -23,6 +25,10 @@ jobs:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x", "1.21.x", "26.1.x", "26.2.x"]'
|
||||||
|
MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up JDKs
|
- name: Set up JDKs
|
||||||
|
|
@ -31,21 +37,41 @@ jobs:
|
||||||
java-version: |
|
java-version: |
|
||||||
21
|
21
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
cache: 'gradle'
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Cache Gradle root and wrapper
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.gradle/caches
|
||||||
|
~/.gradle/wrapper
|
||||||
|
key: gradle-root-${{ runner.os }}-${{ hashFiles('build.gradle*') }}
|
||||||
|
restore-keys: gradle-root-${{ runner.os }}-
|
||||||
|
|
||||||
|
# Setup paperweight cache
|
||||||
|
- name: Cache paperweight
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
./nms/*/.gradle/caches/paperweight
|
||||||
|
key: paperweight-submodules-${{ runner.os }}-${{ hashFiles('nms/*/build.gradle*') }}
|
||||||
|
restore-keys: |
|
||||||
|
paperweight-submodules-${{ runner.os }}-
|
||||||
|
|
||||||
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
|
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
|
||||||
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
|
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
|
||||||
- name: Setup Gradle
|
- name: Setup Gradle
|
||||||
uses: gradle/actions/setup-gradle@v4
|
uses: gradle/actions/setup-gradle@v5
|
||||||
|
|
||||||
- name: Make gradlew executable
|
- name: Make gradlew executable
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Get small commit hash
|
- name: Get small commit hash
|
||||||
|
if: ${{ github.event_name != 'release' && success() }}
|
||||||
run: echo "SMALL_COMMIT_HASH=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV
|
run: echo "SMALL_COMMIT_HASH=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build with Gradle Wrapper
|
- name: Build with Gradle Wrapper
|
||||||
run: ./gradlew build --parallel
|
run: ./gradlew build --parallel --stacktrace
|
||||||
|
|
||||||
# only submit dependency on push
|
# only submit dependency on push
|
||||||
- name: Generate and submit dependency graph
|
- name: Generate and submit dependency graph
|
||||||
|
|
@ -63,7 +89,7 @@ jobs:
|
||||||
echo "ONLINE_JAR_NAME=$(basename $ONLINE_JAR_PATH)" >> $GITHUB_ENV
|
echo "ONLINE_JAR_NAME=$(basename $ONLINE_JAR_PATH)" >> $GITHUB_ENV
|
||||||
echo "OFFLINE_JAR_NAME=$(basename $OFFLINE_JAR_PATH)" >> $GITHUB_ENV
|
echo "OFFLINE_JAR_NAME=$(basename $OFFLINE_JAR_PATH)" >> $GITHUB_ENV
|
||||||
|
|
||||||
# upload the named jars
|
# upload the named jars as artifact
|
||||||
- name: Upload online JAR artifact
|
- name: Upload online JAR artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -79,3 +105,59 @@ jobs:
|
||||||
- name: Summarize tests results
|
- name: Summarize tests results
|
||||||
uses: jeantessier/test-summary-action@v1
|
uses: jeantessier/test-summary-action@v1
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
|
|
||||||
|
# upload the jar to release
|
||||||
|
- name: Upload jar to release
|
||||||
|
if: ${{ github.event_name == 'release' && success() }}
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
build/libs/${{ env.ONLINE_JAR_NAME }}
|
||||||
|
build/libs/${{ env.OFFLINE_JAR_NAME }}
|
||||||
|
|
||||||
|
- name: Hangar release
|
||||||
|
if: ${{ (github.event_name != 'release' || github.event_name != 'push') && github.repository_owner == 'alexcrea' && success() }}
|
||||||
|
env:
|
||||||
|
HANGAR_API_TOKEN: ${{ secrets.HANGAR_API_TOKEN }}
|
||||||
|
RELEASE_CHANGELOG: ${{ github.event.release.body }}
|
||||||
|
run: ./gradlew publishAllPublicationsToHangar --stacktrace
|
||||||
|
|
||||||
|
- name: Modrinth publish alpha
|
||||||
|
if: ${{ github.event_name == 'push' && github.repository_owner == 'alexcrea' && success() }}
|
||||||
|
uses: cloudnode-pro/modrinth-publish@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.MODRINTH_TOKEN }}
|
||||||
|
project: S75Ueiq9
|
||||||
|
name: dev-${{ env.SMALL_COMMIT_HASH }}
|
||||||
|
version: dev-${{ env.SMALL_COMMIT_HASH }}
|
||||||
|
loaders: ${{ env.MODRINTH_PLATFORMS }}
|
||||||
|
game-versions: ${{ env.MODRINTH_VERSIONS }}
|
||||||
|
channel: alpha
|
||||||
|
files: build/libs/${{ env.ONLINE_JAR_NAME }}
|
||||||
|
changelog: ${{ github.event.head_commit.message }}
|
||||||
|
|
||||||
|
- name: Modrinth publish release
|
||||||
|
if: ${{ github.event_name == 'release' && github.repository_owner == 'alexcrea' && success() }}
|
||||||
|
uses: cloudnode-pro/modrinth-publish@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.MODRINTH_TOKEN }}
|
||||||
|
project: S75Ueiq9
|
||||||
|
name: ${{ github.event.release.name }}
|
||||||
|
version: ${{ github.event.release.tag_name }}${{ github.event.release.prerelease && '-pre' || '' }}
|
||||||
|
loaders: ${{ env.MODRINTH_PLATFORMS }}
|
||||||
|
game-versions: ${{ env.MODRINTH_VERSIONS }}
|
||||||
|
channel: ${{ github.event.release.prerelease == false && 'release' || 'beta' }}
|
||||||
|
files: build/libs/${{ env.ONLINE_JAR_NAME }}
|
||||||
|
changelog: ${{ github.event.release.body }}
|
||||||
|
|
||||||
|
- name: Send release note to discord
|
||||||
|
if: ${{ github.event_name == 'release' && github.repository_owner == 'alexcrea' && success() }}
|
||||||
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
|
with:
|
||||||
|
webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }}
|
||||||
|
content: |
|
||||||
|
${{ github.event.release.prerelease == false && '<@&1338546156325568642>' || '<@&1352296092989001768>' }}
|
||||||
|
# New ${{ github.event.release.prerelease && 'beta ' || '' }}version of custom anvil ! <:CustomAnvil:1262550667986342001>([Modrinth](https://modrinth.com/plugin/customanvil), [Hangar](https://hangar.papermc.io/alexcrea/CustomAnvil) and [GitHub](${{ github.event.release.html_url }}) links)
|
||||||
|
-# note: automated release. spigot is not uploaded yet.
|
||||||
|
|
||||||
|
${{ github.event.release.body }}
|
||||||
|
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -14,6 +14,9 @@
|
||||||
/impl/*/build
|
/impl/*/build
|
||||||
/impl/*/.gradle
|
/impl/*/.gradle
|
||||||
|
|
||||||
|
# run folder
|
||||||
|
/run/
|
||||||
|
|
||||||
# other random folders
|
# other random folders
|
||||||
/htmlReport
|
/htmlReport
|
||||||
/.kotlin/errors
|
/.kotlin/errors
|
||||||
|
|
|
||||||
9
.run/Server.run.xml
Normal file
9
.run/Server.run.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Server" type="JarApplication">
|
||||||
|
<option name="JAR_PATH" value="$PROJECT_DIR$/run/server.jar" />
|
||||||
|
<option name="PROGRAM_PARAMETERS" value="-nogui" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/run" />
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
63
COMPATIBILITY.md
Normal file
63
COMPATIBILITY.md
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
### Bedrock issue
|
||||||
|
For server using geyser, bedrock player cannot use custom "recipes" in the anvil.
|
||||||
|
This is cannot be fixed on geyser or my side.
|
||||||
|
|
||||||
|
### Plugin Compatibility
|
||||||
|
Here is various plugins that had issues with CustomAnvil
|
||||||
|
where efforts was made for compatibility and should be working right:
|
||||||
|
|
||||||
|
some if not all of them are cool ! I recommend checking them out !
|
||||||
|
|
||||||
|
## Supported By CustomAnvil
|
||||||
|
These plugins have compatibility handled by custom anvil. seek help on custom anvil and do not bother these developers
|
||||||
|
|
||||||
|
#### Enchantment Plugins
|
||||||
|
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/) by NightExpress:
|
||||||
|
Use ExcellentEnchants item type \
|
||||||
|
Also use ExcellentEnchant max enchant limit
|
||||||
|
|
||||||
|
- [EcoEnchant](https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/) by Auxilor:
|
||||||
|
Need to use /anvilconfigreload or a server restart to add newly added enchantment.
|
||||||
|
Use EcoEnchant restriction system but new restriction can be added in custom anvil
|
||||||
|
|
||||||
|
- [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/) by Athlaeos:
|
||||||
|
Support by Custom Anvil but still experimental. Automatic configuration. Plugin is not actively developed anymore
|
||||||
|
|
||||||
|
- [SuperEnchants](https://modrinth.com/plugin/superenchants) by Aznos:
|
||||||
|
Use SuperEnchant restrictions system but new restriction can be added in custom anvil
|
||||||
|
|
||||||
|
|
||||||
|
#### Custom Items Plugins
|
||||||
|
Custom Items support is considered unstable. If you find issue please report it !
|
||||||
|
|
||||||
|
- [EcoItem](https://www.spigotmc.org/resources/30-sale%E2%8F%B3-ecoitems-%E2%AD%95-create-custom-items-%E2%9C%85-weapons-armors-tools-charms-%E2%9C%A8-item-levels-rarities.94601/) by Exanthiax:
|
||||||
|
May have some issue. but should partially work I hope
|
||||||
|
|
||||||
|
- [ItemAdder](https://www.spigotmc.org/resources/%E2%9C%A8itemsadder%E2%AD%90emotes-mobs-items-armors-hud-gui-emojis-blocks-wings-hats-liquids.73355/) by LoneDev:
|
||||||
|
Need to fix unit item not working completly correctly as in can't have twice same base item
|
||||||
|
|
||||||
|
#### Anvil Mechanics Plugins
|
||||||
|
- [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) by H7KZ
|
||||||
|
Partially use Custom Anvil maximum XP settings (>= 6.1.5)
|
||||||
|
|
||||||
|
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/) by hyperdefined
|
||||||
|
For bag upgrade and skin via anvil. (version >= 1.31.0)
|
||||||
|
|
||||||
|
- [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi) by ArtillexStudios
|
||||||
|
For its anvil inventory usage
|
||||||
|
|
||||||
|
- [ToolsStats](https://modrinth.com/project/oBZj9E15) by Valorless
|
||||||
|
For token application using anvil
|
||||||
|
|
||||||
|
### Known Partially Incompatible
|
||||||
|
- [UberEnchant](https://modrinth.com/plugin/uberenchant) by coltonj96
|
||||||
|
Anvil handling as they are doing something similar to CustomAnvil.
|
||||||
|
It is by no mean there faults and I recommend checking them out especially if custom anvil do not work for your use case !
|
||||||
|
|
||||||
|
- [AdvencedEnchantments](https://ae.advancedplugins.net/) by Advanced Plugins
|
||||||
|
Paid plugin I do not own as I did not get commissioned for support.
|
||||||
|
may be able to use api but cannot test on my side
|
||||||
|
|
||||||
|
If you like Custom Anvil to support a specific plugin (custom enchant or anvil mechanic).
|
||||||
|
You can ask, but please note implementing compatibility will be considered
|
||||||
|
as low priority as I work for the plugin as an hobby on my free time for free.
|
||||||
34
CREDITS.md
Normal file
34
CREDITS.md
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
Thanks **DelilahEve** for making [Unsafe Enchants](https://github.com/DelilahEve/UnsafeEnchants). \
|
||||||
|
CustomAnvil was initially a fork of Unsafe Enchants where I wanted to add more and more and here we are now !
|
||||||
|
|
||||||
|
Thanks for all the contributors of bukkit, spigot, the paper team and the adventure API developers \
|
||||||
|
Thanks JetBrain for making IntelliJ
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
These dependencies (or a modified version of) are used by custom anvil
|
||||||
|
- [IF](https://github.com/stefvanschie/IF) an inventory framework by stefvanschie
|
||||||
|
- [Mockbukkit](https://github.com/MockBukkit/MockBukkit) for unit testing
|
||||||
|
- [CentralPortalPlus](https://github.com/lalakii/central-portal-plus) by lalakii
|
||||||
|
- [test-summary-action](https://github.com/jeantessier/test-summary-action) by jeantessier
|
||||||
|
- [modrinth-publish](https://github.com/cloudnode-pro/modrinth-publish) by Zefir
|
||||||
|
- [discord-webhook](https://github.com/tsickert/discord-webhook) by tsickert
|
||||||
|
- Thanks [bstats](https://bstats.org/) for keeping me motivated
|
||||||
|
- And [FastStats](https://faststats.dev/) alternative to bstats in beta test
|
||||||
|
- [ModrinthUpdateChecker](https://github.com/Clickism/ModrinthUpdateChecker) by Clickism and thanks to the modrinth team
|
||||||
|
|
||||||
|
### Compatibility
|
||||||
|
Thanks to all the cool creator making the minecraft plugin's ecosystem works ! \
|
||||||
|
See [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) for details
|
||||||
|
|
||||||
|
but especially, Big Thanks for H7KZ maker of [Disenchantment](https://github.com/H7KZ/Disenchantment)
|
||||||
|
|
||||||
|
### Special Thanks
|
||||||
|
|
||||||
|
Thanks for all the users trying my plugin for these niche use cases
|
||||||
|
, reporting issues and giving ideas !
|
||||||
|
|
||||||
|
Thanks coltonj96 for [UberEnchant](https://modrinth.com/plugin/uberenchant).
|
||||||
|
we may be incompatible with the anvil, but I do think it is a good alternative ! \
|
||||||
|
I wish one day to work on cross compatibiltiy \
|
||||||
|
* If custom anvil do not work well for you or your use case give it a try ! *
|
||||||
|
|
||||||
99
README.md
99
README.md
|
|
@ -1,18 +1,11 @@
|
||||||
# Custom Anvil
|
# Custom Anvil
|
||||||
|
|
||||||
**Custom Anvil** is a plugin that allows server administrators to customize every aspect of the anvil's mechanics.
|
**Custom Anvil** is a plugin that allows server administrators to customize every aspect of the anvil's mechanics.
|
||||||
It is expected to work on 1.18 to 1.21.7 minecraft servers running spigot or paper.
|
|
||||||
(the plugin support of 1.16.5 to 1.17.1 is experimental and may encounter issues)
|
|
||||||
|
|
||||||
**Custom Anvil** was previously named **Unsafe Enchants+**.
|
|
||||||
It was renamed because it now affects every anvil aspect and not only unsafe enchants\
|
|
||||||
**Custom Anvil** is based on [Unsafe Enchants](https://github.com/DelilahEve/UnsafeEnchants) by DelilahEve.
|
|
||||||
|
|
||||||
### Download Locations:
|
### Download Locations:
|
||||||
|
|
||||||
the plugin can be downloaded on
|
the plugin can be downloaded on
|
||||||
[Spigot](https://www.spigotmc.org/resources/custom-anvil.114884),
|
[Modrinth](https://modrinth.com/plugin/customanvil),
|
||||||
[modrinth](https://modrinth.com/plugin/customanvil),
|
|
||||||
[Hangar](https://hangar.papermc.io/alexcrea/CustomAnvil)
|
[Hangar](https://hangar.papermc.io/alexcrea/CustomAnvil)
|
||||||
or here [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest)
|
or here [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest)
|
||||||
|
|
||||||
|
|
@ -21,7 +14,7 @@ the plugin can be downloaded on
|
||||||
- Vanilla like default configuration.
|
- Vanilla like default configuration.
|
||||||
- Custom enchantment level limit.
|
- Custom enchantment level limit.
|
||||||
- Custom anvil recipes.
|
- Custom anvil recipes.
|
||||||
- Custom enchant restrictions (allow unsafe enchantment only for a group of item or create new restriction).
|
- Custom enchant restrictions (allows unsafe enchantment only for a group of item or create new restriction).
|
||||||
- Custom items of unit repairs (repair damaged with unit of "material", for example the repair of diamond sword by diamonds).
|
- Custom items of unit repairs (repair damaged with unit of "material", for example the repair of diamond sword by diamonds).
|
||||||
- Custom XP cost for every aspect of the anvil.
|
- Custom XP cost for every aspect of the anvil.
|
||||||
- Permissions to bypass level limit or enchantment restriction.
|
- Permissions to bypass level limit or enchantment restriction.
|
||||||
|
|
@ -30,72 +23,63 @@ the plugin can be downloaded on
|
||||||
- Gui to configure the plugin in game.
|
- Gui to configure the plugin in game.
|
||||||
- Support use of color code, hexadecimal color and minimessage for color/decoration
|
- Support use of color code, hexadecimal color and minimessage for color/decoration
|
||||||
- (Experimental) Folia support (gui do not work)
|
- (Experimental) Folia support (gui do not work)
|
||||||
|
- (Experimental) Dialog rename (allows longer rename)
|
||||||
|
- (Experimental) Anvil with monetary cost (using vault) (require dialog rename)
|
||||||
|
|
||||||
|
And more !
|
||||||
|
|
||||||
---
|
---
|
||||||
### Permissions:
|
### Permissions:
|
||||||
|
Note that for most of them you also need to enable feature and in most case enable use of permission for the specfic feature (indicated with `(toggleable)`)
|
||||||
```yml
|
```yml
|
||||||
|
# Generic and bypass permissions
|
||||||
ca.affected: Player with this permission will be affected by the plugin
|
ca.affected: Player with this permission will be affected by the plugin
|
||||||
ca.bypass.fuse: Allow player to combine every enchantments to every item (no custom limit)
|
ca.bypass.fuse: Allow player to combine every enchantments to every item (no custom limit)
|
||||||
ca.bypass.level: Allow player to bypass every level limit (no custom limit)
|
ca.bypass.level: Allow player to bypass every level limit (no custom limit)
|
||||||
ca.command.reload: Allow administrator to reload the plugin's configs
|
|
||||||
ca.config.edit: Allow administrator to edit the plugin's config in game
|
|
||||||
# Bellow permissions also require some config change to allow usage of features
|
|
||||||
# usage of these permission is toggleable in basic config gui or config.yml
|
|
||||||
|
|
||||||
|
# Command permissions
|
||||||
|
ca.command.reload: Allow administrator to reload the plugin's configs
|
||||||
|
ca.command.diagnostic: Allow adminastator to diagnistic some simple problem with the plugin
|
||||||
|
ca.config.edit: Allow administrator to edit the plugin's config in game
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Bellow permissions also require some config change to allow usage of features
|
||||||
|
# Usage of these permission is toggleable in basic config gui or config.yml
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
# Permissions related to use of color and minimessage
|
# Permissions related to use of color and minimessage
|
||||||
ca.color.code: Allow player to use color code on rename if enabled (toggleable)
|
ca.color.code: Allow player to use color code on rename if enabled (toggleable)
|
||||||
|
ca.color.code.[thecode] (for example ca.color.code.a): Allows usage of only certain color code (toggleable)
|
||||||
ca.color.hex: Allow player to use hexadecimal color on rename if enabled (toggleable)
|
ca.color.hex: Allow player to use hexadecimal color on rename if enabled (toggleable)
|
||||||
ca.rename.minimessage: Allow player to use minimessage formating on rename if enabled (toggleable) (only legacy compatible at the time)
|
ca.rename.minimessage: Allow player to use minimessage formating on rename if enabled (toggleable)
|
||||||
|
|
||||||
# Permissions related to edition of the lore
|
# Permissions related to edition of the lore
|
||||||
ca.lore_edit.book: Allow player to edit lore via book and quil if enabled (toggleable)
|
ca.lore_edit.book: Allow player to edit lore via book and quil if enabled (toggleable)
|
||||||
ca.lore_edit.paper: Allow player to edit lore via paper if enabled (toggleable)
|
ca.lore_edit.paper: Allow player to edit lore via paper if enabled (toggleable)
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ca.rename.dialog: Allow player to use the rename dialog (toggleable)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
```yml
|
|
||||||
anvilconfigreload or carl: Reload every config of this plugin
|
run `/customanvil help` to get information about available commands \
|
||||||
customanvilconfig or configanvil: open a menu for administrator to edit plugin's config in game
|
this only show subcommands you have permission for
|
||||||
```
|
|
||||||
### Supported Plugins
|
### Supported Plugins
|
||||||
Custom Anvil can be compatible with some custom enchantments and anvil mechanics plugins.
|
See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md)
|
||||||
|
|
||||||
Here is a list of supported custom enchantment plugins with support status:
|
|
||||||
- [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/):
|
|
||||||
Support by Custom Anvil but still experimental. Automatic configuration.
|
|
||||||
|
|
||||||
- [EcoEnchant](https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/):
|
|
||||||
Support by Custom Anvil but still experimental. Need to use /anvilconfigreload or a server restart to add newly added enchantment.
|
|
||||||
Use EcoEnchant restriction system by default.
|
|
||||||
|
|
||||||
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/):
|
|
||||||
Support by Custom Anvil but still experimental. Use ExcellentEnchants item type.
|
|
||||||
|
|
||||||
- [Superenchants](https://modrinth.com/plugin/superenchants)
|
|
||||||
support by Superenchants. Use CustomAnvil to combine enchantment in anvil in survival.
|
|
||||||
|
|
||||||
Here is a list of supported anvil mechanic plugins with support status:
|
|
||||||
- [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/)
|
|
||||||
support by Custom Anvil but still experimental. Mostly use Custom Anvil basic XP settings. (version >= 6.1.5)
|
|
||||||
|
|
||||||
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/)
|
|
||||||
support by Custom Anvil. Not really enchantment related but CustomAnvil should not impact bag upgrade and skin via anvil. (version >= 1.31.0)
|
|
||||||
|
|
||||||
If you like Custom Anvil to support a specific plugin (custom enchant or anvil mechanic).
|
|
||||||
You can ask, but please note implementing compatibility will be considered
|
|
||||||
as low priority as I work for the plugin on my free time for free.
|
|
||||||
|
|
||||||
### Overriding Too Expensive
|
### Overriding Too Expensive
|
||||||
|
|
||||||
One of the configurations allow displaying price about 40 and removing Too Expensive. \
|
One of the configurations allow displaying price about 40 and removing Too Expensive. \
|
||||||
By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level.
|
By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level.
|
||||||
Minecraft version 1.17 to 1.21.7 do not need any dependency. Other version need ProtocoLib enabled on your server for this feature. \
|
spigot version 1.18 to 1.21.11 do not need any ProtocoLib dependency. (26.1.0 or above requires it) \
|
||||||
You can also wait for an update of the plugin to support a newer version.
|
Any recent paper version also are supported for this feature.
|
||||||
|
But you should wait for update for new version containing new enchantable item or new enchantments if any of this got added.
|
||||||
Please note that 1.16.5 to 1.17.1 are not officially supported. Run at your own risk.
|
Else it is, likely, fine to use the current version you are ussing on a new paper version
|
||||||
|
|
||||||
### For custom enchantment plugin developers
|
### For custom enchantment plugin developers
|
||||||
For information about the API, please refer to [the Wiki](https://github.com/alexcrea/CustomAnvil/wiki) \
|
For information about the API, please refer to [the Wiki](https://github.com/alexcrea/CustomAnvil/wiki) \
|
||||||
(Please note that the wiki is currently incomplete)
|
(Please note that the wiki is currently incomplete)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -103,12 +87,25 @@ For information about the API, please refer to [the Wiki](https://github.com/ale
|
||||||
see [Here](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs)
|
see [Here](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs)
|
||||||
|
|
||||||
---
|
---
|
||||||
Custom anvil [use bstat](https://bstats.org/plugin/bukkit/Unsafe%20Enchants%20Plus/20923) for metric. You can [disable it](https://bstats.org/getting-started) if you like.
|
### Metric And Telemetry
|
||||||
|
Custom anvil [use bstat](https://bstats.org/plugin/bukkit/Unsafe%20Enchants%20Plus/20923)
|
||||||
|
and [faststats](https://faststats.dev/project/customanvil/minecraft-plugin) for metric and error reporting.
|
||||||
|
|
||||||
|
You can select specific telemetry or disable all in config.yml. \
|
||||||
|
You can also [disable bstat](https://bstats.org/getting-started) and [faststats](https://faststats.dev/info) in their /plugin folder if you like too.
|
||||||
|
|
||||||
|
faststats is in beta testing please report me or them any error you encounter
|
||||||
|
|
||||||
|
### Credits and Thanks
|
||||||
|
Credits and thanks can be seen [here](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/CREDITS.md)
|
||||||
|
|
||||||
### Planned:
|
### Planned:
|
||||||
- Better Folia support (make gui work. fix some dirty handled parts)
|
- Better Folia support (make gui work. fix some dirty handled parts)
|
||||||
- Get restriction on unknown enchantments
|
- Get restriction on unknown enchantments (planned for V2)
|
||||||
- More features for custom anvil craft
|
- More features for custom anvil craft
|
||||||
|
|
||||||
### Known issue:
|
### Known issue:
|
||||||
Most unknown registered enchantments (by unsupported custom enchantment plugin & datapacks) will not have restriction by default. Planned but no eta.
|
Most unknown registered enchantments (by unsupported custom enchantment plugin & datapacks) will not have restriction by default. Planned but no eta.
|
||||||
|
|
||||||
|
### Do you need help with the plugin, or have any issue or suggestion?
|
||||||
|
You can ask on the discussion page, create a [GitHub issue](https://github.com/alexcrea/CustomAnvil/issues) or join my [discord](https://discord.gg/KHUNsUfRYJ)
|
||||||
|
|
|
||||||
249
build.gradle.kts
249
build.gradle.kts
|
|
@ -2,26 +2,33 @@ import cn.lalaki.pub.BaseCentralPortalPlusExtension
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
import groovy.util.Node
|
import groovy.util.Node
|
||||||
import groovy.util.NodeList
|
import groovy.util.NodeList
|
||||||
|
import io.papermc.hangarpublishplugin.model.HangarPublication
|
||||||
|
import io.papermc.hangarpublishplugin.model.Platforms
|
||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "2.1.0"
|
kotlin("jvm") version "2.3.0"
|
||||||
java
|
java
|
||||||
id("org.jetbrains.dokka").version("1.9.20")
|
id("org.jetbrains.dokka").version("1.9.20")
|
||||||
id("com.gradleup.shadow").version("9.0.0-beta16")
|
id("com.gradleup.shadow").version("9.3.0")
|
||||||
// Maven publish
|
// Maven publish
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
signing
|
signing
|
||||||
id("cn.lalaki.central").version("1.2.8")
|
id("cn.lalaki.central").version("1.2.8")
|
||||||
// Paper
|
// Paper
|
||||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false
|
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false
|
||||||
|
id("io.papermc.hangar-publish-plugin") version "0.1.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "xyz.alexcrea"
|
group = "xyz.alexcrea"
|
||||||
version = "1.15.6"
|
version = "1.17.5"
|
||||||
|
|
||||||
|
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
|
||||||
|
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
|
||||||
|
|
||||||
val effectiveVersion = "$version" +
|
val effectiveVersion = "$version" +
|
||||||
(if (System.getenv("SMALL_COMMIT_HASH") != null) "-dev-${System.getenv("SMALL_COMMIT_HASH")!!}" else "")
|
(if (isDevBuild) "-dev-${System.getenv("SMALL_COMMIT_HASH")!!}" else "")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// EcoEnchants
|
// EcoEnchants
|
||||||
|
|
@ -29,12 +36,30 @@ repositories {
|
||||||
|
|
||||||
// ExcellentEnchants
|
// ExcellentEnchants
|
||||||
maven(url = "https://repo.nightexpressdev.com/releases")
|
maven(url = "https://repo.nightexpressdev.com/releases")
|
||||||
|
|
||||||
|
// ItemsAdder
|
||||||
|
maven(url = "https://maven.devs.beer/")
|
||||||
|
|
||||||
|
// For fast stats
|
||||||
|
maven {
|
||||||
|
name = "thenextlvlReleases"
|
||||||
|
url = uri("https://repo.thenextlvl.net/releases")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For vault unlocked
|
||||||
|
maven { url = uri("https://repo.codemc.io/repository/creatorfromhell/") }
|
||||||
|
}
|
||||||
|
|
||||||
|
val reobfNMS = providers.gradleProperty("subprojects.reobfnms")
|
||||||
|
.get().split(",")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Spigot api
|
// Spigot api
|
||||||
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
|
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
|
||||||
|
|
||||||
|
// fast stats
|
||||||
|
implementation("dev.faststats.metrics:bukkit:0.27.0")
|
||||||
|
|
||||||
// minimessage
|
// minimessage
|
||||||
implementation("net.kyori:adventure-text-minimessage:4.25.0")
|
implementation("net.kyori:adventure-text-minimessage:4.25.0")
|
||||||
|
|
||||||
|
|
@ -46,13 +71,17 @@ dependencies {
|
||||||
// EnchantsSquaredRewritten
|
// EnchantsSquaredRewritten
|
||||||
compileOnly(files("libs/EnchantsSquared.jar"))
|
compileOnly(files("libs/EnchantsSquared.jar"))
|
||||||
|
|
||||||
// EcoEnchants
|
// EcoEnchants & item
|
||||||
compileOnly("com.willfp:EcoEnchants:12.11.1")
|
compileOnly("com.willfp:libreforge:4.79.0:all")
|
||||||
compileOnly("com.willfp:eco:6.74.5")
|
compileOnly("com.willfp:eco:6.74.5")
|
||||||
|
|
||||||
|
compileOnly("com.willfp:EcoEnchants:12.11.1")
|
||||||
compileOnly(project(":impl:LegacyEcoEnchant"))
|
compileOnly(project(":impl:LegacyEcoEnchant"))
|
||||||
|
|
||||||
|
compileOnly("com.willfp:EcoItems:5.66.0")
|
||||||
|
|
||||||
// ExcellentEnchants
|
// ExcellentEnchants
|
||||||
implementation(project(":impl:ExcellentEnchant5_3"))
|
implementation(project(":impl:ExcellentEnchant5_4"))
|
||||||
compileOnly("su.nightexpress.excellentenchants:Core:5.1.0") {
|
compileOnly("su.nightexpress.excellentenchants:Core:5.1.0") {
|
||||||
exclude("org.spigotmc")
|
exclude("org.spigotmc")
|
||||||
}
|
}
|
||||||
|
|
@ -71,25 +100,21 @@ dependencies {
|
||||||
// AxPlayerWarps
|
// AxPlayerWarps
|
||||||
compileOnly(files("libs/AxPlayerWarps-1.10.3.jar"))
|
compileOnly(files("libs/AxPlayerWarps-1.10.3.jar"))
|
||||||
|
|
||||||
|
// SuperEnchants
|
||||||
|
compileOnly(files("libs/SuperEnchants-4.6.2-all.jar"))
|
||||||
|
|
||||||
|
// ItemsAdder API
|
||||||
|
compileOnly("dev.lone:api-itemsadder:4.0.10")
|
||||||
|
|
||||||
|
// Vault api
|
||||||
|
compileOnly("net.milkbowl.vault:VaultUnlockedAPI:2.16")
|
||||||
|
|
||||||
// Include nms
|
// Include nms
|
||||||
implementation(project(":nms:nms-common"))
|
implementation(project(":nms:nms-common"))
|
||||||
implementation(project(":nms:v1_17R1", configuration = "reobf"))
|
implementation(project(":nms:nms-paper"))
|
||||||
implementation(project(":nms:v1_18R1", configuration = "reobf"))
|
for (nmsPart in reobfNMS) {
|
||||||
implementation(project(":nms:v1_18R2", configuration = "reobf"))
|
implementation(project(":nms:$nmsPart", configuration = "reobf"))
|
||||||
implementation(project(":nms:v1_19R1", configuration = "reobf"))
|
}
|
||||||
implementation(project(":nms:v1_19R2", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_19R3", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_20R1", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_20R2", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_20R3", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_20R4", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R1", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R2", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R3", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R4", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R5", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R6", configuration = "reobf"))
|
|
||||||
implementation(project(":nms:v1_21R7"))// TODO reobf on release, configuration = "reobf"))
|
|
||||||
|
|
||||||
// include kotlin for the offline jar
|
// include kotlin for the offline jar
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
|
|
@ -135,7 +160,7 @@ allprojects {
|
||||||
// Set target version
|
// Set target version
|
||||||
tasks.withType<JavaCompile>().configureEach {
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
sourceCompatibility =
|
sourceCompatibility =
|
||||||
"16" // We aim for java 16 for minecraft 1.16.5. even if it not really suported by custom anvil.
|
"16" // We aim for java 16 for minecraft 1.16.5. even if it not really supported by custom anvil.
|
||||||
targetCompatibility = "16"
|
targetCompatibility = "16"
|
||||||
|
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
|
|
@ -143,33 +168,29 @@ allprojects {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_16)
|
jvmTarget.set(JvmTarget.JVM_16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|
||||||
// Online jar (use of libraries)
|
fun ShadowJar.configureBaseShadow(suffix: String, libraries: Array<String>) {
|
||||||
shadowJar {
|
val processedSuffix = if(suffix.isEmpty()) "" else "-$suffix"
|
||||||
// No suffix for this jar
|
val name = "${rootProject.name}-${effectiveVersion}${processedSuffix}.jar"
|
||||||
val name = "${rootProject.name}-${effectiveVersion}.jar"
|
|
||||||
archiveFileName.set(name)
|
archiveFileName.set(name)
|
||||||
|
|
||||||
// Exclude kotlin std and its annotation
|
|
||||||
exclude("**/kotlin-stdlib*.jar")
|
|
||||||
exclude("**/annotations*.jar")
|
|
||||||
|
|
||||||
// Shadow necessary dependency
|
// Shadow necessary dependency
|
||||||
relocate("com.github.stefvanschie.inventoryframework", "xyz.alexcrea.inventoryframework")
|
relocate("com.github.stefvanschie.inventoryframework", "xyz.alexcrea.cuanvil.inventoryframework")
|
||||||
|
relocate("dev.faststats", "xyz.alexcrea.cuanvil.faststats")
|
||||||
|
|
||||||
// Replace version and example fields in plugin.yml
|
|
||||||
filesMatching("plugin.yml") {
|
filesMatching("plugin.yml") {
|
||||||
expand(
|
expand(
|
||||||
"version" to effectiveVersion,
|
"version" to effectiveVersion + processedSuffix,
|
||||||
"libraries" to " \"org.jetbrains.kotlin:kotlin-stdlib:2.1.0\" "
|
"libraries" to libraries.joinToString(transform = { "\"$it\"" }),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,36 +198,28 @@ tasks {
|
||||||
dependsOn(processResources)
|
dependsOn(processResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offline jar (include kotlin std in the final jar fine)
|
// Online jar (use of libraries)
|
||||||
val offlineJar by // Shadow necessary dependency
|
shadowJar {
|
||||||
registering(
|
configureBaseShadow("",
|
||||||
|
arrayOf(
|
||||||
|
"org.jetbrains.kotlin:kotlin-stdlib:2.3.0",
|
||||||
|
"net.kyori:adventure-text-minimessage:4.25.0",
|
||||||
|
"net.kyori:adventure-text-serializer-plain:4.25.0",
|
||||||
|
"net.kyori:adventure-text-serializer-legacy:4.25.0",
|
||||||
|
))
|
||||||
|
|
||||||
// Include all project other dependencies
|
// Exclude kotlin std, annotations and adventure api
|
||||||
ShadowJar
|
exclude("*kotlin/**")
|
||||||
|
exclude("**/annotations/**")
|
||||||
// Add custom anvil compiled
|
exclude("net/kyori/**")
|
||||||
::class, fun ShadowJar.() {
|
|
||||||
val name = "${rootProject.name}-${effectiveVersion}-offline.jar"
|
|
||||||
archiveFileName.set(name)
|
|
||||||
|
|
||||||
// Shadow necessary dependency
|
|
||||||
relocate("com.github.stefvanschie.inventoryframework", "xyz.alexcrea.inventoryframework")
|
|
||||||
|
|
||||||
filesMatching("plugin.yml") {
|
|
||||||
expand(
|
|
||||||
"version" to "$effectiveVersion-offline",
|
|
||||||
"libraries" to ""
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include all project other dependencies
|
val offlineJar by registering(ShadowJar::class) {
|
||||||
from(project.configurations.runtimeClasspath)
|
configureBaseShadow("offline", emptyArray())
|
||||||
|
|
||||||
// Add custom anvil compiled
|
|
||||||
from(sourceSets.main.get().output)
|
from(sourceSets.main.get().output)
|
||||||
|
configurations = listOf(project.configurations.runtimeClasspath.get())
|
||||||
dependsOn(processResources)
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// Make the online and offline jar on build
|
// Make the online and offline jar on build
|
||||||
named("build") {
|
named("build") {
|
||||||
|
|
@ -259,13 +272,9 @@ object Meta {
|
||||||
const val snapshot = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
|
const val snapshot = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
|
||||||
}
|
}
|
||||||
|
|
||||||
val disalowedDependency = setOf(
|
val disallowedDependency = HashSet<String>()
|
||||||
"nms-common", "kotlin-stdlib",
|
disallowedDependency.addAll(reobfNMS)
|
||||||
"v1_17R1",
|
disallowedDependency.addAll(listOf("nms-common", "nms-paper", "kotlin-stdlib"))
|
||||||
"v1_18R1", "v1_18R2", "v1_19R1", "v1_19R2", "v1_19R3",
|
|
||||||
"v1_20R1", "v1_20R2", "v1_20R3", "v1_20R4",
|
|
||||||
"v1_21R1", "v1_21R2", "v1_21R3", "v1_21R4", "v1_21R5"
|
|
||||||
)
|
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
repositories {
|
repositories {
|
||||||
|
|
@ -333,7 +342,7 @@ publishing {
|
||||||
val artifactNode = ((child as Node).get("artifactId") as NodeList)[0] as Node
|
val artifactNode = ((child as Node).get("artifactId") as NodeList)[0] as Node
|
||||||
val artifactID = artifactNode.value() as String
|
val artifactID = artifactNode.value() as String
|
||||||
|
|
||||||
if(disalowedDependency.contains(artifactID)) {
|
if(disallowedDependency.contains(artifactID)) {
|
||||||
toRemove.add(child)
|
toRemove.add(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -346,3 +355,101 @@ publishing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hangar publish
|
||||||
|
|
||||||
|
fun executeGitCommand(vararg command: String): String {
|
||||||
|
val byteOut = ByteArrayOutputStream()
|
||||||
|
exec {
|
||||||
|
commandLine = listOf("git", *command)
|
||||||
|
standardOutput = byteOut
|
||||||
|
}
|
||||||
|
return byteOut.toString(Charsets.UTF_8.name()).trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun latestCommitMessage(): String {
|
||||||
|
return executeGitCommand("log", "-1", "--pretty=%B")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changelog(isOnline: Boolean): String {
|
||||||
|
var changelog = if(isDevBuild) latestCommitMessage()
|
||||||
|
else System.getenv("RELEASE_CHANGELOG")
|
||||||
|
|
||||||
|
if(!isOnline) {
|
||||||
|
changelog = "This is an offline version of the plugin. \\\n" +
|
||||||
|
"This mean that this plugin libraries are shaded into this plugin \\\n" +
|
||||||
|
"You likely want to use the normal version of this plugin\n\n" + changelog
|
||||||
|
}
|
||||||
|
|
||||||
|
if(changelog == null || changelog.isEmpty()) {
|
||||||
|
changelog = "empty changelog"
|
||||||
|
}
|
||||||
|
|
||||||
|
return changelog
|
||||||
|
}
|
||||||
|
|
||||||
|
hangarPublish {
|
||||||
|
|
||||||
|
fun HangarPublication.configure(isOnline: Boolean, devChannel: String, releaseChannel: String) {
|
||||||
|
var versionName = effectiveVersion
|
||||||
|
if(isPreRelease) versionName+= "-pre"
|
||||||
|
if(!isOnline) versionName+= "-offline"
|
||||||
|
|
||||||
|
version.set(versionName)
|
||||||
|
channel.set(if (isDevBuild || isPreRelease) devChannel else releaseChannel)
|
||||||
|
|
||||||
|
changelog.set(changelog(isOnline))
|
||||||
|
id.set("CustomAnvil")
|
||||||
|
apiKey.set(System.getenv("HANGAR_API_TOKEN"))
|
||||||
|
|
||||||
|
platforms {
|
||||||
|
register(Platforms.PAPER) {
|
||||||
|
// Set the JAR file to upload
|
||||||
|
var task = if(isOnline) tasks.shadowJar
|
||||||
|
else tasks.named<ShadowJar>("offlineJar")
|
||||||
|
|
||||||
|
jar.set(task.flatMap { it.archiveFile })
|
||||||
|
|
||||||
|
// Set platform versions from gradle.properties file
|
||||||
|
val versions: List<String> = (property("paperVersion") as String)
|
||||||
|
.split(",")
|
||||||
|
.map { it.trim() }
|
||||||
|
platformVersions.set(versions)
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
hangar("ProtocolLib") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
url("Disenchantment", "https://modrinth.com/plugin/disenchantment") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
url("ToolStats", "https://modrinth.com/plugin/toolstats") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
url("HavenBags", "https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
url("EcoEnchants", "https://www.spigotmc.org/resources/ecoenchants-%E2%AD%95-250-enchantments-%E2%9C%85-create-custom-enchants-%E2%9C%A8-essentials-cmi-support.79573/") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
hangar("EnchantsSquared") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
url("ExcellentEnchants", "https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/") {
|
||||||
|
required.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publications.register("plugin") {
|
||||||
|
configure(true, "DevSnapshot", "Release")
|
||||||
|
}
|
||||||
|
|
||||||
|
publications.register("offline") {
|
||||||
|
configure(false, "OfflineSnapshot", "OfflineRelease")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,19 @@
|
||||||
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# What service of metric should custom anvil use
|
||||||
|
# Custom anvil collect generic information like server minecraft version, type, etc...
|
||||||
|
# It can also collect error information if error is happening (currently faststats only)
|
||||||
|
# It can also be disabled
|
||||||
|
# Please refer to README for public metric link
|
||||||
|
# Possible options: auto, bstat, faststats, disabled (auto by default)
|
||||||
|
metric_type: auto
|
||||||
|
|
||||||
|
# Allow to report errors made caused by this plugin (only for faststats)
|
||||||
|
# This allows me to fix potentials issue that I'm not aware of
|
||||||
|
# Accept true or false (true by default)
|
||||||
|
metric_collect_errors: true
|
||||||
|
|
||||||
# All anvil cost will be capped to limit_repair_value if enabled.
|
# All anvil cost will be capped to limit_repair_value if enabled.
|
||||||
#
|
#
|
||||||
# In other words:
|
# In other words:
|
||||||
|
|
@ -64,6 +77,18 @@ allow_color_code: false
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: false
|
allow_minimessage: false
|
||||||
|
|
||||||
|
# This enables restricting color code for player having specific permission
|
||||||
|
# It requires allow_color_code enabled for... obvious reasons
|
||||||
|
#
|
||||||
|
# For example: if player want to use "&aHello" it will be required that the player has
|
||||||
|
# the permission "ca.color.code.a" as he used the color code "a"
|
||||||
|
# In general permission to give to the player is "ca.color.code.[code]"
|
||||||
|
# where [code] is the color code you wish to allow the player
|
||||||
|
#
|
||||||
|
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||||
|
# that using the equivalent minimessage tag
|
||||||
|
per_color_code_permission: false
|
||||||
|
|
||||||
# Toggle if color should only be applicable if the player a certain permission.
|
# Toggle if color should only be applicable if the player a certain permission.
|
||||||
#
|
#
|
||||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||||
|
|
@ -74,10 +99,23 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
use_of_color_cost: 0
|
||||||
|
|
||||||
# Default limit to apply to any enchants missing from enchant_limits
|
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||||
|
# You can also change the maximum size and set it to -1 or less for maximum
|
||||||
#
|
#
|
||||||
# Valid values include 1 to 1000
|
# This feature only work on paper 1.21.7 or later
|
||||||
default_limit: 5
|
#
|
||||||
|
# At the moment only english is available for this menu... sorry !
|
||||||
|
#
|
||||||
|
# CustomAnvil use "ca.rename.dialog" when permission
|
||||||
|
enable_dialog_rename: false
|
||||||
|
dialog_rename_max_size: 256
|
||||||
|
permission_needed_for_dialog_rename: false
|
||||||
|
|
||||||
|
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||||
|
# It will make item stackable only and only if it had used the same rename text
|
||||||
|
#
|
||||||
|
# For practical reason. this only work when dialog rename is enabled
|
||||||
|
dialog_rename_keep_user_text: true
|
||||||
|
|
||||||
# Override limits for specific enchants
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
|
|
@ -85,7 +123,8 @@ default_limit: 5
|
||||||
#
|
#
|
||||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||||
#
|
#
|
||||||
# Valid range of 1 - 255 for each enchantment
|
# Valid range of 0 - 255 for each enchantment
|
||||||
|
# -1 mean keep default
|
||||||
enchant_limits:
|
enchant_limits:
|
||||||
minecraft:aqua_affinity: 1
|
minecraft:aqua_affinity: 1
|
||||||
minecraft:binding_curse: 1
|
minecraft:binding_curse: 1
|
||||||
|
|
@ -267,7 +306,7 @@ enchant_values:
|
||||||
# Even if disable-merge-over of unbreaking is set to 2
|
# Even if disable-merge-over of unbreaking is set to 2
|
||||||
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
||||||
disable-merge-over:
|
disable-merge-over:
|
||||||
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla)
|
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla on default configuration)
|
||||||
minecraft:sharpness: -1
|
minecraft:sharpness: -1
|
||||||
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
||||||
#minecraft:unbreaking: 2
|
#minecraft:unbreaking: 2
|
||||||
|
|
@ -391,16 +430,37 @@ lore_edit:
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: true
|
allow_minimessage: true
|
||||||
|
|
||||||
|
# Allow to replace the xp cost by a monetary cost
|
||||||
|
# If enabled it will not be bound to the experience level limits
|
||||||
|
#
|
||||||
|
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||||
|
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||||
|
#
|
||||||
|
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||||
|
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||||
|
#
|
||||||
|
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||||
|
monetary_cost:
|
||||||
|
enabled: false
|
||||||
|
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||||
|
# default being the default currency
|
||||||
|
currency: default
|
||||||
|
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||||
|
multipliers:
|
||||||
|
# global multipliers. all usage type will be multiplied by this value
|
||||||
|
global: 1.0
|
||||||
|
# usage specific type. it will only apply for specific xp "reason"
|
||||||
|
enchantment: 1.0 # related to enchantments level
|
||||||
|
repair: 1.0 # for repairing via unit repair (per unit)
|
||||||
|
rename: 1.0 # for renaming the item
|
||||||
|
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||||
|
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||||
|
recipe: 1.0 # for custom anvil recipe cost
|
||||||
|
|
||||||
# Whether to show debug logging
|
# Whether to show debug logging
|
||||||
debug_log: false
|
debug_log: false
|
||||||
|
|
||||||
# Whether to show verbose debug logging
|
# Whether to show verbose debug logging
|
||||||
debug_log_verbose: false
|
debug_log_verbose: false
|
||||||
|
|
||||||
# In case something when wrong with CustomAnvil packet manager.
|
|
||||||
# If you see "missing class exception" or similar you may test this.
|
|
||||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
|
||||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
|
||||||
force_protocolib: false
|
|
||||||
|
|
||||||
configVersion: 1.11.0
|
configVersion: 1.11.0
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,19 @@
|
||||||
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# What service of metric should custom anvil use
|
||||||
|
# Custom anvil collect generic information like server minecraft version, type, etc...
|
||||||
|
# It can also collect error information if error is happening (currently faststats only)
|
||||||
|
# It can also be disabled
|
||||||
|
# Please refer to README for public metric link
|
||||||
|
# Possible options: auto, bstat, faststats, disabled (auto by default)
|
||||||
|
metric_type: auto
|
||||||
|
|
||||||
|
# Allow to report errors made caused by this plugin (only for faststats)
|
||||||
|
# This allows me to fix potentials issue that I'm not aware of
|
||||||
|
# Accept true or false (true by default)
|
||||||
|
metric_collect_errors: true
|
||||||
|
|
||||||
# All anvil cost will be capped to limit_repair_value if enabled.
|
# All anvil cost will be capped to limit_repair_value if enabled.
|
||||||
#
|
#
|
||||||
# In other words:
|
# In other words:
|
||||||
|
|
@ -66,6 +79,18 @@ allow_color_code: false
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: false
|
allow_minimessage: false
|
||||||
|
|
||||||
|
# This enables restricting color code for player having specific permission
|
||||||
|
# It requires allow_color_code enabled for... obvious reasons
|
||||||
|
#
|
||||||
|
# For example: if player want to use "&aHello" it will be required that the player has
|
||||||
|
# the permission "ca.color.code.a" as he used the color code "a"
|
||||||
|
# In general permission to give to the player is "ca.color.code.[code]"
|
||||||
|
# where [code] is the color code you wish to allow the player
|
||||||
|
#
|
||||||
|
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||||
|
# that using the equivalent minimessage tag
|
||||||
|
per_color_code_permission: false
|
||||||
|
|
||||||
# Toggle if color should only be applicable if the player a certain permission.
|
# Toggle if color should only be applicable if the player a certain permission.
|
||||||
#
|
#
|
||||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||||
|
|
@ -76,10 +101,23 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
use_of_color_cost: 0
|
||||||
|
|
||||||
# Default limit to apply to any enchants missing from enchant_limits
|
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||||
|
# You can also change the maximum size and set it to -1 or less for maximum
|
||||||
#
|
#
|
||||||
# Valid values include 1 to 1000
|
# This feature only work on paper 1.21.7 or later
|
||||||
default_limit: 5
|
#
|
||||||
|
# At the moment only english is available for this menu... sorry !
|
||||||
|
#
|
||||||
|
# CustomAnvil use "ca.rename.dialog" when permission
|
||||||
|
enable_dialog_rename: false
|
||||||
|
dialog_rename_max_size: 256
|
||||||
|
permission_needed_for_dialog_rename: false
|
||||||
|
|
||||||
|
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||||
|
# It will make item stackable only and only if it had used the same rename text
|
||||||
|
#
|
||||||
|
# For practical reason. this only work when dialog rename is enabled
|
||||||
|
dialog_rename_keep_user_text: true
|
||||||
|
|
||||||
# Override limits for specific enchants
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
|
|
@ -87,7 +125,8 @@ default_limit: 5
|
||||||
#
|
#
|
||||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||||
#
|
#
|
||||||
# Valid range of 1 - 255 for each enchantment
|
# Valid range of 0 - 255 for each enchantment
|
||||||
|
# -1 mean keep default
|
||||||
enchant_limits:
|
enchant_limits:
|
||||||
minecraft:aqua_affinity: 1
|
minecraft:aqua_affinity: 1
|
||||||
minecraft:binding_curse: 1
|
minecraft:binding_curse: 1
|
||||||
|
|
@ -285,7 +324,7 @@ enchant_values:
|
||||||
# Even if disable-merge-over of unbreaking is set to 2
|
# Even if disable-merge-over of unbreaking is set to 2
|
||||||
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
||||||
disable-merge-over:
|
disable-merge-over:
|
||||||
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla)
|
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla on default configuration)
|
||||||
minecraft:sharpness: -1
|
minecraft:sharpness: -1
|
||||||
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
||||||
# minecraft:unbreaking: 2
|
# minecraft:unbreaking: 2
|
||||||
|
|
@ -411,17 +450,38 @@ lore_edit:
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: true
|
allow_minimessage: true
|
||||||
|
|
||||||
|
# Allow to replace the xp cost by a monetary cost
|
||||||
|
# If enabled it will not be bound to the experience level limits
|
||||||
|
#
|
||||||
|
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||||
|
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||||
|
#
|
||||||
|
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||||
|
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||||
|
#
|
||||||
|
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||||
|
monetary_cost:
|
||||||
|
enabled: false
|
||||||
|
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||||
|
# default being the default currency
|
||||||
|
currency: default
|
||||||
|
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||||
|
multipliers:
|
||||||
|
# global multipliers. all usage type will be multiplied by this value
|
||||||
|
global: 1.0
|
||||||
|
# usage specific type. it will only apply for specific xp "reason"
|
||||||
|
enchantment: 1.0 # related to enchantments level
|
||||||
|
repair: 1.0 # for repairing via unit repair (per unit)
|
||||||
|
rename: 1.0 # for renaming the item
|
||||||
|
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||||
|
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||||
|
recipe: 1.0 # for custom anvil recipe cost
|
||||||
|
|
||||||
# Whether to show debug logging
|
# Whether to show debug logging
|
||||||
debug_log: false
|
debug_log: false
|
||||||
|
|
||||||
# Whether to show verbose debug logging
|
# Whether to show verbose debug logging
|
||||||
debug_log_verbose: false
|
debug_log_verbose: false
|
||||||
|
|
||||||
# In case something when wrong with CustomAnvil packet manager.
|
|
||||||
# If you see "missing class exception" or similar you may test this.
|
|
||||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
|
||||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
|
||||||
force_protocolib: false
|
|
||||||
|
|
||||||
configVersion: 1.15.5
|
configVersion: 1.15.5
|
||||||
lowMinecraftVersion: 1.21.11
|
lowMinecraftVersion: 1.21.11
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,19 @@
|
||||||
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# What service of metric should custom anvil use
|
||||||
|
# Custom anvil collect generic information like server minecraft version, type, etc...
|
||||||
|
# It can also collect error information if error is happening (currently faststats only)
|
||||||
|
# It can also be disabled
|
||||||
|
# Please refer to README for public metric link
|
||||||
|
# Possible options: auto, bstat, faststats, disabled (auto by default)
|
||||||
|
metric_type: auto
|
||||||
|
|
||||||
|
# Allow to report errors made caused by this plugin (only for faststats)
|
||||||
|
# This allows me to fix potentials issue that I'm not aware of
|
||||||
|
# Accept true or false (true by default)
|
||||||
|
metric_collect_errors: true
|
||||||
|
|
||||||
# All anvil cost will be capped to limit_repair_value if enabled.
|
# All anvil cost will be capped to limit_repair_value if enabled.
|
||||||
#
|
#
|
||||||
# In other words:
|
# In other words:
|
||||||
|
|
@ -64,6 +77,18 @@ allow_color_code: false
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: false
|
allow_minimessage: false
|
||||||
|
|
||||||
|
# This enables restricting color code for player having specific permission
|
||||||
|
# It requires allow_color_code enabled for... obvious reasons
|
||||||
|
#
|
||||||
|
# For example: if player want to use "&aHello" it will be required that the player has
|
||||||
|
# the permission "ca.color.code.a" as he used the color code "a"
|
||||||
|
# In general permission to give to the player is "ca.color.code.[code]"
|
||||||
|
# where [code] is the color code you wish to allow the player
|
||||||
|
#
|
||||||
|
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||||
|
# that using the equivalent minimessage tag
|
||||||
|
per_color_code_permission: false
|
||||||
|
|
||||||
# Toggle if color should only be applicable if the player a certain permission.
|
# Toggle if color should only be applicable if the player a certain permission.
|
||||||
#
|
#
|
||||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||||
|
|
@ -74,10 +99,23 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
use_of_color_cost: 0
|
||||||
|
|
||||||
# Default limit to apply to any enchants missing from enchant_limits
|
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||||
|
# You can also change the maximum size and set it to -1 or less for maximum
|
||||||
#
|
#
|
||||||
# Valid values include 1 to 1000
|
# This feature only work on paper 1.21.7 or later
|
||||||
default_limit: 5
|
#
|
||||||
|
# At the moment only english is available for this menu... sorry !
|
||||||
|
#
|
||||||
|
# CustomAnvil use "ca.rename.dialog" when permission
|
||||||
|
enable_dialog_rename: false
|
||||||
|
dialog_rename_max_size: 256
|
||||||
|
permission_needed_for_dialog_rename: false
|
||||||
|
|
||||||
|
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||||
|
# It will make item stackable only and only if it had used the same rename text
|
||||||
|
#
|
||||||
|
# For practical reason. this only work when dialog rename is enabled
|
||||||
|
dialog_rename_keep_user_text: true
|
||||||
|
|
||||||
# Override limits for specific enchants
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
|
|
@ -85,7 +123,8 @@ default_limit: 5
|
||||||
#
|
#
|
||||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||||
#
|
#
|
||||||
# Valid range of 1 - 255 for each enchantment
|
# Valid range of 0 - 255 for each enchantment
|
||||||
|
# -1 mean keep default
|
||||||
enchant_limits:
|
enchant_limits:
|
||||||
minecraft:aqua_affinity: 1
|
minecraft:aqua_affinity: 1
|
||||||
minecraft:binding_curse: 1
|
minecraft:binding_curse: 1
|
||||||
|
|
@ -279,7 +318,7 @@ enchant_values:
|
||||||
# Even if disable-merge-over of unbreaking is set to 2
|
# Even if disable-merge-over of unbreaking is set to 2
|
||||||
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
||||||
disable-merge-over:
|
disable-merge-over:
|
||||||
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla)
|
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla on default configuration)
|
||||||
minecraft:sharpness: -1
|
minecraft:sharpness: -1
|
||||||
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
||||||
# minecraft:unbreaking: 2
|
# minecraft:unbreaking: 2
|
||||||
|
|
@ -403,17 +442,38 @@ lore_edit:
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: true
|
allow_minimessage: true
|
||||||
|
|
||||||
|
# Allow to replace the xp cost by a monetary cost
|
||||||
|
# If enabled it will not be bound to the experience level limits
|
||||||
|
#
|
||||||
|
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||||
|
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||||
|
#
|
||||||
|
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||||
|
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||||
|
#
|
||||||
|
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||||
|
monetary_cost:
|
||||||
|
enabled: false
|
||||||
|
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||||
|
# default being the default currency
|
||||||
|
currency: default
|
||||||
|
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||||
|
multipliers:
|
||||||
|
# global multipliers. all usage type will be multiplied by this value
|
||||||
|
global: 1.0
|
||||||
|
# usage specific type. it will only apply for specific xp "reason"
|
||||||
|
enchantment: 1.0 # related to enchantments level
|
||||||
|
repair: 1.0 # for repairing via unit repair (per unit)
|
||||||
|
rename: 1.0 # for renaming the item
|
||||||
|
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||||
|
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||||
|
recipe: 1.0 # for custom anvil recipe cost
|
||||||
|
|
||||||
# Whether to show debug logging
|
# Whether to show debug logging
|
||||||
debug_log: false
|
debug_log: false
|
||||||
|
|
||||||
# Whether to show verbose debug logging
|
# Whether to show verbose debug logging
|
||||||
debug_log_verbose: false
|
debug_log_verbose: false
|
||||||
|
|
||||||
# In case something when wrong with CustomAnvil packet manager.
|
|
||||||
# If you see "missing class exception" or similar you may test this.
|
|
||||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
|
||||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
|
||||||
force_protocolib: false
|
|
||||||
|
|
||||||
configVersion: 1.11.0
|
configVersion: 1.11.0
|
||||||
lowMinecraftVersion: 1.21.9
|
lowMinecraftVersion: 1.21.9
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,19 @@
|
||||||
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# What service of metric should custom anvil use
|
||||||
|
# Custom anvil collect generic information like server minecraft version, type, etc...
|
||||||
|
# It can also collect error information if error is happening (currently faststats only)
|
||||||
|
# It can also be disabled
|
||||||
|
# Please refer to README for public metric link
|
||||||
|
# Possible options: auto, bstat, faststats, disabled (auto by default)
|
||||||
|
metric_type: auto
|
||||||
|
|
||||||
|
# Allow to report errors made caused by this plugin (only for faststats)
|
||||||
|
# This allows me to fix potentials issue that I'm not aware of
|
||||||
|
# Accept true or false (true by default)
|
||||||
|
metric_collect_errors: true
|
||||||
|
|
||||||
# All anvil cost will be capped to limit_repair_value if enabled.
|
# All anvil cost will be capped to limit_repair_value if enabled.
|
||||||
#
|
#
|
||||||
# In other words:
|
# In other words:
|
||||||
|
|
@ -64,6 +77,18 @@ allow_color_code: false
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: false
|
allow_minimessage: false
|
||||||
|
|
||||||
|
# This enables restricting color code for player having specific permission
|
||||||
|
# It requires allow_color_code enabled for... obvious reasons
|
||||||
|
#
|
||||||
|
# For example: if player want to use "&aHello" it will be required that the player has
|
||||||
|
# the permission "ca.color.code.a" as he used the color code "a"
|
||||||
|
# In general permission to give to the player is "ca.color.code.[code]"
|
||||||
|
# where [code] is the color code you wish to allow the player
|
||||||
|
#
|
||||||
|
# It is kinda of useless when minimessage is supported as players would be able to bypass
|
||||||
|
# that using the equivalent minimessage tag
|
||||||
|
per_color_code_permission: false
|
||||||
|
|
||||||
# Toggle if color should only be applicable if the player a certain permission.
|
# Toggle if color should only be applicable if the player a certain permission.
|
||||||
#
|
#
|
||||||
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
|
||||||
|
|
@ -74,10 +99,23 @@ permission_needed_for_color: true
|
||||||
# Valid values include 0 to 1000.
|
# Valid values include 0 to 1000.
|
||||||
use_of_color_cost: 0
|
use_of_color_cost: 0
|
||||||
|
|
||||||
# Default limit to apply to any enchants missing from enchant_limits
|
# Dialogue rename menu make use of dialog menu to allow bigger rename
|
||||||
|
# You can also change the maximum size and set it to -1 or less for maximum
|
||||||
#
|
#
|
||||||
# Valid values include 1 to 1000
|
# This feature only work on paper 1.21.7 or later
|
||||||
default_limit: 5
|
#
|
||||||
|
# At the moment only english is available for this menu... sorry !
|
||||||
|
#
|
||||||
|
# CustomAnvil use "ca.rename.dialog" when permission
|
||||||
|
enable_dialog_rename: false
|
||||||
|
dialog_rename_max_size: 256
|
||||||
|
permission_needed_for_dialog_rename: false
|
||||||
|
|
||||||
|
# This allows custom anvil to not "guess" the text used for rename but store it in the item
|
||||||
|
# It will make item stackable only and only if it had used the same rename text
|
||||||
|
#
|
||||||
|
# For practical reason. this only work when dialog rename is enabled
|
||||||
|
dialog_rename_keep_user_text: true
|
||||||
|
|
||||||
# Override limits for specific enchants
|
# Override limits for specific enchants
|
||||||
#
|
#
|
||||||
|
|
@ -85,7 +123,8 @@ default_limit: 5
|
||||||
#
|
#
|
||||||
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
|
||||||
#
|
#
|
||||||
# Valid range of 1 - 255 for each enchantment
|
# Valid range of 0 - 255 for each enchantment
|
||||||
|
# -1 mean keep default
|
||||||
enchant_limits:
|
enchant_limits:
|
||||||
minecraft:aqua_affinity: 1
|
minecraft:aqua_affinity: 1
|
||||||
minecraft:binding_curse: 1
|
minecraft:binding_curse: 1
|
||||||
|
|
@ -267,7 +306,7 @@ enchant_values:
|
||||||
# Even if disable-merge-over of unbreaking is set to 2
|
# Even if disable-merge-over of unbreaking is set to 2
|
||||||
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
# -1 mean enchantment merge for this enchantment is not disabled. default to -1 if absent.
|
||||||
disable-merge-over:
|
disable-merge-over:
|
||||||
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla)
|
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla on default configuration)
|
||||||
minecraft:sharpness: -1
|
minecraft:sharpness: -1
|
||||||
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
|
||||||
# minecraft:unbreaking: 2
|
# minecraft:unbreaking: 2
|
||||||
|
|
@ -391,16 +430,37 @@ lore_edit:
|
||||||
allow_hexadecimal_color: false
|
allow_hexadecimal_color: false
|
||||||
allow_minimessage: true
|
allow_minimessage: true
|
||||||
|
|
||||||
|
# Allow to replace the xp cost by a monetary cost
|
||||||
|
# If enabled it will not be bound to the experience level limits
|
||||||
|
#
|
||||||
|
# It also requires to enable dialog rename (set "enable_dialog_rename: false" a bit higher)
|
||||||
|
# If dialog rename permission is enabled and player do not have the permission merge will fall back to vanilla xp cost
|
||||||
|
#
|
||||||
|
# If you are using custom craft I recommend using Linear Xp Cost with Exact Linear Xp as normal Xp Cost will act "weird"
|
||||||
|
# But Linear Xp will act as 1$ time global multiplier. In other word: like you expect
|
||||||
|
#
|
||||||
|
# As this feature require dialog rename, it can only be enabled starting with paper 1.21.6 and later
|
||||||
|
monetary_cost:
|
||||||
|
enabled: false
|
||||||
|
# If using vault unlocked this allow to specify what currency should be used for anvil usage
|
||||||
|
# default being the default currency
|
||||||
|
currency: default
|
||||||
|
# multiply the anvil cost by a value to allow to have price a big bigger than like 40
|
||||||
|
multipliers:
|
||||||
|
# global multipliers. all usage type will be multiplied by this value
|
||||||
|
global: 1.0
|
||||||
|
# usage specific type. it will only apply for specific xp "reason"
|
||||||
|
enchantment: 1.0 # related to enchantments level
|
||||||
|
repair: 1.0 # for repairing via unit repair (per unit)
|
||||||
|
rename: 1.0 # for renaming the item
|
||||||
|
lore_edit: 1.0 # for changing the lore of the item (only if lore edit is enabled)
|
||||||
|
work_penalty: 1.0 # for work penalty (aka use penalty)
|
||||||
|
recipe: 1.0 # for custom anvil recipe cost
|
||||||
|
|
||||||
# Whether to show debug logging
|
# Whether to show debug logging
|
||||||
debug_log: false
|
debug_log: false
|
||||||
|
|
||||||
# Whether to show verbose debug logging
|
# Whether to show verbose debug logging
|
||||||
debug_log_verbose: false
|
debug_log_verbose: false
|
||||||
|
|
||||||
# In case something when wrong with CustomAnvil packet manager.
|
|
||||||
# If you see "missing class exception" or similar you may test this.
|
|
||||||
# If enabled and Protocolib absent or disabled "Replace to expensive" will not work.
|
|
||||||
# ProtocoLib may also be used if the server is in an "unsupported" version even if this option is disabled.
|
|
||||||
force_protocolib: false
|
|
||||||
|
|
||||||
configVersion: 1.11.0
|
configVersion: 1.11.0
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
### Default Plugin's Configurations
|
### Default Plugin's Configurations
|
||||||
From 1.18 to 1.20.6 use [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18) \
|
From 1.18 to 1.20.6 use [1.18 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.18) \
|
||||||
From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21)
|
From 1.21 to 1.21.8 use [1.21 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21) \
|
||||||
From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9)
|
From 1.21.9 to 1.21.10 use [1.21.9 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.9) \
|
||||||
From 1.21.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11)
|
From 1.21.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11)
|
||||||
|
|
@ -4,3 +4,10 @@ kotlin.code.style=official
|
||||||
signing.secretKeyRingFile=~/.gnupg/secring.gpg
|
signing.secretKeyRingFile=~/.gnupg/secring.gpg
|
||||||
|
|
||||||
kotlin.daemon.jvmargs=-Xmx8G
|
kotlin.daemon.jvmargs=-Xmx8G
|
||||||
|
|
||||||
|
# list of nms
|
||||||
|
subprojects.reobfnms=v1_17R1,v1_18R1,v1_18R2,v1_19R1,v1_19R2,v1_19R3,v1_20R1,v1_20R2,v1_20R3,v1_20R4,v1_21R1,v1_21R2,v1_21R3,v1_21R4,v1_21R5,v1_21R6,v1_21R7
|
||||||
|
|
||||||
|
# list of version for hangar release
|
||||||
|
paperVersion=1.18-26.2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
group = rootProject.group
|
|
||||||
version = rootProject.version
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
kotlin("jvm") version "2.1.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
// ExcellentEnchants
|
|
||||||
maven(url = "https://repo.nightexpressdev.com/releases")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Spigot api
|
|
||||||
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
|
|
||||||
|
|
||||||
// Excellent Enchant
|
|
||||||
compileOnly("su.nightexpress.excellentenchants:Core:5.3.0") {
|
|
||||||
exclude("org.spigotmc")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
17
impl/ExcellentEnchant5_4/build.gradle.kts
Normal file
17
impl/ExcellentEnchant5_4/build.gradle.kts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
group = rootProject.group
|
||||||
|
version = rootProject.version
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("jvm") version "2.3.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
// ExcellentEnchants
|
||||||
|
maven(url = "https://repo.nightexpressdev.com/releases")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Excellent Enchant
|
||||||
|
compileOnly("su.nightexpress.excellentenchants:Core:5.4.3")
|
||||||
|
compileOnly("su.nightexpress.nightcore:main:2.16.2")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dependency.plugins;
|
||||||
|
|
||||||
|
import su.nightexpress.excellentenchants.EnchantsAPI;
|
||||||
|
|
||||||
|
public class ExcellentEnchant5_4EnchantSettings {
|
||||||
|
|
||||||
|
|
||||||
|
public static int anvilLimit() {
|
||||||
|
return EnchantsAPI.getEnchantManager().getSettings().getAnvilEnchantsLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ group = rootProject.group
|
||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "2.1.0"
|
kotlin("jvm") version "2.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imitate needed class and method to support legacy version of EcoEnchant
|
// Imitate needed class and method to support legacy version of EcoEnchant
|
||||||
|
|
|
||||||
BIN
libs/SuperEnchants-4.6.2-all.jar
Normal file
BIN
libs/SuperEnchants-4.6.2-all.jar
Normal file
Binary file not shown.
|
|
@ -21,15 +21,15 @@ repositories {
|
||||||
|
|
||||||
// Set target version
|
// Set target version
|
||||||
tasks.withType<JavaCompile>().configureEach {
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
sourceCompatibility = "21"
|
sourceCompatibility = "16"
|
||||||
targetCompatibility = "21"
|
targetCompatibility = "16"
|
||||||
|
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui
|
|
||||||
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
|
|
||||||
|
|
||||||
interface ExternGuiTester {
|
|
||||||
|
|
||||||
object Const{
|
|
||||||
val cannonicalPaperAnvilMenu = "net.minecraft.world.inventory.AnvilMenu"
|
|
||||||
}
|
|
||||||
|
|
||||||
val wesjdAnvilGuiName: String?
|
|
||||||
|
|
||||||
fun getContainerClass(inventory: InventoryView): Class<Any>?
|
|
||||||
|
|
||||||
fun testIfGui(inventory: InventoryView): Boolean {
|
|
||||||
// this mean we are on test
|
|
||||||
//TODO review why needed knowing previous mitigations should works
|
|
||||||
if(inventory.javaClass.name.endsWith("AnvilViewMock")) return false
|
|
||||||
|
|
||||||
val clazz = getContainerClass(inventory) ?: return false
|
|
||||||
|
|
||||||
val clazzName = clazz.name
|
|
||||||
if(!PlatformUtil.isPaper){
|
|
||||||
// Blacklist gui causing issue
|
|
||||||
if (expectWesjd(clazzName)) return true
|
|
||||||
if (expectXenondevUI(clazzName)) return true
|
|
||||||
if (expectVanePortal(clazzName)) return true
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only allow cannonical anvil menu class
|
|
||||||
return !Const.cannonicalPaperAnvilMenu.equals(clazzName, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun expectWesjd(name: String): Boolean {
|
|
||||||
val expectedWesjdGuiPath = "anvilgui.version.$wesjdAnvilGuiName"
|
|
||||||
|
|
||||||
return name.contains(expectedWesjdGuiPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val XenondevUIPrefix: String
|
|
||||||
get() = "xyz.xenondevs.inventoryaccess."
|
|
||||||
private val XenondevUISufix: String
|
|
||||||
get() = ".AnvilInventoryImpl"
|
|
||||||
|
|
||||||
fun expectXenondevUI(name: String): Boolean {
|
|
||||||
return name.startsWith(XenondevUIPrefix)
|
|
||||||
&& name.endsWith(XenondevUISufix)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun expectVanePortal(name: String): Boolean {
|
|
||||||
val expected = "org.oddlama.vane.core.menu.AnvilMenu\$AnvilContainer"
|
|
||||||
|
|
||||||
return name == expected
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dialog
|
||||||
|
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.entity.HumanEntity
|
||||||
|
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
|
|
||||||
|
interface AnvilRenameDialog {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val PCD_KEEP_RENAME_TEXT_KEY = NamespacedKey.fromString("customanvil:last_rename_text")!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canSendDialog(): Boolean
|
||||||
|
|
||||||
|
fun tryShowDialog(player: HumanEntity, event: PrepareAnvilEvent)
|
||||||
|
|
||||||
|
fun closeInventory(player: HumanEntity)
|
||||||
|
|
||||||
|
fun currentText(player: HumanEntity): String?
|
||||||
|
|
||||||
|
fun isOpenFor(player: HumanEntity): Boolean
|
||||||
|
|
||||||
|
}
|
||||||
1
nms/nms-paper/.gitignore
vendored
Normal file
1
nms/nms-paper/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
.lastDeploymentsId
|
||||||
35
nms/nms-paper/build.gradle.kts
Normal file
35
nms/nms-paper/build.gradle.kts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
|
group = rootProject.group
|
||||||
|
version = rootProject.version
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("io.papermc.paperweight.userdev")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":nms:nms-common"))
|
||||||
|
|
||||||
|
// Used for nms
|
||||||
|
paperweight.paperDevBundle("1.21.7-R0.1-SNAPSHOT")
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set target version
|
||||||
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
|
sourceCompatibility = "18"
|
||||||
|
targetCompatibility = "18"
|
||||||
|
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
compilerOptions {
|
||||||
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
|
jvmTarget.set(JvmTarget.JVM_18)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dependency.packet.versions
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
|
||||||
|
import net.minecraft.world.entity.player.Abilities
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
|
||||||
|
|
||||||
|
class PaperPacketManager : PacketManagerBase(), PacketManager {
|
||||||
|
override val canSetInstantBuild: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override fun setInstantBuild(player: Player, instantBuild: Boolean) {
|
||||||
|
val nmsPlayer = (player as CraftPlayer).handle
|
||||||
|
val playerAbilities = nmsPlayer.abilities
|
||||||
|
val sendedAbilities: Abilities
|
||||||
|
if (playerAbilities.instabuild == instantBuild) {
|
||||||
|
sendedAbilities = playerAbilities
|
||||||
|
} else {
|
||||||
|
sendedAbilities = Abilities()
|
||||||
|
sendedAbilities.invulnerable = playerAbilities.invulnerable
|
||||||
|
sendedAbilities.flying = playerAbilities.flying
|
||||||
|
sendedAbilities.mayfly = playerAbilities.mayfly
|
||||||
|
sendedAbilities.instabuild = instantBuild
|
||||||
|
sendedAbilities.mayBuild = playerAbilities.mayBuild
|
||||||
|
sendedAbilities.setFlyingSpeed(playerAbilities.getFlyingSpeed())
|
||||||
|
sendedAbilities.setWalkingSpeed(playerAbilities.getWalkingSpeed())
|
||||||
|
}
|
||||||
|
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
|
||||||
|
nmsPlayer.connection.send(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,236 @@
|
||||||
|
package xyz.alexcrea.cuanvil.dialog
|
||||||
|
|
||||||
|
import io.papermc.paper.dialog.Dialog
|
||||||
|
import io.papermc.paper.registry.data.dialog.ActionButton
|
||||||
|
import io.papermc.paper.registry.data.dialog.DialogBase
|
||||||
|
import io.papermc.paper.registry.data.dialog.action.DialogAction
|
||||||
|
import io.papermc.paper.registry.data.dialog.body.DialogBody
|
||||||
|
import io.papermc.paper.registry.data.dialog.input.DialogInput
|
||||||
|
import io.papermc.paper.registry.data.dialog.type.DialogType
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.event.ClickCallback
|
||||||
|
import net.kyori.adventure.text.format.TextColor
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer
|
||||||
|
import net.minecraft.world.inventory.AnvilMenu
|
||||||
|
import org.bukkit.craftbukkit.event.CraftEventFactory
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
||||||
|
import org.bukkit.craftbukkit.inventory.view.CraftAnvilView
|
||||||
|
import org.bukkit.entity.HumanEntity
|
||||||
|
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||||
|
import org.bukkit.inventory.InventoryView
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
import org.bukkit.plugin.Plugin
|
||||||
|
import java.util.*
|
||||||
|
import java.util.function.BiFunction
|
||||||
|
import java.util.function.Consumer
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
@Suppress("UnstableApiUsage")
|
||||||
|
class AnvilRenameDialogImpl(
|
||||||
|
val fromFormated: BiFunction<HumanEntity, Component?, String?>,
|
||||||
|
val keepUserPreviousDialog: Supplier<Boolean>,
|
||||||
|
val maxLength: Supplier<Int>,
|
||||||
|
val plugin: Plugin,
|
||||||
|
) : AnvilRenameDialog {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val RENAME_TEXT_KEY = "rename"
|
||||||
|
|
||||||
|
private const val MAX_WIDTH = 512
|
||||||
|
|
||||||
|
private val PLAIN_TEXT_SERIALIZER = PlainTextComponentSerializer.plainText()
|
||||||
|
|
||||||
|
// Need to be able to translate it later !
|
||||||
|
private val USER_FACING_RENAME_TITLE = Component.text("Rename Your Item")
|
||||||
|
private val USER_FACING_WARNING = Component.text(
|
||||||
|
"Note that the repair text will appear blank after Confirm\n" +
|
||||||
|
"But the name will be correctly applied"
|
||||||
|
)
|
||||||
|
private val USER_FACING_CONFIRM = Component.text("Confirm").color(TextColor.fromHexString("#40FF40"))
|
||||||
|
private val USER_FACING_CANCEL = Component.text("Cancel").color(TextColor.fromHexString("#FF4040"))
|
||||||
|
|
||||||
|
fun itemDefaultName(item: ItemStack?): String? {
|
||||||
|
return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val lastNames = HashMap<UUID, String>()
|
||||||
|
private val lastRenames = HashMap<UUID, String>()
|
||||||
|
|
||||||
|
|
||||||
|
private val lastLeftItem = HashMap<UUID, String>()
|
||||||
|
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||||
|
|
||||||
|
// For monetary cost
|
||||||
|
val hasUiOpen = HashSet<UUID>()
|
||||||
|
|
||||||
|
private val containerField = CraftInventoryView::class.java.getDeclaredField("container")
|
||||||
|
|
||||||
|
init {
|
||||||
|
containerField.setAccessible(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canSendDialog(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun makeDialog(playerID: UUID, initial: String?, callback: Consumer<String?>): Dialog {
|
||||||
|
val maxLength = this.maxLength.get()
|
||||||
|
val initialFinal = initial?.take(maxLength)
|
||||||
|
|
||||||
|
val baseBuilder = DialogBase.builder(USER_FACING_RENAME_TITLE)
|
||||||
|
.canCloseWithEscape(true)
|
||||||
|
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||||
|
.inputs(
|
||||||
|
listOf(
|
||||||
|
DialogInput.text(RENAME_TEXT_KEY, Component.text("Rename text"))
|
||||||
|
.maxLength(maxLength)
|
||||||
|
.initial(initialFinal ?: "")
|
||||||
|
.labelVisible(false)
|
||||||
|
.width(MAX_WIDTH)
|
||||||
|
.build(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
baseBuilder.body(
|
||||||
|
listOf(
|
||||||
|
DialogBody.plainMessage(USER_FACING_WARNING, MAX_WIDTH)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Dialog.create { builder ->
|
||||||
|
builder.empty()
|
||||||
|
.base(baseBuilder.build())
|
||||||
|
.type(
|
||||||
|
DialogType.confirmation(
|
||||||
|
ActionButton.builder(USER_FACING_CONFIRM)
|
||||||
|
.action(DialogAction.customClick({ response, _ ->
|
||||||
|
hasUiOpen.remove(playerID)
|
||||||
|
val text = response.getText(RENAME_TEXT_KEY)!!
|
||||||
|
callback.accept(text)
|
||||||
|
}, ClickCallback.Options.builder().build()))
|
||||||
|
.build(),
|
||||||
|
ActionButton.builder(USER_FACING_CANCEL)
|
||||||
|
.action(DialogAction.customClick({ response, _ ->
|
||||||
|
hasUiOpen.remove(playerID)
|
||||||
|
}, ClickCallback.Options.builder().build()))
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setResult(player: HumanEntity, view: InventoryView, result: String?) {
|
||||||
|
val defaultName = itemDefaultName(view.getItem(0))
|
||||||
|
if (defaultName == result) {
|
||||||
|
setName(player, view, "", null)
|
||||||
|
if (defaultName != null) lastNames[player.uniqueId] = defaultName
|
||||||
|
} else setName(player, view, result, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setName(player: HumanEntity, view: InventoryView, name: String?, rename: String?) {
|
||||||
|
val menu = (containerField.get(view) as AnvilMenu)
|
||||||
|
val isSameName = menu.itemName == name
|
||||||
|
menu.itemName = rename
|
||||||
|
|
||||||
|
if (name == null)
|
||||||
|
lastNames.remove(player.uniqueId)
|
||||||
|
else
|
||||||
|
lastNames[player.uniqueId] = name
|
||||||
|
|
||||||
|
if (rename == null)
|
||||||
|
lastRenames.remove(player.uniqueId)
|
||||||
|
else
|
||||||
|
lastRenames[player.uniqueId] = rename
|
||||||
|
|
||||||
|
if (!isSameName)
|
||||||
|
CraftEventFactory.callPrepareResultEvent(menu, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nameFromItem(player: HumanEntity, item: ItemStack?): String? {
|
||||||
|
// Already has text
|
||||||
|
if (item?.hasItemMeta() != true || !item.itemMeta.hasCustomName())
|
||||||
|
return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName())
|
||||||
|
|
||||||
|
if (keepUserPreviousDialog.get() && item.hasItemMeta()) {
|
||||||
|
val lastName = item.itemMeta.persistentDataContainer.get(
|
||||||
|
AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY,
|
||||||
|
PersistentDataType.STRING
|
||||||
|
)
|
||||||
|
|
||||||
|
if (lastName != null) return lastName
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromFormated.apply(player, item.effectiveName())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun tryShowDialogScheduled(player: HumanEntity, event: PrepareAnvilEvent) {
|
||||||
|
val view = event.view
|
||||||
|
if (view !is CraftAnvilView) return
|
||||||
|
|
||||||
|
val renameText = view.renameText
|
||||||
|
val leftItem = view.getItem(0)
|
||||||
|
val leftItemStr = leftItem?.toString()
|
||||||
|
|
||||||
|
val lastName = lastNames.getOrDefault(player.uniqueId, null)
|
||||||
|
val lastRename = lastRenames.getOrDefault(player.uniqueId, null)
|
||||||
|
|
||||||
|
if (lastLeftItem.getOrDefault(player.uniqueId, null) != leftItemStr) {
|
||||||
|
if (leftItemStr == null)
|
||||||
|
lastLeftItem.remove(player.uniqueId)
|
||||||
|
else lastLeftItem[player.uniqueId] = leftItemStr
|
||||||
|
|
||||||
|
setName(player, view, renameText, nameFromItem(player, leftItem))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastName == renameText || lastRename == renameText)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (renameText?.isBlank() == true || renameText == itemDefaultName(leftItem)) {
|
||||||
|
setName(player, view, lastName, lastRename)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val dialog = makeDialog(player.uniqueId, lastRename)
|
||||||
|
{ result -> setResult(player, view, result) }
|
||||||
|
player.showDialog(dialog)
|
||||||
|
|
||||||
|
hasUiOpen.add(player.uniqueId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to wait for a short time as changing item will change the name BEFORE the item change
|
||||||
|
// no guaranty both of them came in the same tick too so let's wait 2 tick....
|
||||||
|
override fun tryShowDialog(player: HumanEntity, event: PrepareAnvilEvent) {
|
||||||
|
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||||
|
|
||||||
|
val task = player.scheduler.runDelayed(
|
||||||
|
plugin,
|
||||||
|
{ _ ->
|
||||||
|
run { tryShowDialogScheduled(player, event) }
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
2
|
||||||
|
)
|
||||||
|
if (task == null) return
|
||||||
|
|
||||||
|
runTaskMap[player.uniqueId] = task
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun closeInventory(player: HumanEntity) {
|
||||||
|
lastNames.remove(player.uniqueId)
|
||||||
|
lastRenames.remove(player.uniqueId)
|
||||||
|
lastLeftItem.remove(player.uniqueId)
|
||||||
|
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun currentText(player: HumanEntity): String? {
|
||||||
|
return lastNames[player.uniqueId]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isOpenFor(player: HumanEntity): Boolean {
|
||||||
|
return hasUiOpen.contains(player.uniqueId)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package xyz.alexcrea.cuanvil.util
|
||||||
|
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask
|
||||||
|
import org.bukkit.entity.HumanEntity
|
||||||
|
import org.bukkit.inventory.InventoryView
|
||||||
|
import org.bukkit.plugin.Plugin
|
||||||
|
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
|
||||||
|
import java.util.HashMap
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
object AnvilTitleUtil {
|
||||||
|
|
||||||
|
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||||
|
|
||||||
|
private fun actualRename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog) {
|
||||||
|
runTaskMap.remove(player.uniqueId)
|
||||||
|
if (view.title == name) return
|
||||||
|
|
||||||
|
// We assume rename impl is used
|
||||||
|
if (anvilDialog.isOpenFor(player)) return
|
||||||
|
|
||||||
|
view.title = name
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to rename instantly it is causing issue with rename text
|
||||||
|
// especially as it can "override" current ui when it is rename ui time but rename ui also need some delay
|
||||||
|
fun rename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog, plugin: Plugin) {
|
||||||
|
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||||
|
|
||||||
|
val task = player.scheduler.runDelayed(
|
||||||
|
plugin,
|
||||||
|
{ _ ->
|
||||||
|
run { actualRename(view, name, player, anvilDialog) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
runTaskMap.remove(player.uniqueId)
|
||||||
|
},
|
||||||
|
2
|
||||||
|
)
|
||||||
|
|
||||||
|
if (task == null) return
|
||||||
|
runTaskMap[player.uniqueId] = task
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_16)
|
jvmTarget.set(JvmTarget.JVM_16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_17R1_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_17_R1"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_17)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_18R1_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_18_R1"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_17)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_18R2_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_18_R2"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_17)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_19R1_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_19_R1"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_17)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_19R2_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_19_R2"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_17)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_19R3_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_19_R3"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_18)
|
jvmTarget.set(JvmTarget.JVM_18)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_20R1_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_20_R1"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_18)
|
jvmTarget.set(JvmTarget.JVM_18)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
import kotlin.jvm.javaClass
|
|
||||||
|
|
||||||
class v1_20R2_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_20_R2"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_18)
|
jvmTarget.set(JvmTarget.JVM_18)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
import kotlin.jvm.javaClass
|
|
||||||
|
|
||||||
class v1_20R3_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_20_R3"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
import kotlin.jvm.javaClass
|
|
||||||
|
|
||||||
class v1_20R4_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_20_R4"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if (view !is CraftInventoryView) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package xyz.alexcrea.cuanvil.util
|
||||||
|
|
||||||
|
import org.bukkit.inventory.meta.Damageable
|
||||||
|
|
||||||
|
// I LOVE support of old versions and needing to do modules like that
|
||||||
|
// That truly is my favorite activity
|
||||||
|
// TODO clean this one of legacy removal branch
|
||||||
|
object MaxDamageCheckerUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return max damage or int max if not set
|
||||||
|
*/
|
||||||
|
fun getMaxDamage(meta: Damageable): Int {
|
||||||
|
if(!meta.hasMaxDamage()) return Integer.MAX_VALUE
|
||||||
|
return meta.maxDamage
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R1_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R1"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R2_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R2"
|
|
||||||
|
|
||||||
var tested = false;
|
|
||||||
var possible = false;
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
// In case we are in a test environment
|
|
||||||
if(!tested) testClassExist()
|
|
||||||
if(!possible) return null
|
|
||||||
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testClassExist(){
|
|
||||||
tested = true;
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
|
|
||||||
possible = true
|
|
||||||
} catch (e: ClassNotFoundException){
|
|
||||||
possible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R3_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R3"
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R4_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R4"
|
|
||||||
|
|
||||||
var tested = false;
|
|
||||||
var possible = false;
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
// In case we are in a test environment
|
|
||||||
if(!tested) testClassExist()
|
|
||||||
if(!possible) return null
|
|
||||||
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testClassExist(){
|
|
||||||
tested = true;
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
|
|
||||||
possible = true
|
|
||||||
} catch (e: ClassNotFoundException){
|
|
||||||
possible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R5_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R5"
|
|
||||||
|
|
||||||
var tested = false;
|
|
||||||
var possible = false;
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
// In case we are in a test environment
|
|
||||||
if(!tested) testClassExist()
|
|
||||||
if(!possible) return null
|
|
||||||
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testClassExist(){
|
|
||||||
tested = true;
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
|
|
||||||
possible = true
|
|
||||||
} catch (e: ClassNotFoundException){
|
|
||||||
possible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R6_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R6"
|
|
||||||
|
|
||||||
var tested = false;
|
|
||||||
var possible = false;
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
// In case we are in a test environment
|
|
||||||
if(!tested) testClassExist()
|
|
||||||
if(!possible) return null
|
|
||||||
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testClassExist(){
|
|
||||||
tested = true;
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
|
|
||||||
possible = true
|
|
||||||
} catch (e: ClassNotFoundException){
|
|
||||||
possible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -11,7 +11,7 @@ dependencies {
|
||||||
implementation(project(":nms:nms-common"))
|
implementation(project(":nms:nms-common"))
|
||||||
|
|
||||||
// Used for nms
|
// Used for nms
|
||||||
paperweight.paperDevBundle("1.21.11-pre3-R0.1-SNAPSHOT") //TODO update to 1.21.11-R0.1-SNAPSHOT on release
|
paperweight.paperDevBundle("1.21.11-R0.1-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|
@ -28,7 +28,7 @@ tasks.withType<JavaCompile>().configureEach {
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
|
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
|
||||||
jvmTarget.set(JvmTarget.JVM_21)
|
jvmTarget.set(JvmTarget.JVM_21)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package xyz.alexcrea.cuanvil.dependency.gui.version
|
|
||||||
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftInventoryView
|
|
||||||
import org.bukkit.inventory.InventoryView
|
|
||||||
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
|
|
||||||
|
|
||||||
class v1_21R7_ExternGuiTester: ExternGuiTester {
|
|
||||||
override val wesjdAnvilGuiName = "Wrapper1_21_R7"
|
|
||||||
|
|
||||||
var tested = false;
|
|
||||||
var possible = false;
|
|
||||||
|
|
||||||
override fun getContainerClass(view: InventoryView): Class<Any>? {
|
|
||||||
// In case we are in a test environment
|
|
||||||
if(!tested) testClassExist()
|
|
||||||
if(!possible) return null
|
|
||||||
|
|
||||||
if(view !is CraftInventoryView<*, *>) return null
|
|
||||||
val container = view.handle
|
|
||||||
|
|
||||||
return container.javaClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fun testClassExist(){
|
|
||||||
tested = true;
|
|
||||||
try {
|
|
||||||
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
|
|
||||||
possible = true
|
|
||||||
} catch (e: ClassNotFoundException){
|
|
||||||
possible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -3,42 +3,20 @@ rootProject.name = "CustomAnvil"
|
||||||
// NMS subproject
|
// NMS subproject
|
||||||
include("nms:nms-common")
|
include("nms:nms-common")
|
||||||
findProject(":nms:nms-common")?.name = "nms-common"
|
findProject(":nms:nms-common")?.name = "nms-common"
|
||||||
include("nms:v1_17R1")
|
include("nms:nms-paper")
|
||||||
findProject(":nms:v1_17R1")?.name = "v1_17R1"
|
findProject(":nms:nms-paper")?.name = "nms-paper"
|
||||||
include("nms:v1_18R1")
|
|
||||||
findProject(":nms:v1_18R1")?.name = "v1_18R1"
|
|
||||||
include("nms:v1_18R2")
|
|
||||||
findProject(":nms:v1_18R2")?.name = "v1_18R2"
|
|
||||||
include("nms:v1_19R1")
|
|
||||||
findProject(":nms:v1_19R1")?.name = "v1_19R1"
|
|
||||||
include("nms:v1_19R2")
|
|
||||||
findProject(":nms:v1_19R2")?.name = "v1_19R2"
|
|
||||||
include("nms:v1_19R3")
|
|
||||||
findProject(":nms:v1_19R3")?.name = "v1_19R3"
|
|
||||||
include("nms:v1_20R1")
|
|
||||||
findProject(":nms:v1_20R1")?.name = "v1_20R1"
|
|
||||||
include("nms:v1_20R2")
|
|
||||||
findProject(":nms:v1_20R2")?.name = "v1_20R2"
|
|
||||||
include("nms:v1_20R3")
|
|
||||||
findProject(":nms:v1_20R3")?.name = "v1_20R3"
|
|
||||||
include("nms:v1_20R4")
|
|
||||||
findProject(":nms:v1_20R4")?.name = "v1_20R4"
|
|
||||||
include("nms:v1_21R1")
|
|
||||||
findProject(":nms:v1_21R1")?.name = "v1_21R1"
|
|
||||||
include("nms:v1_21R2")
|
|
||||||
findProject(":nms:v1_21R2")?.name = "v1_21R2"
|
|
||||||
include("nms:v1_21R3")
|
|
||||||
findProject(":nms:v1_21R3")?.name = "v1_21R3"
|
|
||||||
include("nms:v1_21R4")
|
|
||||||
findProject(":nms:v1_21R4")?.name = "v1_21R4"
|
|
||||||
include("nms:v1_21R5")
|
|
||||||
findProject(":nms:v1_21R5")?.name = "v1_21R5"
|
|
||||||
include("nms:v1_21R6")
|
|
||||||
findProject(":nms:v1_21R6")?.name = "v1_21R6"
|
|
||||||
include("nms:v1_21R7")
|
|
||||||
findProject(":nms:v1_21R7")?.name = "v1_21R7"
|
|
||||||
|
|
||||||
|
|
||||||
|
val reobfNMS = providers.gradleProperty("subprojects.reobfnms")
|
||||||
|
.get().split(",")
|
||||||
|
|
||||||
|
for (nmsPart in reobfNMS) {
|
||||||
|
include("nms:$nmsPart")
|
||||||
|
findProject(":nms:$nmsPart")?.name = nmsPart
|
||||||
|
}
|
||||||
|
|
||||||
|
// compatibility subprojects
|
||||||
include(":impl:LegacyEcoEnchant")
|
include(":impl:LegacyEcoEnchant")
|
||||||
findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant"
|
findProject(":impl:LegacyEcoEnchant")?.name = "LegacyEcoEnchant"
|
||||||
include("impl:ExcellentEnchant5_3")
|
include("impl:ExcellentEnchant5_4")
|
||||||
findProject(":impl:ExcellentEnchant5_3")?.name = "ExcellentEnchant5_3"
|
findProject(":impl:ExcellentEnchant5_4")?.name = "ExcellentEnchant5_4"
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
//TODO add conflict after level
|
||||||
/**
|
/**
|
||||||
* A Builder for material conflict.
|
* A Builder for material conflict.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.alexcrea.cuanvil.api;
|
package xyz.alexcrea.cuanvil.api;
|
||||||
|
|
||||||
import io.delilaheve.CustomAnvil;
|
import io.delilaheve.CustomAnvil;
|
||||||
|
import io.delilaheve.util.ConfigOptions;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
|
@ -180,13 +181,13 @@ public class EnchantmentApi {
|
||||||
private static boolean tryWriteDefaultConfig(FileConfiguration defaultConfig, CAEnchantment enchantment, boolean override) {
|
private static boolean tryWriteDefaultConfig(FileConfiguration defaultConfig, CAEnchantment enchantment, boolean override) {
|
||||||
boolean hasChange = false;
|
boolean hasChange = false;
|
||||||
|
|
||||||
String levelPath = "enchant_limits." + enchantment.getKey();
|
String levelPath = ConfigOptions.ENCHANT_LIMIT_ROOT + "." + enchantment.getKey();
|
||||||
if(override || !defaultConfig.isSet(levelPath)){
|
if(override || !defaultConfig.isSet(levelPath)){
|
||||||
defaultConfig.set(levelPath, enchantment.defaultMaxLevel());
|
defaultConfig.set(levelPath, enchantment.defaultMaxLevel());
|
||||||
hasChange = true;
|
hasChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String basePath = "enchant_values." + enchantment.getKey();
|
String basePath = ConfigOptions.ENCHANT_VALUES_ROOT + "." + enchantment.getKey();
|
||||||
EnchantmentRarity rarity = enchantment.defaultRarity();
|
EnchantmentRarity rarity = enchantment.defaultRarity();
|
||||||
|
|
||||||
String itemPath = basePath + ".item";
|
String itemPath = basePath + ".item";
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.api;
|
||||||
import io.delilaheve.CustomAnvil;
|
import io.delilaheve.CustomAnvil;
|
||||||
import io.delilaheve.util.ConfigOptions;
|
import io.delilaheve.util.ConfigOptions;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
@ -123,7 +124,7 @@ public class MaterialGroupApi {
|
||||||
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
|
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
|
||||||
|
|
||||||
String basePath = group.getName() + ".";
|
String basePath = group.getName() + ".";
|
||||||
Set<Material> materialSet = group.getNonGroupInheritedMaterials();
|
Set<NamespacedKey> materialSet = group.getNonGroupInheritedMaterials();
|
||||||
Set<AbstractMaterialGroup> groupSet = group.getGroups();
|
Set<AbstractMaterialGroup> groupSet = group.getGroups();
|
||||||
|
|
||||||
boolean empty = true;
|
boolean empty = true;
|
||||||
|
|
@ -153,7 +154,7 @@ public class MaterialGroupApi {
|
||||||
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
|
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
|
||||||
|
|
||||||
String basePath = group.getName() + ".";
|
String basePath = group.getName() + ".";
|
||||||
EnumSet<Material> materials = group.getMaterials();
|
Set<NamespacedKey> materials = group.getMaterials();
|
||||||
|
|
||||||
if (materials.isEmpty()) return false;
|
if (materials.isEmpty()) return false;
|
||||||
|
|
||||||
|
|
@ -163,8 +164,8 @@ public class MaterialGroupApi {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> materialSetToStringList(@NotNull Set<Material> materials) {
|
public static List<String> materialSetToStringList(@NotNull Set<NamespacedKey> materials) {
|
||||||
return materials.stream().map(material -> material.getKey().getKey().toLowerCase()).toList();
|
return materials.stream().map(NamespacedKey::toString).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> materialGroupSetToStringList(@NotNull Set<AbstractMaterialGroup> groups) {
|
public static List<String> materialGroupSetToStringList(@NotNull Set<AbstractMaterialGroup> groups) {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
* Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
|
* Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
|
||||||
* for this event to be useful.
|
* for this event to be useful.
|
||||||
* <p>
|
* <p>
|
||||||
* There is also {@link CATreatAnvilResultEvent} that may be better for some use case.
|
* There is also {@link CATreatAnvilResult2Event} that may be better for some use case.
|
||||||
*/
|
*/
|
||||||
public class CAClickResultBypassEvent extends Event implements Cancellable {
|
public class CAClickResultBypassEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
* <p>
|
* <p>
|
||||||
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
||||||
* <p>
|
* <p>
|
||||||
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
|
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event}
|
||||||
* as your use case may be more prone to use theses.
|
* as your use case may be more prone to use theses.
|
||||||
*/
|
*/
|
||||||
public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {
|
public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
* <p>
|
* <p>
|
||||||
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
|
||||||
* <p>
|
* <p>
|
||||||
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
|
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event}
|
||||||
* as your use case may be more prone to use theses.
|
* as your use case may be more prone to use theses.
|
||||||
*/
|
*/
|
||||||
public class CAPreAnvilBypassEvent extends Event implements Cancellable {
|
public class CAPreAnvilBypassEvent extends Event implements Cancellable {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
package xyz.alexcrea.cuanvil.api.event.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryView;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import xyz.alexcrea.cuanvil.anvil.AnvilCost;
|
||||||
|
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after custom anvil processed the click on the result on the anvil inventory.
|
||||||
|
* This event should be used to modify the result of an anvil use.
|
||||||
|
* <p>
|
||||||
|
* You may also want to check {@link CAClickResultBypassEvent},
|
||||||
|
* {@link CAPreAnvilBypassEvent}
|
||||||
|
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
|
||||||
|
* <p>
|
||||||
|
* A null result will cancel this event
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class CATreatAnvilResult2Event extends Event {
|
||||||
|
|
||||||
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final InventoryView view;
|
||||||
|
|
||||||
|
private final AnvilUseType useType;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final ItemStack left;
|
||||||
|
@Nullable
|
||||||
|
private final ItemStack right;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ItemStack result;
|
||||||
|
|
||||||
|
private final AnvilCost cost;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public CATreatAnvilResult2Event(
|
||||||
|
@NotNull InventoryView view,
|
||||||
|
Inventory inv,
|
||||||
|
AnvilUseType useType,
|
||||||
|
@Nullable ItemStack result,
|
||||||
|
AnvilCost cost) {
|
||||||
|
this.view = view;
|
||||||
|
this.useType = useType;
|
||||||
|
|
||||||
|
this.left = inv.getItem(0); // TODO use view here
|
||||||
|
this.right = inv.getItem(1);
|
||||||
|
this.result = result;
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bukkit inventory view.
|
||||||
|
* <p>
|
||||||
|
* Temporarily marked as internal as it will get changed to anvil view on legacy removal
|
||||||
|
* so signature will change
|
||||||
|
*
|
||||||
|
* @return The inventory view of this event.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public @NotNull InventoryView getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of use source of the result.
|
||||||
|
*
|
||||||
|
* @return The craft use type.
|
||||||
|
*/
|
||||||
|
public AnvilUseType getUseType() {
|
||||||
|
return useType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the left item of the anvil use
|
||||||
|
*
|
||||||
|
* @return the left item
|
||||||
|
*/
|
||||||
|
public @Nullable ItemStack getLeftItem() {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the right item of the anvil use
|
||||||
|
*
|
||||||
|
* @return the right item
|
||||||
|
*/
|
||||||
|
public @Nullable ItemStack getRightItem() {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current result
|
||||||
|
* <p>
|
||||||
|
* note that it will not be null unless another listener previously set it to null.
|
||||||
|
*
|
||||||
|
* @return The current result.
|
||||||
|
*/
|
||||||
|
public @Nullable ItemStack getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current result
|
||||||
|
* <p>
|
||||||
|
* note that a null result will cancel this anvil use.
|
||||||
|
*
|
||||||
|
* @param result The new result
|
||||||
|
*/
|
||||||
|
public void setResult(@Nullable ItemStack result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the level cost displayed on the anvil.
|
||||||
|
* <h3>Important note:</h3>
|
||||||
|
* the final price are re calculated on click for the following use case:
|
||||||
|
* <ul>
|
||||||
|
* <li>Custom craft</li>
|
||||||
|
* <li>Unit repair</li>
|
||||||
|
* <li>Lore edit</li>
|
||||||
|
* </ul>
|
||||||
|
* This value will be used as final price for:
|
||||||
|
* <li>Item merge</li>
|
||||||
|
* <li>Item rename</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return The current cost.
|
||||||
|
* @deprecated use #{@link #getCost()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||||
|
public int getLevelCost() {
|
||||||
|
return cost.asXpCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the level cost displayed on the anvil.
|
||||||
|
* <h3>Important note:</h3>
|
||||||
|
* the final price are re calculated on click for the following use case:
|
||||||
|
* <ul>
|
||||||
|
* <li>Custom craft</li>
|
||||||
|
* <li>Unit repair</li>
|
||||||
|
* <li>Lore edit</li>
|
||||||
|
* </ul>
|
||||||
|
* This value will be used as final price for:
|
||||||
|
* <li>Item merge</li>
|
||||||
|
* <li>Item rename</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param levelCost The new cost.
|
||||||
|
* @deprecated use #{@link #getCost()} and set value on this instead
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||||
|
public void setLevelCost(int levelCost) {
|
||||||
|
cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow access to the current cost of the event
|
||||||
|
* Note that modifying this object will change the event resulting cost
|
||||||
|
*
|
||||||
|
* <h3>Important note:</h3>
|
||||||
|
* the final price are re calculated on click for the following use case:
|
||||||
|
* <ul>
|
||||||
|
* <li>Custom craft</li>
|
||||||
|
* <li>Unit repair</li>
|
||||||
|
* <li>Lore edit</li>
|
||||||
|
* </ul>
|
||||||
|
* This value will be used as final price for:
|
||||||
|
* <li>Item merge</li>
|
||||||
|
* <li>Item rename</li>
|
||||||
|
*
|
||||||
|
* @return the current anvil cost
|
||||||
|
*/
|
||||||
|
public AnvilCost getCost() {
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,8 @@ import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
import xyz.alexcrea.cuanvil.anvil.AnvilCost;
|
||||||
|
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after custom anvil processed the click on the result on the anvil inventory.
|
* Called after custom anvil processed the click on the result on the anvil inventory.
|
||||||
|
|
@ -17,8 +18,12 @@ import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
||||||
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
|
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
|
||||||
* <p>
|
* <p>
|
||||||
* A null result will cancel this pre anvil event
|
* A null result will cancel this pre anvil event
|
||||||
|
*
|
||||||
|
* @deprecated Prepare anvil Event cannot be provided as it can be called on result and therefore not have prepared anvil event
|
||||||
|
* use {@link CATreatAnvilResult2Event} instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||||
public class CATreatAnvilResultEvent extends Event {
|
public class CATreatAnvilResultEvent extends Event {
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
private static final HandlerList HANDLERS = new HandlerList();
|
||||||
|
|
@ -40,13 +45,13 @@ public class CATreatAnvilResultEvent extends Event {
|
||||||
@Nullable
|
@Nullable
|
||||||
private ItemStack result;
|
private ItemStack result;
|
||||||
|
|
||||||
private int levelCost;
|
private final AnvilCost cost;
|
||||||
|
|
||||||
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, int levelCost) {
|
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, AnvilCost cost) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.useType = useType;
|
this.useType = useType;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.levelCost = levelCost;
|
this.cost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,9 +109,11 @@ public class CATreatAnvilResultEvent extends Event {
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @return The current cost.
|
* @return The current cost.
|
||||||
|
* @deprecated use #{@link #getCost()} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||||
public int getLevelCost() {
|
public int getLevelCost() {
|
||||||
return levelCost;
|
return cost.asXpCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -124,8 +131,32 @@ public class CATreatAnvilResultEvent extends Event {
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param levelCost The new cost.
|
* @param levelCost The new cost.
|
||||||
|
* @deprecated use #{@link #getCost()} and set value on this instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "1.17.0")
|
||||||
public void setLevelCost(int levelCost) {
|
public void setLevelCost(int levelCost) {
|
||||||
this.levelCost = levelCost;
|
cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow access to the current cost of the event
|
||||||
|
* Note that modifying this object will change the event resulting cost
|
||||||
|
*
|
||||||
|
* <h3>Important note:</h3>
|
||||||
|
* the final price are re calculated on click for the following use case:
|
||||||
|
* <ul>
|
||||||
|
* <li>Custom craft</li>
|
||||||
|
* <li>Unit repair</li>
|
||||||
|
* <li>Lore edit</li>
|
||||||
|
* </ul>
|
||||||
|
* This value will be used as final price for:
|
||||||
|
* <li>Item merge</li>
|
||||||
|
* <li>Item rename</li>
|
||||||
|
*
|
||||||
|
* @return the current anvil cost
|
||||||
|
*/
|
||||||
|
public AnvilCost getCost() {
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import xyz.alexcrea.cuanvil.group.EnchantConflictManager;
|
import xyz.alexcrea.cuanvil.group.EnchantConflictManager;
|
||||||
import xyz.alexcrea.cuanvil.group.ItemGroupManager;
|
import xyz.alexcrea.cuanvil.group.ItemGroupManager;
|
||||||
import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager;
|
import xyz.alexcrea.cuanvil.recipe.CustomAnvilRecipeManager;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MetricsUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -145,6 +146,7 @@ public abstract class ConfigHolder {
|
||||||
sufficientSuccess = true;
|
sufficientSuccess = true;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not copy backup saving config " + base.getName(), e);
|
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not copy backup saving config " + base.getName(), e);
|
||||||
|
MetricsUtil.INSTANCE.trackError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// save last backup
|
// save last backup
|
||||||
|
|
@ -275,6 +277,7 @@ public abstract class ConfigHolder {
|
||||||
this.deletedConfigFile.createNewFile();
|
this.deletedConfigFile.createNewFile();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not create " + this.deletedConfigFile.getPath(), e);
|
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not create " + this.deletedConfigFile.getPath(), e);
|
||||||
|
MetricsUtil.INSTANCE.trackError(e);
|
||||||
}
|
}
|
||||||
loadDeletedListFile(false);
|
loadDeletedListFile(false);
|
||||||
|
|
||||||
|
|
@ -312,6 +315,7 @@ public abstract class ConfigHolder {
|
||||||
this.deletedListConfig.save(this.deletedConfigFile);
|
this.deletedListConfig.save(this.deletedConfigFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not save " + this.deletedConfigFile.getPath(), e);
|
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not save " + this.deletedConfigFile.getPath(), e);
|
||||||
|
MetricsUtil.INSTANCE.trackError(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package xyz.alexcrea.cuanvil.config;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.alexcrea.cuanvil.enchant;
|
package xyz.alexcrea.cuanvil.enchant;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
@ -11,24 +12,23 @@ public interface AdditionalTestEnchantment {
|
||||||
/**
|
/**
|
||||||
* Test if the provided enchantments can be compatible with this enchantment. only non-Custom Anvil conflict.
|
* Test if the provided enchantments can be compatible with this enchantment. only non-Custom Anvil conflict.
|
||||||
* @param enchantments Immutable map of validated enchantments for the item.
|
* @param enchantments Immutable map of validated enchantments for the item.
|
||||||
* @param itemMat Material of the tested item.
|
* @param itemType Material namespaced key of the tested item.
|
||||||
* @return If there is a conflict with the enchantments.
|
* @return If there is a conflict with the enchantments.
|
||||||
*/
|
*/
|
||||||
boolean isEnchantConflict(
|
boolean isEnchantConflict(
|
||||||
@NotNull Map<CAEnchantment, Integer> enchantments,
|
@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||||
@NotNull Material itemMat);
|
@NotNull NamespacedKey itemType);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the provided item can be compatible with this enchantment. only non-Custom Anvil conflict.
|
* Test if the provided item can be compatible with this enchantment. only non-Custom Anvil conflict.
|
||||||
* @param enchantments Immutable map of validated enchantments for the item.
|
* @param enchantments Immutable map of validated enchantments for the item.
|
||||||
* @param itemMat Material of the tested item.
|
* @param itemType Material namespaced key of the tested item.
|
||||||
* @param item Provide a new instance of the used item stack with the partial enchantment applied.
|
* @param item Provide a new instance of the used item stack with the partial enchantment applied.
|
||||||
* @return If there is a conflict with the enchantment and the item.
|
* @return If there is a conflict with the enchantment and the item.
|
||||||
*/
|
*/
|
||||||
boolean isItemConflict(
|
boolean isItemConflict(
|
||||||
@NotNull Map<CAEnchantment, Integer> enchantments,
|
@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||||
@NotNull Material itemMat,
|
@NotNull NamespacedKey itemType,
|
||||||
@NotNull ItemStack item);
|
@NotNull ItemStack item);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import xyz.alexcrea.cuanvil.enchant.bulk.BukkitEnchantBulkOperation;
|
||||||
import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation;
|
import xyz.alexcrea.cuanvil.enchant.bulk.BulkCleanEnchantOperation;
|
||||||
import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation;
|
import xyz.alexcrea.cuanvil.enchant.bulk.BulkGetEnchantOperation;
|
||||||
import xyz.alexcrea.cuanvil.enchant.wrapped.CABukkitEnchantment;
|
import xyz.alexcrea.cuanvil.enchant.wrapped.CABukkitEnchantment;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MetricsUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
@ -85,11 +86,13 @@ public class CAEnchantmentRegistry {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var error = new IllegalStateException("enchantment " + enchantment.getKey() + " was already registered");
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING,
|
CustomAnvil.instance.getLogger().log(Level.WARNING,
|
||||||
"Duplicate distinct registered enchantment. This should NOT happen any time.\n" +
|
"Duplicate distinct registered enchantment. This should NOT happen any time.\n" +
|
||||||
"If you are a custom anvil developer: Maybe custom anvil detected your enchantment as a bukkit enchantment. " +
|
"If you are a custom anvil developer: Maybe custom anvil detected your enchantment as a bukkit enchantment. " +
|
||||||
"you should maybe remove enchantment with the same key before registering yours",
|
"you should maybe remove enchantment with the same key before registering yours",
|
||||||
new IllegalStateException("enchantment " + enchantment.getKey() + " was already registered"));
|
error);
|
||||||
|
MetricsUtil.INSTANCE.trackError(error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package xyz.alexcrea.cuanvil.enchant.bulk;
|
||||||
|
|
||||||
|
import com.maddoxh.superEnchants.items.EnchantApplicator;
|
||||||
|
import com.maddoxh.superEnchants.items.EnchantReader;
|
||||||
|
import io.delilaheve.CustomAnvil;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.alexcrea.cuanvil.api.EnchantmentApi;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SuperEnchantBulkOperation implements BulkGetEnchantOperation, BulkCleanEnchantOperation {
|
||||||
|
|
||||||
|
private Plugin plugin;
|
||||||
|
public SuperEnchantBulkOperation(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bulkGet(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||||
|
EnchantReader.INSTANCE.readEnchants(item).forEach((ench, level) -> {
|
||||||
|
var enchantment = EnchantmentApi.getByKey(NamespacedKey.fromString(ench, plugin));
|
||||||
|
if(enchantment == null) {
|
||||||
|
CustomAnvil.log("Enchantment " + ench + " not found in custom anvil");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enchantmentMap.put(enchantment, level);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bulkClear(@NotNull ItemStack item) {
|
||||||
|
EnchantApplicator.INSTANCE.clearAllCustomEnchants(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bulkClear(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||||
|
// item meta is not preferred for enchantment squared clear
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||||
|
|
@ -39,7 +40,7 @@ public class CAEEPreV5Enchantment extends CABukkitEnchantment implements Additio
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
if (!definition.hasConflicts()) return false;
|
if (!definition.hasConflicts()) return false;
|
||||||
|
|
||||||
Set<String> conflicts = definition.getConflicts();
|
Set<String> conflicts = definition.getConflicts();
|
||||||
|
|
@ -52,8 +53,8 @@ public class CAEEPreV5Enchantment extends CABukkitEnchantment implements Additio
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) return false;
|
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) return false;
|
||||||
|
|
||||||
return !definition.getSupportedItems().is(item);
|
return !definition.getSupportedItems().is(item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,51 @@
|
||||||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||||
import su.nightexpress.excellentenchants.api.item.ItemSet;
|
import su.nightexpress.excellentenchants.api.item.ItemSet;
|
||||||
import su.nightexpress.excellentenchants.api.wrapper.EnchantDefinition;
|
|
||||||
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||||
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class CAEEV5Enchantment extends CABukkitEnchantment implements AdditionalTestEnchantment {
|
public class CAEEV5Enchantment extends CABukkitEnchantment implements AdditionalTestEnchantment {
|
||||||
|
|
||||||
@NotNull CustomEnchantment eeenchantment;
|
@NotNull CustomEnchantment eeenchantment;
|
||||||
@NotNull EnchantDefinition definition;
|
@NotNull Object definition;
|
||||||
|
|
||||||
public CAEEV5Enchantment(@NotNull CustomEnchantment enchantment) {
|
public CAEEV5Enchantment(@NotNull CustomEnchantment enchantment) {
|
||||||
super(enchantment.getBukkitEnchantment(), EnchantmentRarity.getRarity(enchantment.getDefinition().getAnvilCost()));
|
super(enchantment.getBukkitEnchantment(), EnchantmentRarity.getRarity(getAnvilCost(enchantment)));
|
||||||
this.eeenchantment = enchantment;
|
this.eeenchantment = enchantment;
|
||||||
this.definition = enchantment.getDefinition();
|
this.definition = getDefinition(enchantment);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
if (!definition.hasConflicts()) return false;
|
if (!hasConflicts()) return false;
|
||||||
|
|
||||||
Set<String> conflicts = definition.getExclusiveSet();
|
Set<String> conflicts = getExclusiveSet();
|
||||||
|
|
||||||
for (CAEnchantment caEnchantment : enchantments.keySet()) {
|
for (CAEnchantment caEnchantment : enchantments.keySet()) {
|
||||||
if (conflicts.contains(caEnchantment.getName())) return true;
|
if (conflicts.contains(caEnchantment.getName())) return true;
|
||||||
|
if (conflicts.contains(caEnchantment.getKey().toString())) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) return false;
|
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) return false;
|
||||||
|
|
||||||
String key = itemMat.getKey().getKey();
|
String key = itemType.getKey();
|
||||||
ItemSet primary = eeenchantment.getPrimaryItems();
|
ItemSet primary = eeenchantment.getPrimaryItems();
|
||||||
if (primary.getMaterials().contains(key)) return false;
|
if (primary.getMaterials().contains(key)) return false;
|
||||||
|
|
||||||
|
|
@ -52,4 +55,74 @@ public class CAEEV5Enchantment extends CABukkitEnchantment implements Additional
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final Method getDefinitonMethod;
|
||||||
|
|
||||||
|
private static final Method getAnvilCostMethod;
|
||||||
|
private static final Method hasConflictsMethod;
|
||||||
|
private static final Method getExclusiveSetMethod;
|
||||||
|
static {
|
||||||
|
var enchClazz = CustomEnchantment.class;
|
||||||
|
try {
|
||||||
|
getDefinitonMethod = enchClazz.getDeclaredMethod("getDefinition");
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> definitionClazz;
|
||||||
|
try {
|
||||||
|
definitionClazz = Class.forName("su.nightexpress.excellentenchants.api.EnchantDefinition");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
try {
|
||||||
|
definitionClazz = Class.forName("su.nightexpress.excellentenchants.api.wrapper.EnchantDefinition");
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now definition methods
|
||||||
|
try {
|
||||||
|
getAnvilCostMethod = definitionClazz.getDeclaredMethod("getAnvilCost");
|
||||||
|
hasConflictsMethod = definitionClazz.getDeclaredMethod("hasConflicts");
|
||||||
|
getExclusiveSetMethod = definitionClazz.getDeclaredMethod("getExclusiveSet");
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object getDefinition(CustomEnchantment enchantment) {
|
||||||
|
try {
|
||||||
|
return getDefinitonMethod.invoke(enchantment);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getAnvilCost(CustomEnchantment enchantment) {
|
||||||
|
try {
|
||||||
|
return (int) getAnvilCostMethod.invoke(getDefinition(enchantment));
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasConflicts() {
|
||||||
|
try {
|
||||||
|
return (boolean) hasConflictsMethod.invoke(definition);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Set<String> getExclusiveSet() {
|
||||||
|
try {
|
||||||
|
return (Set<String>) getExclusiveSetMethod.invoke(definition);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import su.nightexpress.excellentenchants.api.enchantment.CustomEnchantment;
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.plugins.ExcellentEnchant5_4EnchantSettings;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CAEEV5_4Enchantment extends CAEEV5Enchantment {
|
||||||
|
|
||||||
|
public CAEEV5_4Enchantment(@NotNull CustomEnchantment enchantment) {
|
||||||
|
super(enchantment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemMat) {
|
||||||
|
if(super.isEnchantConflict(enchantments, itemMat)) return true;
|
||||||
|
|
||||||
|
var limit = ExcellentEnchant5_4EnchantSettings.anvilLimit();
|
||||||
|
var count = enchantments.keySet().stream()
|
||||||
|
.filter(key -> key instanceof CAEEV5_4Enchantment)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
return count > limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ import com.willfp.ecoenchants.enchant.EcoEnchant;
|
||||||
import com.willfp.ecoenchants.target.EnchantmentTarget;
|
import com.willfp.ecoenchants.target.EnchantmentTarget;
|
||||||
import com.willfp.ecoenchants.type.EnchantmentType;
|
import com.willfp.ecoenchants.type.EnchantmentType;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||||
|
|
@ -23,9 +24,13 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
if (enchantments.isEmpty()) return false;
|
if (enchantments.isEmpty()) return false;
|
||||||
|
|
||||||
|
// Check if there is only self
|
||||||
|
if (enchantments.size() == 1 && this.equals(enchantments.keySet().stream().findFirst().get()))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (this.ecoEnchant.getConflictsWithEverything()) {
|
if (this.ecoEnchant.getConflictsWithEverything()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -57,9 +62,9 @@ public class CAEcoEnchant extends CABukkitEnchantment implements AdditionalTestE
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||||
@NotNull Material itemMat,
|
@NotNull NamespacedKey itemType,
|
||||||
@NotNull ItemStack item) {
|
@NotNull ItemStack item) {
|
||||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) {
|
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
@ -24,12 +25,12 @@ public class CAIncompatibleAllEnchant extends CABukkitEnchantment implements Add
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
return !enchantments.isEmpty() && !(enchantments.size() == 1 && enchantments.containsKey(this));
|
return !enchantments.isEmpty() && !(enchantments.size() == 1 && enchantments.containsKey(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
import su.nightexpress.excellentenchants.api.enchantment.EnchantmentData;
|
||||||
|
|
@ -22,7 +23,7 @@ public class CALegacyEEEnchantment extends CABukkitEnchantment implements Additi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
if (!eeenchantment.hasConflicts()) return false;
|
if (!eeenchantment.hasConflicts()) return false;
|
||||||
|
|
||||||
Set<String> conflicts = eeenchantment.getConflicts();
|
Set<String> conflicts = eeenchantment.getConflicts();
|
||||||
|
|
@ -35,8 +36,8 @@ public class CALegacyEEEnchantment extends CABukkitEnchantment implements Additi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat, @NotNull ItemStack item) {
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) return false;
|
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) return false;
|
||||||
|
|
||||||
return !eeenchantment.getSupportedItems().is(item);
|
return !eeenchantment.getSupportedItems().is(item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@ import com.willfp.ecoenchants.enchantments.EcoEnchant;
|
||||||
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
|
import com.willfp.ecoenchants.enchantments.meta.EnchantmentTarget;
|
||||||
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
|
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||||
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||||
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MaterialUtil;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -23,7 +25,7 @@ public class CALegacyEcoEnchant extends CABukkitEnchantment implements Additiona
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull Material itemMat) {
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
if (enchantments.isEmpty()) return false;
|
if (enchantments.isEmpty()) return false;
|
||||||
|
|
||||||
EnchantmentType type = this.ecoEnchant.getType();
|
EnchantmentType type = this.ecoEnchant.getType();
|
||||||
|
|
@ -48,14 +50,15 @@ public class CALegacyEcoEnchant extends CABukkitEnchantment implements Additiona
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments,
|
||||||
@NotNull Material itemMat,
|
@NotNull NamespacedKey itemType,
|
||||||
@NotNull ItemStack item) {
|
@NotNull ItemStack item) {
|
||||||
if (Material.ENCHANTED_BOOK.equals(itemMat)) {
|
if (Material.ENCHANTED_BOOK.getKey().equals(itemType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mat = MaterialUtil.INSTANCE.getMatFromKey(itemType);
|
||||||
for (EnchantmentTarget target : this.ecoEnchant.getTargets()) {
|
for (EnchantmentTarget target : this.ecoEnchant.getTargets()) {
|
||||||
if (target.getMaterials().contains(itemMat)) {
|
if (target.getMaterials().contains(mat)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package xyz.alexcrea.cuanvil.enchant.wrapped;
|
||||||
|
|
||||||
|
import com.maddoxh.superEnchants.enchants.CustomEnchant;
|
||||||
|
import com.maddoxh.superEnchants.enchants.EnchantManager;
|
||||||
|
import com.maddoxh.superEnchants.items.EnchantApplicator;
|
||||||
|
import com.maddoxh.superEnchants.items.EnchantReader;
|
||||||
|
import com.maddoxh.superEnchants.util.ConflictChecker;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentBase;
|
||||||
|
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CASuperEnchantEnchantment extends CAEnchantmentBase implements AdditionalTestEnchantment {
|
||||||
|
|
||||||
|
private @NotNull CustomEnchant enchant;
|
||||||
|
private @NotNull EnchantManager enchantManager;
|
||||||
|
|
||||||
|
public CASuperEnchantEnchantment(@NotNull CustomEnchant enchant, @NotNull Plugin plugin, @NotNull EnchantManager enchantManager) {
|
||||||
|
super(NamespacedKey.fromString(enchant.getId(), plugin), EnchantmentRarity.COMMON, enchant.getMaxLevel());
|
||||||
|
|
||||||
|
this.enchant = enchant;
|
||||||
|
this.enchantManager = enchantManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||||
|
return EnchantReader.INSTANCE.getEnchantLevel(item, enchant.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnchantmentPresent(@NotNull ItemStack item, @NotNull ItemMeta meta) {
|
||||||
|
return EnchantReader.INSTANCE.hasEnchant(item, enchant.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEnchantmentUnsafe(@NotNull ItemStack item, int level) {
|
||||||
|
EnchantApplicator.INSTANCE.applyEnchant(item, enchant.getId(), level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeFrom(@NotNull ItemStack item) {
|
||||||
|
EnchantApplicator.INSTANCE.removeEnchant(item, enchant.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnchantConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType) {
|
||||||
|
var idMap = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
enchantments.forEach((enchant, level) -> {
|
||||||
|
if(!(enchant instanceof CASuperEnchantEnchantment superEnch)) return;
|
||||||
|
idMap.put(superEnch.enchant.getId(), level);
|
||||||
|
});
|
||||||
|
|
||||||
|
return ConflictChecker.INSTANCE.hasConflict(
|
||||||
|
idMap,
|
||||||
|
enchant.getId(),
|
||||||
|
enchantManager
|
||||||
|
) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) {
|
||||||
|
if(Material.ENCHANTED_BOOK.equals(item.getType())) return false;
|
||||||
|
|
||||||
|
return !enchant.canApplyTo(item.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,34 +1,35 @@
|
||||||
package xyz.alexcrea.cuanvil.gui.config;
|
package xyz.alexcrea.cuanvil.gui.config;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public interface SelectMaterialContainer {
|
public interface SelectMaterialContainer {
|
||||||
|
|
||||||
EnumSet<Material> getSelectedMaterials();
|
Set<NamespacedKey> getSelectedMaterials();
|
||||||
|
|
||||||
boolean setSelectedMaterials(EnumSet<Material> materials);
|
boolean setSelectedMaterials(Set<NamespacedKey> materials);
|
||||||
|
|
||||||
EnumSet<Material> illegalMaterials();
|
Set<NamespacedKey> illegalMaterials();
|
||||||
|
|
||||||
static List<String> getMaterialLore(SelectMaterialContainer container, String containerType, String action){
|
static List<String> getMaterialLore(SelectMaterialContainer container, String containerType, String action){
|
||||||
// Prepare material lore
|
// Prepare material lore
|
||||||
ArrayList<String> groupLore = new ArrayList<>();
|
ArrayList<String> groupLore = new ArrayList<>();
|
||||||
groupLore.add("§7Allow you to select a list of §ematerials §7that this " + containerType + " should " + action);
|
groupLore.add("§7Allow you to select a list of §ematerials §7that this " + containerType + " should " + action);
|
||||||
Set<Material> materialSet = container.getSelectedMaterials();
|
Set<NamespacedKey> materialSet = container.getSelectedMaterials();
|
||||||
if (materialSet.isEmpty()) {
|
if (materialSet.isEmpty()) {
|
||||||
groupLore.add("§7There is no "+action+"d material for this "+containerType+".");
|
groupLore.add("§7There is no "+action+"d material for this "+containerType+".");
|
||||||
} else {
|
} else {
|
||||||
groupLore.add("§7List of "+action+"d materials for this "+containerType+":");
|
groupLore.add("§7List of "+action+"d materials for this "+containerType+":");
|
||||||
Iterator<Material> materialIterator = materialSet.iterator();
|
Iterator<NamespacedKey> materialIterator = materialSet.iterator();
|
||||||
|
|
||||||
boolean greaterThanMax = materialSet.size() > 5;
|
boolean greaterThanMax = materialSet.size() > 5;
|
||||||
int maxindex = (greaterThanMax ? 4 : materialSet.size());
|
int maxindex = (greaterThanMax ? 4 : materialSet.size());
|
||||||
for (int i = 0; i < maxindex; i++) {
|
for (int i = 0; i < maxindex; i++) {
|
||||||
// format string like "- Stone Sword"
|
// format string like "- Stone Sword"
|
||||||
String formattedName = CasedStringUtil.snakeToUpperSpacedCase(materialIterator.next().name().toLowerCase());
|
String formattedName = CasedStringUtil.snakeToUpperSpacedCase(materialIterator.next().getKey().toLowerCase());
|
||||||
groupLore.add("§7- §e" + formattedName);
|
groupLore.add("§7- §e" + formattedName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MetricsUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
@ -41,6 +42,7 @@ public class ConfirmActionGui extends AbstractAskGui {
|
||||||
success = onConfirm.get();
|
success = onConfirm.get();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not process confirmation supplier.", e);
|
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not process confirmation supplier.", e);
|
||||||
|
MetricsUtil.INSTANCE.trackError(e);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MaterialUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
@ -52,7 +53,7 @@ public class SelectItemTypeGui extends AbstractAskGui {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
ItemStack cursor = event.getWhoClicked().getItemOnCursor();
|
ItemStack cursor = event.getWhoClicked().getItemOnCursor();
|
||||||
if(cursor.getType().isAir()) return;
|
if(MaterialUtil.INSTANCE.isAir(cursor)) return;
|
||||||
|
|
||||||
ItemStack finalItem;
|
ItemStack finalItem;
|
||||||
if(materialOnly){
|
if(materialOnly){
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||||
|
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil;
|
||||||
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager;
|
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager;
|
||||||
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
|
||||||
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
|
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
|
||||||
|
|
@ -283,7 +284,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
|
||||||
|
|
||||||
if(!this.packetManager.getCanSetInstantBuild()){
|
if(!this.packetManager.getCanSetInstantBuild()){
|
||||||
lore.add("");
|
lore.add("");
|
||||||
lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a newer version of this plugin for this to work.");
|
lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a paper server.");
|
||||||
lore.add("§cCurrently ProtocoLib is not detected.");
|
lore.add("§cCurrently ProtocoLib is not detected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import java.util.Locale;
|
||||||
*/
|
*/
|
||||||
public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsGui.IntSettingFactory> {
|
public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsGui.IntSettingFactory> {
|
||||||
|
|
||||||
private static final String SECTION_NAME = "enchant_limits";
|
private static final String SECTION_NAME = ConfigOptions.ENCHANT_LIMIT_ROOT;
|
||||||
|
|
||||||
private static EnchantLimitConfigGui INSTANCE = null;
|
private static EnchantLimitConfigGui INSTANCE = null;
|
||||||
|
|
||||||
|
|
@ -41,18 +41,34 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
|
||||||
String key = enchant.getKey().toString().toLowerCase(Locale.ROOT);
|
String key = enchant.getKey().toString().toLowerCase(Locale.ROOT);
|
||||||
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_"));
|
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key.replace(":", "_"));
|
||||||
|
|
||||||
|
var defaultValue = enchant.defaultMaxLevel();
|
||||||
|
|
||||||
return new IntSettingsGui.IntSettingFactory(prettyKey + " Limit", this,
|
return new IntSettingsGui.IntSettingFactory(prettyKey + " Limit", this,
|
||||||
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
|
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
|
||||||
Collections.singletonList(
|
Collections.singletonList(
|
||||||
"§7Maximum applied level of " + prettyKey
|
"§7Maximum applied level of " + prettyKey
|
||||||
),
|
),
|
||||||
0, 255,
|
-1, 255, -1,
|
||||||
enchant.defaultMaxLevel(),
|
|
||||||
1, 5, 10, 50, 100){
|
1, 5, 10, 50, 100){
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getConfiguredValue() {
|
public int getConfiguredValue() {
|
||||||
return ConfigOptions.INSTANCE.enchantLimit(enchant);
|
var value = ConfigOptions.INSTANCE.rawEnchantLimit(enchant);
|
||||||
|
return Math.min(value, ConfigOptions.ENCHANT_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String valueDisplayName(IntSettingsGui.ValueDisplayType type, int value) {
|
||||||
|
|
||||||
|
if(value < 0) {
|
||||||
|
return switch (type) {
|
||||||
|
case CURRENT -> "Default (" + defaultValue + ")";
|
||||||
|
case RESET -> String.valueOf(defaultValue);
|
||||||
|
default -> "Default";
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
else return super.valueDisplayName(type, value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MetricsUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
@ -264,6 +265,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
|
||||||
updateGuiValues();
|
updateGuiValues();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e);
|
CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e);
|
||||||
|
MetricsUtil.INSTANCE.trackError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save file configuration to disk
|
// Save file configuration to disk
|
||||||
|
|
@ -308,6 +310,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
|
||||||
updateGuiValues();
|
updateGuiValues();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating group for " + this.enchantConflict, e);
|
CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating group for " + this.enchantConflict, e);
|
||||||
|
MetricsUtil.INSTANCE.trackError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save file configuration to disk
|
// Save file configuration to disk
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.github.stefvanschie.inventoryframework.pane.PatternPane;
|
||||||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||||
import io.delilaheve.CustomAnvil;
|
import io.delilaheve.CustomAnvil;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.inventory.ItemFlag;
|
import org.bukkit.inventory.ItemFlag;
|
||||||
|
|
@ -325,19 +326,19 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumSet<Material> getSelectedMaterials() {
|
public Set<NamespacedKey> getSelectedMaterials() {
|
||||||
return this.group.getNonGroupInheritedMaterials();
|
return this.group.getNonGroupInheritedMaterials();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setSelectedMaterials(EnumSet<Material> materials) {
|
public boolean setSelectedMaterials(Set<NamespacedKey> materials) {
|
||||||
this.group.setNonGroupInheritedMaterials(materials);
|
this.group.setNonGroupInheritedMaterials(materials);
|
||||||
|
|
||||||
// Write to file configuration
|
// Write to file configuration
|
||||||
String[] groupNames = new String[materials.size()];
|
String[] groupNames = new String[materials.size()];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Material otherGroup : materials) {
|
for (NamespacedKey otherGroup : materials) {
|
||||||
groupNames[index++] = otherGroup.name().toLowerCase();
|
groupNames[index++] = otherGroup.getKey().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(this.group.getName()+"."+ItemGroupManager.MATERIAL_LIST_PATH, groupNames);
|
ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(this.group.getName()+"."+ItemGroupManager.MATERIAL_LIST_PATH, groupNames);
|
||||||
|
|
@ -353,8 +354,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumSet<Material> illegalMaterials() {
|
public Set<NamespacedKey> illegalMaterials() {
|
||||||
return EnumSet.of(Material.AIR);
|
return Set.of(Material.AIR.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,8 @@ public class IntSettingsGui extends AbstractSettingGui {
|
||||||
assert meta != null;
|
assert meta != null;
|
||||||
|
|
||||||
meta.setDisplayName("§eReset to default value");
|
meta.setDisplayName("§eReset to default value");
|
||||||
meta.setLore(Collections.singletonList("§7Default value is §e" + holder.defaultVal));
|
meta.setLore(Collections.singletonList("§7Default value is §e" +
|
||||||
|
holder.valueDisplayName(ValueDisplayType.RESET, holder.defaultVal)));
|
||||||
item.setItemMeta(meta);
|
item.setItemMeta(meta);
|
||||||
returnToDefault = new GuiItem(item, event -> {
|
returnToDefault = new GuiItem(item, event -> {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
@ -86,41 +87,23 @@ public class IntSettingsGui extends AbstractSettingGui {
|
||||||
* Update item using the setting value to match the new value.
|
* Update item using the setting value to match the new value.
|
||||||
*/
|
*/
|
||||||
protected void updateValueDisplay() {
|
protected void updateValueDisplay() {
|
||||||
|
|
||||||
PatternPane pane = getPane();
|
PatternPane pane = getPane();
|
||||||
|
|
||||||
// minus item
|
// minus item
|
||||||
GuiItem minusItem;
|
GuiItem minusItem;
|
||||||
if (now > holder.min) {
|
if (now > holder.min) {
|
||||||
int planned = Math.max(holder.min, now - step);
|
int planned = Math.max(holder.min, now - step);
|
||||||
ItemStack item = new ItemStack(Material.RED_TERRACOTTA);
|
minusItem = valueEditItem(Material.RED_TERRACOTTA, ValueDisplayType.REMOVE, planned);
|
||||||
ItemMeta meta = item.getItemMeta();
|
|
||||||
assert meta != null;
|
|
||||||
|
|
||||||
meta.setDisplayName("§e" + now + " §f-> §e" + planned + " §r(§c-" + (now - planned) + "§r)");
|
|
||||||
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE));
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
|
|
||||||
minusItem = new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
|
|
||||||
} else {
|
} else {
|
||||||
minusItem = GuiGlobalItems.backgroundItem(Material.BARRIER);
|
minusItem = GuiGlobalItems.backgroundItem(Material.BARRIER);
|
||||||
}
|
}
|
||||||
pane.bindItem('-', minusItem);
|
pane.bindItem('-', minusItem);
|
||||||
|
|
||||||
//plus item
|
//plus item
|
||||||
// may do a function to generalise ?
|
|
||||||
GuiItem plusItem;
|
GuiItem plusItem;
|
||||||
if (now < holder.max) {
|
if (now < holder.max) {
|
||||||
int planned = Math.min(holder.max, now + step);
|
int planned = Math.min(holder.max, now + step);
|
||||||
ItemStack item = new ItemStack(Material.GREEN_TERRACOTTA);
|
plusItem = valueEditItem(Material.GREEN_TERRACOTTA, ValueDisplayType.ADD, planned);
|
||||||
ItemMeta meta = item.getItemMeta();
|
|
||||||
assert meta != null;
|
|
||||||
|
|
||||||
meta.setDisplayName("§e" + now + " §f-> §e" + planned + " §r(§a+" + (planned - now) + "§r)");
|
|
||||||
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE));
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
|
|
||||||
plusItem = new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
|
|
||||||
} else {
|
} else {
|
||||||
plusItem = GuiGlobalItems.backgroundItem(Material.BARRIER);
|
plusItem = GuiGlobalItems.backgroundItem(Material.BARRIER);
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +114,7 @@ public class IntSettingsGui extends AbstractSettingGui {
|
||||||
ItemMeta resultMeta = resultPaper.getItemMeta();
|
ItemMeta resultMeta = resultPaper.getItemMeta();
|
||||||
assert resultMeta != null;
|
assert resultMeta != null;
|
||||||
|
|
||||||
resultMeta.setDisplayName("§fValue: §e" + now);
|
resultMeta.setDisplayName("§fValue: §e" + holder.valueDisplayName(ValueDisplayType.CURRENT, now));
|
||||||
resultMeta.setLore(holder.displayLore);
|
resultMeta.setLore(holder.displayLore);
|
||||||
|
|
||||||
resultPaper.setItemMeta(resultMeta);
|
resultPaper.setItemMeta(resultMeta);
|
||||||
|
|
@ -149,7 +132,21 @@ public class IntSettingsGui extends AbstractSettingGui {
|
||||||
}
|
}
|
||||||
pane.bindItem('D', returnToDefault);
|
pane.bindItem('D', returnToDefault);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private GuiItem valueEditItem(Material mat, ValueDisplayType type, int planned) {
|
||||||
|
ItemStack item = new ItemStack(mat);
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
assert meta != null;
|
||||||
|
|
||||||
|
var nowDisplay = holder.valueDisplayName(type, now);
|
||||||
|
var plannedDisplay = holder.valueDisplayName(type, planned);
|
||||||
|
var deltaDisplay = holder.deltaDisplay(type, now, planned);
|
||||||
|
meta.setDisplayName("§e" + nowDisplay + " §f-> §e" + plannedDisplay + " §r(§c" + deltaDisplay + "§r)");
|
||||||
|
|
||||||
|
meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE));
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -389,6 +386,23 @@ public class IntSettingsGui extends AbstractSettingGui {
|
||||||
return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath));
|
return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String valueDisplayName(ValueDisplayType type, int value) {
|
||||||
|
return String.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String deltaDisplay(ValueDisplayType type, int now, int planned) {
|
||||||
|
var delta = planned - now;
|
||||||
|
if(delta < 0) return "§c" + delta;
|
||||||
|
else return "§a+" + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ValueDisplayType {
|
||||||
|
ADD,
|
||||||
|
CURRENT,
|
||||||
|
REMOVE,
|
||||||
|
RESET,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
|
||||||
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
|
||||||
import io.delilaheve.CustomAnvil;
|
import io.delilaheve.CustomAnvil;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.inventory.ItemFlag;
|
import org.bukkit.inventory.ItemFlag;
|
||||||
|
|
@ -18,18 +19,19 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
|
||||||
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MaterialUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class MaterialSelectSettingGui extends MappedElementListConfigGui<Material, GuiItem> {
|
public class MaterialSelectSettingGui extends MappedElementListConfigGui<NamespacedKey, GuiItem> {
|
||||||
|
|
||||||
private final SelectMaterialContainer selector;
|
private final SelectMaterialContainer selector;
|
||||||
private final Gui backGui;
|
private final Gui backGui;
|
||||||
private boolean instantRemove;
|
private boolean instantRemove;
|
||||||
|
|
||||||
private final List<Material> defaultMaterials;
|
private final List<NamespacedKey> defaultMaterials;
|
||||||
private final EnumSet<Material> illegalMaterials;
|
private final Set<NamespacedKey> illegalMaterials;
|
||||||
private final int defaultMaterialHash;
|
private final int defaultMaterialHash;
|
||||||
private int nowMaterialHash;
|
private int nowMaterialHash;
|
||||||
|
|
||||||
|
|
@ -161,8 +163,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
||||||
|
|
||||||
|
|
||||||
// Save setting
|
// Save setting
|
||||||
EnumSet<Material> result = EnumSet.noneOf(Material.class);
|
Set<NamespacedKey> result = new HashSet<>(this.elementGuiMap.keySet());
|
||||||
result.addAll(this.elementGuiMap.keySet());
|
|
||||||
|
|
||||||
if(!this.selector.setSelectedMaterials(result)){
|
if(!this.selector.setSelectedMaterials(result)){
|
||||||
player.sendMessage("§cSomething went wrong while saving the change of value.");
|
player.sendMessage("§cSomething went wrong while saving the change of value.");
|
||||||
|
|
@ -185,8 +186,8 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
||||||
ItemStack cursor = player.getItemOnCursor();
|
ItemStack cursor = player.getItemOnCursor();
|
||||||
|
|
||||||
// Test if cursor material allowed
|
// Test if cursor material allowed
|
||||||
Material cursorMat = cursor.getType();
|
NamespacedKey cursorMat = MaterialUtil.INSTANCE.getCustomType(cursor);
|
||||||
if(cursorMat.isAir()) return;
|
if(MaterialUtil.INSTANCE.isAir(cursorMat)) return;
|
||||||
if(this.illegalMaterials.contains(cursorMat)) return;
|
if(this.illegalMaterials.contains(cursorMat)) return;
|
||||||
|
|
||||||
// Update gui only if item did not exist before.
|
// Update gui only if item did not exist before.
|
||||||
|
|
@ -201,12 +202,12 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemStack createItemForGeneric(Material material) {
|
protected ItemStack createItemForGeneric(NamespacedKey material) {
|
||||||
ItemStack item = new ItemStack(material);
|
ItemStack item = new ItemStack(Objects.requireNonNull(MaterialUtil.INSTANCE.getMatFromKey(material)));
|
||||||
ItemMeta meta = item.getItemMeta();
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
|
||||||
if(meta == null) return item;
|
if(meta == null) return item;
|
||||||
meta.setDisplayName("§a" + CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase()));
|
meta.setDisplayName("§a" + CasedStringUtil.snakeToUpperSpacedCase(material.getKey().toLowerCase()));
|
||||||
meta.setLore(Collections.singletonList("§7Click here to remove this material from the list"));
|
meta.setLore(Collections.singletonList("§7Click here to remove this material from the list"));
|
||||||
meta.addItemFlags(ItemFlag.values());
|
meta.addItemFlags(ItemFlag.values());
|
||||||
|
|
||||||
|
|
@ -216,22 +217,22 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Collection<Material> getEveryDisplayableInstanceOfGeneric() {
|
protected Collection<NamespacedKey> getEveryDisplayableInstanceOfGeneric() {
|
||||||
return this.defaultMaterials;
|
return this.defaultMaterials;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateElement(Material material, GuiItem element) {
|
protected void updateElement(NamespacedKey material, GuiItem element) {
|
||||||
// Nothing happen here I think
|
// Nothing happen here I think
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GuiItem newElementRequested(Material material, GuiItem newItem) {
|
protected GuiItem newElementRequested(NamespacedKey material, GuiItem newItem) {
|
||||||
newItem.setAction(event -> {
|
newItem.setAction(event -> {
|
||||||
if(this.instantRemove){
|
if(this.instantRemove){
|
||||||
removeMaterial(material);
|
removeMaterial(material);
|
||||||
}else {
|
}else {
|
||||||
String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase());
|
String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.getKey().toLowerCase());
|
||||||
|
|
||||||
// Create and show confirm remove gui.
|
// Create and show confirm remove gui.
|
||||||
ConfirmActionGui confirmGui = new ConfirmActionGui(
|
ConfirmActionGui confirmGui = new ConfirmActionGui(
|
||||||
|
|
@ -250,7 +251,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeMaterial(Material material) {
|
private void removeMaterial(NamespacedKey material) {
|
||||||
if(this.elementGuiMap.containsKey(material)){
|
if(this.elementGuiMap.containsKey(material)){
|
||||||
this.nowMaterialHash ^= material.hashCode();
|
this.nowMaterialHash ^= material.hashCode();
|
||||||
setSaveItem();
|
setSaveItem();
|
||||||
|
|
@ -260,18 +261,18 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GuiItem findItemFromElement(Material generic, GuiItem element) {
|
protected GuiItem findItemFromElement(NamespacedKey generic, GuiItem element) {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GuiItem findGuiItemForRemoval(Material generic, GuiItem element) {
|
protected GuiItem findGuiItemForRemoval(NamespacedKey generic, GuiItem element) {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int hashFromMaterialList(List<Material> materialList){
|
private static int hashFromMaterialList(List<NamespacedKey> materialList){
|
||||||
int defaultMaterialHash = 0;
|
int defaultMaterialHash = 0;
|
||||||
for (Material material : materialList) {
|
for (NamespacedKey material : materialList) {
|
||||||
defaultMaterialHash ^= material.hashCode();
|
defaultMaterialHash ^= material.hashCode();
|
||||||
}
|
}
|
||||||
return defaultMaterialHash;
|
return defaultMaterialHash;
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||||
import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
|
import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
|
||||||
import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui;
|
import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui;
|
||||||
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
|
||||||
import xyz.alexcrea.cuanvil.util.AnvilUseType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Clickism
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package xyz.alexcrea.cuanvil.update;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class to check for newer versions of a project hosted on Modrinth.
|
||||||
|
*/
|
||||||
|
public class ModrinthUpdateChecker {
|
||||||
|
|
||||||
|
private static final String API_URL = "https://api.modrinth.com/v2/project/{id}/version";
|
||||||
|
|
||||||
|
private final String projectId;
|
||||||
|
private final String loader;
|
||||||
|
@Nullable
|
||||||
|
private final String minecraftVersion;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Boolean featured = null;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Consumer<Exception> onError = null;
|
||||||
|
@Nullable
|
||||||
|
public Function<String, String> getRawVersion = ModrinthUpdateChecker::getRawVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new update checker for the given project.
|
||||||
|
* This will check the latest version for the given loader and any minecraft version.
|
||||||
|
*
|
||||||
|
* @param projectId the project ID
|
||||||
|
* @param loader the loader
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker(String projectId, String loader) {
|
||||||
|
this(projectId, loader, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new update checker for the given project.
|
||||||
|
* This will check the latest version for the given loader and minecraft version.
|
||||||
|
*
|
||||||
|
* @param projectId the project ID
|
||||||
|
* @param loader the loader
|
||||||
|
* @param minecraftVersion the minecraft version, or null for any version
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker(String projectId, String loader, @Nullable String minecraftVersion) {
|
||||||
|
this.projectId = projectId;
|
||||||
|
this.loader = loader;
|
||||||
|
this.minecraftVersion = minecraftVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the latest version of the project for the given loader and minecraft version
|
||||||
|
* and call the consumer with it.
|
||||||
|
*
|
||||||
|
* @param consumer the consumer
|
||||||
|
*/
|
||||||
|
public void checkVersion(Consumer<String> consumer) {
|
||||||
|
try {
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(prepareURI())
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
|
||||||
|
.thenAcceptAsync(response -> {
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
if(onError != null)
|
||||||
|
onError.accept(new RuntimeException("wrong response status code: " + response.statusCode()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonArray versionsArray = JsonParser.parseString(response.body()).getAsJsonArray();
|
||||||
|
String latestVersion = getLatestVersion(versionsArray);
|
||||||
|
if (latestVersion == null) {
|
||||||
|
if(onError != null)
|
||||||
|
onError.accept(new RuntimeException("latest version is null"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
consumer.accept(latestVersion);
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
if(onError != null) onError.accept(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latest compatible version from the versions array.
|
||||||
|
*
|
||||||
|
* @param versions the versions array
|
||||||
|
* @return the latest compatible version
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
protected String getLatestVersion(JsonArray versions) {
|
||||||
|
return versions.asList().stream().findFirst()
|
||||||
|
.map(JsonElement::getAsJsonObject)
|
||||||
|
.map(version -> version.get("version_number").getAsString())
|
||||||
|
.map(getRawVersion != null ? getRawVersion : (v -> v))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the raw version from a version string.
|
||||||
|
* i.E: "fabric-1.2+1.17.1" -> "1.2"
|
||||||
|
*
|
||||||
|
* @param version the version string
|
||||||
|
* @return the raw version string
|
||||||
|
*/
|
||||||
|
public static String getRawVersion(String version) {
|
||||||
|
if (version.isEmpty()) return version;
|
||||||
|
version = version.replaceAll("^\\D+", "");
|
||||||
|
String[] split = version.split("\\+");
|
||||||
|
return split[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare this request uri based on current parameters.
|
||||||
|
* @return the request uri
|
||||||
|
*/
|
||||||
|
private URI prepareURI() {
|
||||||
|
var url = new StringBuilder(API_URL.replace("{id}", projectId));
|
||||||
|
|
||||||
|
var parameters = prepareParameters();
|
||||||
|
String[] paramArray = new String[parameters.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (Map.Entry<String, String> entry : parameters.entrySet()) {
|
||||||
|
paramArray[i++] = entry.getKey() + '=' + entry.getValue();
|
||||||
|
}
|
||||||
|
url.append('?').append(String.join("&", paramArray));
|
||||||
|
|
||||||
|
return URI.create(url.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the parameters for the version request.
|
||||||
|
*
|
||||||
|
* @return a map of key-value map of the request parameters
|
||||||
|
*/
|
||||||
|
private Map<String, String> prepareParameters(){
|
||||||
|
var parameters = new HashMap<String, String>();
|
||||||
|
|
||||||
|
parameters.put("loaders", List.of(loader).toString());
|
||||||
|
if(minecraftVersion != null) parameters.put("game_versions", List.of(minecraftVersion).toString());
|
||||||
|
if(featured != null) parameters.put("featured", featured.toString());
|
||||||
|
|
||||||
|
parameters.put("include_changelog", "false");
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only get featured or non-featured versions.
|
||||||
|
* Null represent no filter.
|
||||||
|
* @param featured should be restricted to featured version ? default null if not called
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker setFeatured(@Nullable Boolean featured) {
|
||||||
|
this.featured = featured;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called on error calling the api.
|
||||||
|
* @param onError What should happen on error
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker setOnError(@Nullable Consumer<Exception> onError) {
|
||||||
|
this.onError = onError;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the function to get raw version from the modrinth version.
|
||||||
|
* If null provided raw version will act as in the identity function.
|
||||||
|
* @param getRawVersion The function transforming modrinth version to raw version
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public ModrinthUpdateChecker setGetRawVersion(@Nullable Function<String, String> getRawVersion) {
|
||||||
|
this.getRawVersion = getRawVersion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import io.delilaheve.util.ConfigOptions;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
import xyz.alexcrea.cuanvil.config.ConfigHolder;
|
||||||
|
import xyz.alexcrea.cuanvil.util.MetricType;
|
||||||
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil;
|
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil;
|
||||||
import xyz.alexcrea.cuanvil.util.config.LoreEditType;
|
import xyz.alexcrea.cuanvil.util.config.LoreEditType;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,9 @@ public class PluginSetDefault {
|
||||||
|
|
||||||
int nbSet = 0;
|
int nbSet = 0;
|
||||||
|
|
||||||
|
nbSet += trySetDefault(config, METRIC_TYPE, MetricType.AUTO.getValue());
|
||||||
|
nbSet += trySetDefault(config, METRIC_COLLECT_ERROR, true);
|
||||||
|
|
||||||
nbSet += trySetDefault(config, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST);
|
nbSet += trySetDefault(config, CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST);
|
||||||
nbSet += trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST);
|
nbSet += trySetDefault(config, MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST);
|
||||||
nbSet += trySetDefault(config, REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT);
|
nbSet += trySetDefault(config, REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT);
|
||||||
|
|
@ -30,7 +34,7 @@ public class PluginSetDefault {
|
||||||
nbSet += trySetDefault(config, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR);
|
nbSet += trySetDefault(config, ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR);
|
||||||
nbSet += trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR);
|
nbSet += trySetDefault(config, PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR);
|
||||||
nbSet += trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST);
|
nbSet += trySetDefault(config, USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST);
|
||||||
nbSet += trySetDefault(config, DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT);
|
nbSet += trySetDefault(config, PER_COLOR_CODE_PERMISSION, DEFAULT_PER_COLOR_CODE_PERMISSION);
|
||||||
|
|
||||||
// Lore Edit defaults
|
// Lore Edit defaults
|
||||||
for (@NotNull LoreEditType value : LoreEditType.values()) {
|
for (@NotNull LoreEditType value : LoreEditType.values()) {
|
||||||
|
|
@ -57,6 +61,11 @@ public class PluginSetDefault {
|
||||||
|
|
||||||
nbSet += trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER);
|
nbSet += trySetDefault(config, PAPER_EDIT_ORDER, DEFAULT_PAPER_EDIT_ORDER);
|
||||||
|
|
||||||
|
nbSet += trySetDefault(config, DIALOG_RENAME_ENABLED, DEFAULT_DIALOG_RENAME_ENABLED);
|
||||||
|
nbSet += trySetDefault(config, DIALOG_MAX_SIZE, DEFAULT_DIALOG_MAX_SIZE);
|
||||||
|
nbSet += trySetDefault(config, DIALOG_RENAME_USE_PERMISSION, DEFAULT_DIALOG_RENAME_USE_PERMISSION);
|
||||||
|
nbSet += trySetDefault(config, DIALOG_KEEP_USER_TEXT, DEFAULT_DIALOG_KEEP_USER_TEXT);
|
||||||
|
|
||||||
if (nbSet > 0) {
|
if (nbSet > 0) {
|
||||||
CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values.");
|
CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values.");
|
||||||
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
|
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,12 @@ public class UpdateHandler {
|
||||||
if (hadUpdate) {
|
if (hadUpdate) {
|
||||||
CustomAnvil.instance.getLogger().info("Updating Done !");
|
CustomAnvil.instance.getLogger().info("Updating Done !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(current.major() == 1 && current.minor() < 21) {
|
||||||
|
var logger = CustomAnvil.instance.getLogger();
|
||||||
|
logger.warning("Your are running an old version of minecraft (lower than 1.21)");
|
||||||
|
logger.warning("Custom Anvil will stop supporting this version on the first of july 2026");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void finishConfiguration(@Nonnull String newVersion, @Nonnull Set<ConfigHolder> toSave) {
|
private static void finishConfiguration(@Nonnull String newVersion, @Nonnull Set<ConfigHolder> toSave) {
|
||||||
|
|
|
||||||
|
|
@ -15,22 +15,6 @@ public class UpdateUtils {
|
||||||
return Version.fromString(versionString);
|
return Version.fromString(versionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static int[] currentMinecraftVersionArray() {
|
|
||||||
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
|
|
||||||
return UpdateUtils.readVersionFromString(versionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] readVersionFromString(String versionString) {
|
|
||||||
String[] partialVersion = versionString.split("\\.");
|
|
||||||
int[] versionParts = new int[]{0, 0, 0};
|
|
||||||
|
|
||||||
for (int i = 0; i < Math.min(3, partialVersion.length); i++) {
|
|
||||||
versionParts[i] = Integer.parseInt(partialVersion[i]);
|
|
||||||
}
|
|
||||||
return versionParts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addToStringList(FileConfiguration config, String path, String... toAdd) {
|
public static void addToStringList(FileConfiguration config, String path, String... toAdd) {
|
||||||
List<String> groups = new ArrayList<>(config.getStringList(path));
|
List<String> groups = new ArrayList<>(config.getStringList(path));
|
||||||
groups.addAll(Arrays.asList(toAdd));
|
groups.addAll(Arrays.asList(toAdd));
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue