Compare commits

..

55 Commits

Author SHA1 Message Date
Auxilor
2ed1f2bb2f Updated to 6.73.6 2024-08-23 15:18:30 +01:00
Auxilor
9cb596e746 Fixed FastItemStack#getEnchants(true) giving incorrect results when the enchantment component was removed from an item 2024-08-23 15:18:21 +01:00
Auxilor
763a3e9a87 Merge branch 'refs/heads/develop' 2024-08-21 18:23:59 +01:00
Auxilor
f01691663a Fixed ProtocolLib 2024-08-21 18:23:33 +01:00
Auxilor
6c91b4e41f Updated to 6.73.5 2024-08-21 18:08:50 +01:00
Auxilor
06fdb25925 Patch for ArgParserEnchantment 2024-08-21 18:08:39 +01:00
Will FP
665857a00f Merge pull request #371 from MCCasper/master
Update config.yml
2024-08-16 00:14:13 +02:00
Nikolai Connolly
f18016b2de Update config.yml 2024-08-15 14:53:23 -05:00
Auxilor
88633f94cb Updated to 6.73.4 2024-08-12 21:48:27 +01:00
Auxilor
903084e574 Added 1.21.1 support 2024-08-12 21:48:04 +01:00
Auxilor
dab0ce2ed2 Updated to 6.73.3 2024-07-30 15:58:04 +01:00
Auxilor
c89edd05f5 Updated to 6.73.2 2024-07-29 18:46:53 +01:00
Auxilor
ce2a53e689 Fixed FancyHolograms integration 2024-07-29 18:46:47 +01:00
Auxilor
6658824f9a Updated to 6.73.1 2024-07-24 15:24:59 +01:00
Auxilor
956d4fa10c Enchantment arg parser is now case insensitive 2024-07-24 15:24:49 +01:00
Will FP
f01e18950c Merge pull request #365 from Exanthiax/develop 2024-07-24 10:44:03 +01:00
Exanthiax
d4a6bf105b Update ParticleFactoryRGB.kt 2024-07-24 01:55:20 +01:00
Auxilor
6a7a825376 Added extra apis to VanillaItemTag 2024-07-21 12:57:55 +01:00
Auxilor
cd232e804c Improved enchantment arg parser 2024-07-21 11:38:35 +01:00
Auxilor
7cf2fa4b4b Improved consistency with custom model data arg parser 2024-07-21 11:22:40 +01:00
Auxilor
cbf88ce678 Improved item tags 2024-07-20 15:36:26 +01:00
Auxilor
79db5978bd Improved ItemTag 2024-07-20 15:16:47 +01:00
Auxilor
0f11f9846c CustomItemTag is now an abstract class 2024-07-20 15:09:26 +01:00
Auxilor
1f460d7a00 Updated to 6.73.0 2024-07-20 15:07:55 +01:00
Auxilor
2fb9525175 Added Item Tags 2024-07-20 15:07:55 +01:00
Auxilor
a9a961ff2b Added FancyHolograms integration 2024-07-20 12:49:07 +01:00
Auxilor
25d572c0db Added AutocrafterPatch 2024-07-20 09:59:58 +01:00
Auxilor
8a4243e434 Fixed XP price 2024-07-19 20:01:20 +01:00
Auxilor
6c40670f5e Updated to 6.72.0 2024-07-19 19:46:26 +01:00
Auxilor
6e94f3cee8 Added support for multiple display modules per plugin 2024-07-19 19:46:26 +01:00
Auxilor
4968d3ff22 Updated to 6.71.6 2024-07-14 16:04:21 +01:00
Auxilor
eecd80be1c Fixed display name 2024-07-14 16:04:14 +01:00
Auxilor
52c1b52f6d Fixed tab completion bug 2024-07-12 18:18:40 +01:00
Auxilor
f321296227 Updated to 6.71.5 2024-07-12 18:08:35 +01:00
Auxilor
ddd12db420 Fixed ExtendedPersistentDataContainerFactory 2024-07-12 18:07:53 +01:00
Auxilor
bd09791b5b Improved command tab-completion 2024-07-08 18:49:29 +01:00
Auxilor
ce9549f03d Updated to 6.71.4 2024-07-08 15:14:24 +01:00
Auxilor
52367dbb95 Fixed Java 17 compatibility 2024-07-08 15:14:18 +01:00
Auxilor
0080c32c23 Updated to 6.71.3 2024-06-25 02:30:45 +01:00
Auxilor
581094a930 Fixed DurabilityUtils 2024-06-25 02:30:37 +01:00
Auxilor
5d9c8775e8 Updated to 6.71.2 2024-06-24 18:44:16 +01:00
Auxilor
9ab51d2c87 Added fix for TopInventory on pre-1.21 2024-06-24 18:42:32 +01:00
Auxilor
b0de341d7f Updated to 6.71.1 2024-06-23 16:45:17 +01:00
Auxilor
1bada835ea Added 1.21 item arg parsers 2024-06-23 14:20:49 +01:00
Auxilor
de04833f0c Updated custom name and lore on 1.21 2024-06-22 23:44:29 +01:00
Auxilor
75dd6be539 Fixed custom name on 1.21 2024-06-22 22:52:01 +01:00
Auxilor
9b47e4777a Dropped 1.20.6 support and made modern commons module for 1.21+ 2024-06-22 22:23:51 +01:00
Will FP
e2a6d6d9ac Merge pull request #359 from MCCasper/master
fix empty nbt
2024-06-22 22:11:36 +01:00
Nikolai Connolly
4c1bc76ee2 fix empty nbt 2024-06-22 17:09:23 -04:00
Auxilor
61c90d85ac Fixed 1.20.6+ getEnchants 2024-06-20 23:14:09 +01:00
Auxilor
6faaac2257 Fixed 1.20.6+ getEnchants 2024-06-20 23:13:52 +01:00
Auxilor
9ad489b9d9 Updated to 6.71.0 2024-06-20 18:48:19 +01:00
Auxilor
3a0e1eaf4d Added 1.21 support and fixed paperweight issues for Java 17 versions 2024-06-18 20:53:04 +01:00
Jason Penilla
80afa9127f Explicitly declare toolchains/make compile work consistently
Signed-off-by: WillFP <william.favierparsons1@gmail.com>
2024-06-18 20:53:04 +01:00
Auxilor
ad44891f5f 1.21 groundwork 2024-06-18 20:53:04 +01:00
152 changed files with 1669 additions and 585 deletions

View File

@@ -22,6 +22,7 @@ dependencies {
implementation(project(path = ":eco-core:core-plugin", configuration = "shadow"))
implementation(project(":eco-core:core-proxy"))
implementation(project(":eco-core:core-backend"))
implementation(project(":eco-core:core-backend-modern"))
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
@@ -31,7 +32,7 @@ dependencies {
implementation(project(path = ":eco-core:core-nms:v1_20_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_20_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_20_R3", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_20_6", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21", configuration = "reobf"))
}
allprojects {
@@ -44,9 +45,10 @@ allprojects {
repositories {
mavenCentral()
mavenLocal()
maven("https://repo.auxilor.io/repository/maven-public/")
maven("https://jitpack.io")
maven("https://jitpack.io") {
content { includeGroupByRegex("com\\.github\\..*") }
}
// SuperiorSkyblock2
maven("https://repo.bg-software.com/repository/api/")
@@ -61,7 +63,7 @@ allprojects {
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
// ProtocolLib
//maven("https://repo.dmulloy2.net/nexus/repository/public/")
maven("https://repo.dmulloy2.net/nexus/repository/public/")
// WorldGuard
maven("https://maven.enginehub.org/repo/")
@@ -95,6 +97,9 @@ allprojects {
// HuskPlugins
maven("https://repo.william278.net/releases")
// FancyHolograms
maven("https://repo.fancyplugins.de/releases")
}
dependencies {
@@ -158,12 +163,6 @@ allprojects {
options.encoding = "UTF-8"
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
withSourcesJar()
}
test {
useJUnitPlatform()
@@ -176,6 +175,17 @@ allprojects {
build {
dependsOn(shadowJar)
}
withType<JavaCompile>().configureEach {
options.release = 17
}
}
java {
withSourcesJar()
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
}
@@ -215,12 +225,5 @@ tasks {
}
}
// Root is Java 21 to support 1.20.6+, rest use Java 17
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
withSourcesJar()
}
group = "com.willfp"
version = findProperty("version")!!

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core;
import com.google.common.collect.ImmutableList;
import com.willfp.eco.core.command.impl.PluginCommand;
import com.willfp.eco.core.config.base.ConfigYml;
import com.willfp.eco.core.config.base.LangYml;
@@ -36,6 +37,8 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -120,9 +123,17 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
/**
* The display module for the plugin.
*
* @deprecated Plugins can now have multiple display modules.
*/
@Deprecated(since = "6.72.0")
private DisplayModule displayModule;
/**
* The display modules for the plugin.
*/
private List<DisplayModule> displayModules = new ArrayList<>();
/**
* The logger for the plugin.
*/
@@ -555,10 +566,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
* Default code to be executed after the server is up.
*/
public final void afterLoad() {
this.displayModule = createDisplayModule();
DisplayModule module = createDisplayModule();
if (module != null) {
Display.registerDisplayModule(module);
this.displayModules.add(module);
}
if (this.getDisplayModule() != null) {
Display.registerDisplayModule(this.getDisplayModule());
for (DisplayModule displayModule : this.loadDisplayModules()) {
Display.registerDisplayModule(displayModule);
this.displayModules.add(displayModule);
}
if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
@@ -899,14 +915,25 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
* Create the display module for the plugin.
*
* @return The display module, or null.
* @deprecated Use {@link #loadDisplayModules()} instead.
*/
@Nullable
@Deprecated(since = "6.72.0")
protected DisplayModule createDisplayModule() {
Validate.isTrue(this.getDisplayModule() == null, "Display module exists!");
return null;
}
/**
* Load display modules.
*
* @return The display modules.
*/
protected List<DisplayModule> loadDisplayModules() {
return new ArrayList<>();
}
/**
* Get the minimum version of eco to use the plugin.
*
@@ -1156,12 +1183,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
* Get the plugin's display module.
*
* @return The display module.
* @deprecated Use {@link #getDisplayModules()} instead.
*/
@Nullable
@Deprecated(since = "6.72.0", forRemoval = true)
public DisplayModule getDisplayModule() {
return this.displayModule;
}
/**
* Get the plugin's display modules.
*
* @return The display modules.
*/
public List<DisplayModule> getDisplayModules() {
return ImmutableList.copyOf(this.displayModules);
}
/**
* Get if the plugin is outdated.
*

View File

@@ -37,11 +37,20 @@ public class Prerequisite {
"Requires server to have ProtocolLib"
);
/**
* Requires the server to be running 1.21.
*/
public static final Prerequisite HAS_1_21 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("1_21"),
"Requires server to be running 1.21+"
);
/**
* Requires the server to be running 1.20.5.
*/
public static final Prerequisite HAS_1_20_5 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("1_20_") && !ProxyConstants.NMS_VERSION.contains("R"),
() -> (ProxyConstants.NMS_VERSION.contains("1_20_") && !ProxyConstants.NMS_VERSION.contains("R"))
|| HAS_1_21.isMet(),
"Requires server to be running 1.20.5+"
);

View File

@@ -211,12 +211,22 @@ public final class Display {
new ArrayList<>()
);
modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
modules.add(module);
REGISTERED_MODULES.put(module.getWeight(), modules);
}
/**
* Unregister a display module.
*
* @param module The module.
*/
public static void unregisterDisplayModule(@NotNull final DisplayModule module) {
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
modules.remove(module);
}
}
private Display() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.Eco;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.provider.ItemProvider;
import com.willfp.eco.core.items.tag.ItemTag;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
@@ -13,7 +14,6 @@ import com.willfp.eco.core.recipe.parts.TestableStack;
import com.willfp.eco.core.recipe.parts.UnrestrictedMaterialTestableItem;
import com.willfp.eco.util.NamespacedKeyUtils;
import com.willfp.eco.util.NumberUtils;
import kotlin.Suppress;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
@@ -93,6 +93,11 @@ public final class Items {
*/
private static final Map<String, Material> FRIENDLY_MATERIAL_NAMES = new HashMap<>();
/**
* All tags.
*/
private static final Map<String, ItemTag> TAGS = new HashMap<>();
/**
* Register a new custom item.
*
@@ -217,7 +222,20 @@ public final class Items {
String[] split = args[0].toLowerCase().split(":");
if (split.length == 1) {
String base = split[0];
boolean isTag = base.startsWith("#");
if (isTag) {
String tag = base.substring(1);
ItemTag itemTag = TAGS.get(tag);
if (itemTag == null) {
return new EmptyTestableItem();
}
item = itemTag.toTestableItem();
}
if (split.length == 1 && !isTag) {
String itemType = args[0];
boolean isWildcard = itemType.startsWith("*");
if (isWildcard) {
@@ -230,7 +248,7 @@ public final class Items {
item = isWildcard ? new UnrestrictedMaterialTestableItem(material) : new MaterialTestableItem(material);
}
if (split.length == 2) {
if (split.length == 2 && !isTag) {
String namespace = split[0];
String keyID = split[1];
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
@@ -274,7 +292,7 @@ public final class Items {
Legacy namespace:id:amount format
This has been superseded by namespace:id amount
*/
if (split.length == 3) {
if (split.length == 3 && !isTag) {
TestableItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
if (part == null) {
return new EmptyTestableItem();
@@ -306,7 +324,8 @@ public final class Items {
List<Predicate<ItemStack>> predicates = new ArrayList<>();
for (LookupArgParser argParser : ARG_PARSERS) {
for (
LookupArgParser argParser : ARG_PARSERS) {
Predicate<ItemStack> predicate = argParser.parseArguments(modifierArgs, meta);
if (predicate != null) {
predicates.add(argParser.parseArguments(modifierArgs, meta));
@@ -611,6 +630,24 @@ public final class Items {
return false;
}
/**
* Register a new item tag.
*
* @param tag The tag.
*/
public static void registerTag(@NotNull final ItemTag tag) {
TAGS.put(tag.getIdentifier(), tag);
}
/**
* Get all tags.
*
* @return All tags.
*/
public static Collection<ItemTag> getTags() {
return TAGS.values();
}
private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core.items.tag;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;
/**
* A custom item tag.
*/
public abstract class CustomItemTag implements ItemTag {
/**
* The key.
*/
private final NamespacedKey key;
/**
* Create a new custom item tag.
*
* @param key The key.
*/
public CustomItemTag(@NotNull final NamespacedKey key) {
this.key = key;
}
@Override
@NotNull
public String getIdentifier() {
return key.toString();
}
}

View File

@@ -0,0 +1,66 @@
package com.willfp.eco.core.items.tag;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A group of items that share a common trait.
*/
public interface ItemTag {
/**
* Get the identifier of the tag.
*
* @return The identifier.
*/
@NotNull
String getIdentifier();
/**
* Check if an item matches the tag.
*
* @param itemStack The item to check.
* @return If the item matches the tag.
*/
boolean matches(@NotNull ItemStack itemStack);
/**
* Get an example item.
*
* @return The example item.
*/
@Nullable
default ItemStack getExampleItem() {
return null;
}
/**
* Convert this tag to a testable item.
*
* @return The testable item.
*/
@NotNull
default TestableItem toTestableItem() {
return new TestableItem() {
@Override
public boolean matches(@Nullable final ItemStack itemStack) {
return itemStack != null && ItemTag.this.matches(itemStack);
}
@Override
public @NotNull ItemStack getItem() {
ItemStack example = ItemTag.this.getExampleItem();
return example == null ? new ItemStack(Material.STONE) : example;
}
@Override
public String toString() {
return "ItemTagTestableItem{" +
"tag=" + ItemTag.this.getIdentifier() +
'}';
}
};
}
}

View File

@@ -0,0 +1,58 @@
package com.willfp.eco.core.items.tag;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* A vanilla item tag.
*/
public final class VanillaItemTag implements ItemTag {
/**
* The identifier.
*/
private final String identifier;
/**
* The tag.
*/
private final Tag<Material> tag;
/**
* Create a new vanilla item tag.
*
* @param identifier The identifier.
* @param tag The tag.
*/
public VanillaItemTag(@NotNull final String identifier,
@NotNull final Tag<Material> tag) {
this.identifier = identifier;
this.tag = tag;
}
/**
* Get the tag.
*
* @return The tag.
*/
public Tag<Material> getTag() {
return tag;
}
@Override
@NotNull
public String getIdentifier() {
return identifier;
}
@Override
public boolean matches(@NotNull final ItemStack itemStack) {
return tag.isTagged(itemStack.getType());
}
@Override
public @NotNull ItemStack getExampleItem() {
return new ItemStack(tag.getValues().stream().findFirst().orElse(Material.STONE));
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.proxy;
import com.willfp.eco.core.version.Version;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
@@ -28,13 +29,20 @@ public final class ProxyConstants {
"v1_20_R1",
"v1_20_R2",
"v1_20_R3",
"v1_20_6"
"v1_21"
);
private ProxyConstants() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
private static String convertVersion(@NotNull final String version) {
return switch (version) {
case "v1_21_1" -> "v1_21";
default -> version;
};
}
static {
String currentMinecraftVersion = Bukkit.getServer().getBukkitVersion().split("-")[0];
String nmsVersion;
@@ -45,6 +53,6 @@ public final class ProxyConstants {
nmsVersion = "v" + currentMinecraftVersion.replace(".", "_");
}
NMS_VERSION = nmsVersion;
NMS_VERSION = convertVersion(nmsVersion);
}
}

View File

@@ -158,11 +158,8 @@ public final class DurabilityUtils {
}
if (item.getItemMeta() instanceof Damageable meta) {
meta.setDamage(meta.getDamage() - repair);
meta.setDamage(Math.max(0, meta.getDamage() - repair));
if (meta.getDamage() < 0) {
meta.setDamage(0);
}
item.setItemMeta((ItemMeta) meta);
}
}

View File

@@ -0,0 +1,19 @@
group = "com.willfp"
version = rootProject.version
dependencies {
compileOnly(project(":eco-core:core-backend"))
compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
}
tasks {
compileJava {
options.release = 21
}
compileKotlin {
kotlinOptions {
jvmTarget = "21"
}
}
}

View File

@@ -0,0 +1,13 @@
package com.willfp.eco.internal.compat.modern.entities
import com.willfp.eco.core.entities.Entities
import com.willfp.eco.internal.compat.modern.entities.parsers.EntityArgParserJumpStrength
import com.willfp.eco.internal.compat.modern.entities.parsers.EntityArgParserScale
import com.willfp.eco.internal.entities.ModernEntityArgParsers
class ModernEntityArgParsersImpl: ModernEntityArgParsers {
override fun registerAll() {
Entities.registerArgParser(EntityArgParserScale)
Entities.registerArgParser(EntityArgParserJumpStrength)
}
}

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.internal.entities
package com.willfp.eco.internal.compat.modern.entities.parsers
import com.willfp.eco.core.entities.args.EntityArgParseResult
import com.willfp.eco.core.entities.args.EntityArgParser
@@ -28,7 +28,7 @@ object EntityArgParserJumpStrength : EntityArgParser {
return@EntityArgParseResult false
}
val inst = it.getAttribute(Attribute.HORSE_JUMP_STRENGTH) ?: return@EntityArgParseResult false
val inst = it.getAttribute(Attribute.GENERIC_JUMP_STRENGTH) ?: return@EntityArgParseResult false
inst.value >= attributeValue
},
{
@@ -36,8 +36,8 @@ object EntityArgParserJumpStrength : EntityArgParser {
return@EntityArgParseResult
}
it.getAttribute(Attribute.HORSE_JUMP_STRENGTH)?.baseValue = attributeValue
it.getAttribute(Attribute.GENERIC_JUMP_STRENGTH)?.baseValue = attributeValue
}
)
}
}
}

View File

@@ -0,0 +1,45 @@
package com.willfp.eco.internal.compat.modern.entities.parsers
import com.willfp.eco.core.entities.args.EntityArgParseResult
import com.willfp.eco.core.entities.args.EntityArgParser
import org.bukkit.attribute.Attribute
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Phantom
import org.bukkit.entity.Slime
object EntityArgParserScale : EntityArgParser {
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {
var attributeValue: Double? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("scale", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
attributeValue = argSplit[1].toDoubleOrNull()
}
attributeValue ?: return null
return EntityArgParseResult(
{
if (it !is LivingEntity) {
return@EntityArgParseResult false
}
val inst = it.getAttribute(Attribute.GENERIC_SCALE) ?: return@EntityArgParseResult false
inst.value >= attributeValue
},
{
if (it !is LivingEntity) {
return@EntityArgParseResult
}
it.getAttribute(Attribute.GENERIC_SCALE)?.baseValue = attributeValue
}
)
}
}

View File

@@ -0,0 +1,21 @@
package com.willfp.eco.internal.compat.modern.items
import com.willfp.eco.core.items.Items
import com.willfp.eco.internal.compat.modern.items.parsers.ArgParserFireResistant
import com.willfp.eco.internal.compat.modern.items.parsers.ArgParserGlint
import com.willfp.eco.internal.compat.modern.items.parsers.ArgParserItemName
import com.willfp.eco.internal.compat.modern.items.parsers.ArgParserMaxDamage
import com.willfp.eco.internal.compat.modern.items.parsers.ArgParserMaxStackSize
import com.willfp.eco.internal.compat.modern.items.parsers.ArgParserTrim
import com.willfp.eco.internal.items.ModernItemArgParsers
class ModernItemArgParsersImpl : ModernItemArgParsers {
override fun registerAll() {
Items.registerArgParser(ArgParserTrim)
Items.registerArgParser(ArgParserFireResistant)
Items.registerArgParser(ArgParserGlint)
Items.registerArgParser(ArgParserItemName)
Items.registerArgParser(ArgParserMaxDamage)
Items.registerArgParser(ArgParserMaxStackSize)
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.internal.compat.modern.items.parsers
import com.willfp.eco.internal.items.templates.FlagArgParser
import org.bukkit.inventory.meta.ItemMeta
object ArgParserFireResistant : FlagArgParser("fire_resistant") {
override fun apply(meta: ItemMeta) {
meta.isFireResistant = true
}
override fun test(meta: ItemMeta): Boolean {
return meta.isFireResistant
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.internal.compat.modern.items.parsers
import com.willfp.eco.internal.items.templates.FlagArgParser
import org.bukkit.inventory.meta.ItemMeta
object ArgParserGlint : FlagArgParser("glint") {
override fun apply(meta: ItemMeta) {
meta.setEnchantmentGlintOverride(true)
}
override fun test(meta: ItemMeta): Boolean {
return meta.hasEnchantmentGlintOverride()
}
}

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.internal.compat.modern.items.parsers
import com.willfp.eco.internal.items.templates.ValueArgParser
import com.willfp.eco.util.StringUtils
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.minimessage.MiniMessage
import org.bukkit.inventory.meta.ItemMeta
object ArgParserItemName : ValueArgParser<Component>("item_name") {
override fun parse(arg: String): Component {
return StringUtils.formatToComponent(arg)
}
override fun apply(meta: ItemMeta, value: Component) {
meta.itemName(value)
}
override fun test(meta: ItemMeta): String? {
if (!meta.hasItemName()) {
return null
}
val name = MiniMessage.miniMessage().serialize(meta.itemName())
return name
}
}

View File

@@ -0,0 +1,31 @@
package com.willfp.eco.internal.compat.modern.items.parsers
import com.willfp.eco.internal.items.templates.ValueArgParser
import org.bukkit.inventory.meta.Damageable
import org.bukkit.inventory.meta.ItemMeta
object ArgParserMaxDamage : ValueArgParser<Int>("max_damage") {
override fun parse(arg: String): Int? {
return arg.toIntOrNull()
}
override fun apply(meta: ItemMeta, value: Int) {
if (meta !is Damageable) {
return
}
meta.setMaxDamage(value)
}
override fun test(meta: ItemMeta): String? {
if (meta !is Damageable) {
return null
}
if (!meta.hasMaxDamage()) {
return null
}
return meta.maxDamage.toString()
}
}

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.internal.compat.modern.items.parsers
import com.willfp.eco.internal.items.templates.ValueArgParser
import org.bukkit.inventory.meta.ItemMeta
object ArgParserMaxStackSize : ValueArgParser<Int>("max_stack_size") {
override fun parse(arg: String): Int? {
return arg.toIntOrNull()
}
override fun apply(meta: ItemMeta, value: Int) {
meta.setMaxStackSize(value)
}
override fun test(meta: ItemMeta): String? {
if (!meta.hasMaxStackSize()) {
return null
}
return meta.maxStackSize.toString()
}
}

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.internal.items
package com.willfp.eco.internal.compat.modern.items.parsers
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.NamespacedKey
@@ -23,7 +23,11 @@ object ArgParserTrim : LookupArgParser {
if (!argSplit[0].equals("trim", ignoreCase = true)) {
continue
}
@Suppress("DEPRECATION")
material = Registry.TRIM_MATERIAL.get(NamespacedKey.minecraft(argSplit.getOrElse(1) {""}))
@Suppress("DEPRECATION")
pattern = Registry.TRIM_PATTERN.get(NamespacedKey.minecraft(argSplit.getOrElse(2) {""}))
}
@@ -43,6 +47,11 @@ object ArgParserTrim : LookupArgParser {
override fun serializeBack(meta: ItemMeta): String? {
val trim = (meta as? ArmorMeta)?.trim ?: return null
return "trim:${trim.material.key.key.lowercase()}:${trim.pattern.key.key.lowercase()}"
@Suppress("DEPRECATION")
val materialKey = Registry.TRIM_MATERIAL.getKey(trim.material) ?: return null
@Suppress("DEPRECATION")
val patternKey = Registry.TRIM_PATTERN.getKey(trim.pattern) ?: return null
return "trim:${materialKey.key.lowercase()}:${patternKey.key.lowercase()}"
}
}
}

View File

@@ -0,0 +1,19 @@
@file:Suppress("UnstableApiUsage")
package com.willfp.eco.internal.compat.modern.recipes
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.recipes.AutocrafterPatch
import org.bukkit.event.EventHandler
import org.bukkit.event.block.CrafterCraftEvent
class AutocrafterPatchImpl: AutocrafterPatch {
@EventHandler
fun preventEcoRecipes(event: CrafterCraftEvent) {
if (!EcoPlugin.getPluginNames().contains(event.recipe.key.namespace)) {
return
}
event.isCancelled = true
}
}

View File

@@ -13,3 +13,15 @@ dependencies {
compileOnly("org.yaml:snakeyaml:1.33")
compileOnly("com.moandjiezana.toml:toml4j:0.7.2")
}
tasks {
compileJava {
options.release = 17
}
compileKotlin {
kotlinOptions {
jvmTarget = "17"
}
}
}

View File

@@ -126,14 +126,19 @@ abstract class HandledCommand(
* @return The tab completion results.
*/
private fun CommandBase.handleTabComplete(sender: CommandSender, args: List<String>): List<String> {
if (!sender.hasPermission(permission)) return emptyList()
if (!sender.hasPermission(permission)) {
return emptyList()
}
if (args.size == 1) {
val completions = subcommands.filter { sender.hasPermission(it.permission) }.map { it.name }
val completions = mutableListOf<String>()
val list = mutableListOf<String>()
StringUtil.copyPartialMatches(
args[0],
subcommands.filter { sender.hasPermission(it.permission) }.map { it.name },
completions
)
StringUtil.copyPartialMatches(args[0], completions, list)
if (completions.isNotEmpty()) {
return completions
}
@@ -156,9 +161,11 @@ abstract class HandledCommand(
}
val completions = tabComplete(sender, args).toMutableList()
if (sender is Player) {
completions.addAll(tabComplete(sender, args))
}
return completions.sorted()
}
}

View File

@@ -0,0 +1,68 @@
package com.willfp.eco.internal.compat
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.proxy.exceptions.ProxyError
private const val BASE_PACKAGE = "com.willfp.eco.internal.compat.modern"
private val isModern = Prerequisite.HAS_PAPER.isMet && Prerequisite.HAS_1_21.isMet
internal annotation class ModernCompatibilityProxy(
val location: String
)
private val cache = mutableMapOf<Class<*>, Any>()
object ModernCompatibilityScope {
inline fun <reified T> loadProxy(): T {
return loadCompatibilityProxy(T::class.java)
}
inline fun <reified T> useProxy(block: T.() -> Any?) {
val proxy = loadProxy<T>()
with(proxy) {
block()
}
}
}
fun <R> ifModern(block: ModernCompatibilityScope.() -> R) {
if (!isModern) {
return
}
block(ModernCompatibilityScope)
}
fun <T> loadCompatibilityProxy(clazz: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return cache.getOrPut(clazz) {
loadProxyUncached(clazz)
} as T
}
private fun loadProxyUncached(clazz: Class<*>): Any {
val proxy = clazz.getAnnotation(ModernCompatibilityProxy::class.java)
val location = proxy?.location ?: throw IllegalArgumentException("Class ${clazz.name} is not a proxy")
val className = "$BASE_PACKAGE.$location"
try {
val found = Class.forName(className)
val constructor = found.getConstructor()
val instance = constructor.newInstance()
if (!clazz.isInstance(instance)) {
throw ProxyError(
"Modern compatibility proxy class $className does not implement ${clazz.name}",
ClassCastException()
)
}
return instance
} catch (e: ClassNotFoundException) {
throw ProxyError("Could not find modern compatibility proxy class $className", e)
} catch (e: NoSuchMethodException) {
throw ProxyError("Could not find no-args constructor for modern compatibility proxy class $className", e)
}
}

View File

@@ -40,4 +40,4 @@ object EntityArgParserFlySpeed : EntityArgParser {
}
)
}
}
}

View File

@@ -0,0 +1,8 @@
package com.willfp.eco.internal.entities
import com.willfp.eco.internal.compat.ModernCompatibilityProxy
@ModernCompatibilityProxy("entities.ModernEntityArgParsersImpl")
interface ModernEntityArgParsers {
fun registerAll()
}

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.Eco
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.gui.menu.events.CaptiveItemChangeEvent
import com.willfp.eco.core.items.isEcoEmpty
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
@@ -20,9 +22,23 @@ fun Player.forceRenderedInventory(menu: RenderedInventory) {
trackedForceRendered[this.uniqueId] = menu
}
// Workaround because 1.21 has OpenInventory as an interface instead of an abstract class like in previous versions
interface TopInventoryProxy {
fun getTopInventory(player: Player): Inventory
}
private val Player.topInventory: Inventory
get() {
return if (!Prerequisite.HAS_1_21.isMet) {
Eco.get().ecoPlugin.getProxy(TopInventoryProxy::class.java).getTopInventory(this)
} else {
this.openInventory.topInventory
}
}
val Player.renderedInventory: RenderedInventory?
get() = trackedForceRendered[this.uniqueId]
?: this.openInventory.topInventory.asRenderedInventory()
?: this.topInventory.asRenderedInventory()
class RenderedInventory(
val menu: EcoMenu,

View File

@@ -49,4 +49,4 @@ object ArgParserColor : LookupArgParser {
return "color:#${Integer.toHexString(meta.color.asRGB())}"
}
}
}

View File

@@ -7,20 +7,12 @@ import java.util.function.Predicate
object ArgParserCustomModelData : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var modelData: Int? = null
val arg = args.firstOrNull {
it.startsWith("custom-model-data:", ignoreCase = true)
|| it.startsWith("custom_model_data:", ignoreCase = true)
} ?: return null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("custom-model-data", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
modelData = argSplit[1].toIntOrNull()
}
modelData ?: return null
val modelData = arg.split(":")[1].toIntOrNull() ?: return null
meta.setCustomModelData(modelData)
@@ -40,6 +32,6 @@ object ArgParserCustomModelData : LookupArgParser {
return null
}
return "custom-model-data:${meta.customModelData}"
return "custom_model_data:${meta.customModelData}"
}
}

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.items
import com.willfp.eco.core.fast.fast
import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.eco.util.NamespacedKeyUtils
import org.bukkit.NamespacedKey
import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.EnchantmentStorageMeta
@@ -14,17 +14,15 @@ object ArgParserEnchantment : LookupArgParser {
val enchants = mutableMapOf<Enchantment, Int>()
for (arg in args) {
val argSplit = arg.split(":")
try {
val argSplit = arg.split(":")
if (argSplit.size < 2) {
continue
}
val enchant = Enchantment.getByKey(NamespacedKey.minecraft(argSplit[0].lowercase())) ?: continue
val level = argSplit.getOrNull(1)?.toIntOrNull() ?: enchant.maxLevel
val enchant = Enchantment.getByKey(NamespacedKeyUtils.create("minecraft", argSplit[0]))
val level = argSplit[1].toIntOrNull()
if (enchant != null && level != null) {
enchants[enchant] = level
} catch (e: IllegalArgumentException) {
continue
}
}

View File

@@ -61,4 +61,4 @@ object ArgParserEntity : LookupArgParser {
return state.spawnedType?.let { "entity:${state.spawnedType!!.name}" } ?: return null
}
}
}

View File

@@ -1,44 +1,30 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.eco.internal.items.templates.ValueArgParser
import com.willfp.eco.util.StringUtils
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
object ArgParserName : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var name: String? = null
object ArgParserName : ValueArgParser<String>("name") {
override fun parse(arg: String): String {
return arg
}
for (arg in args) {
if (!arg.lowercase().startsWith("name:")) {
continue
}
name = arg.substring(5, arg.length)
}
name ?: return null
val formatted = StringUtils.format(name)
override fun apply(meta: ItemMeta, value: String) {
val formatted = StringUtils.format(value)
// I don't know why it says it's redundant, the compiler yells at me
@Suppress("UsePropertyAccessSyntax", "RedundantSuppression", "DEPRECATION")
meta.setDisplayName(formatted)
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
@Suppress("DEPRECATION")
testMeta.displayName == formatted
}
}
override fun serializeBack(meta: ItemMeta): String? {
override fun test(meta: ItemMeta): String? {
if (!meta.hasDisplayName()) {
return null
}
@Suppress("DEPRECATION")
return "name:\"${meta.displayName}\""
return meta.displayName
}
}
}

View File

@@ -44,4 +44,4 @@ object ArgParserTexture : LookupArgParser {
return "texture:${SkullUtils.getSkullTexture(meta)}"
}
}
}

View File

@@ -1,38 +1,14 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.inventory.ItemStack
import com.willfp.eco.internal.items.templates.FlagArgParser
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
object ArgParserUnbreakable : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var unbreakable = false
for (arg in args) {
if (arg.equals("unbreakable", true)) {
unbreakable = true
}
}
if (!unbreakable) {
return null
}
object ArgParserUnbreakable : FlagArgParser("unbreakable") {
override fun apply(meta: ItemMeta) {
meta.isUnbreakable = true
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
testMeta.isUnbreakable
}
}
override fun serializeBack(meta: ItemMeta): String? {
if (!meta.isUnbreakable) {
return null
}
return "unbreakable"
override fun test(meta: ItemMeta): Boolean {
return meta.isUnbreakable
}
}
}

View File

@@ -0,0 +1,8 @@
package com.willfp.eco.internal.items
import com.willfp.eco.internal.compat.ModernCompatibilityProxy
@ModernCompatibilityProxy("items.ModernItemArgParsersImpl")
interface ModernItemArgParsers {
fun registerAll()
}

View File

@@ -0,0 +1,39 @@
package com.willfp.eco.internal.items.tags
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.tag.VanillaItemTag
import org.bukkit.Keyed
import org.bukkit.Material
import org.bukkit.Tag
object VanillaItemTags {
fun register() {
// Get all tags
val allTags = Tag::class.java.declaredFields
.filter { it.type == Tag::class.java }
.mapNotNull {
val tag = it.get(null) as? Tag<*>
if (tag == null) {
null
} else {
NamedTag(it.name.lowercase(), tag)
}
}
// Register all tags
for (tag in allTags) {
if (tag.isMaterial) {
Items.registerTag(
@Suppress("UNCHECKED_CAST")
VanillaItemTag(tag.name, tag.tag as Tag<Material>)
)
}
}
}
private data class NamedTag<T : Keyed>(val name: String, val tag: Tag<T>) {
// Check if tag is material
val isMaterial: Boolean
get() = tag.values.firstOrNull() is Material
}
}

View File

@@ -0,0 +1,44 @@
package com.willfp.eco.internal.items.templates
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
abstract class FlagArgParser(
protected val flag: String
) : LookupArgParser {
abstract fun apply(meta: ItemMeta)
abstract fun test(meta: ItemMeta): Boolean
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var has = false
for (arg in args) {
if (arg.equals(flag, true)) {
has = true
}
}
if (!has) {
return null
}
apply(meta)
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
test(testMeta)
}
}
override fun serializeBack(meta: ItemMeta): String? {
if (!test(meta)) {
return null
}
return flag
}
}

View File

@@ -0,0 +1,50 @@
package com.willfp.eco.internal.items.templates
import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.eco.util.StringUtils
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
abstract class ValueArgParser<T: Any>(
protected val flag: String
) : LookupArgParser {
abstract fun parse(arg: String): T?
abstract fun apply(meta: ItemMeta, value: T)
abstract fun test(meta: ItemMeta): String?
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var argument: String? = null
for (arg in args) {
if (!arg.lowercase().startsWith("${flag}:")) {
continue
}
argument = arg.substring(flag.length + 1, arg.length)
}
argument ?: return null
val parsed = parse(argument) ?: return null
apply(meta, parsed)
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
test(testMeta) == parsed
}
}
override fun serializeBack(meta: ItemMeta): String? {
val test = test(meta)
if (test.isNullOrBlank()) {
return null
}
return "${flag}:\"$test\""
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.internal.particle
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.particle.ParticleFactory
import com.willfp.eco.core.particle.SpawnableParticle
import org.bukkit.Color
@@ -7,6 +8,14 @@ import org.bukkit.Location
import org.bukkit.Particle
object ParticleFactoryRGB : ParticleFactory {
private val dustParticle = runCatching {
if (Prerequisite.HAS_1_20_5.isMet) {
Particle.valueOf("DUST")
} else {
Particle.valueOf("REDSTONE")
}
}.getOrNull()
override fun getNames() = listOf(
"color",
"rgb",
@@ -30,7 +39,9 @@ object ParticleFactoryRGB : ParticleFactory {
override fun spawn(location: Location, amount: Int) {
val world = location.world ?: return
world.spawnParticle(Particle.REDSTONE, location, amount, 0.0, 0.0, 0.0, 0.0, options)
val particle = dustParticle ?: return
world.spawnParticle(particle, location, amount, 0.0, 0.0, 0.0, 0.0, options)
}
}
}

View File

@@ -8,6 +8,11 @@ import org.bukkit.entity.Player
import java.util.UUID
import kotlin.math.roundToInt
private fun getXPNeededForLevel(level: Int): Int {
// XP Formula from NMS Player
return if (level >= 30) 112 + (level - 30) * 9 else (if (level >= 15) 37 + (level - 15) * 5 else 7 + level * 2)
}
object PriceFactoryXP : PriceFactory {
override fun getNames() = listOf(
"xp",
@@ -25,15 +30,37 @@ object PriceFactoryXP : PriceFactory {
) : Price {
private val multipliers = mutableMapOf<UUID, Double>()
override fun canAfford(player: Player, multiplier: Double): Boolean =
player.totalExperience >= getValue(player, multiplier)
override fun canAfford(player: Player, multiplier: Double): Boolean {
var totalExperience = 0
for (level in 0 until player.level) {
totalExperience += getXPNeededForLevel(level)
}
totalExperience += (player.exp * getXPNeededForLevel(player.level)).toInt()
return totalExperience >= getValue(player, multiplier).roundToInt()
}
override fun pay(player: Player, multiplier: Double) {
player.totalExperience -= getValue(player, multiplier).roundToInt()
takeXP(player, getValue(player, multiplier).roundToInt())
}
private fun takeXP(player: Player, amount: Int) {
val currentLevel = player.level
val currentExp = player.exp * getXPNeededForLevel(currentLevel)
if (currentExp >= amount) {
player.exp = (currentExp - amount) / getXPNeededForLevel(currentLevel)
} else {
// Handle recursive level down
player.exp = 1f
player.level = (currentLevel - 1).coerceAtLeast(0)
takeXP(player, (amount - currentExp).toInt())
}
}
override fun giveTo(player: Player, multiplier: Double) {
player.totalExperience += getValue(player, multiplier).roundToInt()
player.giveExp(getValue(player, multiplier).roundToInt())
}
override fun getValue(player: Player, multiplier: Double): Double {

View File

@@ -0,0 +1,7 @@
package com.willfp.eco.internal.recipes
import com.willfp.eco.internal.compat.ModernCompatibilityProxy
import org.bukkit.event.Listener
@ModernCompatibilityProxy("recipes.AutocrafterPatchImpl")
interface AutocrafterPatch: Listener

View File

@@ -7,4 +7,11 @@ version = rootProject.version
dependencies {
paperweight.paperDevBundle("1.17.1-R0.1-SNAPSHOT")
pluginRemapper("net.fabricmc:tiny-remapper:0.10.3:fat")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

View File

@@ -85,10 +85,18 @@ class EcoFastItemStack(
override fun setLoreComponents(lore: List<Component>?) {
val jsonLore = mutableListOf<String>()
if (lore != null) {
for (s in lore) {
jsonLore.add(StringUtils.componentToJson(s))
if (lore.isNullOrEmpty()) {
val element = handle.getOrCreateTagElement("display")
element.remove("Lore")
if (element.isEmpty) {
handle.removeTagKey("display")
}
apply()
return
}
for (s in lore) {
jsonLore.add(StringUtils.componentToJson(s))
}
val displayTag = handle.getOrCreateTagElement("display")

Some files were not shown because too many files have changed in this diff Show More