Skip to content

Commit

Permalink
Added 1.21.3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
WillFP committed Nov 4, 2024
1 parent 81de46a commit b47b383
Show file tree
Hide file tree
Showing 23 changed files with 837 additions and 15 deletions.
8 changes: 6 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {

plugins {
id("java-library")
id("io.github.goooler.shadow") version "8.1.7"
id("com.gradleup.shadow") version "8.3.5"
id("maven-publish")
id("java")
kotlin("jvm") version "1.9.21"
Expand All @@ -32,13 +32,14 @@ dependencies {
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_21", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21_3", configuration = "reobf"))
}

allprojects {
apply(plugin = "java")
apply(plugin = "java-library")
apply(plugin = "maven-publish")
apply(plugin = "io.github.goooler.shadow")
apply(plugin = "com.gradleup.shadow")
apply(plugin = "kotlin")

repositories {
Expand All @@ -48,6 +49,9 @@ allprojects {
content { includeGroupByRegex("com\\.github\\..*") }
}

// Paper
maven("https://repo.papermc.io/repository/maven-public/")

// SuperiorSkyblock2
maven("https://repo.bg-software.com/repository/api/")

Expand Down
24 changes: 16 additions & 8 deletions eco-api/src/main/java/com/willfp/eco/core/Prerequisite.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,23 @@ public class Prerequisite {
);

/**
* Requires the server to be running 1.21.
* Requires the server to be running at least 1.21.3.
*/
public static final Prerequisite HAS_1_21_3 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("1_21_3"),
"Requires server to be running 1.21.3+"
);

/**
* Requires the server to be running at least 1.21.
*/
public static final Prerequisite HAS_1_21 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("1_21"),
() -> ProxyConstants.NMS_VERSION.contains("1_21") || HAS_1_21_3.isMet(),
"Requires server to be running 1.21+"
);

/**
* Requires the server to be running 1.20.5.
* Requires the server to be running at least 1.20.5.
*/
public static final Prerequisite HAS_1_20_5 = new Prerequisite(
() -> (ProxyConstants.NMS_VERSION.contains("1_20_") && !ProxyConstants.NMS_VERSION.contains("R"))
Expand All @@ -55,39 +63,39 @@ public class Prerequisite {
);

/**
* Requires the server to be running 1.20.3.
* Requires the server to be running at least 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.
* Requires the server to be running at least 1.20.
*/
public static final Prerequisite HAS_1_20 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("20") || HAS_1_20_3.isMet(),
"Requires server to be running 1.20+"
);

/**
* Requires the server to be running 1.19.4.
* Requires the server to be running at least 1.19.4.
*/
public static final Prerequisite HAS_1_19_4 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19_R3") || HAS_1_20.isMet(),
"Requires server to be running 1.19.4+"
);

/**
* Requires the server to be running 1.19.
* Requires the server to be running at least 1.19.
*/
public static final Prerequisite HAS_1_19 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19") || HAS_1_20.isMet(),
"Requires server to be running 1.19+"
);

/**
* Requires the server to be running 1.18.
* Requires the server to be running at least 1.18.
*/
public static final Prerequisite HAS_1_18 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("18") || HAS_1_19.isMet(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public final class ProxyConstants {
"v1_20_R1",
"v1_20_R2",
"v1_20_R3",
"v1_21"
"v1_21",
"v1_21_3"
);

private ProxyConstants() {
Expand All @@ -39,6 +40,7 @@ private ProxyConstants() {
private static String convertVersion(@NotNull final String version) {
return switch (version) {
case "v1_21_1" -> "v1_21";
case "v1_21_2" -> "v1_21_3";
default -> version;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ class EcoProxyFactory(
)
} else {
ProxyError(
"Could not initialize proxy. If you're seeing this error message"
+ ", something has gone badly wrong. This almost definitely isn't user error, blame the developer.",
"Could not initialize proxy. Are you running a supported server version?",
e
)
}
Expand Down
50 changes: 50 additions & 0 deletions eco-core/core-nms/v1_21_3/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
plugins {
id("io.papermc.paperweight.userdev")
}

group = "com.willfp"
version = rootProject.version

dependencies {
implementation(project(":eco-core:core-nms:modern"))
implementation(project(":eco-core:core-nms:common"))
paperweight.paperDevBundle("1.21.3-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_21_3.common"
)
relocate(
"net.kyori.adventure.text.minimessage",
"com.willfp.eco.internal.spigot.proxy.v1_21_3.minimessage"
)
}

compileJava {
options.release = 21
}

compileKotlin {
kotlinOptions {
jvmTarget = "21"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_3

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}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_3

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)!!
}
}
}
Loading

0 comments on commit b47b383

Please sign in to comment.