Compare commits

...

23 commits

Author SHA1 Message Date
8447233b1e
Merge remote-tracking branch 'origin/v1.x.x' into v1.x.x 2026-06-22 03:12:11 +02:00
eb2e7b3abb
allow enchanted book for super enchant 2026-06-22 03:12:04 +02:00
7f7f049b7b
Update COMPATIBILITY.md 2026-06-22 01:01:45 +02:00
37e8ca7da9
update excellentenchants 2026-06-20 23:49:03 +02:00
95d3cf3228
update nightexpress 2026-06-20 23:43:01 +02:00
178b372255
paper mns use getter/setter no property access [ci skip] 2026-06-20 14:57:12 +02:00
106cd53b02
mark 26.2.x as supported on modrinth & hangar [ci skip] 2026-06-20 03:28:07 +02:00
950bad2168
versions bump 2026-06-19 20:31:43 +02:00
bc9cbe0b44
fix and simplify xp handling
- Fix xp limit not being respected
- Fix player xp not being check causing error
2026-06-19 20:29:10 +02:00
9d616d2fd0
remove use of legacy currentMinecraftVersionArray 2026-06-17 02:15:34 +02:00
f82ccfa07e
make Version work with experimental 26.1 paper build 2026-06-17 02:15:04 +02:00
cff94a2c5a
better thanks and put names in compatibility note [ci skip] 2026-06-16 04:05:17 +02:00
4b5133c872
markdown issue² 2026-06-16 03:49:32 +02:00
98d359f59f
markdown issue [skip ci] 2026-06-16 03:49:16 +02:00
96754fd260
better readme [skip ci] 2026-06-16 03:48:47 +02:00
b92b762551
overdid \ [skip ci] 2026-06-16 03:33:03 +02:00
c064e4b1e1
forgot \ [skip ci] 2026-06-16 03:32:46 +02:00
fc33b6fbd5
Update README.md 2026-06-16 03:27:10 +02:00
29e08fe29b
fix double space issue [ci skip] 2026-06-16 03:17:53 +02:00
151666fd21
better excellent enchant fake event [skip ci] 2026-06-16 03:10:34 +02:00
593527241a
fix bugged unit repair & version bump 2026-06-16 02:57:41 +02:00
3578322686
Update README.md 2026-06-13 15:22:39 +02:00
12ec4e1f54
update faststats
fix a potential plugin issue with disabling faststat in a certain way and fix potential submission on first run
2026-06-13 15:14:33 +02:00
20 changed files with 125 additions and 137 deletions

View file

@ -26,7 +26,7 @@ jobs:
contents: write contents: write
env: env:
MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x", "1.21.x", "26.1.x"]' 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"]' MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]'
steps: steps:
@ -157,7 +157,7 @@ jobs:
webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }} webhook-url: ${{ secrets.RELEASE_WEBHOOK_URL }}
content: | content: |
${{ github.event.release.prerelease == false && '<@&1338546156325568642>' || '<@&1352296092989001768>' }} ${{ 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) # 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. -# note: automated release. spigot is not uploaded yet.
${{ github.event.release.body }} ${{ github.event.release.body }}

View file

@ -6,54 +6,55 @@ This is cannot be fixed on geyser or my side.
Here is various plugins that had issues with CustomAnvil Here is various plugins that had issues with CustomAnvil
where efforts was made for compatibility and should be working right: where efforts was made for compatibility and should be working right:
some of them are cool I recommend checking them out ! some if not all of them are cool ! I recommend checking them out !
## Supported By CustomAnvil ## Supported By CustomAnvil
These plugins have compatibility handled by custom anvil. seek help on custom anvil and do not bother these developers These plugins have compatibility handled by custom anvil. seek help on custom anvil and do not bother these developers
#### Enchantment Plugins #### Enchantment Plugins
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/): - [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/) by NightExpress:
Use ExcellentEnchants item type 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/): - [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. 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 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/): - [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 Support by Custom Anvil but still experimental. Automatic configuration. Plugin is not actively developed anymore
- [SuperEnchants](https://modrinth.com/plugin/superenchants) - [SuperEnchants](https://modrinth.com/plugin/superenchants) by Aznos:
Use SuperEnchant restrictions system but new restriction can be added in custom anvil Use SuperEnchant restrictions system but new restriction can be added in custom anvil
#### Custom Items Plugins #### Custom Items Plugins
Custom Items support is considered unstable. If you find issue please report it ! 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/) - [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 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/) - [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 Need to fix unit item not working completly correctly as in can't have twice same base item
#### Anvil Mechanics Plugins #### Anvil Mechanics Plugins
- [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) - [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) 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/) - [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) For bag upgrade and skin via anvil. (version >= 1.31.0)
- [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi) - [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi) by ArtillexStudios
For its anvil inventory usage For its anvil inventory usage
- [ToolsStats](https://modrinth.com/project/oBZj9E15) - [ToolsStats](https://modrinth.com/project/oBZj9E15) by Valorless
For token application using anvil For token application using anvil
### Known Partially Incompatible ### Known Partially Incompatible
- [UberEnchant](https://modrinth.com/plugin/uberenchant) - [UberEnchant](https://modrinth.com/plugin/uberenchant) by coltonj96
Anvil handling as they are doing something similar to CustomAnvil. Anvil handling as they are doing something similar to CustomAnvil.
It is by no mean there faults and I recomend checking them out 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/) - [AdvencedEnchantments](https://ae.advancedplugins.net/) by Advanced Plugins
Paid plugin I do not own as I did not get commissioned for support. 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 may be able to use api but cannot test on my side

View file

@ -5,7 +5,7 @@ Thanks for all the contributors of bukkit, spigot, the paper team and the advent
Thanks JetBrain for making IntelliJ Thanks JetBrain for making IntelliJ
### Dependencies ### Dependencies
Here dependencies are used by custom anvil These dependencies (or a modified version of) are used by custom anvil
- [IF](https://github.com/stefvanschie/IF) an inventory framework by stefvanschie - [IF](https://github.com/stefvanschie/IF) an inventory framework by stefvanschie
- [Mockbukkit](https://github.com/MockBukkit/MockBukkit) for unit testing - [Mockbukkit](https://github.com/MockBukkit/MockBukkit) for unit testing
- [CentralPortalPlus](https://github.com/lalakii/central-portal-plus) by lalakii - [CentralPortalPlus](https://github.com/lalakii/central-portal-plus) by lalakii
@ -17,23 +17,18 @@ Here dependencies are used by custom anvil
- [ModrinthUpdateChecker](https://github.com/Clickism/ModrinthUpdateChecker) by Clickism and thanks to the modrinth team - [ModrinthUpdateChecker](https://github.com/Clickism/ModrinthUpdateChecker) by Clickism and thanks to the modrinth team
### Compatibility ### Compatibility
Here is to credits all the author of plugins Thanks to all the cool creator making the minecraft plugin's ecosystem works ! \
It partially repeat the the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) See [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) for details
- Big Thanks for H7KZ for [Disenchantment](https://github.com/H7KZ/Disenchantment)
- [Enchantment²](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/) by Athlaeos but especially, Big Thanks for H7KZ maker of [Disenchantment](https://github.com/H7KZ/Disenchantment)
- [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
- [ExcellentEnchants](https://www.spigotmc.org/resources/excellentenchants-%E2%AD%90-75-vanilla-like-enchantments.61693/) by NightExpress
- [HavenBags](https://www.spigotmc.org/resources/havenbags-shulker-like-player-bound-bags-1-17-1-21-4.110420/) by hyperdefined
- [AxPlayerWarp](https://modrinth.com/project/QDJHDKvi) by ArtillexStudios
- [ToolsStats](https://modrinth.com/project/oBZj9E15) by Valorless
### Special Thanks ### Special Thanks
Thanks for Microsoft leading me into using a better operating system \
Thanks for all the users trying my plugin for these niche use cases Thanks for all the users trying my plugin for these niche use cases
and for reporting issues and giving ideas ! , reporting issues and giving ideas !
Thanks coltonj96 for [UberEnchant](https://modrinth.com/plugin/uberenchant). 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 ! \ 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 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 ! *

View file

@ -1,8 +1,6 @@
# 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)
### Download Locations: ### Download Locations:
@ -16,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.
@ -25,8 +23,14 @@ 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 # 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
@ -44,17 +48,22 @@ ca.config.edit: Allow administrator to edit the plugin's config in game
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# 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
run `customanvil help` to get information about available commands (need permissions to use them) run `/customanvil help` to get information about available commands \
this only show subcommands you have permission for
### Supported Plugins ### Supported Plugins
See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md) See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x/COMPATIBILITY.md)
@ -63,13 +72,10 @@ See the [Compatibility list](https://github.com/alexcrea/CustomAnvil/blob/v1.x.x
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.18 to latest marked as supported do not need any ProtocoLib dependency. \ spigot version 1.18 to 1.21.11 do not need any ProtocoLib dependency. (26.1.0 or above requires it) \
Any recent paper version also are supported for this feature. 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. But you should wait for update for new version containing new enchantable item or new enchantments if any of this got added.
Other version need ProtocoLib enabled on your server for this feature. \ Else it is, likely, fine to use the current version you are ussing on a new paper version
You can also wait for an update of the plugin to support a newer version.
Please note that 1.16.5 to 1.17.1 are not officially supported. Run at your own risk.
### 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) \
@ -100,3 +106,6 @@ Credits and thanks can be seen [here](https://github.com/alexcrea/CustomAnvil/bl
### 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)

View file

@ -22,7 +22,7 @@ plugins {
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.17.0" version = "1.17.5"
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true" val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
@ -58,7 +58,7 @@ dependencies {
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
// fast stats // fast stats
implementation("dev.faststats.metrics:bukkit:0.25.1") 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")

View file

@ -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)

View file

@ -9,5 +9,5 @@ kotlin.daemon.jvmargs=-Xmx8G
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 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 # list of version for hangar release
paperVersion=1.18-26.1.2 paperVersion=1.18-26.2

View file

@ -12,6 +12,6 @@ repositories {
dependencies { dependencies {
// Excellent Enchant // Excellent Enchant
compileOnly("su.nightexpress.excellentenchants:Core:5.4.1") compileOnly("su.nightexpress.excellentenchants:Core:5.4.3")
compileOnly("su.nightexpress.nightcore:main:2.14.1") compileOnly("su.nightexpress.nightcore:main:2.16.2")
} }

View file

@ -24,8 +24,8 @@ class PaperPacketManager : PacketManagerBase(), PacketManager {
sendedAbilities.mayfly = playerAbilities.mayfly sendedAbilities.mayfly = playerAbilities.mayfly
sendedAbilities.instabuild = instantBuild sendedAbilities.instabuild = instantBuild
sendedAbilities.mayBuild = playerAbilities.mayBuild sendedAbilities.mayBuild = playerAbilities.mayBuild
sendedAbilities.flyingSpeed = playerAbilities.flyingSpeed sendedAbilities.setFlyingSpeed(playerAbilities.getFlyingSpeed())
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed sendedAbilities.setWalkingSpeed(playerAbilities.getWalkingSpeed())
} }
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities) val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet) nmsPlayer.connection.send(packet)

View file

@ -1,12 +0,0 @@
package xyz.alexcrea.cuanvil.util
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
object ModernPrepareAnvilCreator {
fun createPrepareAnvil(view: InventoryView, item: ItemStack?): PrepareAnvilEvent {
return PrepareAnvilEvent(view as AnvilView, item)
}
}

View file

@ -5,6 +5,7 @@ import com.maddoxh.superEnchants.enchants.EnchantManager;
import com.maddoxh.superEnchants.items.EnchantApplicator; import com.maddoxh.superEnchants.items.EnchantApplicator;
import com.maddoxh.superEnchants.items.EnchantReader; import com.maddoxh.superEnchants.items.EnchantReader;
import com.maddoxh.superEnchants.util.ConflictChecker; import com.maddoxh.superEnchants.util.ConflictChecker;
import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -68,6 +69,8 @@ public class CASuperEnchantEnchantment extends CAEnchantmentBase implements Addi
@Override @Override
public boolean isItemConflict(@NotNull Map<CAEnchantment, Integer> enchantments, @NotNull NamespacedKey itemType, @NotNull ItemStack item) { 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()); return !enchant.canApplyTo(item.getType());
} }
} }

View file

@ -283,15 +283,9 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
lore.add("§7If the player do not have the required xp level, the action will not be completable."); lore.add("§7If the player do not have the required xp level, the action will not be completable.");
if(!this.packetManager.getCanSetInstantBuild()){ if(!this.packetManager.getCanSetInstantBuild()){
if(MinecraftVersionUtil.INSTANCE.isTooNewForSpigot()){
lore.add(""); lore.add("");
lore.add("§4/!\\§cCaution§4/!\\ §cYou need ProtocoLib installed and working or a paper server."); 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.");
} else {
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("§cCurrently ProtocoLib is not detected.");
}
} }
String[] loreAsArray = new String[lore.size()]; String[] loreAsArray = new String[lore.size()];

View file

@ -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));

View file

@ -21,7 +21,11 @@ public record Version(int major, int minor, int patch) {
int[] versionParts = new int[]{0, 0, 0}; int[] versionParts = new int[]{0, 0, 0};
for (int i = 0; i < Math.min(3, partialVersion.length); i++) { for (int i = 0; i < Math.min(3, partialVersion.length); i++) {
try {
versionParts[i] = Integer.parseInt(partialVersion[i]); versionParts[i] = Integer.parseInt(partialVersion[i]);
} catch (NumberFormatException e) {
break;
}
} }
return new Version(versionParts[0], versionParts[1], versionParts[2]); return new Version(versionParts[0], versionParts[1], versionParts[2]);
} }

View file

@ -1,6 +1,8 @@
package xyz.alexcrea.cuanvil.anvil package xyz.alexcrea.cuanvil.anvil
import io.delilaheve.util.ConfigOptions
import java.math.BigDecimal import java.math.BigDecimal
import kotlin.math.min
import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier
open class AnvilCost { open class AnvilCost {
@ -30,6 +32,21 @@ open class AnvilCost {
return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe
} }
fun filteredXpCost(ignoreRules: Boolean = false): Int {
val original = asXpCost()
// Test repair cost limit
return if (
!ignoreRules &&
!ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost
) {
min(original, ConfigOptions.maxAnvilCost)
} else {
original
}
}
open fun asMonetaryCost(): BigDecimal { open fun asMonetaryCost(): BigDecimal {
// multiply by per use type multipliers // multiply by per use type multipliers
return BigDecimal(generic) return BigDecimal(generic)

View file

@ -6,29 +6,29 @@ object MinecraftVersionUtil {
val craftbukkitVersion: String? val craftbukkitVersion: String?
get() { get() {
val versionParts = UpdateUtils.currentMinecraftVersionArray() val version = UpdateUtils.currentMinecraftVersion()
if (versionParts[0] != 1) return null if (version.major != 1) return null
return when (versionParts[1]) { return when (version.minor) {
17 -> when (versionParts[2]) { 17 -> when (version.patch) {
0, 1 -> "1_17R1" 0, 1 -> "1_17R1"
else -> null else -> null
} }
18 -> when (versionParts[2]) { 18 -> when (version.patch) {
0, 1 -> "1_18R1" 0, 1 -> "1_18R1"
2 -> "1_18R2" 2 -> "1_18R2"
else -> null else -> null
} }
19 -> when (versionParts[2]) { 19 -> when (version.patch) {
0, 1, 2 -> "1_19R1" 0, 1, 2 -> "1_19R1"
3 -> "1_19R2" 3 -> "1_19R2"
4 -> "1_19R3" 4 -> "1_19R3"
else -> null else -> null
} }
20 -> when (versionParts[2]) { 20 -> when (version.patch) {
0, 1 -> "1_20R1" 0, 1 -> "1_20R1"
2 -> "1_20R2" 2 -> "1_20R2"
3, 4 -> "1_20R3" 3, 4 -> "1_20R3"
@ -36,7 +36,7 @@ object MinecraftVersionUtil {
else -> null else -> null
} }
21 -> when (versionParts[2]) { 21 -> when (version.patch) {
0, 1 -> "1_21R1" 0, 1 -> "1_21R1"
2, 3 -> "1_21R2" 2, 3 -> "1_21R2"
4 -> "1_21R3" 4 -> "1_21R3"
@ -52,8 +52,7 @@ object MinecraftVersionUtil {
} }
val isTooNewForSpigot: Boolean get() { val isTooNewForSpigot: Boolean get() {
val versionParts = UpdateUtils.currentMinecraftVersionArray() return UpdateUtils.currentMinecraftVersion().major != 1
return versionParts[0] != 1
} }
} }

View file

@ -38,8 +38,8 @@ object PacketManagerSelector {
// Reobfuscated packet manager for spigot or paper as it remap // Reobfuscated packet manager for spigot or paper as it remap
private val reobfPacketManager: PacketManagerBase? private val reobfPacketManager: PacketManagerBase?
get() { get() {
val versionParts = UpdateUtils.currentMinecraftVersionArray() val versionParts = UpdateUtils.currentMinecraftVersion()
if (versionParts[0] != 1) return null if (versionParts.major != 1) return null
try { try {
val clazz = Class.forName("xyz.alexcrea.cuanvil.dependency.packet.versions." + val clazz = Class.forName("xyz.alexcrea.cuanvil.dependency.packet.versions." +
@ -47,7 +47,7 @@ object PacketManagerSelector {
val manager = clazz.getConstructor().newInstance() val manager = clazz.getConstructor().newInstance()
return manager as PacketManagerBase return manager as PacketManagerBase
} catch (e: ClassNotFoundException) { } catch (_: ClassNotFoundException) {
return null return null
} }
} }

View file

@ -13,7 +13,7 @@ import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment
import xyz.alexcrea.cuanvil.util.ModernPrepareAnvilCreator import java.lang.reflect.Constructor
import java.lang.reflect.Method import java.lang.reflect.Method
import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry
import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant
@ -118,6 +118,8 @@ class ExcellentEnchantsDependency {
private lateinit var handleRechargeMethod: Method private lateinit var handleRechargeMethod: Method
private lateinit var handleCombineMethod: Method private lateinit var handleCombineMethod: Method
private val prepareAnvilConstructor = PrepareAnvilEvent::class.java.constructors.first() as Constructor<PrepareAnvilEvent>
fun redirectListeners() { fun redirectListeners() {
val toUnregister = ArrayList<RegisteredListener>() val toUnregister = ArrayList<RegisteredListener>()
// get required PrepareAnvilEvent listener // get required PrepareAnvilEvent listener
@ -224,12 +226,8 @@ class ExcellentEnchantsDependency {
val first: ItemStack = treatInput(event.leftItem) val first: ItemStack = treatInput(event.leftItem)
val second: ItemStack = treatInput(event.rightItem) val second: ItemStack = treatInput(event.rightItem)
val fakeEvent: PrepareAnvilEvent = try { val fakeEvent = prepareAnvilConstructor.newInstance(event.view, result)
//TODO remove this on legacy removal
PrepareAnvilEvent(event.view, result)
} catch (_: NoSuchMethodError) {
ModernPrepareAnvilCreator.createPrepareAnvil(event.view, result)
}
handleCombineMethod.invoke(this.usedAnvilListener, fakeEvent, first, second, result) handleCombineMethod.invoke(this.usedAnvilListener, fakeEvent, first, second, result)
event.result = fakeEvent.result event.result = fakeEvent.result

View file

@ -121,7 +121,7 @@ class AnvilResultListener : Listener {
view, inventory, player, view, inventory, player,
leftItem, rightItem leftItem, rightItem
) )
if (unitRepairResult.isEmpty()) { if (!unitRepairResult.isEmpty()) {
onUnitRepairExtract( onUnitRepairExtract(
rightItem, event, player, inventory, rightItem, event, player, inventory,
unitRepairResult unitRepairResult
@ -270,13 +270,19 @@ class AnvilResultListener : Listener {
} }
private fun tryRemoveCost(player: Player, cost: AnvilCost): Boolean { private fun tryRemoveCost(player: Player, result: AnvilResult): Boolean {
if (player.gameMode == GameMode.CREATIVE) return true if (player.gameMode == GameMode.CREATIVE) return true
val cost = result.cost
if (cost.isMonetary) { if (cost.isMonetary) {
val result = EconomyManager.economy!!.remove(player, cost.asMonetaryCost()) val result = EconomyManager.economy!!.remove(player, cost.asMonetaryCost())
if (!result) return false if (!result) return false
} else { } else {
player.level -= cost.asXpCost() val xpCost = cost.filteredXpCost()
if (xpCost > AnvilXpUtil.maximumXpCost(result.ignoreXpRules)) return false
if (player.level < xpCost) return false
player.level -= xpCost
} }
return true return true
@ -308,7 +314,7 @@ class AnvilResultListener : Listener {
// If not creative middle click... // If not creative middle click...
if (event.click != ClickType.MIDDLE) { if (event.click != ClickType.MIDDLE) {
if (!tryRemoveCost(player, cost)) return false if (!tryRemoveCost(player, result)) return false
// We remove what should be removed // We remove what should be removed
if (leftItem != null) leftItem.amount -= leftRemoveCount if (leftItem != null) leftItem.amount -= leftRemoveCount

View file

@ -22,7 +22,6 @@ import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.util.AnvilTitleUtil import xyz.alexcrea.cuanvil.util.AnvilTitleUtil
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
import kotlin.math.min
object AnvilXpUtil { object AnvilXpUtil {
@ -42,7 +41,15 @@ object AnvilXpUtil {
cost.isMonetary = true cost.isMonetary = true
setAnvilPrice(inventory, view, player, cost) setAnvilPrice(inventory, view, player, cost)
} else } else
setAnvilInvXp(inventory, view, player, cost.asXpCost(), ignoreRules) setAnvilInvXp(inventory, view, player, cost.filteredXpCost(ignoreRules), ignoreRules)
}
fun maximumXpCost(ignoreRules: Boolean = false): Int {
return if (ConfigOptions.doRemoveCostLimit || ignoreRules) {
Int.MAX_VALUE
} else {
ConfigOptions.maxAnvilCost + 1
}
} }
/** /**
@ -55,28 +62,11 @@ object AnvilXpUtil {
anvilCost: Int, anvilCost: Int,
ignoreRules: Boolean = false ignoreRules: Boolean = false
) { ) {
val maximumRepairCost = maximumXpCost(ignoreRules)
// Test repair cost limit
val finalAnvilCost = if (
!ignoreRules &&
!ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost
) {
min(anvilCost, ConfigOptions.maxAnvilCost)
} else {
anvilCost
}
val maximumRepairCost =
if (ConfigOptions.doRemoveCostLimit || ignoreRules) {
Int.MAX_VALUE
} else {
ConfigOptions.maxAnvilCost + 1
}
// Try first just in case another plugin, or the test need this // Try first just in case another plugin, or the test need this
inventory.maximumRepairCost = maximumRepairCost inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = finalAnvilCost inventory.repairCost = anvilCost
// TODO for 2.x.x use anvil view & set directly there // TODO for 2.x.x use anvil view & set directly there
/* Because Minecraft likes to have the final say in the repair cost displayed /* Because Minecraft likes to have the final say in the repair cost displayed
@ -87,15 +77,15 @@ object AnvilXpUtil {
) { ) {
// retry after a tick // retry after a tick
inventory.maximumRepairCost = maximumRepairCost inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = finalAnvilCost inventory.repairCost = anvilCost
// TODO for 2.x.x use anvil view & set directly there // TODO for 2.x.x use anvil view & set directly there
if (player !is Player) return@scheduleOnEntity if (player !is Player) return@scheduleOnEntity
if (player.gameMode != GameMode.CREATIVE) { if (player.gameMode != GameMode.CREATIVE) {
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) && val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
(finalAnvilCost >= 40) && (anvilCost >= 40) &&
finalAnvilCost < inventory.maximumRepairCost anvilCost < inventory.maximumRepairCost
DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive) DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive)
} }