big cleanup & update legacy code

This commit is contained in:
alexcrea 2025-06-14 17:49:41 +02:00 committed by alexcrea
parent eaa9adf213
commit 6ede990987
Signed by: alexcrea
GPG key ID: E346CD16413450E3
38 changed files with 282 additions and 312 deletions

View file

@ -6,14 +6,14 @@ interface ExternGuiTester {
val wesjdAnvilGuiName: String?
fun getContainerClass(inventory: InventoryView): Class<Any>?
fun getContainerClass(view: InventoryView): Class<Any>?
fun testIfGui(inventory: InventoryView): Boolean {
fun testIfGui(view: InventoryView): Boolean {
// this mean we are on test
//TODO review why needed knowing previous mitigations should works
if(inventory.javaClass.name.endsWith("AnvilViewMock")) return false
if(view.javaClass.name.endsWith("AnvilViewMock")) return false
val clazz = getContainerClass(inventory) ?: return false
val clazz = getContainerClass(view) ?: return false
val clazzName = clazz.name
//TODO maybe instead of testing non default, better to be testing we are default ?

View file

@ -2,37 +2,12 @@ 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
.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){
// Assume cause UnimplementedOperationException on mock server
return Collections.emptyList()
}
return Bukkit.getDatapackManager().enabledPacks
.stream().map { obj: Datapack -> obj.name }
.toList()
}
}

View file

@ -4,11 +4,11 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView
import org.bukkit.inventory.InventoryView
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
class v1_21R1_ExternGuiTester: ExternGuiTester {
class v1_21R1_ExternGuiTester : ExternGuiTester {
override val wesjdAnvilGuiName = "Wrapper1_21_R1"
override fun getContainerClass(view: InventoryView): Class<Any>? {
if(view !is CraftInventoryView<*, *>) return null
if (view !is CraftInventoryView<*, *>) return null
val container = view.handle
return container.javaClass

View file

@ -4,11 +4,10 @@ import io.papermc.paper.threadedregions.scheduler.ScheduledTask
import org.bukkit.Bukkit
import org.bukkit.entity.Entity
import org.bukkit.plugin.Plugin
import java.util.function.Consumer
class FoliaScheduler : TaskScheduler {
override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any? {
if(time < 1){
override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any {
if (time < 1) {
return Bukkit.getGlobalRegionScheduler().run(
plugin
) { scheduledTask: ScheduledTask? -> task.run() }
@ -22,7 +21,7 @@ class FoliaScheduler : TaskScheduler {
override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any? {
if(time < 1){
if (time < 1) {
return entity.scheduler.run(
plugin,
{ scheduledTask: ScheduledTask? -> task.run() },

View file

@ -4,31 +4,14 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView
import org.bukkit.inventory.InventoryView
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
class v1_21R2_ExternGuiTester: ExternGuiTester {
class v1_21R2_ExternGuiTester : ExternGuiTester {
override val wesjdAnvilGuiName = "Wrapper1_21_R2"
var tested = false;
var possible = false;
override fun getContainerClass(view: InventoryView): Class<Any>? {
// In case we are in a test environment
if(!tested) testClassExist()
if(!possible) return null
if(view !is CraftInventoryView<*, *>) return null
if (view !is CraftInventoryView<*, *>) return null
val container = view.handle
return container.javaClass
}
fun testClassExist(){
tested = true;
try {
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
possible = true
} catch (e: ClassNotFoundException){
possible = false
}
}
}

View file

@ -4,29 +4,29 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView
import org.bukkit.inventory.InventoryView
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
class v1_21R4_ExternGuiTester: ExternGuiTester {
class v1_21R4_ExternGuiTester : ExternGuiTester {
override val wesjdAnvilGuiName = "Wrapper1_21_R4"
var tested = false;
var possible = false;
var tested = false
var possible = false
override fun getContainerClass(view: InventoryView): Class<Any>? {
// In case we are in a test environment
if(!tested) testClassExist()
if(!possible) return null
if (!tested) testClassExist()
if (!possible) return null
if(view !is CraftInventoryView<*, *>) return null
if (view !is CraftInventoryView<*, *>) return null
val container = view.handle
return container.javaClass
}
fun testClassExist(){
tested = true;
fun testClassExist() {
tested = true
try {
Class.forName("org.bukkit.craftbukkit.inventory.CraftInventoryView")
possible = true
} catch (e: ClassNotFoundException){
} catch (e: ClassNotFoundException) {
possible = false
}
}

View file

@ -116,7 +116,7 @@ public class EnchantmentApi {
* @return True if successful.
*/
public static boolean unregisterEnchantment(@NotNull Enchantment enchantment){
return unregisterEnchantment(enchantment.getKey());
return unregisterEnchantment(enchantment.getKeyOrThrow());
}
/**

View file

@ -164,7 +164,7 @@ public class MaterialGroupApi {
}
public static List<String> materialSetToStringList(@NotNull Set<Material> materials) {
return materials.stream().map(material -> material.getKey().getKey().toLowerCase()).toList();
return materials.stream().map(material -> material.getKeyOrThrow().getKey().toLowerCase()).toList();
}
public static List<String> materialGroupSetToStringList(@NotNull Set<AbstractMaterialGroup> groups) {

View file

@ -9,7 +9,6 @@ import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui;
import java.util.ArrayList;
@ -22,7 +21,8 @@ import java.util.List;
@SuppressWarnings("unused")
public class UnitRepairApi {
private UnitRepairApi(){}
private UnitRepairApi() {
}
private static Object saveChangeTask = null;
@ -35,7 +35,7 @@ public class UnitRepairApi {
* @param repairable The item to be repaired.
* @return true if successful.
*/
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable){
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable) {
return addUnitRepair(unit, repairable, 0.25, false);
}
@ -48,7 +48,7 @@ public class UnitRepairApi {
* @param value The amount to be repaired by every unit. (1% = 0.01)
* @return true if successful.
*/
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value){
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value) {
return addUnitRepair(unit, repairable, value, false);
}
@ -62,12 +62,12 @@ public class UnitRepairApi {
* @param overrideDeleted If we should write even if the recipe was previously deleted.
* @return true if successful.
*/
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value, boolean overrideDeleted){
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value, boolean overrideDeleted) {
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
String path = unit.name().toLowerCase() + "." + repairable.name().toLowerCase();
if(!overrideDeleted && ConfigHolder.UNIT_REPAIR_HOLDER.isDeleted(path)) return false;
if(config.contains(path)) return false;
if (!overrideDeleted && ConfigHolder.UNIT_REPAIR_HOLDER.isDeleted(path)) return false;
if (config.contains(path)) return false;
// Set unit repair
return setUnitRepair(unit, repairable, value);
@ -82,7 +82,7 @@ public class UnitRepairApi {
* @param value The amount to be repaired by every unit. (1% = 0.01)
* @return true if successful.
*/
public static boolean setUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value){
public static boolean setUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value) {
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
String repairableName = repairable.name().toLowerCase();
@ -94,10 +94,10 @@ public class UnitRepairApi {
// Add to gui
UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance();
if(repairConfigGui != null) {
if (repairConfigGui != null) {
UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit).getStored();
if(elementGui != null) elementGui.updateValueForGeneric(repairableName, true);
if (elementGui != null) elementGui.updateValueForGeneric(repairableName, true);
repairConfigGui.updateValueForGeneric(unit, true);
}
@ -111,7 +111,7 @@ public class UnitRepairApi {
* @param repairable The item used to be repaired.
* @return true if successful.
*/
public static boolean removeUnitRepair(@NotNull Material unit, @NotNull Material repairable){
public static boolean removeUnitRepair(@NotNull Material unit, @NotNull Material repairable) {
// Delete every possible variation and save to file
String unitName = unit.name();
String repairableName = repairable.name();
@ -124,17 +124,17 @@ public class UnitRepairApi {
// Test if it was the last value of this section
boolean lastValue = false;
if(config.isConfigurationSection(unitName.toLowerCase())) {
if (config.isConfigurationSection(unitName.toLowerCase())) {
ConfigurationSection section = config.getConfigurationSection(unitName.toLowerCase());
if(section != null && section.getKeys(false).isEmpty()) {
if (section != null && section.getKeys(false).isEmpty()) {
lastValue = true;
config.set(unitName.toLowerCase(), null);
}
} else if (config.isConfigurationSection(unitName.toUpperCase())) {
ConfigurationSection section = config.getConfigurationSection(unitName.toUpperCase());
if(section != null && section.getKeys(false).isEmpty()) {
if (section != null && section.getKeys(false).isEmpty()) {
lastValue = true;
config.set(unitName.toUpperCase(), null);
}
@ -148,11 +148,11 @@ public class UnitRepairApi {
// Remove from gui
UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance();
if(repairConfigGui != null) {
if (repairConfigGui != null) {
UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit).getStored();
if(elementGui != null) elementGui.removeGeneric(repairableName);
if(lastValue){
if (elementGui != null) elementGui.removeGeneric(repairableName);
if (lastValue) {
repairConfigGui.removeGeneric(unit);
}
}
@ -164,9 +164,9 @@ public class UnitRepairApi {
* Prepare a task to save custom unit repair recipe configuration.
*/
private static void prepareSaveTask() {
if(saveChangeTask != null) return;
if (saveChangeTask != null) return;
saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{
saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, () -> {
ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true);
saveChangeTask = null;
});
@ -174,6 +174,7 @@ public class UnitRepairApi {
/**
* Get every unit repair recipes.
*
* @return An immutable collection of unit repair recipes.
* <p>
* Each element of the provided triple represent a part of the recipe
@ -184,27 +185,28 @@ public class UnitRepairApi {
* </ul>
*/
@NotNull
public static List<Triple<Material, Material, Double>> getUnitRepairs(){
public static List<Triple<Material, Material, Double>> getUnitRepairs() {
List<Triple<Material, Material, Double>> mutableList = new ArrayList<>();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
for (String unitKey : config.getKeys(false)) {
// Test if config section exist
if(!config.isConfigurationSection(unitKey)) continue;
if (!config.isConfigurationSection(unitKey)) continue;
// Test if unit is a material
Material unit = Material.getMaterial(unitKey.toUpperCase());
if(unit == null) continue;
if (unit == null) continue;
// Iterate over reparable items
ConfigurationSection section = config.getConfigurationSection(unitKey);
assert section != null; // We tested config.isConfigurationSection(unitKey)
for (String repairableKey : section.getKeys(false)) {
// Test if value section exist
if(!section.isDouble(repairableKey)) continue;
if (!section.isDouble(repairableKey)) continue;
// Test if repairable is valid a material
Material repairable = Material.getMaterial(repairableKey.toUpperCase());
if(repairable == null) continue;
if (repairable == null) continue;
// Add the values
mutableList.add(new Triple<>(unit, repairable, section.getDouble(repairableKey)));

View file

@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.api.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when the configuration of CustomAnvil is ready.
@ -29,7 +30,7 @@ public class CAConfigReadyEvent extends Event {
}
@Override
public HandlerList getHandlers() {
public @NotNull HandlerList getHandlers() {
return HANDLERS;
}

View file

@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.api.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
/**
* Called when custom anvil is ready to accept registration on custom enchantment.
@ -23,7 +24,7 @@ public class CAEnchantRegistryReadyEvent extends Event {
}
@Override
public HandlerList getHandlers() {
public @NotNull HandlerList getHandlers() {
return HANDLERS;
}
}

View file

@ -26,6 +26,7 @@ public abstract class ConfigHolder {
/**
* Load default configuration.
*
* @return True if successful.
*/
public static boolean loadDefaultConfig() {
@ -36,6 +37,7 @@ public abstract class ConfigHolder {
/**
* Load non default configuration.
*
* @return True if successful.
*/
public static boolean loadNonDefaultConfig() {
@ -54,7 +56,7 @@ public abstract class ConfigHolder {
return removeNonDefaultFromDisk(hardfail);
}
private static boolean removeNonDefaultFromDisk(boolean hardfail){
private static boolean removeNonDefaultFromDisk(boolean hardfail) {
boolean sucess = ITEM_GROUP_HOLDER.reloadFromDisk(hardfail);
if (!sucess) return false;
sucess = CONFLICT_HOLDER.reloadFromDisk(hardfail);
@ -105,7 +107,7 @@ public abstract class ConfigHolder {
// Save logic
public boolean saveToDisk(boolean doBackup) {
CustomAnvil.Companion.log("Saving "+getConfigFileName());
CustomAnvil.Companion.log("Saving " + getConfigFileName());
if (doBackup) {
if (!saveBackup()) {
CustomAnvil.instance.getLogger().severe("Could not save backup. see above.");
@ -122,12 +124,11 @@ public abstract class ConfigHolder {
try {
config.save(base);
} catch (IOException e) {
e.printStackTrace();
CustomAnvil.instance.getLogger().severe("Could not save config...");
CustomAnvil.instance.getLogger().log(Level.SEVERE, "Could not save config...", e);
return false;
}
CustomAnvil.Companion.log(getConfigFileName()+" saved successfully");
CustomAnvil.Companion.log(getConfigFileName() + " saved successfully");
return true;
}
@ -137,6 +138,7 @@ public abstract class ConfigHolder {
boolean sufficientSuccess = false;
BACKUP_FOLDER.mkdirs();
// save first backup if do not exist
File firstBackup = getFirstBackup();
if (!firstBackup.exists()) {
@ -158,7 +160,7 @@ public abstract class ConfigHolder {
Files.move(base, lastBackup);
sufficientSuccess = true;
} catch (IOException e) {
e.printStackTrace();
CustomAnvil.instance.getLogger().log(Level.SEVERE, "Exception while moving backup file " + base.getName(), e);
}
return sufficientSuccess;
@ -213,7 +215,7 @@ public abstract class ConfigHolder {
}
public abstract static class DeletableResource extends ResourceConfigHolder{
public abstract static class DeletableResource extends ResourceConfigHolder {
private static final String DELETED_FOLDER_PATH = "deleted";
@ -221,6 +223,7 @@ public abstract class ConfigHolder {
private final @NotNull File deletedConfigFile;
private @Nullable YamlConfiguration deletedListConfig;
private DeletableResource(String resourceName) {
super(resourceName);
this.parent = new File(CustomAnvil.instance.getDataFolder(), DELETED_FOLDER_PATH);
@ -229,57 +232,62 @@ public abstract class ConfigHolder {
@Override
public boolean reloadFromDisk(boolean hardFail) {
if(!super.reloadFromDisk(hardFail)) return false;
if (!super.reloadFromDisk(hardFail)) return false;
loadDeletedListFile(hardFail);
return true;
}
private void loadDeletedListFile(boolean hardFail){
private void loadDeletedListFile(boolean hardFail) {
this.deletedListConfig = CustomAnvil.instance.reloadResource(this.deletedConfigFile, hardFail);
}
/**
* Test if the provided element was deleted.
*
* @param objectPath The object path to delete.
* @return True if successful.
*/
public boolean isDeleted(String objectPath){
if(this.deletedListConfig == null) return false;
public boolean isDeleted(String objectPath) {
if (this.deletedListConfig == null) return false;
return this.deletedListConfig.getBoolean(objectPath, false);
}
/**
* Delete a certain object by its path. do not save the config.
*
* @param objectPath The object path to delete.
* @return True if successful.
*/
public boolean delete(String objectPath){
public boolean delete(String objectPath) {
return delete(objectPath, false, false);
}
/**
* Delete a certain object by its path.
*
* @param objectPath The object path to delete.
* @param doSave If we should save the config after deleting.
* @param doBackup If we should create a backup.
* @param doSave If we should save the config after deleting.
* @param doBackup If we should create a backup.
* @return True if successful.
*/
public boolean delete(String objectPath, boolean doSave, boolean doBackup){
public boolean delete(String objectPath, boolean doSave, boolean doBackup) {
// Create deleted list if it does not yet exist
if(this.deletedListConfig == null){
if (this.deletedListConfig == null) {
this.parent.mkdirs();
try {
this.deletedConfigFile.createNewFile();
if (!this.deletedConfigFile.createNewFile()) {
throw new RuntimeException("Could not create \"deleted config\" file");
}
} catch (IOException e) {
CustomAnvil.instance.getLogger().log(Level.WARNING, "Could not create " + this.deletedConfigFile.getPath(), e);
}
loadDeletedListFile(false);
// Something was wrong somehow
if(this.deletedListConfig == null) return false;
if (this.deletedListConfig == null) return false;
}
// Add to the deleted config
@ -287,7 +295,7 @@ public abstract class ConfigHolder {
this.getConfig().set(objectPath, null);
// Save the deleted config (may not be the most efficient, but I will handle it later)
if(doSave){
if (doSave) {
return saveToDisk(doBackup);
}
@ -303,10 +311,11 @@ public abstract class ConfigHolder {
/**
* Save list of deleted elements.
*
* @return true if successful.
*/
public boolean saveDeletedList() {
if(this.deletedListConfig == null) return true;
if (this.deletedListConfig == null) return true;
try {
this.deletedListConfig.save(this.deletedConfigFile);

View file

@ -2,7 +2,7 @@ package xyz.alexcrea.cuanvil.enchant;
import io.delilaheve.CustomAnvil;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.Registry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
@ -53,9 +53,9 @@ public class CAEnchantmentRegistry {
*/
public void registerBukkit() {
// Register enchantment
for (Enchantment enchantment : Enchantment.values()) {
register(new CABukkitEnchantment(enchantment));
}
Registry.ENCHANTMENT.iterator().forEachRemaining(enchantment ->
register(new CABukkitEnchantment(enchantment))
);
// Add bukkit enchantment bulk operation
BukkitEnchantBulkOperation bukkitOperation = new BukkitEnchantBulkOperation();

View file

@ -33,9 +33,9 @@ public class BukkitEnchantBulkOperation implements BulkGetEnchantOperation, Bulk
}
public void addEnchantment(@NotNull Map<CAEnchantment, Integer> enchantmentMap, @NotNull Enchantment enchantment, int level) {
CAEnchantment enchant = EnchantmentApi.getByKey(enchantment.getKey());
CAEnchantment enchant = EnchantmentApi.getByKey(enchantment.getKeyOrThrow());
if (enchant == null) {
CustomAnvil.instance.getLogger().warning("Enchantment of key " + enchantment.getKey() +
CustomAnvil.instance.getLogger().warning("Enchantment of key " + enchantment.getKeyOrThrow() +
" somehow not found in CustomAnvil ?");
return;
}

View file

@ -30,7 +30,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
public final @NotNull Enchantment bukkit;
public CABukkitEnchantment(@NotNull Enchantment bukkit, @Nullable EnchantmentRarity rarity) {
super(bukkit.getKey(),
super(bukkit.getKeyOrThrow(),
rarity,
bukkit.getMaxLevel());
this.bukkit = bukkit;
@ -103,8 +103,8 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
@NotNull
public static EnchantmentRarity getRarity(Enchantment enchantment) {
try {
return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();
} catch (IllegalArgumentException ignored) {
return EnchantmentProperties.valueOf(enchantment.getKeyOrThrow().getKey().toUpperCase(Locale.ENGLISH)).getRarity();
} catch (Exception ignored) {
return findRarity(enchantment);
}
}

View file

@ -5,7 +5,6 @@ import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import org.bukkit.event.inventory.InventoryClickEvent;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
@ -20,7 +19,7 @@ import java.util.function.Consumer;
*
* @param <T> Type of the factory of the type of setting the gui should edit.
*/
public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFactory> extends SettingGuiListConfigGui<CAEnchantment, T>{
public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFactory> extends SettingGuiListConfigGui<CAEnchantment, T> {
/**
* Constructor for a gui displaying available enchantment to edit a enchantment setting.
@ -42,7 +41,7 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
}
@Override
protected Pattern getBackgroundPattern(){
protected Pattern getBackgroundPattern() {
return new Pattern(
GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
@ -59,12 +58,12 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
}
public void updateValueForGeneric(CAEnchantment generic, boolean shouldUpdate, boolean prepareSorting) {
if(!prepareSorting) {
if (!prepareSorting) {
super.updateValueForGeneric(generic, shouldUpdate);
return;
}
if(!this.factoryMap.containsKey(generic)){
if (!this.factoryMap.containsKey(generic)) {
// We need to sort elements again
super.updateValueForGeneric(generic, false);
@ -76,17 +75,17 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
for (CAEnchantment enchantment : getEveryDisplayableInstanceOfGeneric()) {
GuiItem item = this.guiItemMap.get(enchantment);
if(item == null) {
if (item == null) {
updateValueForGeneric(enchantment, false, false);
}else {
} else {
addToPage(item);
}
}
if(shouldUpdate) update();
if (shouldUpdate) update();
}else{
} else {
super.updateValueForGeneric(generic, shouldUpdate);
}
@ -104,6 +103,7 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
protected List<String> getCreateItemLore() {
return Collections.emptyList();
}
@Override
protected Consumer<InventoryClickEvent> getCreateClickConsumer() {
return null;

View file

@ -27,6 +27,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Global config to edit basic basic settings.
@ -188,7 +189,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
range = ConfigOptions.ITEM_RENAME_COST_RANGE;
this.itemRenameCost = new IntSettingsGui.IntSettingFactory("§8Rename Cost", this,
ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList(
List.of(
"§7XP Level amount added to the anvil when the item is renamed."
),
range.getFirst(), range.getLast(),

View file

@ -7,8 +7,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.EnchantmentProperties;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
@ -37,7 +35,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
*/
public EnchantCostConfigGui() {
super("§8Enchantment Level Cost");
if(INSTANCE == null) INSTANCE = this;
if (INSTANCE == null) INSTANCE = this;
init();
}
@ -74,7 +72,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
lore.add("§7Book Cost: §e" + bookCost);
List<String> displayLore = factory.getDisplayLore();
if(!displayLore.isEmpty()){
if (!displayLore.isEmpty()) {
lore.add("");
lore.addAll(displayLore);
}

View file

@ -15,7 +15,6 @@ import xyz.alexcrea.cuanvil.group.ItemGroupManager;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui;
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.LazyValue;
import java.util.ArrayList;
import java.util.Arrays;
@ -26,13 +25,13 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, MappedG
private static GroupConfigGui INSTANCE;
@Nullable
public static GroupConfigGui getCurrentInstance(){
public static GroupConfigGui getCurrentInstance() {
return INSTANCE;
}
@NotNull
public static GroupConfigGui getInstance(){
if(INSTANCE == null) INSTANCE = new GroupConfigGui();
public static GroupConfigGui getInstance() {
if (INSTANCE == null) INSTANCE = new GroupConfigGui();
return INSTANCE;
}
@ -50,12 +49,12 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, MappedG
assert meta != null;
meta.addItemFlags(ItemFlag.values());
meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName())+ " §fGroup");
meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " §fGroup");
meta.setLore(Arrays.asList(
"§7Number of selected groups : " + group.getGroups().size(),
"§7Number of included material : " + group.getNonGroupInheritedMaterials().size(),
"",
"§7Total number of included material "+group.getMaterials().size()));
"§7Total number of included material " + group.getMaterials().size()));
item.setItemMeta(meta);
return item;
@ -66,7 +65,7 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, MappedG
ArrayList<IncludeGroup> includeGroups = new ArrayList<>();
for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) {
if(group instanceof IncludeGroup){
if (group instanceof IncludeGroup) {
includeGroups.add((IncludeGroup) group);
}
}
@ -86,10 +85,10 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, MappedG
@Override
protected IncludeGroup createAndSaveNewEmptyGeneric(String name) {
ItemGroupManager manager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager();
if(manager.getGroupMap().containsKey(name)) return null;
if (manager.getGroupMap().containsKey(name)) return null;
ConfigurationSection config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
config.set(name+"."+ItemGroupManager.GROUP_TYPE_PATH, GroupType.INCLUDE.getGroupID());
config.set(name + "." + ItemGroupManager.GROUP_TYPE_PATH, GroupType.INCLUDE.getGroupID());
return (IncludeGroup) manager.createGroup(config, name);
}

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import io.delilaheve.CustomAnvil;

View file

@ -21,10 +21,7 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.function.Consumer;
public class DoubleSettingGui extends AbstractSettingGui {
@ -413,11 +410,7 @@ public class DoubleSettingGui extends AbstractSettingGui {
this.steps[i] = BigDecimal.valueOf(steps[i]).setScale(scale, RoundingMode.HALF_UP);
}
if(displayLore == null){
this.displayLore = Collections.emptyList();
}else {
this.displayLore = displayLore;
}
this.displayLore = Objects.requireNonNullElse(displayLore, Collections.emptyList());
}
/**

View file

@ -20,6 +20,7 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
/**
@ -321,11 +322,7 @@ public class IntSettingsGui extends AbstractSettingGui {
this.defaultVal = defaultVal;
this.steps = steps;
if(displayLore == null){
this.displayLore = Collections.emptyList();
}else {
this.displayLore = displayLore;
}
this.displayLore = Objects.requireNonNullElse(displayLore, Collections.emptyList());
}
/**

View file

@ -26,25 +26,24 @@ public class PUpdate_1_8_0 {
partEnum = new EnumMap<>(ConfigOptions.INSTANCE.getWorkPenaltyType().getPartMap());
boolean keepIncrease;
boolean keepAdditive;
switch (penaltyTypeValue.toLowerCase()) {
case "add_only":
boolean keepAdditive = switch (penaltyTypeValue.toLowerCase()) {
case "add_only" -> {
keepIncrease = false;
keepAdditive = true;
break;
case "increase_only":
yield true;
}
case "increase_only" -> {
keepIncrease = true;
keepAdditive = false;
break;
case "disabled":
yield false;
}
case "disabled" -> {
keepIncrease = false;
keepAdditive = false;
break;
default:
yield false;
}
default -> {
keepIncrease = true;
keepAdditive = true;
}
yield true;
}
};
for (AnvilUseType type : partEnum.keySet()) {
WorkPenaltyType.WorkPenaltyPart part = partEnum.get(type);

View file

@ -87,7 +87,7 @@ object ConfigOptions {
const val DEFAULT_ITEM_RENAME_COST = 1
const val DEFAULT_SACRIFICE_ILLEGAL_COST = 1
const val DEFAULT_ADD_BOOK_ENCHANTMENT_AS_STORED_ENCHANTMENT = false;
const val DEFAULT_ADD_BOOK_ENCHANTMENT_AS_STORED_ENCHANTMENT = false
const val DEFAULT_ENCHANT_COUNT_LIMIT = -1

View file

@ -8,12 +8,12 @@ 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.ItemStack
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.CATreatAnvilResultEvent
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
@ -28,23 +28,25 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT
import xyz.alexcrea.cuanvil.util.AnvilUseType
import java.util.logging.Level
@Suppress("unstableApiUsage")
object DependencyManager {
var isFolia: Boolean = false
lateinit var scheduler: TaskScheduler
lateinit var packetManager: PacketManager
var externGuiTester: ExternGuiTester? = null
private var externGuiTester: ExternGuiTester? = null
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
var ecoEnchantCompatibility: EcoEnchantDependency? = null
var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null
private var ecoEnchantCompatibility: EcoEnchantDependency? = null
private var excellentEnchantsCompatibility: ExcellentEnchantsDependency? = null
var disenchantmentCompatibility: DisenchantmentDependency? = null
var havenBagsCompatibility: HavenBagsDependency? = null
private var disenchantmentCompatibility: DisenchantmentDependency? = null
private var havenBagsCompatibility: HavenBagsDependency? = null
var axPlayerWarpsCompatibility: AxPlayerWarpsDependency? = null
val genericDependencies = ArrayList<GenericPluginDependency>()
private val genericDependencies = ArrayList<GenericPluginDependency>()
fun loadDependency() {
val pluginManager = Bukkit.getPluginManager()
@ -128,7 +130,7 @@ object DependencyManager {
ecoEnchantCompatibility?.handleConfigReload()
}
// Return true if should bypass (either by a dependency or error)
// Return true if we should bypass (either by a dependency or error)
// called before immutability test
fun earlyTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
try {
@ -168,7 +170,7 @@ object DependencyManager {
return bypass
}
// Return true if should bypass (either by a dependency or error)
// Return true if we should bypass (either by a dependency or error)
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
try {
return unsafeTryEventPreAnvilBypass(event, player)
@ -247,10 +249,10 @@ object DependencyManager {
excellentEnchantsCompatibility?.treatAnvilResult(event)
}
// Return true if should bypass (either by a dependency or error)
fun tryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
// Return true if we should bypass (either by a dependency or error)
fun tryClickAnvilResultBypass(event: InventoryClickEvent, view: AnvilView): Boolean {
try {
return unsafeTryClickAnvilResultBypass(event, inventory)
return unsafeTryClickAnvilResultBypass(event, view)
} catch (e: Exception) {
CustomAnvil.instance.logger.log(
Level.SEVERE,
@ -270,7 +272,7 @@ object DependencyManager {
}
}
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)
@ -278,10 +280,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

View file

@ -22,13 +22,13 @@ object DataPackDependency {
/**
* Map of the latest CustomAnvil update related to the pack
*/
private val LASTEST_VERSION = mapOf(
private val LATEST_VERSION = mapOf(
Pair("bracken", Version(1, 11, 0)),
Pair("enchantplus", Version(1, 13, 0)),
Pair("dungeons_and_taverns", Version(1, 13, 0))
)
val enabledDatapacks: List<String>
private val enabledDatapacks: List<String>
get() {
val version: Version = UpdateUtils.currentMinecraftVersion()
if (version.lesserThan(START_DETECT_VERSION)) return emptyList()
@ -71,7 +71,7 @@ object DataPackDependency {
private fun handlePackInitialConfig(pack: String) {
val defConfig = ConfigHolder.DEFAULT_CONFIG
val version = LASTEST_VERSION[pack]
val version = LATEST_VERSION[pack]
if(version == null) {
throw RuntimeException("The pack $pack has no latest version hard coded in the plugin")
}

View file

@ -1,7 +1,10 @@
package xyz.alexcrea.cuanvil.dependency.packet
import org.bukkit.Bukkit
import xyz.alexcrea.cuanvil.dependency.packet.versions.*
import xyz.alexcrea.cuanvil.dependency.packet.versions.V1_21R1_PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.versions.V1_21R2_PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.versions.V1_21R3_PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.versions.V1_21R4_PacketManager
import xyz.alexcrea.cuanvil.update.UpdateUtils
object PacketManagerSelector {

View file

@ -11,13 +11,14 @@ import org.bukkit.entity.HumanEntity
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.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
import java.util.logging.Level
import kotlin.reflect.KClass
@Suppress("unstableApiUsage")
class DisenchantmentDependency {
init {
@ -55,14 +56,14 @@ class DisenchantmentDependency {
DisenchantEvent.onEvent(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil item extract bypass.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
AnvilXpUtil.setAnvilInvXp(event.view, player)
return true
}
ShatterEvent.onEvent(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil split enchant bypass.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
AnvilXpUtil.setAnvilInvXp(event.view, player)
return true
}
@ -70,18 +71,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 (!testAnvilInventoryChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click item extract bypass.")
return true
}
ShatterClickEvent.onEvent(event)
if (!testAnvilInventoryChange(inventory, previousResultSlot) || event.isCancelled) {
if (!testAnvilInventoryChange(view, previousResultSlot) || event.isCancelled) {
CustomAnvil.log("Detected anvil click split enchant bypass.")
return true
}
@ -89,8 +90,8 @@ class DisenchantmentDependency {
return false
}
private fun testAnvilInventoryChange(inventory: AnvilInventory, previous: ItemStack?): Boolean {
val currentResult = inventory.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
private fun testAnvilInventoryChange(view: AnvilView, previous: ItemStack?): Boolean {
val currentResult = view.getItem(PrepareAnvilListener.ANVIL_OUTPUT_SLOT)
return currentResult == previous
}

View file

@ -24,7 +24,7 @@ class ExcellentEnchantsDependency {
// As excellent enchants is loaded before custom anvil and register enchantment to registry, we need to unregister old "vanilla" enchant.
for (enchantment in V5EnchantRegistry.getRegistered()) {
EnchantmentApi.unregisterEnchantment(enchantment.bukkitEnchantment.key)
EnchantmentApi.unregisterEnchantment(enchantment.bukkitEnchantment.keyOrThrow)
EnchantmentApi.registerEnchantment(CAEEV5Enchantment(enchantment))
}

View file

@ -42,7 +42,7 @@ abstract class GenericPluginDependency(protected val plugin: Plugin) {
if (event.result != null) return true
}
event.result = previousResult;
event.result = previousResult
return false
}

View file

@ -4,7 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity
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
@ -12,6 +12,7 @@ import valorless.havenbags.features.BagUpgrade
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
@Suppress("unstableApiUsage")
class HavenBagsDependency {
init {
@ -53,14 +54,14 @@ class HavenBagsDependency {
bagSkin.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil skin.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
AnvilXpUtil.setAnvilInvXp(event.view, player)
return true
}
bagUpgrade.onPrepareAnvil(event)
if (event.result != null) {
CustomAnvil.log("Detected pre anvil heaven bag anvil upgrade.")
AnvilXpUtil.setAnvilInvXp(event.inventory, event.view, player, event.inventory.repairCost)
AnvilXpUtil.setAnvilInvXp(event.view, player)
return true
}
@ -68,8 +69,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

@ -13,7 +13,7 @@ class ToolStatsDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
// Sadly, getTokens function is private, so I need to do that
private val getTokenMethod: Method =
ItemChecker::class.java.getDeclaredMethod("getTokens", ItemStack::class.java);
ItemChecker::class.java.getDeclaredMethod("getTokens", ItemStack::class.java)
init {
getTokenMethod.trySetAccessible()
@ -38,6 +38,6 @@ class ToolStatsDependency(plugin: Plugin) : GenericPluginDependency(plugin) {
val leftTokens = itemChecker.getTokenSafe(left)
val resultToken = itemChecker.getTokenSafe(result)
return !leftTokens.contentDeepEquals(resultToken);
return !leftTokens.contentDeepEquals(resultToken)
}
}

View file

@ -6,12 +6,12 @@ import org.bukkit.plugin.Plugin
class BukkitScheduler : TaskScheduler {
override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any? {
override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any {
return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task, time)
}
override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any? {
override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any {
return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task, time)
}
}

View file

@ -32,7 +32,7 @@ class EnchantConflictManager {
// 1.20.5 compatibility TODO better update system
private val SWEEPING_EDGE_ENCHANT = Collections.singletonList<CAEnchantment>(
CAEnchantment.getByKey(NamespacedKey.minecraft("sweeping_edge"))
?: CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.key)
?: CAEnchantment.getByKey(Enchantment.SWEEPING_EDGE.keyOrThrow)
)
}
@ -176,7 +176,7 @@ class EnchantConflictManager {
newEnchant: CAEnchantment
): ConflictType {
val mat = item.type
CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}")
CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.keyOrThrow}")
val conflictList = newEnchant.conflicts
var result = ConflictType.NO_CONFLICT

View file

@ -12,10 +12,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.dependency.DependencyManager
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
@ -32,6 +31,7 @@ import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import kotlin.math.min
@Suppress("unstableApiUsage")
class AnvilResultListener : Listener {
companion object {
@ -46,22 +46,22 @@ 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 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)
if (GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) {
if (GameMode.CREATIVE != player.gameMode && view.repairCost >= view.maximumRepairCost) {
event.result = Event.Result.DENY
return
}
@ -72,13 +72,13 @@ class AnvilResultListener : Listener {
event.result = Event.Result.ALLOW
onCustomCraft(
event, recipe, player,
leftItem, rightItem, output, inventory
leftItem, rightItem, output, view
)
return
}
// Do not continue if there was no change
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))) {
if ((output == view.getItem(ANVIL_INPUT_LEFT))) {
event.result = Event.Result.DENY
return
}
@ -101,15 +101,15 @@ class AnvilResultListener : Listener {
if (unitRepairResult != null) {
onUnitRepairExtract(
leftItem, rightItem, output,
unitRepairResult, event, player, inventory
unitRepairResult, event, player, view
)
return
}
// For lore edit
if (handleBookLoreEdit(event, inventory, player, leftItem, rightItem, output)) {
if (handleBookLoreEdit(event, view, player, leftItem, rightItem, output)) {
return
} else if (handlePaperLoreEdit(event, inventory, player, leftItem, rightItem, output)) {
} else if (handlePaperLoreEdit(event, view, player, leftItem, rightItem, output)) {
return
}
@ -124,7 +124,7 @@ class AnvilResultListener : Listener {
leftItem: ItemStack,
rightItem: ItemStack?,
output: ItemStack,
inventory: AnvilInventory
view: AnvilView
) {
event.result = Event.Result.DENY
@ -154,9 +154,7 @@ class AnvilResultListener : Listener {
// Handle not creative middle click...
if (event.click != ClickType.MIDDLE &&
!handleCustomCraftClick(
event,
recipe,
inventory,
recipe, view,
player,
leftItem,
rightItem,
@ -175,8 +173,8 @@ class AnvilResultListener : Listener {
}
private fun handleCustomCraftClick(
event: InventoryClickEvent, recipe: AnvilCustomRecipe,
inventory: AnvilInventory, player: Player,
recipe: AnvilCustomRecipe,
view: AnvilView, player: Player,
leftItem: ItemStack, rightItem: ItemStack?,
amount: Int, xpCost: Int, linearCost: Boolean = false
): Boolean {
@ -185,11 +183,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)
if (player.gameMode != GameMode.CREATIVE) {
if (linearCost) {
@ -216,17 +214,16 @@ 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)
view.repairCost = newXp
inventory.setItem(ANVIL_OUTPUT_SLOT, resultItem)
view.setItem(ANVIL_OUTPUT_SLOT, resultItem)
player.updateInventory()
}
@ -236,7 +233,7 @@ class AnvilResultListener : Listener {
private fun extractAnvilResult(
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory,
view: AnvilView,
leftItem: ItemStack?,
leftRemoveCount: Int,
rightItem: ItemStack?,
@ -259,12 +256,12 @@ class AnvilResultListener : Listener {
if (event.click != ClickType.MIDDLE) {
// 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)
player.level -= repairCost
}
@ -286,7 +283,7 @@ class AnvilResultListener : Listener {
unitRepairResult: Double,
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory
view: AnvilView
) {
val resultCopy = leftItem.clone()
val resultAmount = resultCopy.unitRepair(
@ -294,11 +291,11 @@ class AnvilResultListener : Listener {
)
// Get repair cost
val repairCost = getUnitRepairCost(inventory, player, leftItem, output, resultCopy, resultAmount)
val repairCost = getUnitRepairCost(view, player, leftItem, output, resultCopy, resultAmount)
// And then we give the item manually
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
rightItem, resultAmount,
resultCopy, repairCost
@ -306,7 +303,7 @@ class AnvilResultListener : Listener {
}
private fun getUnitRepairCost(
inventory: AnvilInventory, player: Player,
view: AnvilView, player: Player,
leftItem: ItemStack, output: ItemStack,
resultCopy: ItemStack, resultAmount: Int
): Int {
@ -339,7 +336,7 @@ class AnvilResultListener : Listener {
repairCost = min(repairCost, ConfigOptions.maxAnvilCost)
}
if ((inventory.maximumRepairCost <= repairCost)
if ((view.maximumRepairCost <= repairCost)
|| (player.level < repairCost)
) return Int.MIN_VALUE
@ -349,12 +346,12 @@ class AnvilResultListener : Listener {
private fun getFromLoreEditXpCost(
xpCost: AtomicInteger,
player: Player,
inventory: AnvilInventory,
view: AnvilView,
): Int {
if (GameMode.CREATIVE == player.gameMode) return 0
val repairCost = xpCost.get()
return if ((inventory.maximumRepairCost <= repairCost)
return if ((view.maximumRepairCost <= repairCost)
|| (player.level < repairCost)
) Int.MIN_VALUE
else repairCost
@ -362,7 +359,7 @@ class AnvilResultListener : Listener {
private fun handleBookLoreEdit(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
@ -388,10 +385,10 @@ class AnvilResultListener : Listener {
}
return extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
clearedBook, 0,
output, getFromLoreEditXpCost(xpCost, player, inventory)
output, getFromLoreEditXpCost(xpCost, player, view)
)
} else {
if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, xpCost)) return false
@ -424,17 +421,17 @@ class AnvilResultListener : Listener {
}
return extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
rightCopy, 0,
output, getFromLoreEditXpCost(xpCost, player, inventory)
output, getFromLoreEditXpCost(xpCost, player, view)
)
}
}
private fun handlePaperLoreEdit(
event: InventoryClickEvent,
inventory: AnvilInventory,
view: AnvilView,
player: Player,
leftItem: ItemStack,
rightItem: ItemStack,
@ -462,17 +459,17 @@ class AnvilResultListener : Listener {
return if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
event, player, view,
paperCopy, 0,
rightItem, 1,
output, getFromLoreEditXpCost(xpCost, player, inventory)
output, getFromLoreEditXpCost(xpCost, player, view)
)
} else {
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
paperCopy, 0,
output, getFromLoreEditXpCost(xpCost, player, inventory)
output, getFromLoreEditXpCost(xpCost, player, view)
)
}
} else {
@ -508,17 +505,17 @@ class AnvilResultListener : Listener {
return if (rightItem.amount > 1) {
extractAnvilResult(
event, player, inventory,
event, player, view,
rightClone, 0,
rightItem, 1,
output, getFromLoreEditXpCost(xpCost, player, inventory)
output, getFromLoreEditXpCost(xpCost, player, view)
)
} else {
extractAnvilResult(
event, player, inventory,
event, player, view,
null, 0,
rightClone, 0,
output, getFromLoreEditXpCost(xpCost, player, inventory)
output, getFromLoreEditXpCost(xpCost, player, view)
)
}
}

View file

@ -15,7 +15,7 @@ class ChatEventListener : Listener {
private val playerListenMap: ConcurrentHashMap<UUID, Consumer<String?>> = ConcurrentHashMap()
fun setListenedCallback(playeruuid: UUID, callback: Consumer<String?>) {
private fun setListenedCallback(playeruuid: UUID, callback: Consumer<String?>) {
playerListenMap[playeruuid] = callback
}
@ -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)
{
eventCallback.accept(event.message)
}, 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.EnchantmentUtil.combineWith
@ -17,10 +16,10 @@ 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.ItemStack
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.view.AnvilView
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.util.*
@ -30,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger
/**
* Listener for anvil events
*/
@Suppress("unstableApiUsage")
class PrepareAnvilListener : Listener {
companion object {
@ -46,18 +46,18 @@ class PrepareAnvilListener : Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
fun anvilCombineCheck(event: PrepareAnvilEvent) {
// Should find player
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
val inventory = event.inventory
val view = event.view
val player: HumanEntity = view.player
// 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.setAnvilInvXp(inventory, event.view, player, event.inventory.repairCost)
AnvilXpUtil.setAnvilInvXp(event.view, player, event.inventory.repairCost)
return
}
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
val first = view.getItem(ANVIL_INPUT_LEFT) ?: return
val second = view.getItem(ANVIL_INPUT_RIGHT)
if (isImmutable(first) || isImmutable(second)) {
CustomAnvil.verboseLog("Skipping anvil process as one of the two item is immutable")
@ -76,25 +76,25 @@ class PrepareAnvilListener : Listener {
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
// Test custom recipe
if (testCustomRecipe(event, inventory, player, first, second)) return
if (testCustomRecipe(event, player, first, second)) return
// Test rename lonely item
if (second == null) {
doRenaming(event, inventory, player, first)
doRenaming(event, view, player, first)
return
}
// Test for merge
if (first.canMergeWith(second)) {
doMerge(event, inventory, player, first, second)
doMerge(event, view, player, first, second)
return
}
// Test for unit repair
if (testUnitRepair(event, inventory, player, first, second)) return
if (testUnitRepair(event, view, player, first, second)) return
// Test for lore edit
if (testLoreEdit(event, inventory, player, first, second)) return
if (testLoreEdit(event, view, player, first, second)) return
CustomAnvil.log("no anvil fuse type found")
event.result = null
@ -113,7 +113,7 @@ class PrepareAnvilListener : Listener {
if (!meta.hasEnchants()) return false
for (enchant in meta.enchants.keys) {
if (ConfigOptions.isImmutable(enchant.key)) return true
if (ConfigOptions.isImmutable(enchant.keyOrThrow)) return true
}
return false
}
@ -122,14 +122,14 @@ class PrepareAnvilListener : Listener {
if (meta !is EnchantmentStorageMeta || !meta.hasStoredEnchants()) return false
for (enchant in meta.storedEnchants.keys) {
if (ConfigOptions.isImmutable(enchant.key)) return true
if (ConfigOptions.isImmutable(enchant.keyOrThrow)) return true
}
return false
}
// return true if a custom recipe exist with these ingredients
private fun testCustomRecipe(
event: PrepareAnvilEvent, inventory: AnvilInventory,
event: PrepareAnvilEvent,
player: HumanEntity,
first: ItemStack, second: ItemStack?
): Boolean {
@ -155,16 +155,16 @@ class PrepareAnvilListener : Listener {
event.result = finalResult.result
if (finalResult.result == null) return false
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost, true)
AnvilXpUtil.setAnvilInvXp(event.view, player, finalResult.levelCost, true)
return true
}
private fun doRenaming(
event: PrepareAnvilEvent, inventory: AnvilInventory,
event: PrepareAnvilEvent, view: AnvilView,
player: HumanEntity, first: ItemStack
) {
val resultItem = first.clone()
var anvilCost = handleRename(resultItem, inventory, player)
var anvilCost = handleRename(resultItem, view, player)
// Test/stop if nothing changed.
if (first == resultItem) {
@ -181,12 +181,12 @@ class PrepareAnvilListener : Listener {
event.result = finalResult.result
if (finalResult.result == null) return
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
AnvilXpUtil.setAnvilInvXp(event.view, player, finalResult.levelCost)
}
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
private fun handleRename(resultItem: ItemStack, view: AnvilView, player: HumanEntity): Int {
// Can be null
var inventoryName = ChatColor.stripColor(inventory.renameText)
var inventoryName = ChatColor.stripColor(view.renameText)
var sumCost = 0
var useColor = false
@ -227,7 +227,7 @@ class PrepareAnvilListener : Listener {
}
private fun doMerge(
event: PrepareAnvilEvent, inventory: AnvilInventory,
event: PrepareAnvilEvent, view: AnvilView,
player: HumanEntity,
first: ItemStack, second: ItemStack
) {
@ -260,7 +260,7 @@ class PrepareAnvilListener : Listener {
// As calculatePenalty edit result, we need to calculate penalty after checking equality
anvilCost += AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE)
// Calculate rename cost
anvilCost += handleRename(resultItem, inventory, player)
anvilCost += handleRename(resultItem, view, player)
// Finally, we set result
val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.MERGE, anvilCost)
@ -269,7 +269,7 @@ class PrepareAnvilListener : Listener {
event.result = finalResult.result
if (finalResult.result == null) return
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
AnvilXpUtil.setAnvilInvXp(view, player, finalResult.levelCost)
}
private fun isIdentical(
@ -286,13 +286,13 @@ class PrepareAnvilListener : Listener {
// return true if there is a valid unit repair with these ingredients
private fun testUnitRepair(
event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
event: PrepareAnvilEvent, view: AnvilView, player: HumanEntity,
first: ItemStack, second: ItemStack
): Boolean {
val unitRepairAmount = first.getRepair(second) ?: return false
val resultItem = first.clone()
var anvilCost = handleRename(resultItem, inventory, player)
var anvilCost = handleRename(resultItem, view, player)
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
if (repairAmount > 0) {
@ -314,12 +314,12 @@ class PrepareAnvilListener : Listener {
event.result = finalResult.result
if (finalResult.result == null) return false
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
AnvilXpUtil.setAnvilInvXp(view, player, finalResult.levelCost)
return true
}
private fun testLoreEdit(
event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
event: PrepareAnvilEvent, view: AnvilView, player: HumanEntity,
first: ItemStack, second: ItemStack
): Boolean {
val type = second.type
@ -339,7 +339,7 @@ class PrepareAnvilListener : Listener {
}
event.result = result
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, xpCost.get())
AnvilXpUtil.setAnvilInvXp(view, player, xpCost.get())
return true
}
}

View file

@ -13,6 +13,7 @@ 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.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager
@ -25,10 +26,21 @@ object AnvilXpUtil {
/**
* Display xp needed for the work on the anvil inventory
* Use the current view repair cost. used to force our price
*/
fun setAnvilInvXp(
inventory: AnvilInventory,
view: InventoryView,
view: AnvilView,
player: HumanEntity,
ignoreRules: Boolean = false
) {
setAnvilInvXp(view, player, view.repairCost, ignoreRules)
}
/**
* Display xp needed for the work on the anvil inventory
*/
fun setAnvilInvXp(
view: AnvilView,
player: HumanEntity,
anvilCost: Int,
ignoreRules: Boolean = false
@ -52,9 +64,8 @@ object AnvilXpUtil {
}
// Try first just in case another plugin, or the test need this
inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = finalAnvilCost
// TODO for 2.x.x use anvil view & set directly there
view.maximumRepairCost = maximumRepairCost
view.repairCost = finalAnvilCost
/* 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
@ -63,22 +74,20 @@ object AnvilXpUtil {
CustomAnvil.instance, player
) {
// retry after a tick
inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = finalAnvilCost
// TODO for 2.x.x use anvil view & set directly there
view.maximumRepairCost = maximumRepairCost
view.repairCost = finalAnvilCost
if (player !is Player) return@scheduleOnEntity
if (player.gameMode != GameMode.CREATIVE) {
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
(finalAnvilCost >= 40) &&
finalAnvilCost < inventory.maximumRepairCost
finalAnvilCost < view.maximumRepairCost
DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive)
}
player.updateInventory()
}
}