Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
5595e95701 Bump com.github.EssentialsX:Essentials from 2.18.2 to 2.20.0
Bumps com.github.EssentialsX:Essentials from 2.18.2 to 2.20.0.

---
updated-dependencies:
- dependency-name: com.github.EssentialsX:Essentials
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 21:53:46 +00:00
135 changed files with 252 additions and 3343 deletions

View File

@@ -1,6 +1,6 @@
name: Java CI
on: [ push, pull_request, workflow_dispatch ]
on: [ push, pull_request ]
jobs:
build:
@@ -14,11 +14,11 @@ jobs:
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Set up JDK 21
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 21
java-version: 17
- name: Setup build cache
uses: actions/cache@v2.1.6

View File

@@ -12,11 +12,11 @@ jobs:
- name: Checkout latest code
uses: actions/checkout@v2
- name: Set up JDK 21
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 21
java-version: 17
- name: Setup build cache
uses: actions/cache@v2.1.6

View File

@@ -14,11 +14,11 @@ jobs:
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Set up JDK 21
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 21
java-version: 17
- name: Setup build cache
uses: actions/cache@v2.1.6

View File

@@ -10,11 +10,10 @@ buildscript {
plugins {
id("java-library")
id("io.github.goooler.shadow") version "8.1.7"
id("com.github.johnrengelman.shadow") version "8.1.1"
id("maven-publish")
id("java")
kotlin("jvm") version "1.9.21"
kotlin("plugin.serialization") version "1.9.21"
}
dependencies {
@@ -30,23 +29,23 @@ dependencies {
implementation(project(path = ":eco-core:core-nms:v1_19_R3", configuration = "reobf"))
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"))
}
allprojects {
apply(plugin = "java")
apply(plugin = "java-library")
apply(plugin = "maven-publish")
apply(plugin = "io.github.goooler.shadow")
apply(plugin = "com.github.johnrengelman.shadow")
apply(plugin = "kotlin")
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
repositories {
mavenCentral()
mavenLocal()
maven("https://repo.auxilor.io/repository/maven-public/")
maven("https://jitpack.io")
maven("https://repo.auxilor.io/repository/maven-public/")
// CustomCrafting
maven("https://maven.wolfyscript.com/repository/public/")
// SuperiorSkyblock2
maven("https://repo.bg-software.com/repository/api/")
@@ -89,12 +88,6 @@ allprojects {
// Denizen
maven("https://maven.citizensnpcs.co/repo")
// IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// HuskPlugins
maven("https://repo.william278.net/releases")
}
dependencies {
@@ -143,16 +136,48 @@ allprojects {
}
tasks {
withType<Jar> {
duplicatesStrategy = DuplicatesStrategy.WARN
}
compileKotlin {
kotlinOptions {
jvmTarget = "17"
}
}
shadowJar {
relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
relocate("org.intellij", "com.willfp.eco.libs.intellij")
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
relocate("org.reflections", "com.willfp.eco.libs.reflections")
relocate("javassist", "com.willfp.eco.libs.javassist")
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
relocate("de.undercouch.bson4jackson", "com.willfp.eco.libs.bson4jackson")
relocate("com.fasterxml.jackson", "com.willfp.eco.libs.jackson")
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
relocate("org.bson", "com.willfp.eco.libs.bson")
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
relocate("com.willfp.modelenginebridge", "com.willfp.eco.libs.modelenginebridge")
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
*/
}
compileJava {
dependsOn(clean)
options.encoding = "UTF-8"
@@ -179,48 +204,5 @@ allprojects {
}
}
tasks {
shadowJar {
relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
relocate("org.intellij", "com.willfp.eco.libs.intellij")
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
relocate("org.reflections", "com.willfp.eco.libs.reflections")
relocate("javassist", "com.willfp.eco.libs.javassist")
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
relocate("org.bson", "com.willfp.eco.libs.bson")
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
relocate("com.willfp.modelenginebridge", "com.willfp.eco.libs.modelenginebridge")
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
*/
}
}
// 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

@@ -167,7 +167,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
/**
* The tasks to run on task creation.
*/
private final ListMap<LifecyclePosition, Runnable> onCreateTasks = new ListMap<>();
private final ListMap<LifecyclePosition, Runnable> createTasks = new ListMap<>();
/**
* Create a new plugin.
@@ -575,9 +575,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
this.getLogger().severe("");
this.getLogger().severe("You don't seem to be running paper!");
this.getLogger().severe("Paper is strongly recommended for all servers,");
this.getLogger().severe("and many features may not function properly without it");
this.getLogger().severe("Download Paper from https://papermc.io");
this.getLogger().severe("It's a drop-in replacement for Spigot, so it's easy to switch.");
this.getLogger().severe("and some things may not function properly without it");
this.getLogger().severe("Download Paper from &fhttps://papermc.io");
this.getLogger().severe("");
this.getLogger().severe("----------------------------");
this.getLogger().severe("");
@@ -639,7 +638,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
this.handleLifecycle(this.onReload, this::handleReload);
if (cancelTasks) {
this.handleLifecycle(this.onCreateTasks, this::createTasks);
this.handleLifecycle(this.createTasks, this::createTasks);
}
for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
@@ -667,26 +666,6 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Regist
this.onReload.append(position, task);
}
/**
* Add new task to run on createTasks.
*
* @param task The task.
*/
public final void onCreateTasks(@NotNull final Runnable task) {
this.onCreateTasks(LifecyclePosition.END, task);
}
/**
* Add new task to run on createTasks.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onCreateTasks(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onCreateTasks.append(position, task);
}
/**
* Reload the plugin and return the time taken to reload.
*

View File

@@ -37,27 +37,11 @@ public class Prerequisite {
"Requires server to have ProtocolLib"
);
/**
* 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"),
"Requires server to be running 1.20.5+"
);
/**
* Requires the server to be running 1.20.3.
*/
public static final Prerequisite HAS_1_20_3 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("20_R3") || HAS_1_20_5.isMet(),
"Requires server to be running 1.20.3+"
);
/**
* Requires the server to be running 1.20.
*/
public static final Prerequisite HAS_1_20 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("20") || HAS_1_20_3.isMet(),
() -> ProxyConstants.NMS_VERSION.contains("20"),
"Requires server to be running 1.20+"
);

View File

@@ -29,22 +29,6 @@ public interface LoadableConfig extends Config {
*/
void save() throws IOException;
/**
* Save the config asynchronously.
*/
default void saveAsync() {
// This default implementation exists purely for backwards compatibility
// with legacy Config implementations that don't have saveAsync().
// Default eco implementations of Config have saveAsync() implemented.
new Thread(() -> {
try {
this.save();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
/**
* Get the config file.
*

View File

@@ -87,10 +87,6 @@ public interface ExtendedPersistentDataContainer {
* @return The extended container.
*/
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
if (base instanceof ExtendedPersistentDataContainer) {
return (ExtendedPersistentDataContainer) base;
}
return Eco.get().adaptPdc(base);
}

View File

@@ -27,7 +27,7 @@ public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
/**
* The items.
*/
private Collection<? extends ItemStack> items;
private final Collection<? extends ItemStack> items;
/**
* The xp.
@@ -114,15 +114,6 @@ public class DropQueuePushEvent extends PlayerEvent implements Cancellable {
return items;
}
/**
* Set the items to be dropped.
*
* @param items The items.
*/
public void setItems(Collection<? extends ItemStack> items) {
this.items = items;
}
/**
* Get the xp to be dropped.
*

View File

@@ -13,8 +13,6 @@ import java.io.File;
* @param version The extension version.
* @param name The extension name.
* @param author The extension's author.
* @param file The extension's file.
* @param minimumPluginVersion The minimum plugin version required for this extension.
*/
public record ExtensionMetadata(@NotNull String version,
@NotNull String name,

View File

@@ -164,23 +164,15 @@ public interface FastItemStack extends PersistentDataHolder {
* The returned PersistentDataContainer will not modify the item until the tag is set.
*
* @return The base NBT tag.
* @deprecated Items are now component-based.
*/
@Deprecated(forRemoval = true, since = "6.70.0")
default PersistentDataContainer getBaseTag() {
throw new UnsupportedOperationException("Not supported in 1.20.5+");
}
PersistentDataContainer getBaseTag();
/**
* Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer.
*
* @param container The PersistentDataContainer.
* @deprecated Items are now component-based.
*/
@Deprecated(forRemoval = true, since = "6.70.0")
default void setBaseTag(@Nullable PersistentDataContainer container) {
throw new UnsupportedOperationException("Not supported in 1.20.5+");
}
void setBaseTag(@Nullable PersistentDataContainer container);
/**
* Get the type of the item.

View File

@@ -5,8 +5,6 @@ import org.jetbrains.annotations.NotNull;
/**
* Handles menu events.
*
* @param <T> The type of event to handle.x
*/
public abstract class MenuEventHandler<T extends MenuEvent> {
/**

View File

@@ -86,7 +86,7 @@ public class ConfigSlot extends CustomSlot {
for (String command : config.getStrings(configKey)) {
if (command.startsWith("console:")) {
commands.add(new CommandToDispatch(
StringUtils.removePrefix(command, "console:"),
StringUtils.removePrefix("console:", command),
true
));
} else {

View File

@@ -13,7 +13,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;
@@ -516,11 +515,8 @@ public final class Items {
*
* @param itemStack The ItemStack.
* @return The base NBT.
* @deprecated Items are now component-based.
*/
@NotNull
@Deprecated(since = "6.70.0", forRemoval = true)
@SuppressWarnings("removal")
public static PersistentDataContainer getBaseNBT(@NotNull final ItemStack itemStack) {
return FastItemStack.wrap(itemStack).getBaseTag();
}
@@ -531,11 +527,8 @@ public final class Items {
* @param itemStack The ItemStack.
* @param container The base NBT tag.
* @return The ItemStack, modified. Not required to use, as this modifies the instance.¬
* @deprecated Items are now component-based.
*/
@NotNull
@Deprecated(since = "6.70.0", forRemoval = true)
@SuppressWarnings("removal")
public static ItemStack setBaseNBT(@NotNull final ItemStack itemStack,
@Nullable final PersistentDataContainer container) {
FastItemStack fis = FastItemStack.wrap(itemStack);

View File

@@ -120,12 +120,8 @@ public final class ConfiguredPrice implements Price {
*/
public String getDisplay(@NotNull final Player player,
final double multiplier) {
double value = this.getPrice().getValue(player, multiplier);
return StringUtils.format(
formatString
.replace("%value%", NumberUtils.format(value))
.replace("%value_commas%", NumberUtils.formatWithCommas(value)),
formatString.replace("%value%", NumberUtils.format(this.getPrice().getValue(player, multiplier))),
player,
StringUtils.FormatOption.WITH_PLACEHOLDERS
);

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.proxy;
import com.willfp.eco.core.version.Version;
import org.bukkit.Bukkit;
import java.util.Arrays;
@@ -13,7 +12,7 @@ public final class ProxyConstants {
/**
* The NMS version that the server is running on.
*/
public static final String NMS_VERSION;
public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
/**
* All supported NMS versions.
@@ -26,25 +25,10 @@ public final class ProxyConstants {
"v1_19_R2",
"v1_19_R3",
"v1_20_R1",
"v1_20_R2",
"v1_20_R3",
"v1_20_6"
"v1_20_R2"
);
private ProxyConstants() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
static {
String currentMinecraftVersion = Bukkit.getServer().getBukkitVersion().split("-")[0];
String nmsVersion;
if (new Version(currentMinecraftVersion).compareTo(new Version("1.20.5")) < 0) {
nmsVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
} else {
nmsVersion = "v" + currentMinecraftVersion.replace(".", "_");
}
NMS_VERSION = nmsVersion;
}
}

View File

@@ -62,7 +62,6 @@ public class Registry<T extends Registrable> implements Iterable<T> {
registry.put(element.getID(), element);
element.onRegister();
onRegister(element);
return element;
}
@@ -79,7 +78,6 @@ public class Registry<T extends Registrable> implements Iterable<T> {
}
element.onRemove();
onRemove(element);
registry.remove(element.getID());
@@ -101,10 +99,10 @@ public class Registry<T extends Registrable> implements Iterable<T> {
T element = registry.get(id);
if (element != null) {
return remove(element);
element.onRemove();
}
return null;
return registry.remove(id);
}
/**
@@ -173,24 +171,6 @@ public class Registry<T extends Registrable> implements Iterable<T> {
isLocked = false;
}
/**
* Run when an element is registered.
*
* @param element The element.
*/
protected void onRegister(@NotNull final T element) {
// Override this method to do something when an element is registered.
}
/**
* Run when an element is removed.
*
* @param element The element.
*/
protected void onRemove(@NotNull final T element) {
// Override this method to do something when an element is removed.
}
/**
* Get if the registry is empty.
*

View File

@@ -203,20 +203,6 @@ public final class NumberUtils {
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
}
/**
* Format double to string with commas.
*
* @param toFormat The number to format.
* @return Formatted.
*/
@NotNull
public static String formatWithCommas(final double toFormat) {
DecimalFormat df = new DecimalFormat("#,##0.00");
String formatted = df.format(toFormat);
return formatted.endsWith(".00") ? formatted.substring(0, formatted.length() - 3) : formatted;
}
/**
* Evaluate an expression.
*

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.util;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.willfp.eco.core.Eco;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.TimeUnit;
@@ -16,7 +15,7 @@ public final class PatternUtils {
* Cache of compiled literal patterns.
*/
private static final Cache<String, Pattern> LITERAL_PATTERN_CACHE = Caffeine.newBuilder()
.expireAfterAccess(Eco.get().getEcoPlugin().getConfigYml().getInt("literal-cache-ttl"), TimeUnit.MINUTES)
.expireAfterAccess(1, TimeUnit.MINUTES)
.build();
/**

View File

@@ -22,8 +22,6 @@ fun ItemMeta.mergeFrom(other: ItemMeta): ItemMeta =
* @see Items.getBaseNBT
* @see Items.setBaseNBT
*/
@Suppress("DEPRECATION")
@Deprecated("Not supported in 1.20.5+", level = DeprecationLevel.ERROR)
var ItemStack.baseNBT: PersistentDataContainer
get() = Items.getBaseNBT(this)
set(value) {
@@ -31,8 +29,6 @@ var ItemStack.baseNBT: PersistentDataContainer
}
/** @see Items.setBaseNBT */
@Suppress("DEPRECATION", "DeprecatedCallableAddReplaceWith")
@Deprecated("Not supported in 1.20.5+", level = DeprecationLevel.ERROR)
fun ItemStack.clearNBT() =
Items.setBaseNBT(this, null)
@@ -41,14 +37,9 @@ fun ItemStack.toSNBT() =
Items.toSNBT(this)
/** @see Items.isEmpty */
@Deprecated("Use ItemStack.isEcoEmpty", ReplaceWith("Items.isEmpty(this)"))
val ItemStack?.isEmpty: Boolean
get() = Items.isEmpty(this)
/** @see Items.isEmpty */
val ItemStack?.isEcoEmpty: Boolean
get() = Items.isEmpty(this)
/** @see Items.matchesAny */
fun Collection<TestableItem>.matches(item: ItemStack): Boolean =
Items.matchesAny(item, this)

View File

@@ -8,10 +8,6 @@ import com.willfp.eco.core.placeholder.context.PlaceholderContext
fun Number.toNumeral(): String =
NumberUtils.toNumeral(this.toInt())
/** @see NumberUtils.formatWithCommas */
fun Number.formatWithCommas(): String =
NumberUtils.formatWithCommas(this.toDouble())
/** @see NumberUtils.fromNumeral */
fun String.parseNumeral(): Int =
NumberUtils.fromNumeral(this)

View File

@@ -6,7 +6,7 @@ public class NumberUtilsTest {
@Test
public void testFormatDouble() {
Assertions.assertEquals("3", NumberUtils.format(3.0D));
//Assertions.assertEquals("3.20", NumberUtils.format(3.2D));
Assertions.assertEquals("3.20", NumberUtils.format(3.2D));
}
@Test

View File

@@ -6,7 +6,7 @@ dependencies {
implementation("org.reflections:reflections:0.9.12")
implementation("org.objenesis:objenesis:3.2")
compileOnly("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT")
compileOnly("me.clip:placeholderapi:2.11.4")
compileOnly("net.kyori:adventure-text-minimessage:4.10.0")
compileOnly("net.kyori:adventure-platform-bukkit:4.1.0")

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.internal.command
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.CommandBase
import com.willfp.eco.core.command.NotificationException
import com.willfp.eco.core.config.base.LangYml
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.internal.config
import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.placeholder.InjectablePlaceholder
import java.util.concurrent.ConcurrentHashMap
class EcoConfigSection(
type: ConfigType,

View File

@@ -10,11 +10,10 @@ import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStream
import java.io.Reader
import java.nio.ByteBuffer
import java.nio.channels.AsynchronousFileChannel
import java.nio.file.Files
import java.nio.file.StandardOpenOption
@Suppress("UNCHECKED_CAST")
open class EcoLoadableConfig(
type: ConfigType,
configName: String,
@@ -75,20 +74,6 @@ open class EcoLoadableConfig(
}
}
override fun saveAsync() {
// Save asynchronously using NIO
AsynchronousFileChannel.open(
configFile.toPath(),
StandardOpenOption.WRITE,
StandardOpenOption.CREATE
).use { channel ->
channel.write(
ByteBuffer.wrap(this.toPlaintext().toByteArray()),
0
)
}
}
private fun makeHeader(contents: String) {
header.clear()

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.internal.drops
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.drops.DropQueue
import com.willfp.eco.core.events.DropQueuePushEvent
import com.willfp.eco.core.integrations.antigrief.AntigriefManager
@@ -54,16 +53,13 @@ open class EcoDropQueue(val player: Player) : DropQueue() {
hasTelekinesis = false
}
val pushEvent = DropQueuePushEvent(player, items.toMutableList(), location, xp, hasTelekinesis)
val pushEvent = DropQueuePushEvent(player, items, location, xp, hasTelekinesis)
Bukkit.getServer().pluginManager.callEvent(pushEvent)
if (pushEvent.isCancelled) {
return
}
items.clear()
items.addAll(pushEvent.items)
val world = location.world!!
location = location.add(0.5, 0.5, 0.5)
items.removeIf { itemStack: ItemStack -> itemStack.type == Material.AIR }
@@ -76,17 +72,10 @@ open class EcoDropQueue(val player: Player) : DropQueue() {
world.dropItem(location, drop!!).velocity = Vector()
}
if (xp > 0) {
if (Prerequisite.HAS_PAPER.isMet) {
player.giveExp(xp, true)
} else {
val orb =
world.spawnEntity(
player.location.add(0.0, 0.2, 0.0),
EntityType.EXPERIENCE_ORB
) as ExperienceOrb
orb.velocity = Vector(0, 0, 0)
orb.experience = xp
}
val orb =
world.spawnEntity(player.location.add(0.0, 0.2, 0.0), EntityType.EXPERIENCE_ORB) as ExperienceOrb
orb.velocity = Vector(0, 0, 0)
orb.experience = xp
}
} else {
for (drop in items) {

View File

@@ -19,7 +19,6 @@ object EntityArgParserName : EntityArgParser {
val formatted = StringUtils.format(name)
@Suppress("DEPRECATION")
return EntityArgParseResult(
{ it.customName == formatted },
{

View File

@@ -42,7 +42,6 @@ class EcoExtensionLoader(
}
}
@Suppress("DEPRECATION")
@Throws(MalformedExtensionException::class)
private fun loadExtension(extensionJar: File) {
val url = extensionJar.toURI().toURL()
@@ -60,7 +59,6 @@ class EcoExtensionLoader(
val pluginVersion = Version(extensionYml.getStringOrNull("plugin-version") ?: "0.0.0")
val pluginName = extensionYml.getStringOrNull("plugin")
@Suppress("DEPRECATION")
if (pluginName != null && !pluginName.equals(this.plugin.description.name, ignoreCase = true)) {
throw ExtensionLoadException("${extensionJar.name} is only compatible with $pluginName!")
}
@@ -84,7 +82,6 @@ class EcoExtensionLoader(
author = "Unnamed Author"
}
@Suppress("DEPRECATION")
if (Version(this.plugin.description.version) < pluginVersion) {
throw ExtensionLoadException("Plugin version is too low for ${extensionJar.name}!")
}

View File

@@ -7,6 +7,6 @@ import org.bukkit.NamespacedKey
class EcoNamespacedKeyFactory(private val plugin: EcoPlugin) : NamespacedKeyFactory {
override fun create(key: String): NamespacedKey {
return NamespacedKeyUtils.create(plugin.id, key)
return NamespacedKeyUtils.create(plugin.name, key)
}
}
}

View File

@@ -25,6 +25,7 @@ class FastInternalNamespacedKeyFactory : InternalNamespacedKeyFactory {
class SafeInternalNamespacedKeyFactory : InternalNamespacedKeyFactory {
override fun create(namespace: String, key: String): NamespacedKey {
@Suppress("DEPRECATION")
return NamespacedKey(namespace, key)
}
}

View File

@@ -43,7 +43,6 @@ class EcoMenu(
getPossiblyReactiveSlot(row, column, player)
override fun open(player: Player): Inventory {
@Suppress("DEPRECATION")
val inventory = if (columns == 9) {
Bukkit.createInventory(null, rows * columns, title)
} else {

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.gui.menu.events.CaptiveItemChangeEvent
import com.willfp.eco.core.items.isEcoEmpty
import com.willfp.eco.core.items.isEmpty
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.util.MenuUtils
import com.willfp.eco.util.openMenu
@@ -55,7 +55,7 @@ class RenderedInventory(
val actualItem = inventory.getItem(bukkit) ?: continue
if (slot.isCaptiveFromEmpty) {
if (!actualItem.isEcoEmpty) {
if (!actualItem.isEmpty) {
newCaptive[position] = actualItem
}
} else {

View File

@@ -6,7 +6,6 @@ import com.willfp.eco.core.placeholder.context.placeholderContext
import me.clip.placeholderapi.expansion.PlaceholderExpansion
import org.bukkit.entity.Player
@Suppress("DEPRECATION")
class PAPIExpansion(private val plugin: EcoPlugin) : PlaceholderExpansion() {
init {
register()
@@ -21,17 +20,14 @@ class PAPIExpansion(private val plugin: EcoPlugin) : PlaceholderExpansion() {
}
override fun getAuthor(): String {
@Suppress("DEPRECATION")
return java.lang.String.join(", ", plugin.description.authors)
}
override fun getIdentifier(): String {
@Suppress("DEPRECATION")
return plugin.description.name.lowercase()
}
override fun getVersion(): String {
@Suppress("DEPRECATION")
return plugin.description.version
}

View File

@@ -1,64 +0,0 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.block.CreatureSpawner
import org.bukkit.entity.EntityType
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BlockStateMeta
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
object ArgParserEntity : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
if (meta !is BlockStateMeta) {
return null
}
if (meta.hasBlockState() || meta.blockState !is CreatureSpawner) {
return null
}
val state = meta.blockState as CreatureSpawner
var type: String? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("entity", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
type = argSplit[1]
}
type ?: return null
val entityType = runCatching { EntityType.valueOf(type.uppercase()) }.getOrNull() ?: return null
state.spawnedType = entityType
meta.blockState = state
return Predicate {
val testMeta = ((it.itemMeta as? BlockStateMeta) as? CreatureSpawner) ?: return@Predicate false
testMeta.spawnedType?.name?.equals(type, true) == true
}
}
override fun serializeBack(meta: ItemMeta): String? {
if (meta !is BlockStateMeta) {
return null
}
if (meta.hasBlockState() || meta.blockState !is CreatureSpawner) {
return null
}
val state = meta.blockState as CreatureSpawner
return state.spawnedType?.let { "entity:${state.spawnedType!!.name}" } ?: return null
}
}

View File

@@ -28,6 +28,7 @@ object ArgParserHead : LookupArgParser {
playerName ?: return null
@Suppress("DEPRECATION")
val player = Bukkit.getOfflinePlayer(playerName)
meta.owningPlayer = player

View File

@@ -22,13 +22,12 @@ object ArgParserName : LookupArgParser {
val formatted = StringUtils.format(name)
// I don't know why it says it's redundant, the compiler yells at me
@Suppress("UsePropertyAccessSyntax", "RedundantSuppression", "DEPRECATION")
@Suppress("UsePropertyAccessSyntax", "RedundantSuppression")
meta.setDisplayName(formatted)
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
@Suppress("DEPRECATION")
testMeta.displayName == formatted
}
}
@@ -38,7 +37,6 @@ object ArgParserName : LookupArgParser {
return null
}
@Suppress("DEPRECATION")
return "name:\"${meta.displayName}\""
}
}

View File

@@ -1,11 +1,13 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.Color
import org.bukkit.NamespacedKey
import org.bukkit.Registry
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ArmorMeta
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.meta.LeatherArmorMeta
import org.bukkit.inventory.meta.trim.ArmorTrim
import org.bukkit.inventory.meta.trim.TrimMaterial
import org.bukkit.inventory.meta.trim.TrimPattern

View File

@@ -7,8 +7,6 @@ import com.willfp.eco.core.placeholder.InjectablePlaceholder
import com.willfp.eco.core.placeholder.Placeholder
import com.willfp.eco.core.placeholder.context.PlaceholderContext
import com.willfp.eco.util.StringUtils
import com.willfp.eco.util.evaluateExpression
import com.willfp.eco.util.toNiceString
import java.util.concurrent.TimeUnit
/*
@@ -21,8 +19,6 @@ but it's still best to minimise the memory overhead.
class PlaceholderParser {
private val placeholderRegex = Regex("%([^% ]+)%")
private val prettyMathExpressionRegex = Regex("(\\{\\^\\{)(.)+(}})")
private val mathExpressionRegex = Regex("(\\{\\{)(.)+(}})")
private val placeholderLookupCache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.SECONDS)
@@ -38,29 +34,6 @@ class PlaceholderParser {
injections: Collection<InjectablePlaceholder>,
translateEcoPlaceholders: Boolean = true
): String {
var processed = text
// Only evaluate math expressions if there might be any
// Checking { as a char is faster than checking a string sequence,
// even if it might lead to false positives.
if ('{' in processed) {
if ('^' in processed) {
// Evaluate pretty math expressions
processed = prettyMathExpressionRegex.findAll(processed).fold(processed) { acc, matchResult ->
val expression = matchResult.value.substring(3, matchResult.value.length - 2)
val result = evaluateExpression(expression, context)
acc.replace(matchResult.value, result.toNiceString())
}
}
// Evaluate math expressions
processed = mathExpressionRegex.findAll(processed).fold(processed) { acc, matchResult ->
val expression = matchResult.value.substring(2, matchResult.value.length - 2)
val result = evaluateExpression(expression, context)
acc.replace(matchResult.value, result.toString())
}
}
/*
Why am I doing injections at the start, and again at the end?
@@ -82,7 +55,7 @@ class PlaceholderParser {
*/
// Apply injections first
processed = injections.fold(processed) { acc, injection ->
var processed = injections.fold(text) { acc, injection ->
injection.tryTranslateQuickly(acc, context)
}
@@ -93,7 +66,7 @@ class PlaceholderParser {
val prefix = "%${additionalPlayer.identifier}_"
processed = found.fold(processed) { acc, placeholder ->
if (placeholder.startsWith(prefix)) {
val newPlaceholder = "%${StringUtils.removePrefix(placeholder, prefix)}"
val newPlaceholder = "%${StringUtils.removePrefix(prefix, placeholder)}"
val translation = translatePlacholders(
newPlaceholder,
context.copyWithPlayer(additionalPlayer.player),

View File

@@ -1,5 +1,5 @@
plugins {
id("io.papermc.paperweight.userdev") version "1.7.1" apply false
id("io.papermc.paperweight.userdev") version "1.5.3" apply false
}

View File

@@ -1,13 +1,9 @@
package com.willfp.eco.internal.spigot.proxy.common
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.entities.ai.EntityGoal
import com.willfp.eco.core.entities.ai.TargetGoal
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.nbt.CompoundTag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
@@ -72,18 +68,6 @@ fun CompoundTag.setPdc(pdc: PersistentDataContainer?, item: net.minecraft.world.
fun Player.toNMS(): ServerPlayer =
impl.toNMS(this)
fun Component.toNMS(): net.minecraft.network.chat.Component =
if (Prerequisite.HAS_PAPER.isMet) PaperAdventure.asVanilla(this) else impl.toNMS(this)
fun net.minecraft.network.chat.Component.toAdventure(): Component {
if (Prerequisite.HAS_PAPER.isMet) {
return PaperAdventure.asAdventure(this)
}
val json = net.minecraft.network.chat.Component.Serializer.toJson(this)
return GsonComponentSerializer.gson().deserialize(json)
}
interface CommonsProvider {
val nbtTagString: Int
@@ -117,8 +101,6 @@ interface CommonsProvider {
fun toNMS(player: Player): ServerPlayer
fun toNMS(component: Component): net.minecraft.network.chat.Component
companion object {
fun setIfNeeded(provider: CommonsProvider) {
if (::impl.isInitialized) {

View File

@@ -29,14 +29,10 @@ import kotlin.experimental.and
import kotlin.experimental.inv
import kotlin.experimental.or
interface ImplementedFIS : FastItemStack {
fun apply()
}
@Suppress("UsePropertyAccessSyntax")
class EcoFastItemStack(
private val bukkit: org.bukkit.inventory.ItemStack
) : ImplementedFIS {
) : FastItemStack {
private val handle = bukkit.asNMSStack()
private val pdc = (if (handle.hasTag()) handle.getTag()!! else CompoundTag()).makePdc()
@@ -188,11 +184,9 @@ class EcoFastItemStack(
return this.flagBits and bitModifier == bitModifier
}
@Deprecated("Not supported in 1.20.5+")
override fun getBaseTag(): PersistentDataContainer =
(if (handle.hasTag()) handle.getTag()!! else CompoundTag()).makePdc(base = true)
@Deprecated("Not supported in 1.20.5+")
override fun setBaseTag(container: PersistentDataContainer?) {
(if (handle.hasTag()) handle.getTag()!! else CompoundTag()).setPdc(container, item = handle)
apply()
@@ -265,7 +259,7 @@ class EcoFastItemStack(
return handle.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem()))
}
override fun apply() {
internal fun apply() {
if (handle.hasTag()) {
handle.getTag()?.setPdc(this.pdc)
}
@@ -282,9 +276,9 @@ class EcoFastItemStack(
}
}
class ContinuallyAppliedPersistentDataContainer(
private class ContinuallyAppliedPersistentDataContainer(
val handle: PersistentDataContainer,
private val fis: ImplementedFIS
val fis: EcoFastItemStack
) : PersistentDataContainer by handle {
override fun <T : Any, Z : Any> set(key: NamespacedKey, type: PersistentDataType<T, Z>, value: Z) {
handle.set(key, type, value)

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.Registry
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = GsonComponentSerializer.gson().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,83 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
private val itemsByIDMapField = SynchedEntityData::class.java
.declaredFields
.filter { it.type == Int2ObjectMap::class.java }
.toList()[0]
.apply { isAccessible = true }
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData,
true
)
player.sendPacket(Packet(packet))
}
private fun <T : Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
private fun <T : Any> SynchedEntityData.hasItem(accessor: EntityDataAccessor<T>): Boolean {
val itemsByIDMap = itemsByIDMapField.get(this) as Int2ObjectMap<Any>
return itemsByIDMap.containsKey(accessor.id)
}
}

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
@@ -29,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.Registry
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = GsonComponentSerializer.gson().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,83 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
private val itemsByIDMapField = SynchedEntityData::class.java
.declaredFields
.filter { it.type == Int2ObjectMap::class.java }
.toList()[0]
.apply { isAccessible = true }
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData,
true
)
player.sendPacket(Packet(packet))
}
private fun <T : Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
private fun <T : Any> SynchedEntityData.hasItem(accessor: EntityDataAccessor<T>): Boolean {
val itemsByIDMap = itemsByIDMapField.get(this) as Int2ObjectMap<Any>
return itemsByIDMap.containsKey(accessor.id)
}
}

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
@@ -29,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_18_R1.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.Registry
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = GsonComponentSerializer.gson().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,83 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
private val itemsByIDMapField = SynchedEntityData::class.java
.declaredFields
.filter { it.type == Int2ObjectMap::class.java }
.toList()[0]
.apply { isAccessible = true }
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData,
true
)
player.sendPacket(Packet(packet))
}
private fun <T : Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
private fun <T : Any> SynchedEntityData.hasItem(accessor: EntityDataAccessor<T>): Boolean {
val itemsByIDMap = itemsByIDMapField.get(this) as Int2ObjectMap<Any>
return itemsByIDMap.containsKey(accessor.id)
}
}

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack
@@ -29,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.Registry
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = GsonComponentSerializer.gson().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,83 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
private val itemsByIDMapField = SynchedEntityData::class.java
.declaredFields
.filter { it.type == Int2ObjectMap::class.java }
.toList()[0]
.apply { isAccessible = true }
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData,
true
)
player.sendPacket(Packet(packet))
}
private fun <T : Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
private fun <T : Any> SynchedEntityData.hasItem(accessor: EntityDataAccessor<T>): Boolean {
val itemsByIDMap = itemsByIDMapField.get(this) as Int2ObjectMap<Any>
return itemsByIDMap.containsKey(accessor.id)
}
}

View File

@@ -28,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
}
}

View File

@@ -8,7 +8,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_19_R1.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -20,9 +19,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -6,8 +6,6 @@ import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import io.netty.channel.Channel
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -159,10 +157,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = GsonComponentSerializer.gson().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,82 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
private val itemsByIDMapField = SynchedEntityData::class.java
.declaredFields
.filter { it.type == Int2ObjectMap::class.java }
.toList()[0]
.apply { isAccessible = true }
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData.packDirty() ?: throw IllegalStateException("No packed entity data")
)
player.sendPacket(Packet(packet))
}
private fun <T : Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
private fun <T : Any> SynchedEntityData.hasItem(accessor: EntityDataAccessor<T>): Boolean {
val itemsByIDMap = itemsByIDMapField.get(this) as Int2ObjectMap<Any>
return itemsByIDMap.containsKey(accessor.id)
}
}

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
@@ -29,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_19_R2.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = GsonComponentSerializer.gson().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,82 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_19_R3
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
private val itemsByIDMapField = SynchedEntityData::class.java
.declaredFields
.filter { it.type == Int2ObjectMap::class.java }
.toList()[0]
.apply { isAccessible = true }
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData.packDirty() ?: throw IllegalStateException("No packed entity data")
)
player.sendPacket(Packet(packet))
}
private fun <T : Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
private fun <T : Any> SynchedEntityData.hasItem(accessor: EntityDataAccessor<T>): Boolean {
val itemsByIDMap = itemsByIDMapField.get(this) as Int2ObjectMap<Any>
return itemsByIDMap.containsKey(accessor.id)
}
}

View File

@@ -28,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -1,51 +0,0 @@
plugins {
id("io.papermc.paperweight.userdev")
}
group = "com.willfp"
version = rootProject.version
dependencies {
implementation(project(":eco-core:core-nms:nms-common"))
paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT")
implementation("net.kyori:adventure-text-minimessage:4.11.0") {
version {
strictly("4.11.0")
}
exclude(group = "net.kyori", module = "adventure-api")
}
}
tasks {
build {
dependsOn(reobfJar)
}
reobfJar {
mustRunAfter(shadowJar)
}
shadowJar {
relocate(
"com.willfp.eco.internal.spigot.proxy.common",
"com.willfp.eco.internal.spigot.proxy.v1_20_6.common"
)
relocate(
"net.kyori.adventure.text.minimessage",
"com.willfp.eco.internal.spigot.proxy.v1_20_6.minimessage"
)
}
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
withSourcesJar()
}
compileKotlin {
kotlinOptions {
jvmTarget = "21"
}
}
}

View File

@@ -1,35 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.command.PluginCommandBase
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.SimpleCommandMap
import org.bukkit.craftbukkit.CraftServer
import java.lang.reflect.Field
class BukkitCommands : BukkitCommandsProxy {
private val knownCommandsField: Field by lazy {
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
.apply {
isAccessible = true
}
}
@Suppress("UNCHECKED_CAST")
private val knownCommands: MutableMap<String, Command>
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
override fun getCommandMap(): SimpleCommandMap {
return (Bukkit.getServer() as CraftServer).commandMap
}
override fun syncCommands() {
(Bukkit.getServer() as CraftServer).syncCommands()
}
override fun unregisterCommand(command: PluginCommandBase) {
knownCommands.remove(command.name)
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
}
}

View File

@@ -1,171 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.core.component.DataComponents
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.item.Item
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.entity.CraftMob
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.inventory.CraftMetaArmor
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.util.CraftMagicNumbers
import org.bukkit.craftbukkit.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy {
override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl)
plugin.onEnable {
plugin.eventManager.registerListener(PacketInjectorListener)
}
}
object CommonsProviderImpl : CommonsProvider {
private val cisHandle: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
isAccessible = true
}
private val pdcRegsitry = CraftMetaArmor::class.java
.superclass // Access CraftMetaItem
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING
override fun toPathfinderMob(mob: Mob): PathfinderMob? {
val craft = mob as? CraftMob ?: return null
return craft.handle as? PathfinderMob
}
override fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation =
CraftNamespacedKey.toMinecraft(namespacedKey)
override fun asNMSStack(itemStack: ItemStack): net.minecraft.world.item.ItemStack {
return if (itemStack !is CraftItemStack) {
CraftItemStack.asNMSCopy(itemStack)
} else {
cisHandle[itemStack] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(itemStack)
}
}
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asCraftMirror(itemStack)
}
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {
if (itemStack !is CraftItemStack) {
itemStack.itemMeta = CraftItemStack.asCraftMirror(nmsStack).itemMeta
}
}
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.allKeys
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.allKeys.toSet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.remove(DataComponents.CUSTOM_DATA)
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
override fun materialToItem(material: Material): Item =
BuiltInRegistries.ITEM.getOptional(material.key.toResourceLocation())
.orElseThrow { IllegalArgumentException("Material is not item!") }
override fun itemToMaterial(item: Item) =
Material.getMaterial(BuiltInRegistries.ITEM.getKey(item).path.uppercase())
?: throw IllegalArgumentException("Invalid material!")
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = JSONComponentSerializer.json().serialize(component)
val holderLookupProvider = (Bukkit.getServer() as CraftServer).server.registryAccess()
return net.minecraft.network.chat.Component.Serializer.fromJson(json, holderLookupProvider)!!
}
}
}

View File

@@ -1,59 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData.Builder(nmsEntity).build()
entityData.set(displayNameAccessor, Optional.of(nmsComponent), true)
entityData.set(customNameVisibleAccessor, visible, true)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData.packDirty() ?: throw IllegalStateException("No packed entity data")
)
player.sendPacket(Packet(packet))
}
}

View File

@@ -1,15 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.internal.entities.EcoDummyEntity
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import org.bukkit.Location
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.entity.Entity
import org.bukkit.entity.Zombie
class DummyEntityFactory : DummyEntityFactoryProxy {
override fun createDummyEntity(location: Location): Entity {
val world = location.world as CraftWorld
return EcoDummyEntity(world.createEntity(location, Zombie::class.java))
}
}

View File

@@ -1,12 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.v1_20_6.entity.EcoEntityController
import org.bukkit.entity.Mob
class EntityControllerFactory : EntityControllerFactoryProxy {
override fun <T : Mob> createEntityController(entity: T): EntityController<T> {
return EcoEntityController(entity)
}
}

View File

@@ -1,82 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
private val registry: CraftPersistentDataTypeRegistry
init {
/*
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
And getting it would mean more janky reflection
*/
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
val pdc = item.itemMeta!!.persistentDataContainer
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
}
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
private val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] =
registry.wrap(dataType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract<T, Tag>(dataType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -1,392 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.asNMSStack
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.common.item.ImplementedFIS
import com.willfp.eco.internal.spigot.proxy.common.makePdc
import com.willfp.eco.internal.spigot.proxy.common.mergeIfNeeded
import com.willfp.eco.internal.spigot.proxy.common.setPdc
import com.willfp.eco.internal.spigot.proxy.common.toAdventure
import com.willfp.eco.internal.spigot.proxy.common.toItem
import com.willfp.eco.internal.spigot.proxy.common.toMaterial
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import com.willfp.eco.util.StringUtils
import com.willfp.eco.util.toComponent
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.TextDecoration
import net.minecraft.core.component.DataComponentType
import net.minecraft.core.component.DataComponents
import net.minecraft.nbt.CompoundTag
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 org.bukkit.craftbukkit.CraftRegistry
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import kotlin.math.max
private val unstyledComponent = Component.empty().style {
it.color(null).decoration(TextDecoration.ITALIC, false)
}
class FastItemStackFactory : FastItemStackFactoryProxy {
override fun create(itemStack: ItemStack): FastItemStack {
return NewEcoFastItemStack(itemStack)
}
@Suppress("UsePropertyAccessSyntax")
class NewEcoFastItemStack(
private val bukkit: ItemStack
) : ImplementedFIS {
// Cast is there because, try as I might, I can't get IntellIJ to recognise half the classes in the dev bundle
@Suppress("USELESS_CAST")
private val handle = bukkit.asNMSStack() as net.minecraft.world.item.ItemStack
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 map = mutableMapOf<Enchantment, Int>()
for ((enchantment, level) in enchantments.entrySet()) {
val bukkit = CraftEnchantment.minecraftToBukkit(enchantment.value())
map[bukkit] = level
}
return map
}
override fun getEnchantmentLevel(
enchantment: Enchantment,
checkStored: Boolean
): Int {
val minecraft = CraftRegistry
.bukkitToMinecraft<Enchantment, net.minecraft.world.item.enchantment.Enchantment>(enchantment)
val enchantments = handle.get(DataComponents.ENCHANTMENTS) ?: return 0
var level = enchantments.getLevel(minecraft)
if (checkStored) {
val storedEnchantments = handle.get(DataComponents.STORED_ENCHANTMENTS) ?: return 0
level = max(level, storedEnchantments.getLevel(minecraft))
}
return level
}
override fun setLore(lore: List<String>?) = setLoreComponents(lore?.map { it.toComponent() })
override fun setLoreComponents(lore: List<Component>?) {
if (lore == null) {
handle.set<ItemLore>(DataComponents.LORE, null)
} else {
val components = lore
.map { unstyledComponent.append(it) }
.map { it.toNMS() }
handle.set(
DataComponents.LORE, ItemLore(
components,
components
)
)
}
apply()
}
override fun getLoreComponents(): List<Component> {
return handle.get(DataComponents.LORE)?.lines?.map { it.toAdventure() } ?: emptyList()
}
override fun getLore(): List<String> =
getLoreComponents().map { StringUtils.toLegacy(it) }
override fun setDisplayName(name: Component?) {
if (name == null) {
handle.set<net.minecraft.network.chat.Component>(DataComponents.CUSTOM_NAME, null)
} else {
handle.set(DataComponents.CUSTOM_NAME, name.toNMS())
}
apply()
}
override fun setDisplayName(name: String?) = setDisplayName(name?.toComponent())
override fun getDisplayNameComponent(): Component {
return handle.get(DataComponents.CUSTOM_NAME)?.toAdventure()
?: Component.translatable(bukkit.type.toItem().getDescriptionId())
}
override fun getDisplayName(): String = displayNameComponent.toLegacy()
private fun <T> net.minecraft.world.item.ItemStack.modifyComponent(
component: DataComponentType<T>,
modifier: (T) -> T
) {
val current = handle.get(component) ?: return
this.set(component, modifier(current))
}
override fun addItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
handle.modifyComponent(DataComponents.ENCHANTMENTS) { enchantments ->
enchantments.withTooltip(false)
}
}
ItemFlag.HIDE_ATTRIBUTES -> {
handle.modifyComponent(DataComponents.ATTRIBUTE_MODIFIERS) { attributes ->
attributes.withTooltip(false)
}
}
ItemFlag.HIDE_UNBREAKABLE -> {
handle.modifyComponent(DataComponents.UNBREAKABLE) { unbreakable ->
unbreakable.withTooltip(false)
}
}
ItemFlag.HIDE_DESTROYS -> {
handle.modifyComponent(DataComponents.CAN_BREAK) { destroys ->
destroys.withTooltip(false)
}
}
ItemFlag.HIDE_PLACED_ON -> {
handle.modifyComponent(DataComponents.CAN_PLACE_ON) { placedOn ->
placedOn.withTooltip(false)
}
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.set(DataComponents.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE)
}
ItemFlag.HIDE_DYE -> {
handle.modifyComponent(DataComponents.DYED_COLOR) { dyed ->
dyed.withTooltip(false)
}
}
ItemFlag.HIDE_ARMOR_TRIM -> {
handle.modifyComponent(DataComponents.TRIM) { trim ->
trim.withTooltip(false)
}
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
handle.modifyComponent(DataComponents.STORED_ENCHANTMENTS) { storedEnchants ->
storedEnchants.withTooltip(false)
}
}
}
}
apply()
}
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
handle.modifyComponent(DataComponents.ENCHANTMENTS) { enchantments ->
enchantments.withTooltip(true)
}
}
ItemFlag.HIDE_ATTRIBUTES -> {
handle.modifyComponent(DataComponents.ATTRIBUTE_MODIFIERS) { attributes ->
attributes.withTooltip(true)
}
}
ItemFlag.HIDE_UNBREAKABLE -> {
handle.modifyComponent(DataComponents.UNBREAKABLE) { unbreakable ->
unbreakable.withTooltip(true)
}
}
ItemFlag.HIDE_DESTROYS -> {
handle.modifyComponent(DataComponents.CAN_BREAK) { destroys ->
destroys.withTooltip(true)
}
}
ItemFlag.HIDE_PLACED_ON -> {
handle.modifyComponent(DataComponents.CAN_PLACE_ON) { placedOn ->
placedOn.withTooltip(true)
}
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.remove(DataComponents.HIDE_ADDITIONAL_TOOLTIP)
}
ItemFlag.HIDE_DYE -> {
handle.modifyComponent(DataComponents.DYED_COLOR) { dyed ->
dyed.withTooltip(true)
}
}
ItemFlag.HIDE_ARMOR_TRIM -> {
handle.modifyComponent(DataComponents.TRIM) { trim ->
trim.withTooltip(true)
}
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
handle.modifyComponent(DataComponents.STORED_ENCHANTMENTS) { storedEnchants ->
storedEnchants.withTooltip(true)
}
}
}
}
apply()
}
override fun getItemFlags(): Set<ItemFlag> {
val currentFlags = mutableSetOf<ItemFlag>()
for (f in ItemFlag.values()) {
if (hasItemFlag(f)) {
currentFlags.add(f)
}
}
return currentFlags
}
override fun hasItemFlag(flag: ItemFlag): Boolean {
return when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
val enchantments = handle.get(DataComponents.ENCHANTMENTS) ?: return false
!enchantments.showInTooltip
}
ItemFlag.HIDE_ATTRIBUTES -> {
val attributes = handle.get(DataComponents.ATTRIBUTE_MODIFIERS) ?: return false
!attributes.showInTooltip
}
ItemFlag.HIDE_UNBREAKABLE -> {
val unbreakable = handle.get(DataComponents.UNBREAKABLE) ?: return false
!unbreakable.showInTooltip
}
ItemFlag.HIDE_DESTROYS -> {
val destroys = handle.get(DataComponents.CAN_BREAK) ?: return false
!destroys.showInTooltip()
}
ItemFlag.HIDE_PLACED_ON -> {
val placedOn = handle.get(DataComponents.CAN_PLACE_ON) ?: return false
!placedOn.showInTooltip()
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.get(DataComponents.HIDE_ADDITIONAL_TOOLTIP) != null
}
ItemFlag.HIDE_DYE -> {
val dyed = handle.get(DataComponents.DYED_COLOR) ?: return false
!dyed.showInTooltip()
}
ItemFlag.HIDE_ARMOR_TRIM -> {
val armorTrim = handle.get(DataComponents.TRIM) ?: return false
!armorTrim.showInTooltip
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
val storedEnchants = handle.get(DataComponents.STORED_ENCHANTMENTS) ?: return false
!storedEnchants.showInTooltip
}
}
}
override fun getRepairCost(): Int {
return handle.get(DataComponents.REPAIR_COST) ?: 0
}
override fun setRepairCost(cost: Int) {
handle.set(DataComponents.REPAIR_COST, cost)
apply()
}
override fun getPersistentDataContainer(): PersistentDataContainer {
return ContinuallyAppliedPersistentDataContainer(this.pdc, this)
}
override fun getAmount(): Int = handle.getCount()
override fun setAmount(amount: Int) {
handle.setCount(amount)
apply()
}
override fun setType(material: org.bukkit.Material) {
@Suppress("DEPRECATION")
handle.setItem(material.toItem())
apply()
}
override fun getType(): org.bukkit.Material = handle.getItem().toMaterial()
override fun getCustomModelData(): Int? =
handle.get(DataComponents.CUSTOM_MODEL_DATA)?.value
override fun setCustomModelData(data: Int?) {
if (data == null) {
handle.remove(DataComponents.CUSTOM_MODEL_DATA)
} else {
handle.set(DataComponents.CUSTOM_MODEL_DATA, CustomModelData(data))
}
apply()
}
override fun equals(other: Any?): Boolean {
if (other !is NewEcoFastItemStack) {
return false
}
return other.hashCode() == this.hashCode()
}
override fun hashCode(): Int {
return net.minecraft.world.item.ItemStack.hashItemAndComponents(handle)
}
override fun apply() {
val customData = handle.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY)
val updated = customData.update {
it.setPdc(pdc)
}
if (updated.isEmpty) {
handle.remove(DataComponents.CUSTOM_DATA)
} else {
handle.set(DataComponents.CUSTOM_DATA, updated)
}
bukkit.mergeIfNeeded(handle)
}
override fun unwrap(): ItemStack {
return bukkit
}
}
}

View File

@@ -1,33 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.minimessage.MiniMessage
class MiniMessageTranslator : MiniMessageTranslatorProxy {
override fun format(message: String): String {
var mut = message
val startsWithPrefix = mut.startsWith(Display.PREFIX)
if (startsWithPrefix) {
mut = mut.substring(2)
}
mut = mut.replace('§', '&')
val miniMessage = runCatching {
MiniMessage.miniMessage().deserialize(
mut
).toLegacy()
}.getOrNull() ?: mut
mut = if (startsWithPrefix) {
Display.PREFIX + miniMessage
} else {
miniMessage
}
return mut
}
}

View File

@@ -1,46 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import com.willfp.eco.internal.spigot.proxy.v1_20_6.packet.NewItemsPacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.v1_20_6.packet.NewItemsPacketSetCreativeSlot
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler : PacketHandlerProxy {
override fun sendPacket(player: Player, packet: com.willfp.eco.core.packet.Packet) {
if (player !is CraftPlayer) {
return
}
val handle = packet.handle
if (handle !is Packet<*>) {
return
}
player.handle.connection.send(handle)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
NewItemsPacketOpenWindowMerchant,
NewItemsPacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin)
)
}
}

View File

@@ -1,80 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.mojang.serialization.Dynamic
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import net.minecraft.server.MinecraftServer
import net.minecraft.util.datafix.fixes.References
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
private val registryAccess = (Bukkit.getServer() as CraftServer).server.registryAccess()
class SNBTConverter : SNBTConverterProxy {
private fun parseItemSNBT(snbt: String): CompoundTag? {
val nbt = runCatching { TagParser.parseTag(snbt) }.getOrNull() ?: return null
val dataVersion = if (nbt.contains("DataVersion")) {
nbt.getInt("DataVersion")
} else null
// If the data version is the same as the server's data version, we don't need to fix it
if (dataVersion == CraftMagicNumbers.INSTANCE.dataVersion) {
return nbt
}
return MinecraftServer.getServer().fixerUpper.update(
References.ITEM_STACK,
Dynamic(NbtOps.INSTANCE, nbt),
dataVersion ?: 3700, // 3700 is the 1.20.4 data version
CraftMagicNumbers.INSTANCE.dataVersion
).value as CompoundTag
}
override fun fromSNBT(snbt: String): ItemStack? {
val tag = parseItemSNBT(snbt) ?: return null
val nms = net.minecraft.world.item.ItemStack.parse(registryAccess, tag).orElse(null) ?: return null
return CraftItemStack.asBukkitCopy(nms)
}
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(registryAccess) as CompoundTag
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
}
override fun makeSNBTTestable(snbt: String): TestableItem {
val tag = parseItemSNBT(snbt) ?: return EmptyTestableItem()
val nms = net.minecraft.world.item.ItemStack.parse(registryAccess, tag).orElse(null)
?: return EmptyTestableItem()
tag.remove("Count")
return SNBTTestableItem(CraftItemStack.asBukkitCopy(nms), tag)
}
class SNBTTestableItem(
private val item: ItemStack,
private val tag: CompoundTag
) : TestableItem {
override fun matches(itemStack: ItemStack?): Boolean {
if (itemStack == null) {
return false
}
val nms = CraftItemStack.asNMSCopy(itemStack)
val nmsTag = nms.save(registryAccess) as CompoundTag
nmsTag.remove("Count")
return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type
}
override fun getItem(): ItemStack = item
}
}

View File

@@ -1,18 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.texture
import org.bukkit.inventory.meta.SkullMeta
class Skull : SkullProxy {
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? = meta.texture
}

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6
import com.willfp.eco.internal.spigot.proxy.TPSProxy
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
class TPS : TPSProxy {
override fun getTPS(): Double {
return (Bukkit.getServer() as CraftServer).handle.server.tps1.average
}
}

View File

@@ -1,95 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6.entity
import com.willfp.eco.core.entities.ai.CustomGoal
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.core.entities.ai.EntityGoal
import com.willfp.eco.core.entities.ai.TargetGoal
import com.willfp.eco.internal.spigot.proxy.common.ai.CustomGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.ai.getGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.toPathfinderMob
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.goal.Goal
import org.bukkit.entity.Mob
class EcoEntityController<T : Mob>(
private val handle: T
) : EntityController<T> {
override fun addEntityGoal(priority: Int, goal: EntityGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
nms.goalSelector.addGoal(
priority,
goal.getGoalFactory()?.create(goal, nms) ?: return this
)
return this
}
override fun removeEntityGoal(goal: EntityGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
val predicate: (Goal) -> Boolean = if (goal is CustomGoal<*>) {
{ CustomGoalFactory.isGoalOfType(it, goal) }
} else {
{ goal.getGoalFactory()?.isGoalOfType(it) == true }
}
for (wrapped in nms.goalSelector.availableGoals.toSet()) {
if (predicate(wrapped.goal)) {
nms.goalSelector.removeGoal(wrapped.goal)
}
}
return this
}
override fun clearEntityGoals(): EntityController<T> {
val nms = getNms() ?: return this
nms.goalSelector.availableGoals.clear()
return this
}
override fun addTargetGoal(priority: Int, goal: TargetGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
nms.targetSelector.addGoal(
priority, goal.getGoalFactory()?.create(goal, nms) ?: return this
)
nms.targetSelector
return this
}
override fun removeTargetGoal(goal: TargetGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
val predicate: (Goal) -> Boolean = if (goal is CustomGoal<*>) {
{ CustomGoalFactory.isGoalOfType(it, goal) }
} else {
{ goal.getGoalFactory()?.isGoalOfType(it) == true }
}
for (wrapped in nms.targetSelector.availableGoals.toSet()) {
if (predicate(wrapped.goal)) {
nms.targetSelector.removeGoal(wrapped.goal)
}
}
return this
}
override fun clearTargetGoals(): EntityController<T> {
val nms = getNms() ?: return this
nms.targetSelector.availableGoals.clear()
return this
}
private fun getNms(): PathfinderMob? {
return handle.toPathfinderMob()
}
override fun getEntity(): T {
return handle
}
}

View File

@@ -1,35 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6.packet
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket
import net.minecraft.world.item.trading.MerchantOffers
object NewItemsPacketOpenWindowMerchant : PacketListener {
private val field = ClientboundMerchantOffersPacket::class.java
.declaredFields
.first { it.type == MerchantOffers::class.java }
.apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundMerchantOffersPacket ?: return
val offers = MerchantOffers()
for (offer in packet.offers) {
val new = offer.copy()
Display.display(new.baseCostA.itemStack.asBukkitStack(), event.player)
if (new.costB.isPresent) {
Display.display(new.costB.get().itemStack.asBukkitStack(), event.player)
}
Display.display(new.result.asBukkitStack(), event.player)
offers += new
}
field.set(packet, offers)
}
}

View File

@@ -1,19 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_6.packet
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
object NewItemsPacketSetCreativeSlot : PacketListener {
override fun onReceive(event: PacketEvent) {
val packet = event.packet.handle as? ServerboundSetCreativeModeSlotPacket ?: return
Display.revert(packet.itemStack.asBukkitStack())
event.player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = JSONComponentSerializer.json().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_20_R1
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
@@ -41,7 +40,8 @@ class DisplayName : DisplayNameProxy {
return
}
val nmsComponent = displayName.toNMS()
val nmsComponent = PaperAdventure.asVanilla(displayName)
?: throw IllegalStateException("Display name component is null!")
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible

View File

@@ -28,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -5,8 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
@@ -157,10 +155,5 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = JSONComponentSerializer.json().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_20_R2
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
@@ -38,7 +37,8 @@ class DisplayName : DisplayNameProxy {
return
}
val nmsComponent = displayName.toNMS()
val nmsComponent = PaperAdventure.asVanilla(displayName)
?: throw IllegalStateException("Display name component is null!")
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible

View File

@@ -28,7 +28,7 @@ class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFa
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
}
}

View File

@@ -7,7 +7,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_20_R2.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
class SNBTConverter : SNBTConverterProxy {
@@ -19,9 +18,7 @@ class SNBTConverter : SNBTConverterProxy {
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(CompoundTag())
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
return SnbtPrinterTagVisitor().visit(nms.save(CompoundTag()))
}
override fun makeSNBTTestable(snbt: String): TestableItem {

View File

@@ -1,39 +0,0 @@
plugins {
id("io.papermc.paperweight.userdev")
}
group = "com.willfp"
version = rootProject.version
dependencies {
implementation(project(":eco-core:core-nms:nms-common"))
paperweight.paperDevBundle("1.20.4-R0.1-SNAPSHOT")
implementation("net.kyori:adventure-text-minimessage:4.11.0") {
version {
strictly("4.11.0")
}
exclude(group = "net.kyori", module = "adventure-api")
}
}
tasks {
build {
dependsOn(reobfJar)
}
reobfJar {
mustRunAfter(shadowJar)
}
shadowJar {
relocate(
"com.willfp.eco.internal.spigot.proxy.common",
"com.willfp.eco.internal.spigot.proxy.v1_20_R3.common"
)
relocate(
"net.kyori.adventure.text.minimessage",
"com.willfp.eco.internal.spigot.proxy.v1_20_R3.minimessage"
)
}
}

View File

@@ -1,35 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.command.PluginCommandBase
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.SimpleCommandMap
import org.bukkit.craftbukkit.v1_20_R3.CraftServer
import java.lang.reflect.Field
class BukkitCommands : BukkitCommandsProxy {
private val knownCommandsField: Field by lazy {
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
.apply {
isAccessible = true
}
}
@Suppress("UNCHECKED_CAST")
private val knownCommands: MutableMap<String, Command>
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
override fun getCommandMap(): SimpleCommandMap {
return (Bukkit.getServer() as CraftServer).commandMap
}
override fun syncCommands() {
(Bukkit.getServer() as CraftServer).syncCommands()
}
override fun unregisterCommand(command: PluginCommandBase) {
knownCommands.remove(command.name)
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
}
}

View File

@@ -1,166 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.item.Item
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.craftbukkit.v1_20_R3.CraftServer
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftMob
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.v1_20_R3.util.CraftMagicNumbers
import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy {
override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl)
plugin.onEnable {
plugin.eventManager.registerListener(PacketInjectorListener)
}
}
object CommonsProviderImpl : CommonsProvider {
private val cisHandle: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
isAccessible = true
}
private val pdcRegsitry = Class.forName("org.bukkit.craftbukkit.v1_20_R3.inventory.CraftMetaItem")
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING
override fun toPathfinderMob(mob: Mob): PathfinderMob? {
val craft = mob as? CraftMob ?: return null
return craft.handle as? PathfinderMob
}
override fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation =
CraftNamespacedKey.toMinecraft(namespacedKey)
override fun asNMSStack(itemStack: ItemStack): net.minecraft.world.item.ItemStack {
return if (itemStack !is CraftItemStack) {
CraftItemStack.asNMSCopy(itemStack)
} else {
cisHandle[itemStack] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(itemStack)
}
}
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asCraftMirror(itemStack)
}
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {
if (itemStack !is CraftItemStack) {
itemStack.itemMeta = CraftItemStack.asCraftMirror(nmsStack).itemMeta
}
}
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.allKeys
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.allKeys.toSet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.tag = null
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
override fun materialToItem(material: Material): Item =
BuiltInRegistries.ITEM.getOptional(material.key.toResourceLocation())
.orElseThrow { IllegalArgumentException("Material is not item!") }
override fun itemToMaterial(item: Item) =
Material.getMaterial(BuiltInRegistries.ITEM.getKey(item).path.uppercase())
?: throw IllegalArgumentException("Invalid material!")
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = JSONComponentSerializer.json().serialize(component)
return net.minecraft.network.chat.Component.Serializer.fromJson(json)!!
}
}
}

View File

@@ -1,68 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftLivingEntity
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftMob
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
override fun setClientsideDisplayName(entity: LivingEntity, player: Player, displayName: Component, visible: Boolean) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
nmsEntity.isCustomNameVisible
val entityData = SynchedEntityData(nmsEntity)
entityData.forceSet(displayNameAccessor, Optional.of(nmsComponent))
entityData.forceSet(customNameVisibleAccessor, visible)
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
entityData.packDirty() ?: throw IllegalStateException("No packed entity data")
)
player.sendPacket(Packet(packet))
}
private fun <T: Any> SynchedEntityData.forceSet(
accessor: EntityDataAccessor<T>,
value: T
) {
if (!this.hasItem(accessor)) {
this.define(accessor, value)
}
this[accessor] = value
this.markDirty(accessor)
}
}

View File

@@ -1,16 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.internal.entities.EcoDummyEntity
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import org.bukkit.Location
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld
import org.bukkit.entity.Entity
import org.bukkit.entity.EntityType
import org.bukkit.entity.Zombie
class DummyEntityFactory : DummyEntityFactoryProxy {
override fun createDummyEntity(location: Location): Entity {
val world = location.world as CraftWorld
return EcoDummyEntity(world.createEntity(location, Zombie::class.java))
}
}

View File

@@ -1,12 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.v1_20_R3.entity.EcoEntityController
import org.bukkit.entity.Mob
class EntityControllerFactory : EntityControllerFactoryProxy {
override fun <T : Mob> createEntityController(entity: T): EntityController<T> {
return EcoEntityController(entity)
}
}

View File

@@ -1,83 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
private val registry: CraftPersistentDataTypeRegistry
init {
/*
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
And getting it would mean more janky reflection
*/
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
val pdc = item.itemMeta!!.persistentDataContainer
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
}
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
private val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] =
registry.wrap(dataType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract<T, Tag>(dataType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -1,12 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.EcoFastItemStack
import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy {
override fun create(itemStack: ItemStack): FastItemStack {
return EcoFastItemStack(itemStack)
}
}

View File

@@ -1,33 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.minimessage.MiniMessage
class MiniMessageTranslator : MiniMessageTranslatorProxy {
override fun format(message: String): String {
var mut = message
val startsWithPrefix = mut.startsWith(Display.PREFIX)
if (startsWithPrefix) {
mut = mut.substring(2)
}
mut = mut.replace('§', '&')
val miniMessage = runCatching {
MiniMessage.miniMessage().deserialize(
mut
).toLegacy()
}.getOrNull() ?: mut
mut = if (startsWithPrefix) {
Display.PREFIX + miniMessage
} else {
miniMessage
}
return mut
}
}

View File

@@ -1,46 +0,0 @@
package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler : PacketHandlerProxy {
override fun sendPacket(player: Player, packet: com.willfp.eco.core.packet.Packet) {
if (player !is CraftPlayer) {
return
}
val handle = packet.handle
if (handle !is Packet<*>) {
return
}
player.handle.connection.send(handle)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
return listOf(
PacketAutoRecipe(plugin),
PacketHeldItemSlot,
PacketOpenWindowMerchant,
PacketSetCreativeSlot,
PacketSetSlot,
PacketWindowItems(plugin)
)
}
}

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