Compare commits

..

13 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
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
21 changed files with 25 additions and 700 deletions

View File

@@ -63,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/")

View File

@@ -1,149 +0,0 @@
package com.willfp.eco.core.blocks;
import com.willfp.eco.core.blocks.impl.EmptyTestableBlock;
import com.willfp.eco.core.blocks.impl.MaterialTestableBlock;
import com.willfp.eco.core.blocks.impl.UnrestrictedMaterialTestableBlock;
import com.willfp.eco.core.blocks.provider.BlockProvider;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Class to manage all custom and vanilla blocks.
*/
public final class Blocks {
/**
* All entities.
*/
private static final Map<NamespacedKey, TestableBlock> REGISTRY = new ConcurrentHashMap<>();
/**
* All block providers.
*/
private static final Map<String, BlockProvider> PROVIDERS = new ConcurrentHashMap<>();
/**
* The lookup handler.
*/
private static final BlocksLookupHandler BLOCKS_LOOKUP_HANDLER = new BlocksLookupHandler(Blocks::doParse);
/**
* Register a new custom block.
*
* @param key The key of the block.
* @param block The block.
*/
public static void registerCustomBlock(@NotNull final NamespacedKey key,
@NotNull final TestableBlock block) {
REGISTRY.put(key, block);
}
/**
* Register a new block provider.
*
* @param provider The provider.
*/
public static void registerBlockProvider(@NotNull final BlockProvider provider) {
PROVIDERS.put(provider.getNamespace(), provider);
}
/**
* Remove a block.
*
* @param key The key of the block.
*/
public static void removeCustomBlock(@NotNull final NamespacedKey key) {
REGISTRY.remove(key);
}
/**
* This is the backbone of the eco block system.
* <p>
* You can look up a TestableBlock for any material or custom block,
* and it will return it.
* <p>
* If you want to get a Block instance from this, then just call
* {@link TestableBlock#place(Location)}.
*
* @param key The lookup string.
* @return The testable block, or an empty testable block if not found.
*/
@NotNull
public static TestableBlock lookup(@NotNull final String key) {
return BLOCKS_LOOKUP_HANDLER.parseKey(key);
}
@NotNull
private static TestableBlock doParse(@NotNull final String[] args) {
if (args.length == 0) {
return new EmptyTestableBlock();
}
String[] split = args[0].toLowerCase().split(":");
if (split.length == 1) {
if (args[0].startsWith("*")) {
Material type = Material.getMaterial(args[0].substring(1));
return (type == null) ? new EmptyTestableBlock() : new UnrestrictedMaterialTestableBlock(type);
} else {
Material type = Material.getMaterial(args[0].toUpperCase());
return (type == null) ? new EmptyTestableBlock() : new MaterialTestableBlock(type);
}
}
NamespacedKey namespacedKey = NamespacedKeyUtils.create(split[0], split[1]);
TestableBlock block = REGISTRY.get(namespacedKey);
if (block != null) {
return block;
}
BlockProvider provider = PROVIDERS.get(split[0]);
if (provider == null) {
return new EmptyTestableBlock();
}
block = provider.provideForKey(split[1]);
if (block == null) {
return new EmptyTestableBlock();
}
registerCustomBlock(namespacedKey, block);
return block;
}
/**
* Get if block is a custom block.
*
* @param block The block to check.
* @return If is custom.
*/
public static boolean isCustomBlock(@NotNull final Block block) {
for (TestableBlock testable : REGISTRY.values()) {
if (testable.matches(block)) {
return true;
}
}
return false;
}
/**
* Get all registered custom blocks.
*
* @return A set of all blocks.
*/
public static Set<TestableBlock> getCustomBlocks() {
return new HashSet<>(REGISTRY.values());
}
private Blocks() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -1,48 +0,0 @@
package com.willfp.eco.core.blocks;
import com.willfp.eco.core.blocks.impl.EmptyTestableBlock;
import com.willfp.eco.core.blocks.impl.GroupedTestableBlocks;
import com.willfp.eco.core.lookup.LookupHandler;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.function.Function;
/**
* Handle block lookup strings.
*/
public class BlocksLookupHandler implements LookupHandler<TestableBlock> {
/**
* The parser.
*/
private final Function<String[], @NotNull TestableBlock> parser;
/**
* Create new lookup handler.
*
* @param parser The parser.
*/
public BlocksLookupHandler(@NotNull final Function<String[], @NotNull TestableBlock> parser) {
this.parser = parser;
}
@Override
public @NotNull TestableBlock parse(@NotNull final String[] args) {
return parser.apply(args);
}
@Override
public boolean validate(@NotNull final TestableBlock object) {
return !(object instanceof EmptyTestableBlock);
}
@Override
public @NotNull TestableBlock getFailsafe() {
return new EmptyTestableBlock();
}
@Override
public @NotNull TestableBlock join(@NotNull final Collection<TestableBlock> options) {
return new GroupedTestableBlocks(options);
}
}

View File

@@ -1,84 +0,0 @@
package com.willfp.eco.core.blocks;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* A custom block has 3 components.
*
* <ul>
* <li>The key to identify it</li>
* <li>The test to check if any block is this custom block</li>
* <li>The supplier to spawn the custom {@link Block}</li>
* </ul>
*/
public class CustomBlock implements TestableBlock {
/**
* The key.
*/
private final NamespacedKey key;
/**
* The test for block to pass.
*/
private final Predicate<@NotNull Block> test;
/**
* The provider to spawn the block.
*/
private final Function<Location, Block> provider;
/**
* Create a new custom block.
*
* @param key The block key.
* @param test The test.
* @param provider The provider to spawn the block.
*/
public CustomBlock(@NotNull final NamespacedKey key,
@NotNull final Predicate<@NotNull Block> test,
@NotNull final Function<Location, Block> provider) {
this.key = key;
this.test = test;
this.provider = provider;
}
@Override
public boolean matches(@Nullable final Block other) {
if (other == null) {
return false;
}
return test.test(other);
}
@Override
public @NotNull Block place(@NotNull final Location location) {
Validate.notNull(location.getWorld());
return provider.apply(location);
}
/**
* Register the block.
*/
public void register() {
Blocks.registerCustomBlock(this.getKey(), this);
}
/**
* Get the key.
*
* @return The key.
*/
public NamespacedKey getKey() {
return this.key;
}
}

View File

@@ -1,31 +0,0 @@
package com.willfp.eco.core.blocks;
import com.willfp.eco.core.lookup.Testable;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A block with a test.
*/
public interface TestableBlock extends Testable<Block> {
/**
* If a Block matches the test.
*
* @param other The other block.
* @return If the block matches.
*/
@Override
boolean matches(@Nullable Block other);
/**
* Place the block.
*
* @param location The location.
* @return The block.
*/
@NotNull
Block place(@NotNull Location location);
}

View File

@@ -1,29 +0,0 @@
package com.willfp.eco.core.blocks.impl;
import com.willfp.eco.core.blocks.TestableBlock;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Empty block.
*/
public class EmptyTestableBlock implements TestableBlock {
/**
* Create a new empty testable block.
*/
public EmptyTestableBlock() {
}
@Override
public boolean matches(@Nullable final Block other) {
return false;
}
@Override
public @NotNull Block place(@NotNull final Location location) {
return location.getBlock();
}
}

View File

@@ -1,60 +0,0 @@
package com.willfp.eco.core.blocks.impl;
import com.willfp.eco.core.blocks.TestableBlock;
import com.willfp.eco.util.NumberUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
/**
* A group of testable blocks.
*/
public class GroupedTestableBlocks implements TestableBlock {
/**
* The children.
*/
private final Collection<TestableBlock> children;
/**
* Create a new group of testable blocks.
*
* @param children The children.
*/
public GroupedTestableBlocks(@NotNull final Collection<TestableBlock> children) {
Validate.isTrue(!children.isEmpty(), "Group must have at least one child!");
this.children = children;
}
@Override
public boolean matches(@Nullable final Block other) {
for (TestableBlock child : children) {
if (child.matches(other)) {
return true;
}
}
return false;
}
@Override
public @NotNull Block place(@NotNull final Location location) {
return new ArrayList<>(children)
.get(NumberUtils.randInt(0, children.size() - 1))
.place(location);
}
/**
* Get the children.
*
* @return The children.
*/
public Collection<TestableBlock> getChildren() {
return new ArrayList<>(children);
}
}

View File

@@ -1,59 +0,0 @@
package com.willfp.eco.core.blocks.impl;
import com.willfp.eco.core.blocks.Blocks;
import com.willfp.eco.core.blocks.TestableBlock;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A testable block for vanilla materials.
*/
public class MaterialTestableBlock implements TestableBlock {
/**
* The block type.
*/
private final Material material;
/**
* Create a new unrestricted material testable block.
*
* @param material The material.
*/
public MaterialTestableBlock(@NotNull final Material material) {
this.material = material;
}
@Override
public boolean matches(@Nullable final Block block) {
boolean simpleMatches = block != null && block.getType() == material;
if (!simpleMatches) {
return false;
}
return !Blocks.isCustomBlock(block);
}
@Override
public @NotNull Block place(@NotNull Location location) {
Validate.notNull(location.getWorld());
Block block = location.getWorld().getBlockAt(location);
block.setType(material);
return block;
}
/**
* Get the material.
*
* @return The material.
*/
public Material getMaterial() {
return this.material;
}
}

View File

@@ -1,52 +0,0 @@
package com.willfp.eco.core.blocks.impl;
import com.willfp.eco.core.blocks.TestableBlock;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A testable block for materials regardless of data.
*/
public class UnrestrictedMaterialTestableBlock implements TestableBlock {
/**
* The block type.
*/
private final Material material;
/**
* Create a new unrestricted material testable block.
*
* @param material The material.
*/
public UnrestrictedMaterialTestableBlock(@NotNull final Material material) {
this.material = material;
}
@Override
public boolean matches(@Nullable final Block other) {
return other != null && other.getType() == material;
}
@Override
public @NotNull Block place(@NotNull Location location) {
Validate.notNull(location.getWorld());
Block block = location.getWorld().getBlockAt(location);
block.setType(material);
return block;
}
/**
* Get the material.
*
* @return The material.
*/
public Material getMaterial() {
return this.material;
}
}

View File

@@ -1,49 +0,0 @@
package com.willfp.eco.core.blocks.provider;
import com.willfp.eco.core.blocks.TestableBlock;
import com.willfp.eco.core.registry.Registry;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Block providers are call-site registrations for blocks. In other words,
* they only register their blocks when a request is made. This is marginally
* slower, however it is required for certain plugins, and fixes bugs related to
* loading orders.
*
* @see TestableBlock
*/
public abstract class BlockProvider {
/**
* The namespace.
*/
private final String namespace;
/**
* Create a new BlockProvider for a specific namespace.
*
* @param namespace The namespace.
*/
protected BlockProvider(@NotNull final String namespace) {
this.namespace = namespace;
}
/**
* Provide a TestableBlock for a given key.
*
* @param key The block ID.
* @return The TestableBlock, or null if not found.
*/
@Nullable
public abstract TestableBlock provideForKey(@NotNull String key);
/**
* Get the namespace.
*
* @return The namespace.
*/
public String getNamespace() {
return this.namespace;
}
}

View File

@@ -1,24 +0,0 @@
package com.willfp.eco.core.integrations.customblocks;
import com.willfp.eco.core.integrations.Integration;
/**
* Wrapper class for custom block integrations.
*/
public interface CustomBlocksIntegration extends Integration {
/**
* Register all the custom block for a specific plugin into eco.
*
* @see com.willfp.eco.core.blocks.Blocks
*/
default void registerAllBlocks() {
// Override when needed.
}
/**
* Register {@link com.willfp.eco.core.blocks.provider.BlockProvider}s.
*/
default void registerProvider() {
// Override when needed.
}
}

View File

@@ -1,45 +0,0 @@
package com.willfp.eco.core.integrations.customblocks;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull;
/**
* Class to handle custom block integrations.
*/
public final class CustomBlocksManager {
/**
* A set of all registered integrations.
*/
private static final IntegrationRegistry<CustomBlocksIntegration> REGISTRY = new IntegrationRegistry<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public static void register(@NotNull final CustomBlocksIntegration integration) {
REGISTRY.register(integration);
}
/**
* Register all the custom block for a specific plugin into eco.
*
* @see com.willfp.eco.core.blocks.Blocks
*/
public static void registerAllBlocks() {
REGISTRY.forEachSafely(CustomBlocksIntegration::registerAllBlocks);
}
/**
* Register all the custom blocks for a specific plugin into eco.
*
* @see com.willfp.eco.core.blocks.Blocks
*/
public static void registerProviders() {
REGISTRY.forEachSafely(CustomBlocksIntegration::registerProvider);
}
private CustomBlocksManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

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;
@@ -35,6 +36,13 @@ public final class 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

@@ -14,12 +14,16 @@ object ArgParserEnchantment : LookupArgParser {
val enchants = mutableMapOf<Enchantment, Int>()
for (arg in args) {
val argSplit = arg.split(":")
try {
val argSplit = arg.split(":")
val enchant = Enchantment.getByKey(NamespacedKey.minecraft(argSplit[0].lowercase())) ?: continue
val level = argSplit.getOrNull(1)?.toIntOrNull() ?: enchant.maxLevel
val enchant = Enchantment.getByKey(NamespacedKey.minecraft(argSplit[0].lowercase())) ?: continue
val level = argSplit.getOrNull(1)?.toIntOrNull() ?: enchant.maxLevel
enchants[enchant] = level
enchants[enchant] = level
} catch (e: IllegalArgumentException) {
continue
}
}
if (enchants.isEmpty()) {

View File

@@ -12,7 +12,7 @@ object ParticleFactoryRGB : ParticleFactory {
if (Prerequisite.HAS_1_20_5.isMet) {
Particle.valueOf("DUST")
} else {
Particle.valueOf("REDSTONE_DUST")
Particle.valueOf("REDSTONE")
}
}.getOrNull()

View File

@@ -25,6 +25,7 @@ import net.minecraft.util.Unit
import net.minecraft.world.item.component.CustomData
import net.minecraft.world.item.component.CustomModelData
import net.minecraft.world.item.component.ItemLore
import net.minecraft.world.item.enchantment.ItemEnchantments
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftRegistry
import org.bukkit.craftbukkit.CraftServer
@@ -53,7 +54,7 @@ class NewEcoFastItemStack(
private val pdc = (handle.get(DataComponents.CUSTOM_DATA)?.copyTag() ?: CompoundTag()).makePdc()
override fun getEnchants(checkStored: Boolean): Map<Enchantment, Int> {
val enchantments = handle.get(DataComponents.ENCHANTMENTS) ?: return emptyMap()
val enchantments = handle.get(DataComponents.ENCHANTMENTS) ?: ItemEnchantments.EMPTY
val map = mutableMapOf<Enchantment, Int>()

View File

@@ -29,7 +29,7 @@ dependencies {
compileOnly("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT")
// Plugin dependencies
compileOnly("com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT")
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.7-SNAPSHOT")
compileOnly("com.github.TechFortress:GriefPrevention:16.17.1")
compileOnly("com.github.TownyAdvanced:Towny:0.99.5.21") {

View File

@@ -9,7 +9,6 @@ import com.willfp.eco.core.integrations.IntegrationLoader
import com.willfp.eco.core.integrations.afk.AFKManager
import com.willfp.eco.core.integrations.anticheat.AnticheatManager
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
import com.willfp.eco.core.integrations.customblocks.CustomBlocksManager
import com.willfp.eco.core.integrations.customentities.CustomEntitiesManager
import com.willfp.eco.core.integrations.customitems.CustomItemsManager
import com.willfp.eco.core.integrations.economy.EconomyManager
@@ -18,6 +17,7 @@ import com.willfp.eco.core.integrations.mcmmo.McmmoManager
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
import com.willfp.eco.core.integrations.shop.ShopManager
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.tag.VanillaItemTag
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.core.particle.Particles
import com.willfp.eco.core.price.Prices
@@ -102,7 +102,6 @@ import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefRPGHorses
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefSuperiorSkyblock2
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefTowny
import com.willfp.eco.internal.spigot.integrations.antigrief.AntigriefWorldGuard
import com.willfp.eco.internal.spigot.integrations.customblocks.CustomBlocksOraxen
import com.willfp.eco.internal.spigot.integrations.customentities.CustomEntitiesMythicMobs
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsCustomCrafting
import com.willfp.eco.internal.spigot.integrations.customitems.CustomItemsDenizen
@@ -409,9 +408,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
// Placeholder
IntegrationLoader("PlaceholderAPI") { PlaceholderManager.addIntegration(PlaceholderIntegrationPAPI()) },
// Custom Blocks
IntegrationLoader("Oraxen") { CustomBlocksManager.register(CustomBlocksOraxen(this)) },
// Misc
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) },
IntegrationLoader("Multiverse-Inventories") {

View File

@@ -1,54 +0,0 @@
package com.willfp.eco.internal.spigot.integrations.customblocks
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.blocks.Blocks
import com.willfp.eco.core.blocks.CustomBlock
import com.willfp.eco.core.blocks.TestableBlock
import com.willfp.eco.core.blocks.provider.BlockProvider
import com.willfp.eco.core.integrations.customblocks.CustomBlocksIntegration
import com.willfp.eco.util.namespacedKeyOf
import io.th0rgal.oraxen.api.OraxenBlocks
import io.th0rgal.oraxen.api.events.OraxenItemsLoadedEvent
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
class CustomBlocksOraxen(
private val plugin: EcoPlugin
) : CustomBlocksIntegration, Listener {
override fun registerProvider() {
plugin.eventManager.registerListener(this)
}
override fun getPluginName(): String {
return "Oraxen"
}
@EventHandler
@Suppress("UNUSED_PARAMETER")
fun onItemRegister(event: OraxenItemsLoadedEvent) {
Blocks.registerBlockProvider(OraxenProvider())
}
private class OraxenProvider : BlockProvider("oraxen") {
override fun provideForKey(key: String): TestableBlock? {
// The key
if (!OraxenBlocks.isOraxenBlock(key)) {
return null
}
val namespacedKey = namespacedKeyOf("oraxen", key)
return CustomBlock(
namespacedKey,
{ block ->
// TODO: Implement this
TODO("Not yet implemented")
},
{ location ->
OraxenBlocks.place(key, location)
location.block
}
)
}
}
}

View File

@@ -101,7 +101,7 @@ math-cache-ttl: 200
# The time (in minutes) for literal patterns to be cached for. Higher values will lead to
# faster evaluation times (less CPU usage) at the expense of slightly more memory usage and
# less reactive values. (Do not change unless you are told to).
literal-cache-ttl: 1
literal-cache-ttl: 10
# If anonymous usage statistics should be tracked. This is very valuable information as it
# helps understand how eco and other plugins are being used by logging player and server

View File

@@ -1,2 +1,2 @@
version = 6.73.2
version = 6.73.6
kotlin.incremental.useClasspathSnapshot=false