This commit is contained in:
alexcrea 2026-06-22 01:45:27 +00:00 committed by GitHub
commit d1c25a0f1b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
96 changed files with 403 additions and 2569 deletions

View file

@ -9,9 +9,9 @@ name: Java CI with Gradle
on:
push:
branches: [ "v1.x.x", "v2.x.x" ]
branches: [ "v1.x.x", "v2.x.x", "v3.x.x" ]
pull_request:
branches: [ "v1.x.x", "v2.x.x" ]
branches: [ "v1.x.x", "v2.x.x", "v3.x.x" ]
release:
types: [published]
@ -26,7 +26,7 @@ jobs:
contents: write
env:
MODRINTH_VERSIONS: '["1.18.x", "1.19.x", "1.20.x", "1.21.x", "26.1.x", "26.2.x"]'
MODRINTH_VERSIONS: '["1.21.x", "26.1.x", "26.2.x"]'
MODRINTH_PLATFORMS: '["spigot", "paper", "purpur", "folia"]'
steps:

View file

@ -72,10 +72,9 @@ 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. \
By how the minecraft client work: price above 40 can only be displayed green, even if the player does not own enough experience level.
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.
But you should wait for update for new version containing new enchantable item or new enchantments if any of this got added.
Else it is, likely, fine to use the current version you are ussing on a new paper version
You do not need Protocolib unless you are using spigot above in 26.1 or above \
But you should wait for update or announcement for new version containing new enchantable item or new enchantments.
### For custom enchantment plugin developers
For information about the API, please refer to [the Wiki](https://github.com/alexcrea/CustomAnvil/wiki) \

View file

@ -22,7 +22,7 @@ plugins {
}
group = "xyz.alexcrea"
version = "1.17.5"
version = "2.0.0"
val isDevBuild = System.getenv("SMALL_COMMIT_HASH") != null
val isPreRelease = System.getenv("IS_GITHUB_PRERELEASE") == "true"
@ -55,7 +55,7 @@ val reobfNMS = providers.gradleProperty("subprojects.reobfnms")
dependencies {
// Spigot api
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
// fast stats
implementation("dev.faststats.metrics:bukkit:0.27.0")

View file

@ -1,6 +0,0 @@
### Default Plugin's Configurations For 1.18 to 1.20.6
- [config.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/config.yml)
- [enchant_conflict.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/enchant_conflict.yml)
- [item_groups.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/item_groups.yml)
- [unit_repair_item.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/unit_repair_item.yml)
- [custom_recipes.yml](https://github.com/alexcrea/CustomAnvil/blob/master/defaultconfigs/1.18/custom_recipes.yml)

View file

@ -1,466 +0,0 @@
#
# It is recommended that you use /configanvil to edit theses config.
# 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.
#
# In other words:
# For any anvil cost greater than limit_repair_value, Cost will be set to limit_repair_value.
limit_repair_cost: false
# Max cost value the Anvil can get to.
#
# Valid values include 0 to 1000.
# Cost will be displayed as "Too Expensive":
# - If Cost is above 39
# - And replace_too_expensive is disabled (false)
limit_repair_value: 39
# Whether the anvil's cost limit should be removed entirely.
#
# The anvil will still visually display "Too Expensive" if "replace_too_expensive" is disabled
# However, the action will be completable if xp requirement is meet.
remove_repair_limit: false
# Whenever anvil cost is above 39 should display the true price and not "Too Expensive".
#
# However, when bypassing "Too Expensive", anvil price will be displayed as Green.
# If the action is not completable, the cost will still be displayed as "Too expensive".
# That mean you also need to change other settings like remove_repair_limit or limit_repair_cost.
#
# Require ProtocoLib.
replace_too_expensive: false
# XP Level amount added to the anvil when the item is repaired by another item of the same type
#
# Valid values include 0 to 1000
item_repair_cost: 2
# XP Level amount added to the anvil when the item is renamed
#
# Valid values include 0 to 1000
item_rename_cost: 1
# XP Level amount added to the anvil when the item is repaired by an "unit"
# For example: a Diamond on a Diamond Sword
# What's considered unit for what can be edited on the unit repair configuration.
#
# Valid values include 0 to 1000
unit_repair_cost: 1
# XP Level amount added to the anvil when a sacrifice enchantment
# conflict with one of the left item enchantment
#
# Valid values include 0 to 1000
sacrifice_illegal_enchant_cost: 1
# Allow using color code and hexadecimal color.
#
# Color code are prefixed by "&" and hexadecimal color by "#".
# Color code will not be applied if it colors nothing. "&&" can be used to write "&".
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
allow_color_code: false
allow_hexadecimal_color: 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.
#
# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color.
permission_needed_for_color: true
# Xp cost if the player use color in the items name on rename.
#
# Valid values include 0 to 1000.
use_of_color_cost: 0
# 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
#
# This feature only work on paper 1.21.7 or later
#
# 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
#
# Enchantments not listed here will use the value of default_limit
#
# Overrides provided default from aqua_affinity to depth_strider won't change effect with extra levels
#
# Valid range of 0 - 255 for each enchantment
# -1 mean keep default
enchant_limits:
minecraft:aqua_affinity: 1
minecraft:binding_curse: 1
minecraft:channeling: 1
minecraft:flame: 1
minecraft:infinity: 1
minecraft:mending: 1
minecraft:multishot: 1
minecraft:silk_touch: 1
minecraft:vanishing_curse: 1
minecraft:depth_strider: 3 # anything more than 3 is treated as 3 by the game
minecraft:protection: 4
minecraft:fire_protection: 4
minecraft:blast_protection: 4
minecraft:projectile_protection: 4
minecraft:feather_falling: 4
minecraft:thorns: 3
minecraft:respiration: 3
minecraft:sharpness: 5
minecraft:smite: 5
minecraft:bane_of_arthropods: 5
minecraft:knockback: 2
minecraft:fire_aspect: 2
minecraft:looting: 3
minecraft:sweeping: 3
minecraft:sweeping_edge: 3
minecraft:efficiency: 5
minecraft:unbreaking: 3
minecraft:fortune: 3
minecraft:power: 5
minecraft:punch: 2
minecraft:luck_of_the_sea: 3
minecraft:lure: 3
minecraft:frost_walker: 2
minecraft:impaling: 5
minecraft:riptide: 3
minecraft:loyalty: 3
minecraft:piercing: 4
minecraft:quick_charge: 3
minecraft:soul_speed: 3
minecraft:swift_sneak: 3
# Multipliers used to calculate the enchantment's value in repair/combining
#
# Values here are pulled from the fandom wiki:
# https://minecraft.fandom.com/wiki/Anvil_mechanics#Costs_for_combining_enchantments
#
# If an enchantment is missing values here, or is less than 0, it will default to 0
#
# Calculated as: [Enchantment lvl] * [multiplier]
#
# With default values protection 4 would have a value of 4 when
# coming from either a book (4 * 1) or an item (4 * 1)
enchant_values:
minecraft:aqua_affinity:
item: 4
book: 2
minecraft:bane_of_arthropods:
item: 2
book: 1
minecraft:binding_curse:
item: 8
book: 4
minecraft:blast_protection:
item: 4
book: 2
minecraft:channeling:
item: 8
book: 4
minecraft:depth_strider:
item: 4
book: 2
minecraft:efficiency:
item: 1
book: 1
minecraft:flame:
item: 4
book: 2
minecraft:feather_falling:
item: 2
book: 1
minecraft:fire_aspect:
item: 4
book: 2
minecraft:fire_protection:
item: 2
book: 1
minecraft:fortune:
item: 4
book: 2
minecraft:frost_walker:
item: 4
book: 2
minecraft:impaling:
item: 4
book: 2
minecraft:infinity:
item: 8
book: 4
minecraft:knockback:
item: 2
book: 1
minecraft:looting:
item: 4
book: 2
minecraft:loyalty:
item: 1
book: 1
minecraft:luck_of_the_sea:
item: 4
book: 2
minecraft:lure:
item: 4
book: 2
minecraft:mending:
item: 4
book: 2
minecraft:multishot:
item: 4
book: 2
minecraft:piercing:
item: 1
book: 1
minecraft:power:
item: 1
book: 1
minecraft:projectile_protection:
item: 2
book: 1
minecraft:protection:
item: 1
book: 1
minecraft:punch:
item: 4
book: 2
minecraft:quick_charge:
item: 2
book: 1
minecraft:respiration:
item: 4
book: 2
minecraft:riptide:
item: 4
book: 2
minecraft:silk_touch:
item: 8
book: 4
minecraft:sharpness:
item: 1
book: 1
minecraft:smite:
item: 2
book: 1
minecraft:soul_speed:
item: 8
book: 4
minecraft:swift_sneak:
item: 8
book: 4
minecraft:sweeping:
item: 4
book: 2
minecraft:sweeping_edge:
item: 4
book: 2
minecraft:thorns:
item: 8
book: 4
minecraft:unbreaking:
item: 2
book: 1
minecraft:vanishing_curse:
item: 8
book: 4
# Disable enchantment merging for level above the set value
# Enchantment merging is when, for example, 2 unbreaking II book combine to give sharpness III
# But Enchantment above this value can still be applied. following the previous example, we could still apply a unbreaking III book to a sword
# 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.
disable-merge-over:
# Sharpness is set to -1. it equivalent to it not being set to anything (and work as vanilla on default configuration)
minecraft:sharpness: -1
# If uncommented. 2 unbreaking II book would not give an unbreaking III book. but unbreaking III book can still be applied
#minecraft:unbreaking: 2
# The maximum number of enchantment an item can get. -1 for infinity
# Use eco enchant enchant_limit if present by default unless "default" is not equal to -1
enchantment_count_limit:
default: -1
# Limit for specific items. example bellow is an example with stick
# Per item enchantment limit override eco enchant enchant_limit and default limit
items:
stick: -1
# Settings for lore modification
lore_edit:
book_and_quil:
# Permission is ca.lore_edit.book
use_permission: true
append:
# If adding lore using book & quil is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Cost used for every lore line added
per_line_cost: 0
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If adding the lore consume the book & quil
do_consume: false
# Allow using color code and hexadecimal color when editing lore via book & quil
#
# Color code are prefixed by "&" and hexadecimal color by "#"
# Color code will not be applied if it colors nothing. "&&" can be used to write "&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
#
# Note that currently minimessage would disable hex code when adding color
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
remove:
# If removing lore using book & quil is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Cost used for every lore line removed
per_line_cost: 0
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If removing the lore consume the book & quil
do_consume: false
# Cost of replacing colors
remove_color_cost: 0
# Allowed some color and tags to be reverted to plain text
# Custom anvil will prioritise format that result is a smaller resulting text
# Note that not allowing certain format will lead to some lost of color or tags.
# If configuration are exact as append appending this book should result in the exact same color
#
# Color code will be prefixed by "&" and hexadecimal color by "#".
# If color code is allowed, "&" in the text will get converted to "&&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
paper:
# Permission is ca.lore_edit.paper
use_permission: true
# what order should the lines should get added/removed (start/end, if invalid or not present will be end)
order: end
append_line:
# If adding lore line using paper is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If adding the lore line consume the paper
do_consume: false
# Allow using color code and hexadecimal color when editing lore via book & quil
#
# Color code are prefixed by "&" and hexadecimal color by "#"
# Color code will not be applied if it colors nothing. "&&" can be used to write "&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
#
# Note that currently minimessage would disable hex code when adding color
allow_color_code: true
allow_hexadecimal_color: false
allow_minimessage: true
color_use_cost: 0
remove_line:
# If removing lore line using paper is enabled
enabled: false
# Cost used every time
fixed_cost: 1
# Use left item vanilla cost penalty if any
shared_increase: false
# Increase shared left item cost penalty
shared_additive: false
# If removing the lore line consume the paper
do_consume: false
# Cost of replacing colors
remove_color_cost: 0
# Allowed some color and tags to be reverted to plain text
# Custom anvil will prioritise format that result is a smaller resulting text
# Note that not allowing certain format will lead to some lost of color or tags.
# If configuration are exact as append appending this paper should result in the exact same color
#
# Color code will be prefixed by "&" and hexadecimal color by "#".
# If color code is allowed, "&" in the text will get converted to "&&"
# For minimessage see minimessage formating https://docs.papermc.io/adventure/minimessage/format/
allow_color_code: true
allow_hexadecimal_color: false
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
debug_log: false
# Whether to show verbose debug logging
debug_log_verbose: false
configVersion: 1.11.0

View file

@ -1,5 +0,0 @@
# ----------------------------------------------------
# This config file is to store custom craft
# It is recommended to use the in game config editor for this configuration.
# /customanvilconfig With ca.config.edit permission
# ----------------------------------------------------

View file

@ -1,247 +0,0 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# material conflicts
#
# If you want to edit this file:
# - A conflict will apply to every item except if in one of the notAffectedGroups group
# - the conflict will count only if the user try to combine at least as
# many conflicting enchantment as "maxEnchantmentBeforeConflict"
#
#
# ----------------------------------------------------
# These restriction are about not allowing enchantment
# on illegal items
# ----------------------------------------------------
restriction_aqua_affinity:
enchantments: [ minecraft:aqua_affinity ]
notAffectedGroups: [ enchanted_book, helmets ]
restriction_bane_of_arthropods:
enchantments: [ minecraft:bane_of_arthropods ]
notAffectedGroups: [ enchanted_book, melee_weapons ]
restriction_blast_protection:
enchantments: [ minecraft:blast_protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_channeling:
enchantments: [ minecraft:channeling ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_binding_curse:
enchantments: [ minecraft:binding_curse ]
notAffectedGroups: [ enchanted_book, wearable ]
restriction_vanishing_curse:
enchantments: [ minecraft:vanishing_curse ]
notAffectedGroups: [ enchanted_book, can_vanish ]
restriction_depth_strider:
enchantments: [ minecraft:depth_strider ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_efficiency:
enchantments: [ minecraft:efficiency ]
notAffectedGroups: [ enchanted_book, tools, shears ]
restriction_feather_falling:
enchantments: [ minecraft:feather_falling ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_fire_aspect:
enchantments: [ minecraft:fire_aspect ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_fire_protection:
enchantments: [ minecraft:fire_protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_flame:
enchantments: [ minecraft:flame ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_fortune:
enchantments: [ minecraft:fortune ]
notAffectedGroups: [ enchanted_book, tools ]
restriction_frost_walker:
enchantments: [ minecraft:frost_walker ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_impaling:
enchantments: [ minecraft:impaling ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_infinity:
enchantments: [ minecraft:infinity ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_knockback:
enchantments: [ minecraft:knockback ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_looting:
enchantments: [ minecraft:looting ]
notAffectedGroups: [ enchanted_book, swords ]
restriction_loyalty:
enchantments: [ minecraft:loyalty ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_luck_of_the_sea:
enchantments: [ minecraft:luck_of_the_sea ]
notAffectedGroups: [ enchanted_book, fishing_rod ]
restriction_lure:
enchantments: [ minecraft:lure ]
notAffectedGroups: [ enchanted_book, fishing_rod ]
restriction_mending:
enchantments: [ minecraft:mending ]
notAffectedGroups: [ enchanted_book, can_unbreak ]
restriction_minecraft_multishot:
enchantments: [ minecraft:multishot ]
notAffectedGroups: [ enchanted_book, crossbow ]
restriction_piercing:
enchantments: [ minecraft:piercing ]
notAffectedGroups: [ enchanted_book, crossbow ]
restriction_power:
enchantments: [ minecraft:power ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_projectile_protection:
enchantments: [ minecraft:projectile_protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_protection:
enchantments: [ minecraft:protection ]
notAffectedGroups: [ enchanted_book, armors ]
restriction_punch:
enchantments: [ minecraft:punch ]
notAffectedGroups: [ enchanted_book, bow ]
restriction_quick_charge:
enchantments: [ minecraft:quick_charge ]
notAffectedGroups: [ enchanted_book, crossbow ]
restriction_respiration:
enchantments: [ minecraft:respiration ]
notAffectedGroups: [ enchanted_book, helmets ]
restriction_riptide:
enchantments: [ minecraft:riptide ]
notAffectedGroups: [ enchanted_book, trident ]
restriction_sharpness:
enchantments: [ minecraft:sharpness ]
notAffectedGroups: [ enchanted_book, melee_weapons ]
restriction__silk_touch:
enchantments: [ minecraft:silk_touch ]
notAffectedGroups: [ enchanted_book, tools ]
restriction_smite:
enchantments: [ minecraft:smite ]
notAffectedGroups: [ enchanted_book, melee_weapons ]
restriction_soul_speed:
enchantments: [ minecraft:soul_speed ]
notAffectedGroups: [ enchanted_book, boots ]
restriction_sweeping_edge:
enchantments: [ minecraft:sweeping, minecraft:sweeping_edge ]
notAffectedGroups: [ enchanted_book, swords ]
# Do not exist in 1.18, that mean useInFuture will be set to true
# useInFuture set to true also mean it will not warn if there is an issue
restriction_swift_sneak:
useInFuture: true
enchantments: [ minecraft:swift_sneak ]
notAffectedGroups: [ enchanted_book, leggings ]
restriction_thorns:
enchantments: [ minecraft:thorns ]
notAffectedGroups: [ enchanted_book, armors ]
restriction__unbreaking:
enchantments: [ minecraft:unbreaking ]
notAffectedGroups: [ enchanted_book, can_unbreak ]
# ----------------------------------------------------
# Now we have conflicts about enchantment Incompatibility
# We just filtered what item enchantments can be applied
# notAffectedGroups is empty as we don't want anything to not respect theses rules
# maxEnchantmentBeforeConflict is set to 1 to only have 1 on those enchantment available
# ----------------------------------------------------
sword_enchant_conflict:
enchantments:
- minecraft:bane_of_arthropods
- minecraft:smite
- minecraft:sharpness
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
protection_enchant_conflict:
enchantments:
- minecraft:blast_protection
- minecraft:fire_protection
- minecraft:projectile_protection
- minecraft:protection
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
trident_conflict1:
enchantments:
- minecraft:channeling
- minecraft:riptide
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
trident_conflict2:
enchantments:
- minecraft:loyalty
- minecraft:riptide
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
boot_conflict:
enchantments:
- minecraft:depth_strider
- minecraft:frost_walker
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
tool_conflict:
enchantments:
- minecraft:fortune
- minecraft:silk_touch
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
bow_conflict:
enchantments:
- minecraft:mending
- minecraft:infinity
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
crossbow_conflict:
enchantments:
- minecraft:multishot
- minecraft:piercing
notAffectedGroups: [ ]
maxEnchantmentBeforeConflict: 1
# ----------------------------------------------------
# Bellow is for custom conflicts.
# This is also where conflict create from the gui will be placed.
# ----------------------------------------------------

View file

@ -1,210 +0,0 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Please note this config use spigot material names.
# It should match minecraft name in most case, maybe every case, but I can't be sure
# In case there an issue with material name, you can found them here:
# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
# An empty Exclude group exclude nothing, so it contain everything
everything:
type: exclude
# An empty include group will include nothing
nothing:
type: include
# This group is an example of a group including only stone and polished granite
example_include:
type: include
items:
- stone
- polished_granite
# This group contain everything except polished granite and elements of example_include
example_exclude:
type: exclude
items:
- polished_granite
groups:
- example_include
# Default configuration should be vanilla enchantment conflict group
# there may have error, if you find one you can fix it !
# https://minecraft.fandom.com/wiki/Enchanting
swords:
type: include
items:
- wooden_sword
- stone_sword
- iron_sword
- diamond_sword
- golden_sword
- netherite_sword
axes:
type: include
items:
- wooden_axe
- stone_axe
- iron_axe
- diamond_axe
- golden_axe
- netherite_axe
melee_weapons:
type: include
groups:
- swords
- axes
helmets:
type: include
items:
- leather_helmet
- chainmail_helmet
- iron_helmet
- diamond_helmet
- golden_helmet
- netherite_helmet
- turtle_helmet
chestplate:
type: include
items:
- leather_chestplate
- chainmail_chestplate
- iron_chestplate
- diamond_chestplate
- golden_chestplate
- netherite_chestplate
leggings:
type: include
items:
- leather_leggings
- chainmail_leggings
- iron_leggings
- diamond_leggings
- golden_leggings
- netherite_leggings
boots:
type: include
items:
- leather_boots
- chainmail_boots
- iron_boots
- diamond_boots
- golden_boots
- netherite_boots
armors:
type: include
groups:
- helmets
- chestplate
- leggings
- boots
wearable:
type: include
items:
- elytra
- carved_pumpkin
- skeleton_skull
- wither_skeleton_skull
- zombie_head
- player_head
- creeper_head
- dragon_head
# do not exist in 1.18 but exist in future update
- piglin_head
groups:
- armors
tools:
type: include
items:
- wooden_pickaxe
- stone_pickaxe
- iron_pickaxe
- diamond_pickaxe
- golden_pickaxe
- netherite_pickaxe
- wooden_shovel
- stone_shovel
- iron_shovel
- diamond_shovel
- golden_shovel
- netherite_shovel
- wooden_hoe
- stone_hoe
- iron_hoe
- diamond_hoe
- golden_hoe
- netherite_hoe
groups:
- axes
enchanted_book:
type: include
items:
- enchanted_book
trident:
type: include
items:
- trident
bow:
type: include
items:
- bow
crossbow:
type: include
items:
- crossbow
fishing_rod:
type: include
items:
- fishing_rod
shears:
type: include
items:
- shears
can_unbreak:
type: include
items:
- elytra
- flint_and_steel
- shield
- carrot_on_a_stick
- warped_fungus_on_a_stick
# do not exist in 1.18 but exist in future update
- brush
groups:
- melee_weapons
- tools
- armors
- trident
- bow
- crossbow
- fishing_rod
- shears
can_vanish:
type: include
items:
- compass
groups:
- wearable
- can_unbreak

View file

@ -1,190 +0,0 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Unit repair configuration
#
# This configuration is to make custom unit repair
# A unit repair is, for example, a diamond to repair a diamond sword
# In vanilla, a unit repair 25% of object durability
# you can make a custom value here
#
# Item name should NOT combine caps and no caps (example: Stone)
# Default value if the config is an invalid value (value <= 0 )
# If value > 1 it will be treated as being = 1
default_repair_amount: 0.25
# You can add custom unit repair
# The example bellow make a shield repaired by 10% by sticks
#stick:
# shield: 0.10
# Vanilla unit repair group is bellow
diamond:
diamond_helmet: 0.25
diamond_chestplate: 0.25
diamond_leggings: 0.25
diamond_boots: 0.25
diamond_sword: 0.25
diamond_pickaxe: 0.25
diamond_axe: 0.25
diamond_shovel: 0.25
diamond_hoe: 0.25
netherite_ingot:
netherite_helmet: 0.25
netherite_chestplate: 0.25
netherite_leggings: 0.25
netherite_boots: 0.25
netherite_sword: 0.25
netherite_pickaxe: 0.25
netherite_axe: 0.25
netherite_shovel: 0.25
netherite_hoe: 0.25
gold_ingot:
golden_helmet: 0.25
golden_chestplate: 0.25
golden_leggings: 0.25
golden_boots: 0.25
golden_sword: 0.25
golden_pickaxe: 0.25
golden_axe: 0.25
golden_shovel: 0.25
golden_hoe: 0.25
iron_ingot:
iron_helmet: 0.25
iron_chestplate: 0.25
iron_leggings: 0.25
iron_boots: 0.25
iron_sword: 0.25
iron_pickaxe: 0.25
iron_axe: 0.25
iron_shovel: 0.25
iron_hoe: 0.25
cobblestone:
stone_sword: 0.25
stone_pickaxe: 0.25
stone_axe: 0.25
stone_shovel: 0.25
stone_hoe: 0.25
cobbled_deepslate:
stone_sword: 0.25
stone_pickaxe: 0.25
stone_axe: 0.25
stone_shovel: 0.25
stone_hoe: 0.25
blackstone:
stone_sword: 0.25
stone_pickaxe: 0.25
stone_axe: 0.25
stone_shovel: 0.25
stone_hoe: 0.25
leather:
leather_helmet: 0.25
leather_chestplate: 0.25
leather_leggings: 0.25
leather_boots: 0.25
phantom_membrane:
elytra: 0.25
scute:
turtle_helmet: 0.25
oak_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
spruce_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
birch_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
jungle_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
acacia_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
dark_oak_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
mangrove_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
cherry_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
bamboo_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
crimson_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25
warped_planks:
wooden_sword: 0.25
wooden_pickaxe: 0.25
wooden_axe: 0.25
wooden_shovel: 0.25
wooden_hoe: 0.25
shield: 0.25

View file

@ -1,5 +1,4 @@
### 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.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.11 use [1.21.11 configurations](https://github.com/alexcrea/CustomAnvil/tree/master/defaultconfigs/1.21.11)

View file

@ -6,7 +6,7 @@ signing.secretKeyRingFile=~/.gnupg/secring.gpg
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
subprojects.reobfnms=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

View file

@ -8,6 +8,6 @@ plugins {
// Imitate needed class and method to support legacy version of EcoEnchant
dependencies {
// Spigot api
compileOnly("org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT")
}

View file

@ -21,8 +21,8 @@ repositories {
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "16"
targetCompatibility = "16"
sourceCompatibility = "21"
targetCompatibility = "21"
options.encoding = "UTF-8"
}
@ -30,6 +30,6 @@ tasks.withType<JavaCompile>().configureEach {
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_16)
jvmTarget.set(JvmTarget.JVM_21)
}
}

View file

@ -21,8 +21,8 @@ repositories {
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "18"
targetCompatibility = "18"
sourceCompatibility = "21"
targetCompatibility = "21"
options.encoding = "UTF-8"
}
@ -30,6 +30,6 @@ tasks.withType<JavaCompile>().configureEach {
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_18)
jvmTarget.set(JvmTarget.JVM_21)
}
}

View file

@ -2,37 +2,19 @@ package xyz.alexcrea.cuanvil.dependency.datapack
import io.papermc.paper.datapack.Datapack
import org.bukkit.Bukkit
import org.bukkit.packs.DataPack
import java.util.*
object DataPackTester {
val legacyNames: List<String>
get() = Bukkit.getDataPackManager().dataPacks
.stream().filter { obj -> obj.isEnabled }
.map { pack -> pack.key.key }
.toList()
val enabledPacks: List<String>
get() {
try {
// will throw error if do not exist
Bukkit::class.java.getDeclaredMethod("getDatapackManager")
return Bukkit.getDatapackManager().enabledPacks
return try {
Bukkit.getDatapackManager().enabledPacks
.stream().map { obj: Datapack -> obj.name }
.toList()
} catch (e: NoSuchMethodException) {
try {
DataPack::class.java.getDeclaredMethod("getKey")
} catch (e: NoSuchMethodException) {
System.err.println("Could not find compatible datapack manager")
System.err.println("If you are using a datapack that should be compatible with CustomAnvil. It will not get detected...")
return emptyList()
}
return legacyNames
} catch (e: Exception){
} catch (_: Exception){
// Assume cause UnimplementedOperationException on mock server
return Collections.emptyList()
Collections.emptyList()
}
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.17.1-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "16"
targetCompatibility = "16"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_16)
}
}

View file

@ -1,33 +0,0 @@
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.v1_17_R1.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_17R1_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.18.1-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -1,33 +0,0 @@
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.v1_18_R1.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_18R1_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.18.2-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -1,33 +0,0 @@
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.v1_18_R2.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_18R2_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.19.2-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -1,33 +0,0 @@
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.v1_19_R1.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_19R1_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.19.3-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -1,33 +0,0 @@
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.v1_19_R2.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_19R2_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.19.4-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "17"
targetCompatibility = "17"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_2)
jvmTarget.set(JvmTarget.JVM_17)
}
}

View file

@ -1,33 +0,0 @@
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.v1_19_R3.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_19R3_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.20.1-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)
}
}

View file

@ -1,33 +0,0 @@
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.v1_20_R1.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R1_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.20.2-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)
}
}

View file

@ -1,33 +0,0 @@
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.v1_20_R2.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R2_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.20.4-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)
}
}

View file

@ -1,33 +0,0 @@
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.v1_20_R3.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_20R3_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1 +0,0 @@
.lastDeploymentsId

View file

@ -1,35 +0,0 @@
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.20.6-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_0)
jvmTarget.set(JvmTarget.JVM_18)
}
}

View file

@ -1,33 +0,0 @@
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 V1_20R4_PacketManager : 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.flyingSpeed = playerAbilities.flyingSpeed
sendedAbilities.walkingSpeed = playerAbilities.walkingSpeed
}
val packet = ClientboundPlayerAbilitiesPacket(sendedAbilities)
nmsPlayer.connection.send(packet)
}
}

View file

@ -1,18 +0,0 @@
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
}
}

View file

@ -90,29 +90,6 @@ public class AnvilRecipeBuilder {
return this;
}
/**
* Get the xp level cost per craft. (default 0)
*
* @return The xp level cost per craft
* @deprecated use {@link #getLevelCostPerCraft() getLevelCostPerCraft} instead
*/
@Deprecated(since = "1.13.0")
public int getXpCostPerCraft() {
return getLevelCostPerCraft();
}
/**
* Sets the xp level cost per craft.
*
* @param xpCostPerCraft The xp level cost per craft
* @return This recipe builder instance.
* @deprecated use {@link #setLevelCostPerCraft(int) setLevelCostPerCraft} instead
*/
@Deprecated(since = "1.13.0")
public AnvilRecipeBuilder setXpCostPerCraft(int xpCostPerCraft) {
return setLevelCostPerCraft(xpCostPerCraft);
}
/**
* Get the xp level cost per craft. (default 0)
*

View file

@ -387,7 +387,7 @@ public class ConflictBuilder {
*/
protected void appendEnchantments(@NotNull EnchantConflictGroup conflict) {
for (String enchantmentName : getEnchantmentNames()) {
if (appendEnchantments(conflict, EnchantmentApi.getListByName(enchantmentName)) == 0) {
if (appendEnchantments(conflict, EnchantmentApi.getByName(enchantmentName)) == 0) {
CustomAnvil.instance.getLogger().warning("Could not find enchantment " + enchantmentName + " for conflict " + getName());
ConflictAPI.logConflictOrigin(this);
}

View file

@ -131,27 +131,14 @@ public class EnchantmentApi {
return CAEnchantment.getByKey(key);
}
/**
* Get by name an enchantment.
*
* @param name The name used to fetch
* @return The custom anvil enchantment of this name. null if not found.
* @deprecated use {@link #getListByName(String)}
*/
@Deprecated(since = "1.6.3")
@Nullable
public static CAEnchantment getByName(@NotNull String name){
return CAEnchantment.getByName(name);
}
/**
* Get list of enchantment using the provided name.
*
* @param name The name used to fetch
* @return List of custom anvil enchantments of this name. May be empty if not found.
*/
public static List<CAEnchantment> getListByName(@NotNull String name){
return CAEnchantment.getListByName(name);
public static List<CAEnchantment> getByName(@NotNull String name){
return CAEnchantment.getByName(name);
}
/**

View file

@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
* Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
* for this event to be useful.
* <p>
* There is also {@link CATreatAnvilResult2Event} that may be better for some use case.
* There is also {@link CATreatAnvilResultEvent} that may be better for some use case.
*/
public class CAClickResultBypassEvent extends Event implements Cancellable {

View file

@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull;
* <p>
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
* <p>
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event}
* It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
* as your use case may be more prone to use theses.
*/
public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {

View file

@ -18,7 +18,7 @@ import org.jetbrains.annotations.NotNull;
* <p>
* You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
* <p>
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResult2Event}
* It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
* as your use case may be more prone to use theses.
*/
public class CAPreAnvilBypassEvent extends Event implements Cancellable {

View file

@ -1,196 +0,0 @@
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;
}
}

View file

@ -2,8 +2,8 @@ package xyz.alexcrea.cuanvil.api.event.listener;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.view.AnvilView;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.anvil.AnvilCost;
@ -17,13 +17,9 @@ import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
* {@link CAPreAnvilBypassEvent}
* and {@link CAEarlyPreAnvilBypassEvent} for your use case
* <p>
* 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
* A null result will cancel this event
*/
@SuppressWarnings("unused")
@Deprecated(forRemoval = true, since = "1.17.0")
@SuppressWarnings({"unused", "UnstableApiUsage"})
public class CATreatAnvilResultEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList();
@ -38,31 +34,44 @@ public class CATreatAnvilResultEvent extends Event {
}
@NotNull
private final PrepareAnvilEvent event;
private final AnvilView view;
private final AnvilUseType useType;
@Nullable
private final ItemStack left;
@Nullable
private final ItemStack right;
@Nullable
private ItemStack result;
private final AnvilCost cost;
public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, AnvilCost cost) {
this.event = event;
public CATreatAnvilResultEvent(
@NotNull AnvilView view,
AnvilUseType useType,
@Nullable ItemStack result,
AnvilCost cost) {
this.view = view;
this.useType = useType;
this.left = view.getItem(0);
this.right = view.getItem(1);
this.result = result;
this.cost = cost;
}
/**
* Get the bukkit inventory click event causing to this event.
* Get the bukkit inventory view.
*
* @return The click event causing to this event.
* @return The inventory view of this event.
*/
public @NotNull PrepareAnvilEvent getEvent() {
return event;
public @NotNull AnvilView getView() {
return view;
}
/**
* Get the type of use source of the result.
*
@ -72,6 +81,24 @@ public class CATreatAnvilResultEvent extends Event {
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>
@ -94,50 +121,6 @@ public class CATreatAnvilResultEvent extends Event {
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
@ -158,5 +141,4 @@ public class CATreatAnvilResultEvent extends Event {
public AnvilCost getCost() {
return cost;
}
}

View file

@ -225,25 +225,14 @@ public interface CAEnchantment {
return CAEnchantmentRegistry.getInstance().getByKey(key);
}
/**
* Gets the enchantment by the provided name.
* @param name Name to fetch.
* @return Registered enchantment. null if absent.
*
* @deprecated use {@link #getListByName(String)}
*/
@Deprecated(since = "1.6.3")
static @Nullable CAEnchantment getByName(@NotNull String name){
return CAEnchantmentRegistry.getInstance().getByName(name);
}
/**
* Gets list of enchantment using the provided name.
*
* @param name Name to fetch.
* @return List of registered enchantment.
*/
static List<CAEnchantment> getListByName(@NotNull String name){
return CAEnchantmentRegistry.getInstance().getListByName(name);
static List<CAEnchantment> getByName(@NotNull String name){
return CAEnchantmentRegistry.getInstance().getByName(name);
}
}

View file

@ -155,22 +155,6 @@ public class CAEnchantmentRegistry {
return byKeyMap.get(key);
}
/**
* Gets the enchantment by the provided name.
*
* @param name Name to fetch.
* @return Registered enchantment. null if absent.
* @deprecated use {@link #getListByName(String)}
*/
@Deprecated(since = "1.6.3")
@Nullable
public CAEnchantment getByName(@NotNull String name) {
List<CAEnchantment> enchantments = getListByName(name);
if (enchantments.isEmpty()) return null;
return enchantments.get(0);
}
/**
* Gets list of enchantment using the provided name.
*
@ -178,7 +162,7 @@ public class CAEnchantmentRegistry {
* @return List of registered enchantment.
*/
@NotNull
public List<CAEnchantment> getListByName(@NotNull String name) {
public List<CAEnchantment> getByName(@NotNull String name) {
return byNameMap.getOrDefault(name, Collections.emptyList());
}

View file

@ -1,6 +1,6 @@
package xyz.alexcrea.cuanvil.enchant;
// because spigot (1.18) do not look like to provide access to enchantment rarity I need to do it myself...
// because spigot (1.21) do not look like to provide access to enchantment rarity I need to do it myself...
public class EnchantmentRarity {
public static final EnchantmentRarity NO_RARITY = new EnchantmentRarity(0, 0);

View file

@ -141,10 +141,10 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui<CAEnchantme
meta.setDisplayName("§" + (isIn ? 'a' : 'c') + CasedStringUtil.snakeToUpperSpacedCase(name));
if (isIn) {
meta.addEnchant(Enchantment.DAMAGE_UNDEAD, 1, true);
meta.addEnchant(Enchantment.SHARPNESS, 1, true);
meta.setLore(TRUE_LORE);
} else {
meta.removeEnchant(Enchantment.DAMAGE_UNDEAD);
meta.removeEnchant(Enchantment.SHARPNESS);
meta.setLore(FALSE_LORE);
}
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS);

View file

@ -112,10 +112,10 @@ public class GroupSelectSettingGui extends AbstractSettingGui {
meta.setDisplayName("§" + (isIn ? 'a' : 'c') + CasedStringUtil.snakeToUpperSpacedCase(name));
if (isIn) {
meta.addEnchant(Enchantment.DAMAGE_UNDEAD, 1, true);
meta.addEnchant(Enchantment.SHARPNESS, 1, true);
meta.setLore(TRUE_LORE);
} else {
meta.removeEnchant(Enchantment.DAMAGE_UNDEAD);
meta.removeEnchant(Enchantment.SHARPNESS);
meta.setLore(FALSE_LORE);
}
meta.addItemFlags(ItemFlag.values());

View file

@ -4,9 +4,7 @@ import org.bukkit.Material.ENCHANTED_BOOK
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.update.UpdateUtils
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import xyz.alexcrea.cuanvil.util.MaxDamageCheckerUtil
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.min
@ -38,13 +36,6 @@ object ItemUtil {
}
private fun maxDamage(damageable: Damageable): Int {
val ver = UpdateUtils.currentMinecraftVersion()
if(ver.major <= 1 && ver.minor <= 20 && ver.patch < 5) return Integer.MAX_VALUE
return MaxDamageCheckerUtil.getMaxDamage(damageable)
}
/**
* Set this [ItemStack]s durability from a combination of the
* [first] and [second] item's durability values
@ -64,8 +55,8 @@ object ItemUtil {
val secondDurability = durability - secondDamage
val combinedDurability = firstDurability + secondDurability
val newDurability = min(combinedDurability, durability)
val maxDamage = if(it.hasMaxDamage()) it.maxDamage else Int.MAX_VALUE
val maxDamage = maxDamage(it)
it.damage = min(durability - newDurability, maxDamage)
itemMeta = it
return true

View file

@ -12,10 +12,9 @@ import org.bukkit.ChatColor
import org.bukkit.Material
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.view.AnvilView
import org.bukkit.persistence.PersistentDataType
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
@ -32,6 +31,7 @@ import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
@Suppress("UnstableApiUsage")
object AnvilMergeLogic {
open class AnvilResult {
@ -98,13 +98,12 @@ object AnvilMergeLogic {
}
fun doRenaming(
view: InventoryView, //TODO use anvil view
inventory: AnvilInventory,
view: AnvilView,
player: Player, first: ItemStack
): AnvilResult {
val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player)
cost.rename = handleRename(resultItem, view, player)
// Test/stop if nothing changed.
if (first == resultItem) {
@ -114,7 +113,7 @@ object AnvilMergeLogic {
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.RENAME_ONLY, cost)
DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.RENAME_ONLY, cost)
return AnvilResult(result, cost)
}
@ -137,9 +136,9 @@ object AnvilMergeLogic {
}
}
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
private fun handleRename(resultItem: ItemStack, view: AnvilView, player: HumanEntity): Int {
// Can be null
var renameText = ChatColor.stripColor(inventory.renameText)
var renameText = ChatColor.stripColor(view.renameText)
var sumCost = 0
var useColor = false
@ -184,8 +183,7 @@ object AnvilMergeLogic {
}
fun doMerge(
view: InventoryView, //TODO use anvil view instead
inventory: AnvilInventory,
view: AnvilView,
player: Player,
first: ItemStack, second: ItemStack
): AnvilResult {
@ -217,10 +215,10 @@ object AnvilMergeLogic {
// As calculatePenalty edit result, we need to calculate penalty after checking equality
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE)
// Calculate rename cost
cost.rename = handleRename(resultItem, inventory, player)
cost.rename = handleRename(resultItem, view, player)
val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.MERGE, cost)
DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.MERGE, cost)
return AnvilResult(result, cost)
}
@ -239,8 +237,7 @@ object AnvilMergeLogic {
// return true if a custom recipe exist with these ingredients
fun testCustomRecipe(
view: InventoryView, //TODO use anvil view instead
inventory: AnvilInventory,
view: AnvilView,
player: Player,
first: ItemStack, second: ItemStack?
): CustomCraftResult {
@ -262,31 +259,29 @@ object AnvilMergeLogic {
else AnvilXpUtil.calculateLevelForXp(xpCost)
val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.CUSTOM_CRAFT, cost)
DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.CUSTOM_CRAFT, cost)
return CustomCraftResult(result, cost, amount, recipe)
}
fun testUnitRepair(
view: InventoryView, //TODO use anvil view
inventory: AnvilInventory,
view: AnvilView,
player: Player,
first: ItemStack, second: ItemStack
): UnitRepairResult {
val unitRepairAmount = first.getRepair(second) ?: return UnitRepairResult.EMPTY
return testUnitRepair(view, inventory, player, first, second, unitRepairAmount)
return testUnitRepair(view, player, first, second, unitRepairAmount)
}
fun testUnitRepair(
view: InventoryView, //TODO use anvil view instead
inventory: AnvilInventory,
view: AnvilView,
player: Player,
first: ItemStack, second: ItemStack,
unitRepairAmount: Double
): UnitRepairResult {
val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player)
cost.rename = handleRename(resultItem, view, player)
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
if (repairAmount > 0)
@ -302,7 +297,7 @@ object AnvilMergeLogic {
}
val result =
DependencyManager.tryTreatAnvilResult(view, inventory, player, resultItem, AnvilUseType.UNIT_REPAIR, cost)
DependencyManager.tryTreatAnvilResult(view, player, resultItem, AnvilUseType.UNIT_REPAIR, cost)
return UnitRepairResult(result, cost, repairAmount)
}

View file

@ -15,8 +15,10 @@ abstract class CASubCommand: CommandExecutor {
args: Array<out String>
): Boolean {
if (!alreadySaid) {
sender.sendMessage(ChatColor.RED.toString() +
"Please not that this command will be replaced as a subcommand of `/customanvil` or `/ca`")
sender.sendMessage(
ChatColor.RED.toString() +
"Please not that this command will be replaced as a subcommand of `/customanvil` or `/ca`"
)
alreadySaid = true
}
@ -27,7 +29,8 @@ abstract class CASubCommand: CommandExecutor {
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>): Boolean
args: Array<out String>
): Boolean
open fun allowed(sender: CommandSender): Boolean {
return true
@ -36,7 +39,8 @@ abstract class CASubCommand: CommandExecutor {
open fun tabCompleter(
sender: CommandSender,
args: Array<out String>,
list: MutableList<String>) {
list: MutableList<String>
) {
}
open fun description(): String {

View file

@ -7,7 +7,6 @@ import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter
import xyz.alexcrea.cuanvil.util.MetricsUtil
import java.util.ArrayList
class CustomAnvilCommand(plugin: CustomAnvil) : CommandExecutor, TabCompleter {

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.command
import com.github.stefvanschie.inventoryframework.inventoryview.interface_.InventoryViewUtil
import io.delilaheve.CustomAnvil
import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent
@ -16,11 +15,10 @@ import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryType
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Damageable
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.dependency.DependencyManager
@ -85,7 +83,8 @@ class DiagnosticExecutor: CASubCommand() {
override fun tabCompleter(
sender: CommandSender,
args: Array<out String>,
list: MutableList<String>) {
list: MutableList<String>
) {
if (!allowed(sender)) return
val map = fetchParameters(args)
@ -124,7 +123,8 @@ class DiagnosticExecutor: CASubCommand() {
if (sender is HumanEntity) {
if (hasError)
sender.spigot().sendMessage(TextComponent(ChatColor.RED.toString() + "There was an error running the diagnostic"))
sender.spigot()
.sendMessage(TextComponent(ChatColor.RED.toString() + "There was an error running the diagnostic"))
val message = TextComponent(ChatColor.GREEN.toString() + "Click to copy diagnostic data")
message.clickEvent = ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, stb.toString())
@ -193,11 +193,11 @@ class DiagnosticExecutor: CASubCommand() {
damagedSword.itemMeta = meta
meta = enchantedSword.itemMeta
meta!!.addEnchant(Enchantment.DAMAGE_ALL, 1, true)
meta!!.addEnchant(Enchantment.SHARPNESS, 1, true)
enchantedSword.itemMeta = meta
meta = enchantedBook.itemMeta
(meta as EnchantmentStorageMeta).addStoredEnchant(Enchantment.DAMAGE_ALL, 1, true)
(meta as EnchantmentStorageMeta).addStoredEnchant(Enchantment.SHARPNESS, 1, true)
enchantedBook.itemMeta = meta
stb.append("\n\nItem to Item repair:")
@ -262,11 +262,11 @@ class DiagnosticExecutor: CASubCommand() {
}
fun simulateAnvil(player: Player, stb: StringBuilder, left: ItemStack?, right: ItemStack?, result: ItemStack?) {
var invView: InventoryView
var invView: AnvilView
var event: PrepareAnvilEvent
try {
val fakeInv = Bukkit.createInventory(player, InventoryType.ANVIL)
invView = player.openInventory(fakeInv)!!
invView = player.openInventory(fakeInv)!! as AnvilView
event = PrepareAnvilEvent(invView, result)
} catch (e: Throwable) {
// Help
@ -274,42 +274,40 @@ class DiagnosticExecutor: CASubCommand() {
val anvilTypeField = menuTypeClazz.getField("ANVIL")
val anvilType = anvilTypeField.get(null)
val createMethod = anvilType.javaClass.getMethod("create", HumanEntity::class.java)
invView = createMethod.invoke(anvilType, player) as InventoryView
invView = createMethod.invoke(anvilType, player) as AnvilView
player.openInventory(invView)
val anvilViewClass = Class.forName("org.bukkit.inventory.view.AnvilView")
val constructor = PrepareAnvilEvent::class.java.getConstructor(anvilViewClass, ItemStack::class.java)
val constructor = PrepareAnvilEvent::class.java.getConstructor(AnvilView::class.java, ItemStack::class.java)
event = constructor.newInstance(invView, result)
}
val fakeInv = InventoryViewUtil.getInstance().getTopInventory(invView) as AnvilInventory
fakeInv.setItem(0, left)
fakeInv.setItem(1, right)
invView.setItem(0, left)
invView.setItem(1, right)
val xp = fakeInv.repairCost
val maxXp = fakeInv.maximumRepairCost
val mergeResult = fakeInv.getItem(2)
val xp = invView.repairCost
val maxXp = invView.maximumRepairCost
val mergeResult = invView.getItem(2)
stb.append("\n${if (result == mergeResult) "E" else "Une"}xpected Result")
PrepareAnvilListener().anvilCombineCheck(event)
// Now we check if item and xp same
stb.append("\nXP/Max XP: ")
.append(if(fakeInv.repairCost == xp) "Correct" else "Incorrect")
.append(if (invView.repairCost == xp) "Correct" else "Incorrect")
.append("/")
.append(if(fakeInv.maximumRepairCost == maxXp) "Correct" else "Incorrect")
.append(" (${fakeInv.repairCost} $xp|${fakeInv.maximumRepairCost} $maxXp)")
.append(if (invView.maximumRepairCost == maxXp) "Correct" else "Incorrect")
.append(" (${invView.repairCost} $xp|${invView.maximumRepairCost} $maxXp)")
.append("\nMerge result: ")
.append(if(fakeInv.getItem(2) == mergeResult) "Correct" else "Incorrect")
.append(if (invView.getItem(2) == mergeResult) "Correct" else "Incorrect")
PrepareAnvilListener.IS_EMPTY_TEST = true
Bukkit.getPluginManager().callEvent(event)
stb.append("\nNull result test: ")
.append(if (event.result == null) "Correct" else "Incorrect")
fakeInv.setItem(0, null)
fakeInv.setItem(1, null)
fakeInv.setItem(2, null)
invView.setItem(0, null)
invView.setItem(1, null)
invView.setItem(2, null)
player.closeInventory()
}
@ -327,11 +325,13 @@ class DiagnosticExecutor: CASubCommand() {
map[enchant.key.namespace] = map.getOrDefault(enchant.key.namespace, 0) + 1
}
stb.append("\nNamespaces: ${
stb.append(
"\nNamespaces: ${
map.entries.stream()
.map { (key, value) -> "$key ($value)" }
.reduce { a, b -> "$a, $b" }.get()
}")
}"
)
}
@ -341,7 +341,6 @@ class DiagnosticExecutor: CASubCommand() {
stb.append("\n\nLast stack trace: ${e.stackTraceToString()}")
}
}

View file

@ -10,10 +10,12 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions
class EditConfigExecutor : CASubCommand() {
override fun executeCommand(sender: CommandSender,
override fun executeCommand(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>): Boolean {
args: Array<out String>
): Boolean {
if (sender !is HumanEntity) return false
if (!allowed(sender)) {

View file

@ -8,10 +8,12 @@ class HelpExecutor: CASubCommand() {
lateinit var commands: ImmutableMap<String, CASubCommand>
override fun executeCommand(sender: CommandSender,
override fun executeCommand(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>): Boolean {
args: Array<out String>
): Boolean {
val stb = StringBuilder("List of available commands:")
for ((key, cmd) in commands) {

View file

@ -3,7 +3,6 @@ package xyz.alexcrea.cuanvil.command
import io.delilaheve.CustomAnvil
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.api.event.CAConfigReadyEvent
import xyz.alexcrea.cuanvil.config.ConfigHolder
@ -13,10 +12,12 @@ import xyz.alexcrea.cuanvil.update.UpdateHandler
class ReloadExecutor : CASubCommand() {
override fun executeCommand(sender: CommandSender,
override fun executeCommand(
sender: CommandSender,
cmd: Command,
cmdstr: String,
args: Array<out String>): Boolean {
args: Array<out String>
): Boolean {
if (!allowed(sender)) {
sender.sendMessage("§cYou do not have permission to reload the config")
return false

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.dependency
import com.maddoxh.superEnchants.SuperEnchants
import io.delilaheve.CustomAnvil
import net.kyori.adventure.text.Component
import org.bukkit.Bukkit
@ -10,16 +9,14 @@ import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
import xyz.alexcrea.cuanvil.dependency.gui.GenericExternGuiTester
@ -35,6 +32,7 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
import java.util.logging.Level
@Suppress("UnstableApiUsage")
object DependencyManager {
lateinit var scheduler: TaskScheduler
@ -117,7 +115,7 @@ object DependencyManager {
genericDependencies.add(GenericPluginDependency(pluginManager.getPlugin("ItemsAdder")!!))
if (pluginManager.isPluginEnabled("SuperEnchants")) {
val compatibility = SuperEnchantDependency(pluginManager.getPlugin("SuperEnchants")!! as SuperEnchants)
val compatibility = SuperEnchantDependency(pluginManager.getPlugin("SuperEnchants")!!)
if (compatibility.registerEnchantments())
genericDependencies.add(compatibility)
}
@ -164,11 +162,11 @@ object DependencyManager {
)
}
private fun logExceptionAndClear(target: CommandSender, inventory: Inventory, e: Exception) {
private fun logExceptionAndClear(view: AnvilView, e: Exception) {
// Just in case to avoid illegal items
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
view.setItem(ANVIL_OUTPUT_SLOT, null)
logException(target, e)
logException(view.player, e)
}
// Return true if should bypass (either by a dependency or error)
@ -177,7 +175,7 @@ object DependencyManager {
try {
return earlyUnsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e)
logExceptionAndClear(event.view, e)
return true
}
}
@ -203,7 +201,7 @@ object DependencyManager {
try {
return unsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e)
logExceptionAndClear(event.view, e)
return true
}
}
@ -233,40 +231,39 @@ object DependencyManager {
// Return null if there was an issue
fun tryTreatAnvilResult(
view: InventoryView,
inventory: Inventory, // TODO REMOVE, use view instead on legacy removal
view: AnvilView,
player: HumanEntity,
result: ItemStack,
useType: AnvilUseType,
cost: AnvilCost
): ItemStack? {
val treatEvent = CATreatAnvilResult2Event(view, inventory, useType, result, cost)
val treatEvent = CATreatAnvilResultEvent(view, useType, result, cost)
try {
unsafeTryTreatAnvilResult(treatEvent)
return treatEvent.result
} catch (e: Exception) {
logExceptionAndClear(player, inventory, e)
logExceptionAndClear(view, e)
return null
}
}
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResult2Event) {
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) {
Bukkit.getPluginManager().callEvent(event)
excellentEnchantsCompatibility?.treatAnvilResult(event)
}
// Return true if should bypass (either by a dependency or error)
fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
fun tryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
try {
return unsafeTryClickAnvilResultBypass(event, inventory)
return unsafeTryClickAnvilResultBypass(event, view)
} catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e)
logExceptionAndClear(view, e)
return true
}
}
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
// Run the event
val bypassEvent = CAClickResultBypassEvent(event)
Bukkit.getPluginManager().callEvent(bypassEvent)
@ -274,10 +271,10 @@ object DependencyManager {
var bypass = bypassEvent.isCancelled
// Test if disenchantment used event click
if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, view) == true)) bypass = true
// Test if haven bag used event click
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, view) == true)) bypass = true
// Test if disenchantment used event click
if (!bypass && (excellentEnchantsCompatibility?.testAnvilResult(event) == true)) bypass = true
@ -287,10 +284,10 @@ object DependencyManager {
}
// Test if the inventory is a gui(version specific)
if (!bypass && externGuiTester.testIfGui(event.view)) bypass = true
if (!bypass && externGuiTester.testIfGui(view)) bypass = true
// Test if in an ax player warp rating gui
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(event.view.player) == true)) bypass = true
if (!bypass && (axPlayerWarpsCompatibility?.testIfGui(view.player) == true)) bypass = true
return bypass
}

View file

@ -10,32 +10,6 @@ object MinecraftVersionUtil {
if (version.major != 1) return null
return when (version.minor) {
17 -> when (version.patch) {
0, 1 -> "1_17R1"
else -> null
}
18 -> when (version.patch) {
0, 1 -> "1_18R1"
2 -> "1_18R2"
else -> null
}
19 -> when (version.patch) {
0, 1, 2 -> "1_19R1"
3 -> "1_19R2"
4 -> "1_19R3"
else -> null
}
20 -> when (version.patch) {
0, 1 -> "1_20R1"
2 -> "1_20R2"
3, 4 -> "1_20R3"
5, 6 -> "1_20R4"
else -> null
}
21 -> when (version.patch) {
0, 1 -> "1_21R1"
2, 3 -> "1_21R2"
@ -46,12 +20,15 @@ object MinecraftVersionUtil {
11 -> "1_21R7"
else -> null
}
//TODO need to continue updating that for anvil gui test dependency....
else -> null
}
}
val isTooNewForSpigot: Boolean get() {
val isTooNewForSpigot: Boolean
get() {
return UpdateUtils.currentMinecraftVersion().major != 1
}

View file

@ -1,3 +1,5 @@
@file:Suppress("DEPRECATION")
package xyz.alexcrea.cuanvil.dependency.economy
import net.milkbowl.vault.economy.Economy

View file

@ -64,11 +64,11 @@ class GenericExternGuiTester {
}
// Try if were in another plugin anvil inventory
fun testIfGui(inventory: InventoryView): Boolean {
fun testIfGui(view: InventoryView): Boolean {
// In case we are in a test environment
if(isInTest()) return false
val clazz = getContainerClass(inventory) ?: return false
val clazz = getContainerClass(view) ?: return false
val clazzName = clazz.name
if(!PlatformUtil.isPaper){

View file

@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.dependency.packet
import org.bukkit.Bukkit
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.MinecraftVersionUtil
import xyz.alexcrea.cuanvil.dependency.packet.versions.*
import xyz.alexcrea.cuanvil.dependency.packet.versions.PaperPacketManager
import xyz.alexcrea.cuanvil.update.UpdateUtils
object PacketManagerSelector {

View file

@ -12,8 +12,8 @@ import org.bukkit.entity.Player
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
@ -21,6 +21,7 @@ import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import java.util.logging.Level
import kotlin.reflect.KClass
@Suppress("UnstableApiUsage")
class DisenchantmentDependency {
init {
@ -59,14 +60,14 @@ class DisenchantmentDependency {
DisenchantEvent.onEvent(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil item extract bypass.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
ShatterEvent.onEvent(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil split enchant bypass.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
@ -74,18 +75,18 @@ class DisenchantmentDependency {
return false
}
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
val previousResultSlot = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
fun testAnvilResult(event: InventoryClickEvent, view: AnvilView): Boolean {
val previousResultSlot = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
// Test event if change the result
DisenchantClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
if (!testAnvilChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click item extract bypass.")
return true
}
ShatterClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
if (!testAnvilChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click split enchant bypass.")
return true
}
@ -93,8 +94,8 @@ class DisenchantmentDependency {
return false
}
private fun testAnvilInventoryChange(inventory: AnvilInventory, previous: ItemStack?): Boolean {
val currentResult = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
private fun testAnvilChange(view: AnvilView, previous: ItemStack?): Boolean {
val currentResult = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
return currentResult == previous
}

View file

@ -30,7 +30,8 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
"disable_anvil, " +
"incompatible_vanilla_enchantments, " +
"incompatible_custom_enchantments and max_level " +
"configuration values.")
"configuration values."
)
}
fun disableAnvilListener() {
@ -69,8 +70,8 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
fun getEnchantmentsSquared(item: ItemStack, enchantments: MutableMap<CAEnchantment, Int>) {
val customEnchants = CustomEnchantManager.getInstance().getItemsEnchantsFromPDC(item)
customEnchants.forEach{
(enchantment, level ) -> enchantments[getWrappedEnchant(enchantment)] = level
customEnchants.forEach { (enchantment, level) ->
enchantments[getWrappedEnchant(enchantment)] = level
}
}
@ -78,6 +79,7 @@ class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin)
fun getKeyFromEnchant(enchant: CustomEnchant): NamespacedKey {
return NamespacedKey.fromString(enchant.type.lowercase(Locale.getDefault()), this.enchantmentSquaredPlugin)!!
}
private fun getWrappedEnchant(enchant: CustomEnchant): CAEnchantment {
return CAEnchantment.getByKey(getKeyFromEnchant(enchant))!!
}

View file

@ -8,7 +8,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult2Event
import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5_4Enchantment
@ -17,10 +17,10 @@ import java.lang.reflect.Constructor
import java.lang.reflect.Method
import su.nightexpress.excellentenchants.api.EnchantRegistry as V5EnchantRegistry
import su.nightexpress.excellentenchants.enchantment.impl.universal.CurseOfFragilityEnchant as LegacyCurseOfFragilityEnchant
import su.nightexpress.excellentenchants.manager.listener.AnvilListener as V5AnvilListener
import su.nightexpress.excellentenchants.enchantment.listener.AnvilListener as PreV5AnvilListener
import su.nightexpress.excellentenchants.enchantment.listener.EnchantAnvilListener as LegacyAnvilListener
import su.nightexpress.excellentenchants.enchantment.registry.EnchantRegistry as LegacyEnchantRegistry
import su.nightexpress.excellentenchants.manager.listener.AnvilListener as V5AnvilListener
import su.nightexpress.excellentenchants.registry.EnchantRegistry as PreV5EnchantRegistry
// I don't like that I need to support older version. if I could just drop older support it would be sooo nice
@ -173,6 +173,7 @@ class ExcellentEnchantsDependency {
ListenerVersion.V5,
ListenerVersion.V5_4,
-> this.usedAnvilListener = v5AnvilListener!!
ListenerVersion.PRE_V5 -> this.usedAnvilListener = preV5AnvilListener!!
ListenerVersion.LEGACY -> this.usedAnvilListener = legacyAnvilListener!!
null -> {}
@ -221,7 +222,7 @@ class ExcellentEnchantsDependency {
return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean
}
fun treatAnvilResult(event: CATreatAnvilResult2Event) {
fun treatAnvilResult(event: CATreatAnvilResultEvent) {
val result = event.result ?: return
val first: ItemStack = treatInput(event.leftItem)
@ -240,6 +241,7 @@ class ExcellentEnchantsDependency {
ListenerVersion.V5_3,
ListenerVersion.V5_4,
-> v5AnvilListener!!.onClickAnvil(event)
ListenerVersion.PRE_V5 -> preV5AnvilListener!!.onClickAnvil(event)
ListenerVersion.LEGACY -> legacyAnvilListener!!.onClickAnvil(event)
null -> {}

View file

@ -35,7 +35,8 @@ open class GenericPluginDependency(protected open val plugin: Plugin, private va
protected open fun fillPostAnvil(
postAnvil: ArrayList<RegisteredListener>,
preAnvil: ArrayList<RegisteredListener>) {
preAnvil: ArrayList<RegisteredListener>
) {
}

View file

@ -4,7 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.view.AnvilView
import org.bukkit.plugin.RegisteredListener
import valorless.havenbags.HavenBags
import valorless.havenbags.features.BagSkin
@ -13,6 +13,7 @@ import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
@Suppress("UnstableApiUsage")
class HavenBagsDependency {
init {
@ -54,14 +55,14 @@ class HavenBagsDependency {
bagSkin.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil skin.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
bagUpgrade.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.")
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(event.view, player, AnvilCost(event.view.repairCost))
return true
}
@ -69,8 +70,8 @@ class HavenBagsDependency {
return false
}
fun testAnvilResult(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
val result = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
fun testAnvilResult(event: InventoryClickEvent, view: AnvilView): Boolean {
val result = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)?.clone()
if (HavenBags.IsBag(result)) {
CustomAnvil.log("Detected anvil click haven bag bypass.")

View file

@ -8,17 +8,23 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.api.EnchantmentApi
import xyz.alexcrea.cuanvil.enchant.bulk.SuperEnchantBulkOperation
import xyz.alexcrea.cuanvil.enchant.wrapped.CASuperEnchantEnchantment
import java.util.logging.Level
class SuperEnchantDependency(override val plugin: SuperEnchants): GenericPluginDependency(plugin, false) {
class SuperEnchantDependency : GenericPluginDependency {
override val plugin: SuperEnchants
lateinit var enchManager: EnchantManager
val enchantments = ArrayList<CASuperEnchantEnchantment>()
constructor(plugin: Plugin) : super(plugin) {
this.plugin = plugin as SuperEnchants
}
fun registerEnchantments(): Boolean {
CustomAnvil.instance.logger.info("Preparing Super Enchant compatibility...")

View file

@ -5,7 +5,6 @@ import lol.hyper.toolstats.tools.ItemChecker
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import java.lang.reflect.Method

View file

@ -18,6 +18,7 @@ class EnchantConflictGroup(
fun addEnchantment(enchant: CAEnchantment) {
enchantments.add(enchant)
}
fun addEnchantments(enchants: List<CAEnchantment>) {
enchantments.addAll(enchants)
}

View file

@ -10,7 +10,6 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.util.MaterialUtil.customType
import java.util.*
import kotlin.collections.set
class EnchantConflictManager {
@ -140,7 +139,11 @@ class EnchantConflictManager {
return conflict
}
private fun fetchConditionalRestriction(restrictions: MutableMap<CAEnchantment, Int>, section: ConfigurationSection?, conflictName: String) {
private fun fetchConditionalRestriction(
restrictions: MutableMap<CAEnchantment, Int>,
section: ConfigurationSection?,
conflictName: String
) {
if (section == null) return
for (enchantName in section.getKeys(false)) {
val enchants = getEnchantByIdentifier(enchantName)
@ -175,7 +178,7 @@ class EnchantConflictManager {
}
}
return CAEnchantment.getListByName(enchantName)
return CAEnchantment.getByName(enchantName)
}

View file

@ -1,7 +1,6 @@
package xyz.alexcrea.cuanvil.group
import org.bukkit.NamespacedKey
import java.util.*
class ExcludeGroup(name: String) : AbstractMaterialGroup(name) {

View file

@ -1,8 +1,6 @@
package xyz.alexcrea.cuanvil.group
import org.bukkit.Material
import org.bukkit.NamespacedKey
import java.util.*
class IncludeGroup(name: String) : AbstractMaterialGroup(name) {
override fun createDefaultSet(): MutableSet<NamespacedKey> {

View file

@ -112,8 +112,7 @@ class ItemGroupManager {
if (!groupMap.containsKey(groupName)) {
if (!config.isConfigurationSection(groupName)) continue
createGroup(config, keys, groupName)
}
else groupMap[groupName]!!
} else groupMap[groupName]!!
// Avoid self reference or it will create an infinite loop
if (otherGroup.isReferencing(group)) {

View file

@ -5,16 +5,17 @@ import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
@Suppress("UnstableApiUsage")
class AnvilCloseListener(private val packetManager: PacketManager) : Listener {
@EventHandler
fun onAnvilClose(event: InventoryCloseEvent) {
val player = event.player
if(event.inventory !is AnvilInventory) return
if (event.view !is AnvilView) return
if (player is Player && GameMode.CREATIVE != player.gameMode) {
packetManager.setInstantBuild(player, false)
}

View file

@ -11,10 +11,9 @@ import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult
@ -37,6 +36,7 @@ import java.util.*
import java.util.concurrent.atomic.AtomicReference
import kotlin.math.min
@Suppress("UnstableApiUsage")
class AnvilResultListener : Listener {
companion object {
@ -51,50 +51,49 @@ class AnvilResultListener : Listener {
@EventHandler(ignoreCancelled = true)
fun anvilExtractionCheck(event: InventoryClickEvent) {
val player = event.whoClicked as? Player ?: return
val inventory = event.inventory as? AnvilInventory ?: return
val view = event.view
val view = event.view as? AnvilView ?: return
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
return
}
// Test if the event should bypass custom anvil.
if (DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
if (DependencyManager.tryClickAnvilResultBypass(event, view)) return
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
val output = view.getItem(ANVIL_OUTPUT_SLOT) ?: return
val leftItem = view.getItem(ANVIL_INPUT_LEFT) ?: return
val rightItem = view.getItem(ANVIL_INPUT_RIGHT)
// Deny by default. allow if working
event.result = Event.Result.DENY
if (GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) {
if (GameMode.CREATIVE != player.gameMode && view.repairCost >= view.maximumRepairCost) {
return
}
// Test custom recipe
val customRecipeResult = AnvilMergeLogic.testCustomRecipe(view, inventory, player, leftItem, rightItem)
val customRecipeResult = AnvilMergeLogic.testCustomRecipe(view, player, leftItem, rightItem)
if (!customRecipeResult.isEmpty()) {
onCustomCraft(
event, player, inventory,
event, player, view,
leftItem, rightItem, customRecipeResult
)
return
}
// Do not continue if there was no change
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))) {
if ((output == view.getItem(ANVIL_INPUT_LEFT))) {
return
}
// Rename
if (rightItem == null) {
val result = AnvilMergeLogic.doRenaming(view, inventory, player, leftItem)
val result = AnvilMergeLogic.doRenaming(view, player, leftItem)
if (result.isEmpty()) return
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
null, 0,
result
@ -105,10 +104,10 @@ class AnvilResultListener : Listener {
// Merge
val canMerge = leftItem.canMergeWith(rightItem)
if (canMerge) {
val result = AnvilMergeLogic.doMerge(view, inventory, player, leftItem, rightItem)
val result = AnvilMergeLogic.doMerge(view, player, leftItem, rightItem)
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
null, 0,
result
@ -118,12 +117,12 @@ class AnvilResultListener : Listener {
// Unit repair
val unitRepairResult = AnvilMergeLogic.testUnitRepair(
view, inventory, player,
view, player,
leftItem, rightItem
)
if (!unitRepairResult.isEmpty()) {
onUnitRepairExtract(
rightItem, event, player, inventory,
rightItem, event, player, view,
unitRepairResult
)
return
@ -133,9 +132,9 @@ class AnvilResultListener : Listener {
val loreResult = AnvilMergeLogic.testLoreEdit(player, leftItem, rightItem)
if (!loreResult.isEmpty()) {
if (loreResult.type.isBook)
handleBookLoreEdit(event, inventory, player, leftItem, rightItem, loreResult)
handleBookLoreEdit(event, view, player, leftItem, rightItem, loreResult)
else
handlePaperLoreEdit(event, inventory, player, leftItem, rightItem, loreResult)
handlePaperLoreEdit(event, view, player, leftItem, rightItem, loreResult)
return
}
}
@ -143,7 +142,7 @@ class AnvilResultListener : Listener {
private fun onCustomCraft(
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory,
view: AnvilView,
leftItem: ItemStack,
rightItem: ItemStack?,
result: CustomCraftResult,
@ -180,8 +179,7 @@ class AnvilResultListener : Listener {
// Handle not creative middle click...
if (event.click != ClickType.MIDDLE &&
!handleCustomCraftClick(
event,
inventory,
view,
player,
leftItem,
rightItem,
@ -198,8 +196,7 @@ class AnvilResultListener : Listener {
}
private fun handleCustomCraftClick(
event: InventoryClickEvent,
inventory: AnvilInventory, player: Player,
view: AnvilView, player: Player,
leftItem: ItemStack, rightItem: ItemStack?,
result: CustomCraftResult
): Boolean {
@ -211,11 +208,11 @@ class AnvilResultListener : Listener {
if (recipe.rightItem == null) return false// in case it changed
rightItem.amount -= amount * recipe.rightItem!!.amount
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
view.setItem(ANVIL_INPUT_RIGHT, rightItem)
}
leftItem.amount -= amount * recipe.leftItem!!.amount
inventory.setItem(ANVIL_INPUT_LEFT, leftItem)
view.setItem(ANVIL_INPUT_LEFT, leftItem)
removeCustomCraftCost(player, result)
@ -224,17 +221,15 @@ class AnvilResultListener : Listener {
CustomAnvil.verboseLog("new amount is $newAmount")
if (newAmount <= 0 || recipe.exactCount) {
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
view.setItem(ANVIL_OUTPUT_SLOT, null)
} else {
val resultItem: ItemStack = recipe.resultItem!!.clone()
resultItem.amount *= newAmount
val newXp = newAmount * newAmount
inventory.repairCost = newXp
event.view.setProperty(InventoryView.Property.REPAIR_COST, newXp)
inventory.setItem(ANVIL_OUTPUT_SLOT, resultItem)
view.repairCost = newXp
view.setItem(ANVIL_OUTPUT_SLOT, resultItem)
player.updateInventory()
}
@ -291,7 +286,7 @@ class AnvilResultListener : Listener {
private fun extractAnvilResult(
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory,
view: AnvilView,
leftItem: ItemStack?,
leftRemoveCount: Int,
rightItem: ItemStack?,
@ -305,7 +300,7 @@ class AnvilResultListener : Listener {
event.isCancelled = true
val cost = result.cost
processCost(inventory, player, cost)
processCost(view, player, cost)
if (!cost.valid && player.gameMode != GameMode.CREATIVE) return false
// Where should we get the item
@ -318,12 +313,12 @@ class AnvilResultListener : Listener {
// We remove what should be removed
if (leftItem != null) leftItem.amount -= leftRemoveCount
inventory.setItem(ANVIL_INPUT_LEFT, leftItem)
view.setItem(ANVIL_INPUT_LEFT, leftItem)
if (rightItem != null) rightItem.amount -= rightRemoveCount
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
view.setItem(ANVIL_INPUT_RIGHT, rightItem)
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
view.setItem(ANVIL_OUTPUT_SLOT, null)
}
@ -338,7 +333,7 @@ class AnvilResultListener : Listener {
return true
}
private fun processCost(inventory: AnvilInventory, player: Player, cost: AnvilCost) {
private fun processCost(view: AnvilView, player: Player, cost: AnvilCost) {
var sum = cost.repair
if (
@ -356,7 +351,7 @@ class AnvilResultListener : Listener {
if (!EconomyManager.economy!!.has(player, cost.asMonetaryCost()))
cost.valid = false
} else {
if ((inventory.maximumRepairCost <= sum)
if ((view.maximumRepairCost <= sum)
|| (player.level < sum)
) cost.valid = false
}
@ -366,12 +361,12 @@ class AnvilResultListener : Listener {
rightItem: ItemStack,
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory,
view: AnvilView,
result: UnitRepairResult,
) {
// We give the item manually
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
rightItem, result.repairAmount,
result
@ -380,21 +375,21 @@ class AnvilResultListener : Listener {
private fun handleBookLoreEdit(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
result: LoreEditResult
) {
if (result.type.isAppend)
handleBookLoreAppend(event, inventory, player, rightItem, result)
handleBookLoreAppend(event, view, player, rightItem, result)
else
handleBookLoreRemove(event, inventory, player, leftItem, rightItem, result)
handleBookLoreRemove(event, view, player, leftItem, rightItem, result)
}
private fun handleBookLoreAppend(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
rightItem: ItemStack,
result: LoreEditResult
@ -412,7 +407,7 @@ class AnvilResultListener : Listener {
}
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
clearedBook, 0,
result
@ -421,7 +416,7 @@ class AnvilResultListener : Listener {
private fun handleBookLoreRemove(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
@ -457,7 +452,7 @@ class AnvilResultListener : Listener {
}
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
rightCopy, 0,
result
@ -466,21 +461,21 @@ class AnvilResultListener : Listener {
private fun handlePaperLoreEdit(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
result: LoreEditResult
) {
if (result.type.isAppend)
handlePaperLoreAppend(event, inventory, player, rightItem, result)
handlePaperLoreAppend(event, view, player, rightItem, result)
else
handlePaperLoreRemove(event, inventory, player, leftItem, rightItem, result)
handlePaperLoreRemove(event, view, player, leftItem, rightItem, result)
}
private fun handlePaperLoreAppend(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
rightItem: ItemStack,
result: LoreEditResult
@ -505,14 +500,14 @@ class AnvilResultListener : Listener {
if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
event, player, view,
paperCopy, 0,
rightItem, 1,
result
)
} else {
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
paperCopy, 0,
result
@ -522,7 +517,7 @@ class AnvilResultListener : Listener {
private fun handlePaperLoreRemove(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
@ -557,14 +552,14 @@ class AnvilResultListener : Listener {
if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
event, player, view,
rightClone, 0,
rightItem, 1,
result
)
} else {
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
rightClone, 0,
result

View file

@ -41,9 +41,10 @@ class ChatEventListener : Listener {
// sync callback with default server thread
DependencyManager.scheduler.scheduleOnEntity(
CustomAnvil.instance, player,
Runnable {
{
eventCallback.accept(event.message)
}, 0L)
}, 0L
)
}
}

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.listener
import com.github.stefvanschie.inventoryframework.util.InventoryViewUtil
import io.delilaheve.CustomAnvil
import io.delilaheve.util.ConfigOptions
import io.delilaheve.util.ItemUtil.canMergeWith
@ -10,12 +9,11 @@ import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.meta.ItemMeta
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.doMerge
import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.doRenaming
@ -30,6 +28,7 @@ import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
/**
* Listener for anvil events
*/
@Suppress("UnstableApiUsage")
class PrepareAnvilListener : Listener {
companion object {
@ -48,9 +47,8 @@ class PrepareAnvilListener : Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
fun anvilCombineCheck(event: PrepareAnvilEvent) {
val view = event.view
val inventory = event.inventory
val player = view.player
val player = InventoryViewUtil.getInstance().getPlayer(view)
if (player !is Player) return
tryRenameDialog(player, event)
@ -58,12 +56,12 @@ class PrepareAnvilListener : Listener {
// Test if custom anvil is bypassed before immutability test
if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) {
// even if we got bypassed we still want to set price
AnvilXpUtil.setAnvilInvCost(inventory, view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(view, player, AnvilCost(view.repairCost))
return
}
val first = inventory.getItem(ANVIL_INPUT_LEFT)
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
val first = view.getItem(ANVIL_INPUT_LEFT)
val second = view.getItem(ANVIL_INPUT_RIGHT)
if (IS_EMPTY_TEST) {
IS_EMPTY_TEST = false
@ -86,27 +84,26 @@ class PrepareAnvilListener : Listener {
// Test if the event should bypass custom anvil.
if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
// even if we got bypassed we still want to set price
AnvilXpUtil.setAnvilInvCost(inventory, view, player, AnvilCost(event.inventory.repairCost))
AnvilXpUtil.setAnvilInvCost(view, player, AnvilCost(view.repairCost))
return
}
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
val result = getResult(view, inventory, player, first, second)
val result = getResult(view, player, first, second)
applyResult(event, player, result)
}
fun getResult(
view: InventoryView, //TODO use anvil view
inventory: AnvilInventory,
view: AnvilView,
player: Player,
first: ItemStack?, second: ItemStack?) : AnvilResult
{
first: ItemStack?, second: ItemStack?
): AnvilResult {
if (first == null)
return AnvilResult.EMPTY
// Test custom recipe
var result: AnvilResult = testCustomRecipe(view, inventory, player, first, second)
var result: AnvilResult = testCustomRecipe(view, player, first, second)
if (!result.isEmpty())
return result
@ -114,14 +111,14 @@ class PrepareAnvilListener : Listener {
val shouldTryRename = second.isAir
CustomAnvil.verboseLog("checking air in main logic: $shouldTryRename")
if (shouldTryRename)
return doRenaming(view, inventory, player, first)
return doRenaming(view, player, first)
// Test for merge
if (first.canMergeWith(second!!))
return doMerge(view, inventory, player, first, second)
return doMerge(view, player, first, second)
// Test for unit repair
result = testUnitRepair(view, inventory, player, first, second)
result = testUnitRepair(view, player, first, second)
if (!result.isEmpty())
return result
@ -175,7 +172,7 @@ class PrepareAnvilListener : Listener {
AnvilXpUtil.onNoResult(player, event.view)
return
}
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, result.cost, result.ignoreXpRules)
AnvilXpUtil.setAnvilInvCost(event.view, player, result.cost, result.ignoreXpRules)
}
}

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.util
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.inventory.ItemStack

View file

@ -9,10 +9,9 @@ import org.bukkit.GameMode
import org.bukkit.NamespacedKey
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Repairable
import org.bukkit.inventory.view.AnvilView
import org.bukkit.persistence.PersistentDataType
import xyz.alexcrea.cuanvil.anvil.AnvilCost
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
@ -23,6 +22,7 @@ import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.util.AnvilTitleUtil
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
@Suppress("UnstableApiUsage")
object AnvilXpUtil {
const val EXCLUSIVE_PENALTY_PREFIX = "repair_cost"
@ -31,17 +31,16 @@ object AnvilXpUtil {
* Display the required cost (either as xp or as )
*/
fun setAnvilInvCost(
inventory: AnvilInventory,
view: InventoryView,
view: AnvilView,
player: Player,
cost: AnvilCost,
ignoreRules: Boolean = false
) {
if (ConfigOptions.shouldUseMoney(player)) {
cost.isMonetary = true
setAnvilPrice(inventory, view, player, cost)
setAnvilPrice(view, player, cost)
} else
setAnvilInvXp(inventory, view, player, cost.filteredXpCost(ignoreRules), ignoreRules)
setAnvilInvXp(view, player, cost.filteredXpCost(ignoreRules), ignoreRules)
}
fun maximumXpCost(ignoreRules: Boolean = false): Int {
@ -56,8 +55,7 @@ object AnvilXpUtil {
* Display xp needed for the work on the anvil inventory
*/
private fun setAnvilInvXp(
inventory: AnvilInventory,
view: InventoryView,
view: AnvilView,
player: HumanEntity,
anvilCost: Int,
ignoreRules: Boolean = false
@ -65,9 +63,8 @@ object AnvilXpUtil {
val maximumRepairCost = maximumXpCost(ignoreRules)
// Try first just in case another plugin, or the test need this
inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = anvilCost
// TODO for 2.x.x use anvil view & set directly there
view.maximumRepairCost = maximumRepairCost
view.repairCost = anvilCost
/* Because Minecraft likes to have the final say in the repair cost displayed
* we need to wait for the event to end before overriding it, this ensures that
@ -76,16 +73,15 @@ object AnvilXpUtil {
CustomAnvil.instance, player
) {
// retry after a tick
inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = anvilCost
// TODO for 2.x.x use anvil view & set directly there
view.maximumRepairCost = maximumRepairCost
view.repairCost = anvilCost
if (player !is Player) return@scheduleOnEntity
if (player.gameMode != GameMode.CREATIVE) {
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
(anvilCost >= 40) &&
anvilCost < inventory.maximumRepairCost
anvilCost < view.maximumRepairCost
DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive)
}
@ -98,8 +94,7 @@ object AnvilXpUtil {
* Display monetary cost needed for the work on the anvil inventory
*/
private fun setAnvilPrice(
inventory: AnvilInventory,
view: InventoryView,
view: AnvilView,
player: Player,
cost: AnvilCost,
) {
@ -117,22 +112,20 @@ object AnvilXpUtil {
CustomAnvil.instance
)
clearAnvilXpCost(inventory, view, player)
clearAnvilXpCost(view, player)
}
private fun clearAnvilXpCost(
inventory: AnvilInventory,
view: InventoryView,
view: AnvilView,
player: HumanEntity,
) {
// TODO for 2.x.x use anvil view & set directly there
inventory.repairCost = 0
view.repairCost = 0
// retry after a tick
DependencyManager.scheduler.scheduleOnEntity(
CustomAnvil.instance, player
) {
inventory.repairCost = 0
view.repairCost = 0
if (player !is Player) return@scheduleOnEntity
player.updateInventory()
@ -185,7 +178,7 @@ object AnvilXpUtil {
return resultSum
}
fun onNoResult(player: HumanEntity, view: InventoryView) {
fun onNoResult(player: HumanEntity, view: AnvilView) {
if (ConfigOptions.shouldUseMoney(player))
AnvilTitleUtil.rename(
view, "Repair & Name",

View file

@ -160,10 +160,7 @@ restriction_sweeping_edge:
enchantments: [ minecraft:sweeping, minecraft:sweeping_edge ]
notAffectedGroups: [ enchanted_book, swords ]
# Do not exist in 1.18, that mean useInFuture will be set to true
# useInFuture set to true also mean it will not warn if there is an issue
restriction_swift_sneak:
useInFuture: true
enchantments: [ minecraft:swift_sneak ]
notAffectedGroups: [ enchanted_book, leggings ]

View file

@ -121,7 +121,6 @@ wearable:
- player_head
- creeper_head
- dragon_head
# do not exist in 1.18 but exist in future update
- piglin_head
groups:
- armors

View file

@ -4,7 +4,7 @@ prefix: "Custom Anvil"
version: ${version}
folia-supported: true
description: Allow to customise anvil mechanics
api-version: 1.16
api-version: 1.21
load: POSTWORLD
authors: [ DelilahEve, alexcrea ]
libraries: [${libraries}]

View file

@ -70,7 +70,7 @@ public class AnvilFuseTestUtil {
List<CAEnchantment> enchantments = new ArrayList<>();
for (String enchantmentName : enchantmentNames) {
List<CAEnchantment> enchantmentList = CAEnchantment.getListByName(enchantmentName);
List<CAEnchantment> enchantmentList = CAEnchantment.getByName(enchantmentName);
Assertions.assertNotEquals(0, enchantmentList.size(),
"Could not find enchantment \"" + enchantmentName + "\"");