Add support for 1.21.2 & 1.21.3 for the "override Too Expensive" feature
Optimized merge when player has bypass permission
Optimized list gui that contain sub gui by lazy loading the sub gui
Fix density enchantment item cost being 1 instead of 2
This commit is contained in:
alexcrea 2024-10-26 16:49:27 +02:00 committed by GitHub
commit 9ad08343ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 267 additions and 94 deletions

View file

@ -1,7 +1,7 @@
# Custom Anvil # Custom Anvil
**Custom Anvil** is a plugin that allows server administrators to customize every aspect of the anvil's mechanics. **Custom Anvil** is a plugin that allows server administrators to customize every aspect of the anvil's mechanics.
It is expected to work on 1.18 to 1.21 minecraft servers running spigot or paper. It is expected to work on 1.18 to 1.21.3 minecraft servers running spigot or paper.
(the plugin support of 1.16.5 to 1.17.1 is experimental and may encounter issues) (the plugin support of 1.16.5 to 1.17.1 is experimental and may encounter issues)
**Custom Anvil** was previously named **Unsafe Enchants+**. **Custom Anvil** was previously named **Unsafe Enchants+**.
@ -95,7 +95,6 @@ Custom anvil [use bstat](https://bstats.org/plugin/bukkit/Unsafe%20Enchants%20Pl
### Planned: ### Planned:
- Better Folia support (make gui work. fix some dirty handled parts) - Better Folia support (make gui work. fix some dirty handled parts)
- Get restriction on unknown enchantments - Get restriction on unknown enchantments
- Warn admin on unsupported minecraft version
- More features for custom anvil craft - More features for custom anvil craft
### Known issue: ### Known issue:

View file

@ -15,7 +15,7 @@ plugins {
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.6.6" version = "1.6.7"
repositories { repositories {
// EcoEnchants // EcoEnchants
@ -57,6 +57,7 @@ dependencies {
implementation(project(":nms:v1_20R3", configuration = "reobf")) implementation(project(":nms:v1_20R3", configuration = "reobf"))
implementation(project(":nms:v1_20R4", configuration = "reobf")) implementation(project(":nms:v1_20R4", configuration = "reobf"))
implementation(project(":nms:v1_21R1", configuration = "reobf")) implementation(project(":nms:v1_21R1", configuration = "reobf"))
implementation(project(":nms:v1_21R2", configuration = "reobf"))
// include kotlin for the offline jar // include kotlin for the offline jar
implementation(kotlin("stdlib")) implementation(kotlin("stdlib"))

View file

@ -11,7 +11,7 @@ dependencies {
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))
// Used for nms // Used for nms
paperweight.paperDevBundle("1.21-R0.1-SNAPSHOT") // 1.21.1 userdev did not release yet but still use R1 paperweight.paperDevBundle("1.21.1-R0.1-SNAPSHOT")
} }
repositories { repositories {

View file

@ -8,7 +8,7 @@ class v1_21R1_ExternGuiTester: ExternGuiTester {
override val wesjdAnvilGuiName = "Wrapper1_21_R1" override val wesjdAnvilGuiName = "Wrapper1_21_R1"
override fun getContainerClass(view: InventoryView): Class<Any>? { override fun getContainerClass(view: InventoryView): Class<Any>? {
if(view !is CraftInventoryView<*>) return null if(view !is CraftInventoryView<*, *>) return null
val container = view.handle val container = view.handle
return container.javaClass return container.javaClass

View file

@ -0,0 +1,43 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
group = rootProject.group
version = rootProject.version
plugins {
id("io.papermc.paperweight.userdev")
}
dependencies {
implementation(project(":nms:nms-common"))
// Used for nms
paperweight.paperDevBundle("1.21.3-R0.1-SNAPSHOT")
}
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
// minecraft 1.21 java version is 21.
// Configure used version of kotlin and java
java {
disableAutoTargetJvm()
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}
// Set target version
tasks.withType<JavaCompile>().configureEach {
sourceCompatibility = "21"
targetCompatibility = "21"
options.encoding = "UTF-8"
}
kotlin {
compilerOptions {
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
jvmTarget.set(JvmTarget.JVM_21)
}
}

View file

@ -0,0 +1,33 @@
package xyz.alexcrea.cuanvil.dependency.packet.versions
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket
import net.minecraft.world.entity.player.Abilities
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerBase
class V1_21R2_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

@ -34,3 +34,5 @@ include("nms:v1_20R4")
findProject(":nms:v1_20R4")?.name = "v1_20R4" findProject(":nms:v1_20R4")?.name = "v1_20R4"
include("nms:v1_21R1") include("nms:v1_21R1")
findProject(":nms:v1_21R1")?.name = "v1_21R1" findProject(":nms:v1_21R1")?.name = "v1_21R1"
include("nms:v1_21R2")
findProject(":nms:v1_21R2")?.name = "v1_21R2"

View file

@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui; 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 xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui;
import java.util.ArrayList; import java.util.ArrayList;
@ -94,9 +95,9 @@ public class UnitRepairApi {
// Add to gui // Add to gui
UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance(); UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance();
if(repairConfigGui != null) { if(repairConfigGui != null) {
UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit); UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit).getStored();
elementGui.updateValueForGeneric(repairableName, true); if(elementGui != null) elementGui.updateValueForGeneric(repairableName, true);
repairConfigGui.updateValueForGeneric(unit, true); repairConfigGui.updateValueForGeneric(unit, true);
} }
@ -124,14 +125,15 @@ public class UnitRepairApi {
boolean lastValue = false; boolean lastValue = false;
if(config.isConfigurationSection(unitName.toLowerCase())) { if(config.isConfigurationSection(unitName.toLowerCase())) {
ConfigurationSection section = config.getConfigurationSection(unitName.toLowerCase()); ConfigurationSection section = config.getConfigurationSection(unitName.toLowerCase());
if(section.getKeys(false).isEmpty()) {
if(section != null && section.getKeys(false).isEmpty()) {
lastValue = true; lastValue = true;
config.set(unitName.toLowerCase(), null); config.set(unitName.toLowerCase(), null);
} }
} else if (config.isConfigurationSection(unitName.toUpperCase())) { } else if (config.isConfigurationSection(unitName.toUpperCase())) {
ConfigurationSection section = config.getConfigurationSection(unitName.toUpperCase()); ConfigurationSection section = config.getConfigurationSection(unitName.toUpperCase());
if(section.getKeys(false).isEmpty()) { if(section != null && section.getKeys(false).isEmpty()) {
lastValue = true; lastValue = true;
config.set(unitName.toUpperCase(), null); config.set(unitName.toUpperCase(), null);
} }
@ -146,9 +148,9 @@ public class UnitRepairApi {
// Remove from gui // Remove from gui
UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance(); UnitRepairConfigGui repairConfigGui = UnitRepairConfigGui.getCurrentInstance();
if(repairConfigGui != null) { if(repairConfigGui != null) {
UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit); UnitRepairElementListGui elementGui = repairConfigGui.getInstanceOrCreate(unit).getStored();
elementGui.removeGeneric(repairableName); if(elementGui != null) elementGui.removeGeneric(repairableName);
if(lastValue){ if(lastValue){
repairConfigGui.removeGeneric(unit); repairConfigGui.removeGeneric(unit);
} }

View file

@ -17,7 +17,8 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRecipe, CustomRecipeSubSettingGui> { public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRecipe,
MappedGuiListConfigGui.LazyElement<CustomRecipeSubSettingGui>> {
private static CustomRecipeConfigGui INSTANCE = new CustomRecipeConfigGui(); private static CustomRecipeConfigGui INSTANCE = new CustomRecipeConfigGui();
@ -44,15 +45,15 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
protected ItemStack createItemForGeneric(AnvilCustomRecipe recipe) { protected ItemStack createItemForGeneric(AnvilCustomRecipe recipe) {
// Get base item to display // Get base item to display
ItemStack craftResultItem = recipe.getResultItem(); ItemStack craftResultItem = recipe.getResultItem();
ItemStack displaydItem; ItemStack displayedItem;
if(craftResultItem == null){ if(craftResultItem == null){
displaydItem = new ItemStack(Material.BARRIER); displayedItem = new ItemStack(Material.BARRIER);
}else{ }else{
displaydItem = craftResultItem.clone(); displayedItem = craftResultItem.clone();
} }
// edit displayed item // edit displayed item
ItemMeta meta = displaydItem.getItemMeta(); ItemMeta meta = displayedItem.getItemMeta();
assert meta != null; assert meta != null;
meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " §fCustom recipe"); meta.setDisplayName("§e" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " §fCustom recipe");
@ -67,13 +68,13 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
)); ));
displaydItem.setItemMeta(meta); displayedItem.setItemMeta(meta);
return displaydItem; return displayedItem;
} }
@Override @Override
protected CustomRecipeSubSettingGui newInstanceOfGui(AnvilCustomRecipe generic, GuiItem item) { protected LazyElement<CustomRecipeSubSettingGui> newInstanceOfGui(AnvilCustomRecipe generic, GuiItem item) {
return new CustomRecipeSubSettingGui(this, generic, item); return new LazyElement<>(item, () -> new CustomRecipeSubSettingGui(this, generic));
} }
@Override @Override

View file

@ -18,7 +18,8 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGroup, EnchantConflictSubSettingGui> { public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGroup,
MappedGuiListConfigGui.LazyElement<EnchantConflictSubSettingGui>> {
private static EnchantConflictGui INSTANCE; private static EnchantConflictGui INSTANCE;
@ -86,8 +87,8 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
} }
@Override @Override
protected EnchantConflictSubSettingGui newInstanceOfGui(EnchantConflictGroup conflict, GuiItem item) { protected LazyElement<EnchantConflictSubSettingGui> newInstanceOfGui(EnchantConflictGroup conflict, GuiItem item) {
return new EnchantConflictSubSettingGui(this, conflict, item); return new LazyElement<>(item, () -> new EnchantConflictSubSettingGui(this, conflict));
} }
@Override @Override

View file

@ -15,12 +15,13 @@ import xyz.alexcrea.cuanvil.group.ItemGroupManager;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import xyz.alexcrea.cuanvil.util.LazyValue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupConfigSubSettingGui> { public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, MappedGuiListConfigGui.LazyElement<GroupConfigSubSettingGui>> {
private static GroupConfigGui INSTANCE; private static GroupConfigGui INSTANCE;
@ -73,8 +74,8 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupCo
} }
@Override @Override
protected GroupConfigSubSettingGui newInstanceOfGui(IncludeGroup group, GuiItem item) { protected LazyElement<GroupConfigSubSettingGui> newInstanceOfGui(IncludeGroup group, GuiItem item) {
return new GroupConfigSubSettingGui(this, group, item); return new LazyElement<>(item, () -> new GroupConfigSubSettingGui(this, group));
} }
@Override @Override

View file

@ -18,7 +18,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRepairElementListGui> { public class UnitRepairConfigGui extends
MappedGuiListConfigGui<Material, MappedGuiListConfigGui.LazyElement<UnitRepairElementListGui>> {
private static UnitRepairConfigGui INSTANCE; private static UnitRepairConfigGui INSTANCE;
@ -41,10 +42,12 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
} }
@Override @Override
protected UnitRepairElementListGui newInstanceOfGui(Material material, GuiItem item) { protected LazyElement<UnitRepairElementListGui> newInstanceOfGui(Material material, GuiItem item) {
UnitRepairElementListGui element = new UnitRepairElementListGui(material, this, item); return new LazyElement<>(item, () -> {
element.init(); UnitRepairElementListGui element = new UnitRepairElementListGui(material, this);
return element; element.init();
return element;
});
} }
@Override @Override
@ -115,7 +118,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
updateValueForGeneric(type, true); updateValueForGeneric(type, true);
// Display material edit setting // Display material edit setting
this.elementGuiMap.get(type).getMappedGui().show(player); this.elementGuiMap.get(type).get().getMappedGui().show(player);
}, },
true true
).show(clickEvent.getWhoClicked()); ).show(clickEvent.getWhoClicked());
@ -123,8 +126,8 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
} }
@NotNull @NotNull
public UnitRepairElementListGui getInstanceOrCreate(Material mat){ public LazyElement<UnitRepairElementListGui> getInstanceOrCreate(Material mat){
UnitRepairElementListGui element = this.elementGuiMap.get(mat); LazyElement<UnitRepairElementListGui> element = this.elementGuiMap.get(mat);
if(element == null){ if(element == null){
updateValueForGeneric(mat, false); updateValueForGeneric(mat, false);

View file

@ -3,15 +3,19 @@ package xyz.alexcrea.cuanvil.gui.config.list;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui; import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.util.LazyValue;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGui> extends MappedElementListConfigGui< T, S > { public abstract class MappedGuiListConfigGui< T, S extends MappedGuiListConfigGui.LazyElement<?>>
extends MappedElementListConfigGui< T, S > {
protected MappedGuiListConfigGui(@NotNull String title) { protected MappedGuiListConfigGui(@NotNull String title) {
super(title); super(title);
@ -20,7 +24,10 @@ public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGu
@Override @Override
public void reloadValues() { public void reloadValues() {
this.elementGuiMap.forEach((conflict, gui) -> gui.cleanAndBeUnusable()); this.elementGuiMap.forEach((conflict, element) -> {
ElementMappedToListGui gui = element.getStored();
if(gui != null) gui.cleanAndBeUnusable();
});
this.elementGuiMap.clear(); this.elementGuiMap.clear();
super.reloadValues(); super.reloadValues();
@ -30,23 +37,24 @@ public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGu
protected S newElementRequested(T generic, GuiItem newItem) { protected S newElementRequested(T generic, GuiItem newItem) {
S element = newInstanceOfGui(generic, newItem); S element = newInstanceOfGui(generic, newItem);
newItem.setAction(GuiGlobalActions.openGuiAction(element.getMappedGui())); newItem.setAction(element.openAction());
return element; return element;
} }
@Override @Override
protected GuiItem findItemFromElement(T generic, S element) { protected GuiItem findItemFromElement(T generic, S element) {
return element.getParentItemForThisGui(); return element.getParentItem();
} }
@Override @Override
protected void updateElement(T generic, S element) { protected void updateElement(T generic, S element) {
element.updateLocal(); ElementMappedToListGui gui = element.getStored();
if(gui != null) gui.updateLocal();
} }
@Override @Override
protected GuiItem findGuiItemForRemoval(T generic, S element) { protected GuiItem findGuiItemForRemoval(T generic, S element) {
return element.getParentItemForThisGui(); return element.getParentItem();
} }
@Override @Override
@ -90,7 +98,7 @@ public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGu
updateValueForGeneric(generic, true); updateValueForGeneric(generic, true);
// show the new conflict config to the player // show the new conflict config to the player
this.elementGuiMap.get(generic).getMappedGui().show(player); this.elementGuiMap.get(generic).get().getMappedGui().show(player);
update(); update();
}; };
@ -105,4 +113,28 @@ public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGu
protected abstract T createAndSaveNewEmptyGeneric(String name); protected abstract T createAndSaveNewEmptyGeneric(String name);
public static class LazyElement<T extends ElementMappedToListGui> extends LazyValue<T> {
private final GuiItem parentItem;
private final LazyValue<Consumer<InventoryClickEvent>> lazyOpenConsumer;
public LazyElement(GuiItem parentItem, Supplier<T> valueSupplier) {
super(valueSupplier);
this.parentItem = parentItem;
this.lazyOpenConsumer = new LazyValue<>(() ->
GuiGlobalActions.openGuiAction(this.get().getMappedGui()))
;
}
public GuiItem getParentItem() {
return parentItem;
}
@NotNull
public Consumer<InventoryClickEvent> openAction(){
return event -> lazyOpenConsumer.get().accept(event);
}
}
} }

View file

@ -26,17 +26,14 @@ import java.util.function.Consumer;
public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, DoubleSettingGui.DoubleSettingFactory> implements ElementMappedToListGui { public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, DoubleSettingGui.DoubleSettingFactory> implements ElementMappedToListGui {
private final GuiItem parentItem;
private final Material parentMaterial; private final Material parentMaterial;
private final UnitRepairConfigGui parentGui; private final UnitRepairConfigGui parentGui;
private final String materialName; private final String materialName;
private boolean shouldWork = true; private boolean shouldWork = true;
public UnitRepairElementListGui(@NotNull Material parentMaterial, public UnitRepairElementListGui(@NotNull Material parentMaterial,
@NotNull UnitRepairConfigGui parentGui, @NotNull UnitRepairConfigGui parentGui) {
@NotNull GuiItem parentItem) {
super("§e" + CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()) + " §rUnit repair"); super("§e" + CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()) + " §rUnit repair");
this.parentItem = parentItem;
this.parentMaterial = parentMaterial; this.parentMaterial = parentMaterial;
this.parentGui = parentGui; this.parentGui = parentGui;
this.materialName = CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()); this.materialName = CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase());
@ -165,11 +162,6 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
// ElementMappedToListGui methods // ElementMappedToListGui methods
@Override
public GuiItem getParentItemForThisGui() {
return this.parentItem;
}
@Override // Not used in this implementation @Override // Not used in this implementation
public void updateLocal() {} public void updateLocal() {}

View file

@ -35,9 +35,8 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
public CustomRecipeSubSettingGui( public CustomRecipeSubSettingGui(
@NotNull CustomRecipeConfigGui parent, @NotNull CustomRecipeConfigGui parent,
@NotNull AnvilCustomRecipe anvilRecipe, @NotNull AnvilCustomRecipe anvilRecipe) {
@NotNull GuiItem parentItemForThisGui) { super(3, "§e" + CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.toString()) + " §8Config");
super(parentItemForThisGui, 3, "§e" + CasedStringUtil.snakeToUpperSpacedCase(anvilRecipe.toString()) + " §8Config");
this.parent = parent; this.parent = parent;
this.anvilRecipe = anvilRecipe; this.anvilRecipe = anvilRecipe;

View file

@ -1,12 +1,9 @@
package xyz.alexcrea.cuanvil.gui.config.list.elements; package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
public interface ElementMappedToListGui { public interface ElementMappedToListGui {
GuiItem getParentItemForThisGui();
void updateLocal(); void updateLocal();
void cleanAndBeUnusable(); void cleanAndBeUnusable();

View file

@ -39,10 +39,8 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
public EnchantConflictSubSettingGui( public EnchantConflictSubSettingGui(
@NotNull EnchantConflictGui parent, @NotNull EnchantConflictGui parent,
@NotNull EnchantConflictGroup enchantConflict, @NotNull EnchantConflictGroup enchantConflict) {
@NotNull GuiItem parentItemForThisGui) { super(3,
super(parentItemForThisGui,
3,
"§e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + " §8Config"); "§e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + " §8Config");
this.parent = parent; this.parent = parent;
this.enchantConflict = enchantConflict; this.enchantConflict = enchantConflict;

View file

@ -37,9 +37,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
public GroupConfigSubSettingGui( public GroupConfigSubSettingGui(
@NotNull GroupConfigGui parent, @NotNull GroupConfigGui parent,
@NotNull IncludeGroup group, @NotNull IncludeGroup group) {
@NotNull GuiItem item) { super(3,
super(item, 3,
CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " Config"); CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " Config");
this.parent = parent; this.parent = parent;
this.group = group; this.group = group;

View file

@ -9,18 +9,10 @@ import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
public abstract class MappedToListSubSettingGui extends ChestGui implements ValueUpdatableGui, ElementMappedToListGui { public abstract class MappedToListSubSettingGui extends ChestGui implements ValueUpdatableGui, ElementMappedToListGui {
private final GuiItem item;
protected MappedToListSubSettingGui( protected MappedToListSubSettingGui(
GuiItem item,
int rows, int rows,
@NotNull String title) { @NotNull String title) {
super(rows, title, CustomAnvil.instance); super(rows, title, CustomAnvil.instance);
this.item = item;
}
@Override
public GuiItem getParentItemForThisGui() {
return item;
} }
@Override @Override

View file

@ -69,14 +69,14 @@ public class Update_1_21 {
baseConfig.set("enchant_limits.minecraft:wind_burst", 3); baseConfig.set("enchant_limits.minecraft:wind_burst", 3);
// Add enchant values // Add enchant values
baseConfig.set("enchant_values.density.item", 1); baseConfig.set("enchant_values.minecraft:density.item", 2);
baseConfig.set("enchant_values.density.book", 1); baseConfig.set("enchant_values.minecraft:density.book", 1);
baseConfig.set("enchant_values.breach.item", 4); baseConfig.set("enchant_values.minecraft:breach.item", 4);
baseConfig.set("enchant_values.breach.book", 2); baseConfig.set("enchant_values.minecraft:breach.book", 2);
baseConfig.set("enchant_values.wind_burst.item", 4); baseConfig.set("enchant_values.minecraft:wind_burst.item", 4);
baseConfig.set("enchant_values.wind_burst.book", 2); baseConfig.set("enchant_values.minecraft:wind_burst.book", 2);
// Add unit repair for mace // Add unit repair for mace
unitConfig.set("breeze_rod.mace", 0.25); unitConfig.set("breeze_rod.mace", 0.25);

View file

@ -0,0 +1,27 @@
package xyz.alexcrea.cuanvil.update.plugin;
import org.bukkit.configuration.file.FileConfiguration;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import javax.annotation.Nonnull;
import java.util.Set;
public class PUpdate_1_6_7 {
public static void handleUpdate(@Nonnull Set<ConfigHolder> toSave) {
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig();
// We fix the density enchantment
String value = config.getString("enchant_values.minecraft:density.item");
if(value == null) value = config.getString("enchant_values.density.item");
if(value == null || "1".equalsIgnoreCase(value)){
config.set("enchant_values.minecraft:density.item", 2);
toSave.add(ConfigHolder.DEFAULT_CONFIG);
}
}
}

View file

@ -21,7 +21,12 @@ public class PluginUpdates {
if(new Version(1, 6, 2).greaterThan(current)){ if(new Version(1, 6, 2).greaterThan(current)){
PUpdate_1_6_2.handleUpdate(toSave); PUpdate_1_6_2.handleUpdate(toSave);
finishConfiguration("1.6.2", toSave); // We assume 1.6.7 will run. TODO a better system instead of that I guess
}
if(new Version(1, 6, 7).greaterThan(current)){
PUpdate_1_6_7.handleUpdate(toSave);
finishConfiguration("1.6.7", toSave);
} }
} }

View file

@ -0,0 +1,36 @@
package xyz.alexcrea.cuanvil.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier;
public class LazyValue<T> {
private final Supplier<T> valueSupplier;
private T storedValue;
public LazyValue(Supplier<T> valueSupplier) {
this.valueSupplier = valueSupplier;
this.storedValue = null;
}
@Nullable
public T getStored(){
return storedValue;
}
@NotNull
public T get(){
if (storedValue != null) return storedValue;
synchronized(this) {
if(storedValue == null) {
storedValue = valueSupplier.get();
}
}
return storedValue;
}
}

View file

@ -30,13 +30,15 @@ object EnchantmentUtil {
) = mutableMapOf<CAEnchantment, Int>().apply { ) = mutableMapOf<CAEnchantment, Int>().apply {
putAll(this@combineWith) putAll(this@combineWith)
val bypassFuse = player.hasPermission(CustomAnvil.bypassFusePermission)
val bypassLevel = player.hasPermission(CustomAnvil.bypassLevelPermission)
other.forEach { (enchantment, level) -> other.forEach { (enchantment, level) ->
if(!enchantment.isAllowed(player)) return@forEach if(!enchantment.isAllowed(player)) return@forEach
// Get max level or 255 if player can bypass // Get max level or 255 if player can bypass
val maxLevel = if (player.hasPermission(CustomAnvil.bypassLevelPermission)) val maxLevel = if (bypassLevel) { 255 }
{ 255 } else else { ConfigOptions.enchantLimit(enchantment) }
{ ConfigOptions.enchantLimit(enchantment) }
val cappedLevel = min(level, maxLevel) val cappedLevel = min(level, maxLevel)
@ -44,11 +46,15 @@ object EnchantmentUtil {
if (!containsKey(enchantment)) { if (!containsKey(enchantment)) {
// Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions // Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions
this[enchantment] = cappedLevel this[enchantment] = cappedLevel
val conflictType = if(bypassFuse){
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this, item, enchantment) CustomAnvil.verboseLog("Bypassed conflict check for ${enchantment.key}")
if (!player.hasPermission(CustomAnvil.bypassFusePermission) && return@forEach
(conflictType != ConflictType.NO_CONFLICT) }
) {
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager
.isConflicting(this, item, enchantment)
if (conflictType != ConflictType.NO_CONFLICT) {
CustomAnvil.verboseLog("Enchantment not yet in result list, but there is conflict (${enchantment.key}, conflict: $conflictType)") CustomAnvil.verboseLog("Enchantment not yet in result list, but there is conflict (${enchantment.key}, conflict: $conflictType)")
this.remove(enchantment) this.remove(enchantment)
} }
@ -58,14 +64,17 @@ object EnchantmentUtil {
else { else {
val oldLevel = this[enchantment]!! // <- should not be null. (enchantment already in result list) val oldLevel = this[enchantment]!! // <- should not be null. (enchantment already in result list)
// ... and they are conflicting if(bypassFuse){
val conflictType = CustomAnvil.verboseLog("Bypassed conflict check for ${enchantment.key}")
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this, item, enchantment) } else {
if ((conflictType != ConflictType.NO_CONFLICT) val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager
&& !player.hasPermission(CustomAnvil.bypassFusePermission) .isConflicting(this, item, enchantment)
) {
CustomAnvil.verboseLog("Enchantment already in result list, and they are conflicting (${enchantment.key}, conflict: $conflictType)") // ... and they are conflicting
return@forEach if(conflictType != ConflictType.NO_CONFLICT){
CustomAnvil.verboseLog(
"Enchantment already in result list, and they are conflicting (${enchantment.key}, conflict: $conflictType)")
}
} }
// ... and they're not the same level // ... and they're not the same level

View file

@ -55,6 +55,7 @@ object PacketManagerSelector {
21 -> when (versionParts[2]) { 21 -> when (versionParts[2]) {
0, 1 -> V1_21R1_PacketManager() 0, 1 -> V1_21R1_PacketManager()
2, 3 -> V1_21R2_PacketManager()
else -> null else -> null
} }