diff --git a/pom.xml b/pom.xml index 6d5beba..33842cb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 pom @@ -17,6 +17,7 @@ UTF-8 + 2.0.3 @@ -92,5 +93,12 @@ vcompat-1_18_R1 vcompat-1_18_R2 vcompat-1_19_R1 + vcompat-1_19_R2 + vcompat-1_19_R3 + vcompat-1_20_R1 + vcompat-1_20_R2 + vcompat-1_20_R3 + vcompat-1_20_R4 + vcompat-1_21_R1 diff --git a/pom.xml.versionsBackup b/pom.xml.versionsBackup new file mode 100644 index 0000000..b0ab98a --- /dev/null +++ b/pom.xml.versionsBackup @@ -0,0 +1,103 @@ + + 4.0.0 + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + pom + + + + github + GitHub OWNER Apache Maven Packages + https://maven.pkg.github.com/SourceWriters/vCompat + + + + + UTF-8 + + + + + spigot + https://hub.spigotmc.org/nexus/content/repositories/public/ + + + minecraft-libraries + https://libraries.minecraft.net + + + + + + + + + com.mojang + authlib + 1.5.25 + provided + + + snakeyaml + org.yaml + + + gson + com.google.code.gson + + + + + org.spigotmc + spigot-api + 1.18.1-R0.1-SNAPSHOT + provided + + + + + + + true + src/main/resources + + + + + maven-compiler-plugin + 3.8.1 + + 11 + 11 + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.0.0-M2 + + true + + + + + + vcompat-api + vcompat-core + vcompat-legacy + vcompat-1_17_R1 + vcompat-1_18_R1 + vcompat-1_18_R2 + vcompat-1_19_R1 + vcompat-1_19_R2 + vcompat-1_19_R3 + vcompat-1_20_R1 + vcompat-1_20_R2 + vcompat-1_20_R3 + vcompat-1_20_R4 + vcompat-1_21_R1 + + diff --git a/scripts/data/mappings.txt b/scripts/data/mappings.txt index 25fd59b..b86addb 100644 --- a/scripts/data/mappings.txt +++ b/scripts/data/mappings.txt @@ -2,3 +2,5 @@ 1.18.1 1.18.2 1.19 +1.20 +1.21 \ No newline at end of file diff --git a/scripts/data/servers.txt b/scripts/data/servers.txt index 6ffe72c..039c666 100644 --- a/scripts/data/servers.txt +++ b/scripts/data/servers.txt @@ -17,3 +17,10 @@ 1.18.1 1.18.2 1.19 +1.19.3 +1.19.4 +1.20.1 +1.20.2 +1.20.4 +1.20.6 +1.21 \ No newline at end of file diff --git a/vcompat-1_17_R1/pom.xml b/vcompat-1_17_R1/pom.xml index d003b12..e769fc4 100644 --- a/vcompat-1_17_R1/pom.xml +++ b/vcompat-1_17_R1/pom.xml @@ -3,7 +3,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat-1_17_R1 @@ -37,7 +37,10 @@ net.md-5 specialsource-maven-plugin - 1.2.2 + ${specialsource.version} + + false + package diff --git a/vcompat-1_17_R1/pom.xml.versionsBackup b/vcompat-1_17_R1/pom.xml.versionsBackup new file mode 100644 index 0000000..d003b12 --- /dev/null +++ b/vcompat-1_17_R1/pom.xml.versionsBackup @@ -0,0 +1,73 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_17_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.17.1 + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + + \ No newline at end of file diff --git a/vcompat-1_18_R1/pom.xml b/vcompat-1_18_R1/pom.xml index b3319ac..1e4419d 100644 --- a/vcompat-1_18_R1/pom.xml +++ b/vcompat-1_18_R1/pom.xml @@ -3,7 +3,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat-1_18_R1 @@ -63,7 +63,10 @@ net.md-5 specialsource-maven-plugin - 1.2.2 + ${specialsource.version} + + false + package diff --git a/vcompat-1_18_R1/pom.xml.versionsBackup b/vcompat-1_18_R1/pom.xml.versionsBackup new file mode 100644 index 0000000..b3319ac --- /dev/null +++ b/vcompat-1_18_R1/pom.xml.versionsBackup @@ -0,0 +1,98 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_18_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.18.1 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_18_R2/pom.xml b/vcompat-1_18_R2/pom.xml index 34d6aab..987009e 100644 --- a/vcompat-1_18_R2/pom.xml +++ b/vcompat-1_18_R2/pom.xml @@ -3,7 +3,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat-1_18_R2 @@ -69,7 +69,10 @@ net.md-5 specialsource-maven-plugin - 1.2.2 + ${specialsource.version} + + false + package diff --git a/vcompat-1_18_R2/pom.xml.versionsBackup b/vcompat-1_18_R2/pom.xml.versionsBackup new file mode 100644 index 0000000..34d6aab --- /dev/null +++ b/vcompat-1_18_R2/pom.xml.versionsBackup @@ -0,0 +1,104 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_18_R2 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.18.2 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_18_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_18_R2/TextureProvider1_18_R2.java b/vcompat-1_18_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_18_R2/TextureProvider1_18_R2.java index 615c2fc..d6afc19 100644 --- a/vcompat-1_18_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_18_R2/TextureProvider1_18_R2.java +++ b/vcompat-1_18_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_18_R2/TextureProvider1_18_R2.java @@ -51,6 +51,7 @@ public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { if (!(itemStack.getItemMeta() instanceof SkullMeta)) { return null; } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); if (profile == null) { diff --git a/vcompat-1_19_R1/pom.xml b/vcompat-1_19_R1/pom.xml index 625acf7..06e8669 100644 --- a/vcompat-1_19_R1/pom.xml +++ b/vcompat-1_19_R1/pom.xml @@ -5,7 +5,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat-1_19_R1 @@ -71,7 +71,10 @@ net.md-5 specialsource-maven-plugin - 1.2.2 + ${specialsource.version} + + false + package diff --git a/vcompat-1_19_R1/pom.xml.versionsBackup b/vcompat-1_19_R1/pom.xml.versionsBackup new file mode 100644 index 0000000..625acf7 --- /dev/null +++ b/vcompat-1_19_R1/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_19_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.19 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_19_R2/.gitignore b/vcompat-1_19_R2/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_19_R2/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_19_R2/pom.xml b/vcompat-1_19_R2/pom.xml new file mode 100644 index 0000000..a169a1a --- /dev/null +++ b/vcompat-1_19_R2/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_19_R2 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.19.3 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_19_R2/pom.xml.versionsBackup b/vcompat-1_19_R2/pom.xml.versionsBackup new file mode 100644 index 0000000..0d723e2 --- /dev/null +++ b/vcompat-1_19_R2/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_19_R2 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.19.3 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/BukkitConversion1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/BukkitConversion1_19_R2.java new file mode 100644 index 0000000..d082a7e --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/BukkitConversion1_19_R2.java @@ -0,0 +1,209 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2; + +import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.BukkitContext1_19_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.BukkitType1_19_R2; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_19_R2 extends BukkitConversion { + + protected BukkitConversion1_19_R2(VersionControl1_19_R2 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.of(toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_19_R2(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_19_R2<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/EntityProvider1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/EntityProvider1_19_R2.java new file mode 100644 index 0000000..d682b17 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/EntityProvider1_19_R2.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.utils.EntityConstructors1_19_R2; + +public class EntityProvider1_19_R2 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_19_R2(VersionControl1_19_R2 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_19_R2.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/PlayerProvider1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/PlayerProvider1_19_R2.java new file mode 100644 index 0000000..db6cc1c --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/PlayerProvider1_19_R2.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.entity.Player1_19_R2; + +public class PlayerProvider1_19_R2 extends PlayerProvider { + + protected PlayerProvider1_19_R2(VersionControl1_19_R2 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_19_R2(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/TextureProvider1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/TextureProvider1_19_R2.java new file mode 100644 index 0000000..f5eba53 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/TextureProvider1_19_R2.java @@ -0,0 +1,111 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_19_R2.block.CraftSkull; +import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_19_R2 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_19_R2(VersionControl1_19_R2 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull") + .searchField("serialized", "serializedProfile").searchField("profile", "profile"); + + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner; + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + CompoundTag compound = (CompoundTag) craftMetaSkullRef.getFieldValue(meta, "serialized"); + if (compound == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + CompoundTag stackTag = stack.getOrCreateTag(); + if (stackTag.contains("SkullOwner", 10)) { + compound = stackTag.getCompound("SkullOwner"); + } else if (stackTag.contains("SkullProfile", 10)) { + compound = stackTag.getCompound("SkullProfile"); + } + } + if (compound == null) { + return null; + } + profile = NbtUtils.readGameProfile(compound); + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(profile); + return true; + } + +} diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/ToolProvider1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/ToolProvider1_19_R2.java new file mode 100644 index 0000000..a1521d4 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/ToolProvider1_19_R2.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.tools.BlockTools1_19_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.tools.ServerTools1_19_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.tools.SkinTools1_19_R2; + +public class ToolProvider1_19_R2 extends ToolProvider { + + private final BlockTools1_19_R2 blockTools = new BlockTools1_19_R2(); + private final SkinTools1_19_R2 skinTools = new SkinTools1_19_R2(); + private final ServerTools1_19_R2 serverTools = new ServerTools1_19_R2(); + + protected ToolProvider1_19_R2(VersionControl1_19_R2 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_19_R2 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_19_R2 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_19_R2 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/VersionControl1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/VersionControl1_19_R2.java new file mode 100644 index 0000000..bd3aa5e --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/VersionControl1_19_R2.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.hook.BukkitContainerAdapterHook1_19_R2; + +public class VersionControl1_19_R2 extends VersionControl { + + public static VersionControl1_19_R2 INSTANCE; + + public static VersionControl1_19_R2 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_19_R2()); + } + + private final ToolProvider1_19_R2 toolProvider = new ToolProvider1_19_R2(this); + private final TextureProvider1_19_R2 textureProvider = new TextureProvider1_19_R2(this); + private final EntityProvider1_19_R2 entityProvider = new EntityProvider1_19_R2(this); + private final PlayerProvider1_19_R2 playerProvider = new PlayerProvider1_19_R2(this); + private final BukkitConversion1_19_R2 bukkitConversion = new BukkitConversion1_19_R2(this); + + private VersionControl1_19_R2() { + BukkitContainerAdapterHook1_19_R2.hookEntity(); + } + + @Override + public ToolProvider1_19_R2 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_19_R2 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_19_R2 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_19_R2 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_19_R2 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_19_R2.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitContainer1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitContainer1_19_R2.java new file mode 100644 index 0000000..eee620a --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitContainer1_19_R2.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_19_R2 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_19_R2(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_19_R2(key), WrappedType1_19_R2.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_19_R2(key), WrappedType1_19_R2.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_19_R2(key), value, WrappedType1_19_R2.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_19_R2(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_19_R2::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_19_R2 getWrapContext() { + return new BukkitContext1_19_R2(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitContext1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitContext1_19_R2.java new file mode 100644 index 0000000..019380c --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitContext1_19_R2.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_19_R2 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_19_R2(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_19_R2 newWrapContainer() { + return new BukkitContainer1_19_R2(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitKey1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitKey1_19_R2.java new file mode 100644 index 0000000..3e343a1 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitKey1_19_R2.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_19_R2 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_19_R2(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_19_R2(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_19_R2(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_19_R2(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitType1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitType1_19_R2.java new file mode 100644 index 0000000..0f28d7c --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/BukkitType1_19_R2.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_19_R2 extends WrappedType1_19_R2, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_19_R2(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_19_R2(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_19_R2(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SimpleBukkitType1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SimpleBukkitType1_19_R2.java new file mode 100644 index 0000000..a6ff7fd --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SimpleBukkitType1_19_R2.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_19_R2 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_19_R2(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_19_R2(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_19_R2(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxContainer1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxContainer1_19_R2.java new file mode 100644 index 0000000..946ab82 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxContainer1_19_R2.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_19_R2 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_19_R2(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_19_R2(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_19_R2.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_19_R2.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_19_R2.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_19_R2.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_19_R2::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_19_R2 getWrapContext() { + return new SyntaxContext1_19_R2(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_19_R2.asBukkit(key), new SimpleBukkitType1_19_R2<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_19_R2.asBukkit(key), new SimpleBukkitType1_19_R2<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_19_R2.asBukkit(key), new SimpleBukkitType1_19_R2<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_19_R2.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxContext1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxContext1_19_R2.java new file mode 100644 index 0000000..86e4728 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxContext1_19_R2.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_19_R2 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_19_R2(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_19_R2 newWrapContainer() { + return new SyntaxContainer1_19_R2(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxType1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxType1_19_R2.java new file mode 100644 index 0000000..2af0ae9 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/SyntaxType1_19_R2.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_19_R2 extends WrappedType1_19_R2, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_19_R2(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_19_R2(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_19_R2(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/WrappedType1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/WrappedType1_19_R2.java new file mode 100644 index 0000000..c9ae459 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/WrappedType1_19_R2.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_19_R2 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_19_R2(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_19_R2.internalState(primitive); + this.complexWrap = WrappedType1_19_R2.internalState(complex); + this.primitiveType = (Class) WrappedType1_19_R2.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_19_R2.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_19_R2((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_19_R2::new) + .toArray(SyntaxContainer1_19_R2[]::new); + case 3: + return (P0) new BukkitContainer1_19_R2((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_19_R2::new) + .toArray(BukkitContainer1_19_R2[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_19_R2((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_19_R2::new).toArray(SyntaxContainer1_19_R2[]::new); + case 3: + return (C0) new BukkitContainer1_19_R2((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_19_R2::new).toArray(BukkitContainer1_19_R2[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_19_R2((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_19_R2::new) + .toArray(BukkitContainer1_19_R2[]::new); + case 3: + return (P1) new SyntaxContainer1_19_R2((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_19_R2::new) + .toArray(SyntaxContainer1_19_R2[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_19_R2((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_19_R2::new).toArray(BukkitContainer1_19_R2[]::new); + case 3: + return (C1) new SyntaxContainer1_19_R2((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_19_R2::new).toArray(SyntaxContainer1_19_R2[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_19_R2.class; + case 2: + return SyntaxContainer1_19_R2[].class; + case 3: + return BukkitContainer1_19_R2.class; + case 4: + return BukkitContainer1_19_R2[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_19_R2 wrap(IDataType type) { + return new BukkitType1_19_R2<>(type); + } + + public static SyntaxType1_19_R2 wrap(PersistentDataType type) { + return new SyntaxType1_19_R2<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/hook/BukkitContainerAdapterHook1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/hook/BukkitContainerAdapterHook1_19_R2.java new file mode 100644 index 0000000..f1fa9d9 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/data/hook/BukkitContainerAdapterHook1_19_R2.java @@ -0,0 +1,137 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_19_R2.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_19_R2.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.BukkitContainer1_19_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.SyntaxContainer1_19_R2; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_19_R2 { + + private static final BukkitContainerAdapterHook1_19_R2 HOOK = new BukkitContainerAdapterHook1_19_R2(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_19_R2() { + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_19_R2.class); + adapters.remove(SyntaxContainer1_19_R2.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_19_R2.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_19_R2.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_19_R2.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_19_R2.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_19_R2 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_19_R2(container); + } + + private SyntaxContainer1_19_R2 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_19_R2(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/ArmorStand1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/ArmorStand1_19_R2.java new file mode 100644 index 0000000..863ab6b --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/ArmorStand1_19_R2.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_19_R2 extends EntityLiving1_19_R2 implements NmsArmorStand { + + public ArmorStand1_19_R2(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/Entity1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/Entity1_19_R2.java new file mode 100644 index 0000000..15e5f57 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/Entity1_19_R2.java @@ -0,0 +1,215 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R2.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_19_R2 implements NmsEntity { + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_19_R2(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + handle.level = ((CraftWorld) location.getWorld()).getHandle(); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/EntityLiving1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/EntityLiving1_19_R2.java new file mode 100644 index 0000000..78fc316 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/EntityLiving1_19_R2.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_19_R2 extends Entity1_19_R2 implements NmsEntityLiving { + + public EntityLiving1_19_R2(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/Player1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/Player1_19_R2.java new file mode 100644 index 0000000..0d67f00 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/entity/Player1_19_R2.java @@ -0,0 +1,300 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R2.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundAddPlayerPacket; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.biome.BiomeManager; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.data.SyntaxContainer1_19_R2; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_19_R2 extends EntityLiving1_19_R2 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_19_R2(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_19_R2(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.latency; + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + ClientboundAddPlayerPacket spawnPacket = new ClientboundAddPlayerPacket(handle); + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(spawnPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level; + + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(world.dimensionTypeId(), world.dimension(), + BiomeManager.obfuscateSeed(world.getSeed()), handle.gameMode.getGameModeForPlayer(), + handle.gameMode.getPreviousGameModeForPlayer(), world.isDebug(), world.isFlat(), ClientboundRespawnPacket.KEEP_ALL_DATA, + handle.getLastDeathLocation()); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0, false); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/BlockTools1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/BlockTools1_19_R2.java new file mode 100644 index 0000000..8a1b68a --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/BlockTools1_19_R2.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_19_R2.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_19_R2 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_19_R2() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.getProperties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.getProperties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/ServerTools1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/ServerTools1_19_R2.java new file mode 100644 index 0000000..083b71d --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/ServerTools1_19_R2.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_19_R2.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.wrapper.ConsoleReaderWrapper1_19_R2; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_19_R2 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_19_R2 getConsole() { + return ConsoleReaderWrapper1_19_R2.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/SkinTools1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/SkinTools1_19_R2.java new file mode 100644 index 0000000..7c4c45d --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/tools/SkinTools1_19_R2.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.tools; + +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_19_R2 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/utils/EntityConstructors1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/utils/EntityConstructors1_19_R2.java new file mode 100644 index 0000000..522fef1 --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/utils/EntityConstructors1_19_R2.java @@ -0,0 +1,12 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.entity.ArmorStand1_19_R2; + +public abstract class EntityConstructors1_19_R2 { + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_19_R2(world)); + +} \ No newline at end of file diff --git a/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/wrapper/ConsoleReaderWrapper1_19_R2.java b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/wrapper/ConsoleReaderWrapper1_19_R2.java new file mode 100644 index 0000000..59067bd --- /dev/null +++ b/vcompat-1_19_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R2/wrapper/ConsoleReaderWrapper1_19_R2.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R2.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_19_R2.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_19_R2 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_19_R2 INSTANCE = new ConsoleReaderWrapper1_19_R2(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_19_R2() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-1_19_R3/.gitignore b/vcompat-1_19_R3/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_19_R3/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_19_R3/pom.xml b/vcompat-1_19_R3/pom.xml new file mode 100644 index 0000000..c3b1bc2 --- /dev/null +++ b/vcompat-1_19_R3/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_19_R3 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.19.4 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_19_R3/pom.xml.versionsBackup b/vcompat-1_19_R3/pom.xml.versionsBackup new file mode 100644 index 0000000..79b0f0b --- /dev/null +++ b/vcompat-1_19_R3/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_19_R3 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.19.4 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/BukkitConversion1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/BukkitConversion1_19_R3.java new file mode 100644 index 0000000..6442aa9 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/BukkitConversion1_19_R3.java @@ -0,0 +1,209 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3; + +import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.BukkitContext1_19_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.BukkitType1_19_R3; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_19_R3 extends BukkitConversion { + + protected BukkitConversion1_19_R3(VersionControl1_19_R3 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.of(toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_19_R3(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_19_R3<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/EntityProvider1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/EntityProvider1_19_R3.java new file mode 100644 index 0000000..085fcd9 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/EntityProvider1_19_R3.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.utils.EntityConstructors1_19_R3; + +public class EntityProvider1_19_R3 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_19_R3(VersionControl1_19_R3 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_19_R3.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/PlayerProvider1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/PlayerProvider1_19_R3.java new file mode 100644 index 0000000..b9c9932 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/PlayerProvider1_19_R3.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.entity.Player1_19_R3; + +public class PlayerProvider1_19_R3 extends PlayerProvider { + + protected PlayerProvider1_19_R3(VersionControl1_19_R3 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_19_R3(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/TextureProvider1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/TextureProvider1_19_R3.java new file mode 100644 index 0000000..df72634 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/TextureProvider1_19_R3.java @@ -0,0 +1,111 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_19_R3.block.CraftSkull; +import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_19_R3 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_19_R3(VersionControl1_19_R3 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull") + .searchField("serialized", "serializedProfile").searchField("profile", "profile"); + + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner; + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + CompoundTag compound = (CompoundTag) craftMetaSkullRef.getFieldValue(meta, "serialized"); + if (compound == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + CompoundTag stackTag = stack.getOrCreateTag(); + if (stackTag.contains("SkullOwner", 10)) { + compound = stackTag.getCompound("SkullOwner"); + } else if (stackTag.contains("SkullProfile", 10)) { + compound = stackTag.getCompound("SkullProfile"); + } + } + if (compound == null) { + return null; + } + profile = NbtUtils.readGameProfile(compound); + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(profile); + return true; + } + +} diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/ToolProvider1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/ToolProvider1_19_R3.java new file mode 100644 index 0000000..06ddfa7 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/ToolProvider1_19_R3.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.tools.BlockTools1_19_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.tools.ServerTools1_19_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.tools.SkinTools1_19_R3; + +public class ToolProvider1_19_R3 extends ToolProvider { + + private final BlockTools1_19_R3 blockTools = new BlockTools1_19_R3(); + private final SkinTools1_19_R3 skinTools = new SkinTools1_19_R3(); + private final ServerTools1_19_R3 serverTools = new ServerTools1_19_R3(); + + protected ToolProvider1_19_R3(VersionControl1_19_R3 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_19_R3 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_19_R3 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_19_R3 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/VersionControl1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/VersionControl1_19_R3.java new file mode 100644 index 0000000..1b85b73 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/VersionControl1_19_R3.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.hook.BukkitContainerAdapterHook1_19_R3; + +public class VersionControl1_19_R3 extends VersionControl { + + public static VersionControl1_19_R3 INSTANCE; + + public static VersionControl1_19_R3 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_19_R3()); + } + + private final ToolProvider1_19_R3 toolProvider = new ToolProvider1_19_R3(this); + private final TextureProvider1_19_R3 textureProvider = new TextureProvider1_19_R3(this); + private final EntityProvider1_19_R3 entityProvider = new EntityProvider1_19_R3(this); + private final PlayerProvider1_19_R3 playerProvider = new PlayerProvider1_19_R3(this); + private final BukkitConversion1_19_R3 bukkitConversion = new BukkitConversion1_19_R3(this); + + private VersionControl1_19_R3() { + BukkitContainerAdapterHook1_19_R3.hookEntity(); + } + + @Override + public ToolProvider1_19_R3 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_19_R3 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_19_R3 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_19_R3 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_19_R3 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_19_R3.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitContainer1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitContainer1_19_R3.java new file mode 100644 index 0000000..64ff61b --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitContainer1_19_R3.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_19_R3 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_19_R3(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_19_R3(key), WrappedType1_19_R3.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_19_R3(key), WrappedType1_19_R3.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_19_R3(key), value, WrappedType1_19_R3.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_19_R3(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_19_R3::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_19_R3 getWrapContext() { + return new BukkitContext1_19_R3(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitContext1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitContext1_19_R3.java new file mode 100644 index 0000000..b166b73 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitContext1_19_R3.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_19_R3 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_19_R3(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_19_R3 newWrapContainer() { + return new BukkitContainer1_19_R3(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitKey1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitKey1_19_R3.java new file mode 100644 index 0000000..9bea28e --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitKey1_19_R3.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_19_R3 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_19_R3(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_19_R3(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_19_R3(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_19_R3(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitType1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitType1_19_R3.java new file mode 100644 index 0000000..b813f0f --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/BukkitType1_19_R3.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_19_R3 extends WrappedType1_19_R3, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_19_R3(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_19_R3(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_19_R3(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SimpleBukkitType1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SimpleBukkitType1_19_R3.java new file mode 100644 index 0000000..e2da25d --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SimpleBukkitType1_19_R3.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_19_R3 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_19_R3(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_19_R3(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_19_R3(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxContainer1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxContainer1_19_R3.java new file mode 100644 index 0000000..aa46c90 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxContainer1_19_R3.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_19_R3 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_19_R3(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_19_R3(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_19_R3.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_19_R3.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_19_R3.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_19_R3.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_19_R3::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_19_R3 getWrapContext() { + return new SyntaxContext1_19_R3(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_19_R3.asBukkit(key), new SimpleBukkitType1_19_R3<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_19_R3.asBukkit(key), new SimpleBukkitType1_19_R3<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_19_R3.asBukkit(key), new SimpleBukkitType1_19_R3<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_19_R3.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxContext1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxContext1_19_R3.java new file mode 100644 index 0000000..42b6871 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxContext1_19_R3.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_19_R3 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_19_R3(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_19_R3 newWrapContainer() { + return new SyntaxContainer1_19_R3(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxType1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxType1_19_R3.java new file mode 100644 index 0000000..5fefc2d --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/SyntaxType1_19_R3.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_19_R3 extends WrappedType1_19_R3, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_19_R3(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_19_R3(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_19_R3(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/WrappedType1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/WrappedType1_19_R3.java new file mode 100644 index 0000000..1c82286 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/WrappedType1_19_R3.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_19_R3 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_19_R3(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_19_R3.internalState(primitive); + this.complexWrap = WrappedType1_19_R3.internalState(complex); + this.primitiveType = (Class) WrappedType1_19_R3.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_19_R3.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_19_R3((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_19_R3::new) + .toArray(SyntaxContainer1_19_R3[]::new); + case 3: + return (P0) new BukkitContainer1_19_R3((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_19_R3::new) + .toArray(BukkitContainer1_19_R3[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_19_R3((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_19_R3::new).toArray(SyntaxContainer1_19_R3[]::new); + case 3: + return (C0) new BukkitContainer1_19_R3((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_19_R3::new).toArray(BukkitContainer1_19_R3[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_19_R3((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_19_R3::new) + .toArray(BukkitContainer1_19_R3[]::new); + case 3: + return (P1) new SyntaxContainer1_19_R3((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_19_R3::new) + .toArray(SyntaxContainer1_19_R3[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_19_R3((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_19_R3::new).toArray(BukkitContainer1_19_R3[]::new); + case 3: + return (C1) new SyntaxContainer1_19_R3((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_19_R3::new).toArray(SyntaxContainer1_19_R3[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_19_R3.class; + case 2: + return SyntaxContainer1_19_R3[].class; + case 3: + return BukkitContainer1_19_R3.class; + case 4: + return BukkitContainer1_19_R3[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_19_R3 wrap(IDataType type) { + return new BukkitType1_19_R3<>(type); + } + + public static SyntaxType1_19_R3 wrap(PersistentDataType type) { + return new SyntaxType1_19_R3<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/hook/BukkitContainerAdapterHook1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/hook/BukkitContainerAdapterHook1_19_R3.java new file mode 100644 index 0000000..3ada6a5 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/data/hook/BukkitContainerAdapterHook1_19_R3.java @@ -0,0 +1,137 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_19_R3.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_19_R3.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.BukkitContainer1_19_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.SyntaxContainer1_19_R3; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_19_R3 { + + private static final BukkitContainerAdapterHook1_19_R3 HOOK = new BukkitContainerAdapterHook1_19_R3(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_19_R3() { + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_19_R3.class); + adapters.remove(SyntaxContainer1_19_R3.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_19_R3.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_19_R3.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_19_R3.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_19_R3.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_19_R3 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_19_R3(container); + } + + private SyntaxContainer1_19_R3 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_19_R3(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/ArmorStand1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/ArmorStand1_19_R3.java new file mode 100644 index 0000000..4fca51e --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/ArmorStand1_19_R3.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_19_R3 extends EntityLiving1_19_R3 implements NmsArmorStand { + + public ArmorStand1_19_R3(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/Entity1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/Entity1_19_R3.java new file mode 100644 index 0000000..83534d7 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/Entity1_19_R3.java @@ -0,0 +1,215 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R3.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_19_R3 implements NmsEntity { + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_19_R3(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + handle.level = ((CraftWorld) location.getWorld()).getHandle(); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/EntityLiving1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/EntityLiving1_19_R3.java new file mode 100644 index 0000000..73eda32 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/EntityLiving1_19_R3.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_19_R3 extends Entity1_19_R3 implements NmsEntityLiving { + + public EntityLiving1_19_R3(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/Player1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/Player1_19_R3.java new file mode 100644 index 0000000..fd8e5fb --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/entity/Player1_19_R3.java @@ -0,0 +1,300 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_19_R3.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundAddPlayerPacket; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.biome.BiomeManager; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.data.SyntaxContainer1_19_R3; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_19_R3 extends EntityLiving1_19_R3 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_19_R3(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_19_R3(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.latency; + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + ClientboundAddPlayerPacket spawnPacket = new ClientboundAddPlayerPacket(handle); + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(spawnPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level; + + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(world.dimensionTypeId(), world.dimension(), + BiomeManager.obfuscateSeed(world.getSeed()), handle.gameMode.getGameModeForPlayer(), + handle.gameMode.getPreviousGameModeForPlayer(), world.isDebug(), world.isFlat(), ClientboundRespawnPacket.KEEP_ALL_DATA, + handle.getLastDeathLocation()); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/BlockTools1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/BlockTools1_19_R3.java new file mode 100644 index 0000000..8481795 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/BlockTools1_19_R3.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_19_R3.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_19_R3 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_19_R3() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.getProperties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.getProperties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/ServerTools1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/ServerTools1_19_R3.java new file mode 100644 index 0000000..dbb47b5 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/ServerTools1_19_R3.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_19_R3.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.wrapper.ConsoleReaderWrapper1_19_R3; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_19_R3 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_19_R3 getConsole() { + return ConsoleReaderWrapper1_19_R3.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/SkinTools1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/SkinTools1_19_R3.java new file mode 100644 index 0000000..155f99b --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/tools/SkinTools1_19_R3.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.tools; + +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_19_R3 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/utils/EntityConstructors1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/utils/EntityConstructors1_19_R3.java new file mode 100644 index 0000000..c8db9a4 --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/utils/EntityConstructors1_19_R3.java @@ -0,0 +1,12 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.entity.ArmorStand1_19_R3; + +public abstract class EntityConstructors1_19_R3 { + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_19_R3(world)); + +} \ No newline at end of file diff --git a/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/wrapper/ConsoleReaderWrapper1_19_R3.java b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/wrapper/ConsoleReaderWrapper1_19_R3.java new file mode 100644 index 0000000..ec6c9da --- /dev/null +++ b/vcompat-1_19_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_19_R3/wrapper/ConsoleReaderWrapper1_19_R3.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_19_R3.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_19_R3.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_19_R3 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_19_R3 INSTANCE = new ConsoleReaderWrapper1_19_R3(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_19_R3() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-1_20_R1/.gitignore b/vcompat-1_20_R1/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_20_R1/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_20_R1/pom.xml b/vcompat-1_20_R1/pom.xml new file mode 100644 index 0000000..608cb0d --- /dev/null +++ b/vcompat-1_20_R1/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_20_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.1 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R1/pom.xml.versionsBackup b/vcompat-1_20_R1/pom.xml.versionsBackup new file mode 100644 index 0000000..93414b9 --- /dev/null +++ b/vcompat-1_20_R1/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_20_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.1 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/BukkitConversion1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/BukkitConversion1_20_R1.java new file mode 100644 index 0000000..41a997d --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/BukkitConversion1_20_R1.java @@ -0,0 +1,209 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1; + +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.BukkitContext1_20_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.BukkitType1_20_R1; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_20_R1 extends BukkitConversion { + + protected BukkitConversion1_20_R1(VersionControl1_20_R1 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.of(toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_20_R1(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_20_R1<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/EntityProvider1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/EntityProvider1_20_R1.java new file mode 100644 index 0000000..a99d63a --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/EntityProvider1_20_R1.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.utils.EntityConstructors1_20_R1; + +public class EntityProvider1_20_R1 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_20_R1(VersionControl1_20_R1 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_20_R1.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/PlayerProvider1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/PlayerProvider1_20_R1.java new file mode 100644 index 0000000..843f820 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/PlayerProvider1_20_R1.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.entity.Player1_20_R1; + +public class PlayerProvider1_20_R1 extends PlayerProvider { + + protected PlayerProvider1_20_R1(VersionControl1_20_R1 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_20_R1(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/TextureProvider1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/TextureProvider1_20_R1.java new file mode 100644 index 0000000..a5fabb8 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/TextureProvider1_20_R1.java @@ -0,0 +1,111 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_20_R1.block.CraftSkull; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_20_R1 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_20_R1(VersionControl1_20_R1 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull") + .searchField("serialized", "serializedProfile").searchField("profile", "profile"); + + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner; + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + CompoundTag compound = (CompoundTag) craftMetaSkullRef.getFieldValue(meta, "serialized"); + if (compound == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + CompoundTag stackTag = stack.getOrCreateTag(); + if (stackTag.contains("SkullOwner", 10)) { + compound = stackTag.getCompound("SkullOwner"); + } else if (stackTag.contains("SkullProfile", 10)) { + compound = stackTag.getCompound("SkullProfile"); + } + } + if (compound == null) { + return null; + } + profile = NbtUtils.readGameProfile(compound); + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(profile); + return true; + } + +} diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/ToolProvider1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/ToolProvider1_20_R1.java new file mode 100644 index 0000000..287243b --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/ToolProvider1_20_R1.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.tools.BlockTools1_20_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.tools.ServerTools1_20_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.tools.SkinTools1_20_R1; + +public class ToolProvider1_20_R1 extends ToolProvider { + + private final BlockTools1_20_R1 blockTools = new BlockTools1_20_R1(); + private final SkinTools1_20_R1 skinTools = new SkinTools1_20_R1(); + private final ServerTools1_20_R1 serverTools = new ServerTools1_20_R1(); + + protected ToolProvider1_20_R1(VersionControl1_20_R1 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_20_R1 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_20_R1 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_20_R1 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/VersionControl1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/VersionControl1_20_R1.java new file mode 100644 index 0000000..c88fb51 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/VersionControl1_20_R1.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.hook.BukkitContainerAdapterHook1_20_R1; + +public class VersionControl1_20_R1 extends VersionControl { + + public static VersionControl1_20_R1 INSTANCE; + + public static VersionControl1_20_R1 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_20_R1()); + } + + private final ToolProvider1_20_R1 toolProvider = new ToolProvider1_20_R1(this); + private final TextureProvider1_20_R1 textureProvider = new TextureProvider1_20_R1(this); + private final EntityProvider1_20_R1 entityProvider = new EntityProvider1_20_R1(this); + private final PlayerProvider1_20_R1 playerProvider = new PlayerProvider1_20_R1(this); + private final BukkitConversion1_20_R1 bukkitConversion = new BukkitConversion1_20_R1(this); + + private VersionControl1_20_R1() { + BukkitContainerAdapterHook1_20_R1.hookEntity(); + } + + @Override + public ToolProvider1_20_R1 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_20_R1 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_20_R1 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_20_R1 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_20_R1 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_20_R1.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitContainer1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitContainer1_20_R1.java new file mode 100644 index 0000000..eaa5dba --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitContainer1_20_R1.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_20_R1 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_20_R1(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_20_R1(key), WrappedType1_20_R1.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_20_R1(key), WrappedType1_20_R1.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_20_R1(key), value, WrappedType1_20_R1.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_20_R1(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_20_R1::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_20_R1 getWrapContext() { + return new BukkitContext1_20_R1(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitContext1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitContext1_20_R1.java new file mode 100644 index 0000000..d21af47 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitContext1_20_R1.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_20_R1 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_20_R1(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_20_R1 newWrapContainer() { + return new BukkitContainer1_20_R1(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitKey1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitKey1_20_R1.java new file mode 100644 index 0000000..b9d0986 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitKey1_20_R1.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_20_R1 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_20_R1(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_20_R1(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_20_R1(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_20_R1(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitType1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitType1_20_R1.java new file mode 100644 index 0000000..ccbfb90 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/BukkitType1_20_R1.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_20_R1 extends WrappedType1_20_R1, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_20_R1(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_20_R1(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_20_R1(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SimpleBukkitType1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SimpleBukkitType1_20_R1.java new file mode 100644 index 0000000..b75746a --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SimpleBukkitType1_20_R1.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_20_R1 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_20_R1(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_20_R1(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_20_R1(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxContainer1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxContainer1_20_R1.java new file mode 100644 index 0000000..cb843ab --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxContainer1_20_R1.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_20_R1 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_20_R1(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_20_R1(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_20_R1.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_20_R1.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_20_R1.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_20_R1.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_20_R1::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_20_R1 getWrapContext() { + return new SyntaxContext1_20_R1(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_20_R1.asBukkit(key), new SimpleBukkitType1_20_R1<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_20_R1.asBukkit(key), new SimpleBukkitType1_20_R1<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_20_R1.asBukkit(key), new SimpleBukkitType1_20_R1<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_20_R1.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxContext1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxContext1_20_R1.java new file mode 100644 index 0000000..ca70b36 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxContext1_20_R1.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_20_R1 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_20_R1(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_20_R1 newWrapContainer() { + return new SyntaxContainer1_20_R1(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxType1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxType1_20_R1.java new file mode 100644 index 0000000..b1caf1f --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/SyntaxType1_20_R1.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_20_R1 extends WrappedType1_20_R1, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_20_R1(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_20_R1(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_20_R1(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/WrappedType1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/WrappedType1_20_R1.java new file mode 100644 index 0000000..51359e8 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/WrappedType1_20_R1.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_20_R1 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_20_R1(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_20_R1.internalState(primitive); + this.complexWrap = WrappedType1_20_R1.internalState(complex); + this.primitiveType = (Class) WrappedType1_20_R1.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_20_R1.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_20_R1((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R1::new) + .toArray(SyntaxContainer1_20_R1[]::new); + case 3: + return (P0) new BukkitContainer1_20_R1((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R1::new) + .toArray(BukkitContainer1_20_R1[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_20_R1((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R1::new).toArray(SyntaxContainer1_20_R1[]::new); + case 3: + return (C0) new BukkitContainer1_20_R1((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R1::new).toArray(BukkitContainer1_20_R1[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_20_R1((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R1::new) + .toArray(BukkitContainer1_20_R1[]::new); + case 3: + return (P1) new SyntaxContainer1_20_R1((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R1::new) + .toArray(SyntaxContainer1_20_R1[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_20_R1((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R1::new).toArray(BukkitContainer1_20_R1[]::new); + case 3: + return (C1) new SyntaxContainer1_20_R1((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R1::new).toArray(SyntaxContainer1_20_R1[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_20_R1.class; + case 2: + return SyntaxContainer1_20_R1[].class; + case 3: + return BukkitContainer1_20_R1.class; + case 4: + return BukkitContainer1_20_R1[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_20_R1 wrap(IDataType type) { + return new BukkitType1_20_R1<>(type); + } + + public static SyntaxType1_20_R1 wrap(PersistentDataType type) { + return new SyntaxType1_20_R1<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/hook/BukkitContainerAdapterHook1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/hook/BukkitContainerAdapterHook1_20_R1.java new file mode 100644 index 0000000..e1c7598 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/data/hook/BukkitContainerAdapterHook1_20_R1.java @@ -0,0 +1,140 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_20_R1.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_20_R1.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.BukkitContainer1_20_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.SyntaxContainer1_20_R1; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_20_R1 { + + private static final BukkitContainerAdapterHook1_20_R1 HOOK = new BukkitContainerAdapterHook1_20_R1(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_20_R1() { + if (HOOK != null) { + throw new UnsupportedOperationException(); + } + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_20_R1.class); + adapters.remove(SyntaxContainer1_20_R1.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_20_R1.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_20_R1.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_20_R1.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_20_R1.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_20_R1 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_20_R1(container); + } + + private SyntaxContainer1_20_R1 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_20_R1(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/ArmorStand1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/ArmorStand1_20_R1.java new file mode 100644 index 0000000..1bec19f --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/ArmorStand1_20_R1.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_20_R1 extends EntityLiving1_20_R1 implements NmsArmorStand { + + public ArmorStand1_20_R1(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/Entity1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/Entity1_20_R1.java new file mode 100644 index 0000000..9a8eb30 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/Entity1_20_R1.java @@ -0,0 +1,220 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_20_R1 implements NmsEntity { + + private static final ClassLookup ENTITY_REF = VersionCompatProvider.get().getLookupProvider().createLookup("Entity", Entity.class).searchMethodsByArguments("setLevel", Level.class); + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_20_R1(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + ENTITY_REF.execute(handle, "setLevel", ((CraftWorld) location.getWorld()).getHandle()); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/EntityLiving1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/EntityLiving1_20_R1.java new file mode 100644 index 0000000..cbc9ea3 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/EntityLiving1_20_R1.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_20_R1 extends Entity1_20_R1 implements NmsEntityLiving { + + public EntityLiving1_20_R1(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/Player1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/Player1_20_R1.java new file mode 100644 index 0000000..2d675ba --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/entity/Player1_20_R1.java @@ -0,0 +1,300 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundAddPlayerPacket; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.biome.BiomeManager; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.data.SyntaxContainer1_20_R1; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_20_R1 extends EntityLiving1_20_R1 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_20_R1(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_20_R1(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.latency; + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + ClientboundAddPlayerPacket spawnPacket = new ClientboundAddPlayerPacket(handle); + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(spawnPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level(); + + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(world.dimensionTypeId(), world.dimension(), + BiomeManager.obfuscateSeed(world.getSeed()), handle.gameMode.getGameModeForPlayer(), + handle.gameMode.getPreviousGameModeForPlayer(), world.isDebug(), world.isFlat(), ClientboundRespawnPacket.KEEP_ALL_DATA, + handle.getLastDeathLocation(), handle.getPortalCooldown()); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/BlockTools1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/BlockTools1_20_R1.java new file mode 100644 index 0000000..123212c --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/BlockTools1_20_R1.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R1.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_20_R1 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_20_R1() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.getProperties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.getProperties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/ServerTools1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/ServerTools1_20_R1.java new file mode 100644 index 0000000..be9894b --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/ServerTools1_20_R1.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_20_R1.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.wrapper.ConsoleReaderWrapper1_20_R1; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_20_R1 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_20_R1 getConsole() { + return ConsoleReaderWrapper1_20_R1.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/SkinTools1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/SkinTools1_20_R1.java new file mode 100644 index 0000000..a11a870 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/tools/SkinTools1_20_R1.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.tools; + +import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_20_R1 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/utils/EntityConstructors1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/utils/EntityConstructors1_20_R1.java new file mode 100644 index 0000000..020bcc2 --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/utils/EntityConstructors1_20_R1.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.entity.ArmorStand1_20_R1; + +public final class EntityConstructors1_20_R1 { + + private EntityConstructors1_20_R1() { + throw new UnsupportedOperationException(); + } + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_20_R1(world)); + +} \ No newline at end of file diff --git a/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/wrapper/ConsoleReaderWrapper1_20_R1.java b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/wrapper/ConsoleReaderWrapper1_20_R1.java new file mode 100644 index 0000000..654313f --- /dev/null +++ b/vcompat-1_20_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R1/wrapper/ConsoleReaderWrapper1_20_R1.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R1.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_20_R1.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_20_R1 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_20_R1 INSTANCE = new ConsoleReaderWrapper1_20_R1(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_20_R1() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-1_20_R2/.gitignore b/vcompat-1_20_R2/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_20_R2/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_20_R2/pom.xml b/vcompat-1_20_R2/pom.xml new file mode 100644 index 0000000..c0e843b --- /dev/null +++ b/vcompat-1_20_R2/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_20_R2 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.2 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R2/pom.xml.versionsBackup b/vcompat-1_20_R2/pom.xml.versionsBackup new file mode 100644 index 0000000..64a2df4 --- /dev/null +++ b/vcompat-1_20_R2/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_20_R2 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.2 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/BukkitConversion1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/BukkitConversion1_20_R2.java new file mode 100644 index 0000000..0851178 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/BukkitConversion1_20_R2.java @@ -0,0 +1,209 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2; + +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.BukkitContext1_20_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.BukkitType1_20_R2; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_20_R2 extends BukkitConversion { + + protected BukkitConversion1_20_R2(VersionControl1_20_R2 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.of(toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_20_R2(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_20_R2<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/EntityProvider1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/EntityProvider1_20_R2.java new file mode 100644 index 0000000..324e0ec --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/EntityProvider1_20_R2.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.utils.EntityConstructors1_20_R2; + +public class EntityProvider1_20_R2 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_20_R2(VersionControl1_20_R2 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_20_R2.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/PlayerProvider1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/PlayerProvider1_20_R2.java new file mode 100644 index 0000000..e41d0fb --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/PlayerProvider1_20_R2.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.entity.Player1_20_R2; + +public class PlayerProvider1_20_R2 extends PlayerProvider { + + protected PlayerProvider1_20_R2(VersionControl1_20_R2 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_20_R2(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/TextureProvider1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/TextureProvider1_20_R2.java new file mode 100644 index 0000000..f9ab4ad --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/TextureProvider1_20_R2.java @@ -0,0 +1,111 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_20_R2.block.CraftSkull; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_20_R2 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_20_R2(VersionControl1_20_R2 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull") + .searchField("serialized", "serializedProfile").searchField("profile", "profile"); + + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner; + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + CompoundTag compound = (CompoundTag) craftMetaSkullRef.getFieldValue(meta, "serialized"); + if (compound == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + CompoundTag stackTag = stack.getOrCreateTag(); + if (stackTag.contains("SkullOwner", 10)) { + compound = stackTag.getCompound("SkullOwner"); + } else if (stackTag.contains("SkullProfile", 10)) { + compound = stackTag.getCompound("SkullProfile"); + } + } + if (compound == null) { + return null; + } + profile = NbtUtils.readGameProfile(compound); + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(profile); + return true; + } + +} diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/ToolProvider1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/ToolProvider1_20_R2.java new file mode 100644 index 0000000..603f182 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/ToolProvider1_20_R2.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.tools.BlockTools1_20_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.tools.ServerTools1_20_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.tools.SkinTools1_20_R2; + +public class ToolProvider1_20_R2 extends ToolProvider { + + private final BlockTools1_20_R2 blockTools = new BlockTools1_20_R2(); + private final SkinTools1_20_R2 skinTools = new SkinTools1_20_R2(); + private final ServerTools1_20_R2 serverTools = new ServerTools1_20_R2(); + + protected ToolProvider1_20_R2(VersionControl1_20_R2 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_20_R2 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_20_R2 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_20_R2 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/VersionControl1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/VersionControl1_20_R2.java new file mode 100644 index 0000000..a3b1987 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/VersionControl1_20_R2.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.hook.BukkitContainerAdapterHook1_20_R2; + +public class VersionControl1_20_R2 extends VersionControl { + + public static VersionControl1_20_R2 INSTANCE; + + public static VersionControl1_20_R2 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_20_R2()); + } + + private final ToolProvider1_20_R2 toolProvider = new ToolProvider1_20_R2(this); + private final TextureProvider1_20_R2 textureProvider = new TextureProvider1_20_R2(this); + private final EntityProvider1_20_R2 entityProvider = new EntityProvider1_20_R2(this); + private final PlayerProvider1_20_R2 playerProvider = new PlayerProvider1_20_R2(this); + private final BukkitConversion1_20_R2 bukkitConversion = new BukkitConversion1_20_R2(this); + + private VersionControl1_20_R2() { + BukkitContainerAdapterHook1_20_R2.hookEntity(); + } + + @Override + public ToolProvider1_20_R2 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_20_R2 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_20_R2 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_20_R2 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_20_R2 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_20_R2.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitContainer1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitContainer1_20_R2.java new file mode 100644 index 0000000..17b2758 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitContainer1_20_R2.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_20_R2 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_20_R2(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_20_R2(key), WrappedType1_20_R2.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_20_R2(key), WrappedType1_20_R2.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_20_R2(key), value, WrappedType1_20_R2.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_20_R2(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_20_R2::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_20_R2 getWrapContext() { + return new BukkitContext1_20_R2(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitContext1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitContext1_20_R2.java new file mode 100644 index 0000000..d418cf0 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitContext1_20_R2.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_20_R2 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_20_R2(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_20_R2 newWrapContainer() { + return new BukkitContainer1_20_R2(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitKey1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitKey1_20_R2.java new file mode 100644 index 0000000..e9b7a1a --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitKey1_20_R2.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_20_R2 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_20_R2(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_20_R2(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_20_R2(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_20_R2(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitType1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitType1_20_R2.java new file mode 100644 index 0000000..5b58b69 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/BukkitType1_20_R2.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_20_R2 extends WrappedType1_20_R2, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_20_R2(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_20_R2(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_20_R2(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SimpleBukkitType1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SimpleBukkitType1_20_R2.java new file mode 100644 index 0000000..af03089 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SimpleBukkitType1_20_R2.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_20_R2 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_20_R2(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_20_R2(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_20_R2(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxContainer1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxContainer1_20_R2.java new file mode 100644 index 0000000..e546ba8 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxContainer1_20_R2.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_20_R2 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_20_R2(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_20_R2(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_20_R2.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_20_R2.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_20_R2.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_20_R2.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_20_R2::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_20_R2 getWrapContext() { + return new SyntaxContext1_20_R2(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_20_R2.asBukkit(key), new SimpleBukkitType1_20_R2<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_20_R2.asBukkit(key), new SimpleBukkitType1_20_R2<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_20_R2.asBukkit(key), new SimpleBukkitType1_20_R2<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_20_R2.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxContext1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxContext1_20_R2.java new file mode 100644 index 0000000..21b6bd2 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxContext1_20_R2.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_20_R2 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_20_R2(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_20_R2 newWrapContainer() { + return new SyntaxContainer1_20_R2(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxType1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxType1_20_R2.java new file mode 100644 index 0000000..98e056b --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/SyntaxType1_20_R2.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_20_R2 extends WrappedType1_20_R2, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_20_R2(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_20_R2(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_20_R2(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/WrappedType1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/WrappedType1_20_R2.java new file mode 100644 index 0000000..838da15 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/WrappedType1_20_R2.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_20_R2 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_20_R2(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_20_R2.internalState(primitive); + this.complexWrap = WrappedType1_20_R2.internalState(complex); + this.primitiveType = (Class) WrappedType1_20_R2.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_20_R2.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_20_R2((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R2::new) + .toArray(SyntaxContainer1_20_R2[]::new); + case 3: + return (P0) new BukkitContainer1_20_R2((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R2::new) + .toArray(BukkitContainer1_20_R2[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_20_R2((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R2::new).toArray(SyntaxContainer1_20_R2[]::new); + case 3: + return (C0) new BukkitContainer1_20_R2((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R2::new).toArray(BukkitContainer1_20_R2[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_20_R2((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R2::new) + .toArray(BukkitContainer1_20_R2[]::new); + case 3: + return (P1) new SyntaxContainer1_20_R2((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R2::new) + .toArray(SyntaxContainer1_20_R2[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_20_R2((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R2::new).toArray(BukkitContainer1_20_R2[]::new); + case 3: + return (C1) new SyntaxContainer1_20_R2((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R2::new).toArray(SyntaxContainer1_20_R2[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_20_R2.class; + case 2: + return SyntaxContainer1_20_R2[].class; + case 3: + return BukkitContainer1_20_R2.class; + case 4: + return BukkitContainer1_20_R2[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_20_R2 wrap(IDataType type) { + return new BukkitType1_20_R2<>(type); + } + + public static SyntaxType1_20_R2 wrap(PersistentDataType type) { + return new SyntaxType1_20_R2<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/hook/BukkitContainerAdapterHook1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/hook/BukkitContainerAdapterHook1_20_R2.java new file mode 100644 index 0000000..500c4ad --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/data/hook/BukkitContainerAdapterHook1_20_R2.java @@ -0,0 +1,140 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_20_R2.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_20_R2.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.BukkitContainer1_20_R2; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.SyntaxContainer1_20_R2; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_20_R2 { + + private static final BukkitContainerAdapterHook1_20_R2 HOOK = new BukkitContainerAdapterHook1_20_R2(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_20_R2() { + if (HOOK != null) { + throw new UnsupportedOperationException(); + } + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_20_R2.class); + adapters.remove(SyntaxContainer1_20_R2.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_20_R2.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_20_R2.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_20_R2.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_20_R2.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_20_R2 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_20_R2(container); + } + + private SyntaxContainer1_20_R2 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_20_R2(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/ArmorStand1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/ArmorStand1_20_R2.java new file mode 100644 index 0000000..154da7e --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/ArmorStand1_20_R2.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_20_R2 extends EntityLiving1_20_R2 implements NmsArmorStand { + + public ArmorStand1_20_R2(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/Entity1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/Entity1_20_R2.java new file mode 100644 index 0000000..075e987 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/Entity1_20_R2.java @@ -0,0 +1,220 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R2.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_20_R2 implements NmsEntity { + + private static final ClassLookup ENTITY_REF = VersionCompatProvider.get().getLookupProvider().createLookup("Entity", Entity.class).searchMethodsByArguments("setLevel", Level.class); + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_20_R2(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + ENTITY_REF.execute(handle, "setLevel", ((CraftWorld) location.getWorld()).getHandle()); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/EntityLiving1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/EntityLiving1_20_R2.java new file mode 100644 index 0000000..7e33de3 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/EntityLiving1_20_R2.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_20_R2 extends Entity1_20_R2 implements NmsEntityLiving { + + public EntityLiving1_20_R2(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/Player1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/Player1_20_R2.java new file mode 100644 index 0000000..12db834 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/entity/Player1_20_R2.java @@ -0,0 +1,293 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R2.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.data.SyntaxContainer1_20_R2; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_20_R2 extends EntityLiving1_20_R2 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_20_R2(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_20_R2(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.connection.latency(); + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level(); + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(handle.createCommonSpawnInfo(world), ClientboundRespawnPacket.KEEP_ALL_DATA); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/BlockTools1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/BlockTools1_20_R2.java new file mode 100644 index 0000000..70dd996 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/BlockTools1_20_R2.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R2.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_20_R2 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_20_R2() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.getProperties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.getProperties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/ServerTools1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/ServerTools1_20_R2.java new file mode 100644 index 0000000..d220619 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/ServerTools1_20_R2.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_20_R2.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.wrapper.ConsoleReaderWrapper1_20_R2; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_20_R2 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_20_R2 getConsole() { + return ConsoleReaderWrapper1_20_R2.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/SkinTools1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/SkinTools1_20_R2.java new file mode 100644 index 0000000..826f74d --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/tools/SkinTools1_20_R2.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.tools; + +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_20_R2 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/utils/EntityConstructors1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/utils/EntityConstructors1_20_R2.java new file mode 100644 index 0000000..03a2f29 --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/utils/EntityConstructors1_20_R2.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.entity.ArmorStand1_20_R2; + +public final class EntityConstructors1_20_R2 { + + private EntityConstructors1_20_R2() { + throw new UnsupportedOperationException(); + } + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_20_R2(world)); + +} \ No newline at end of file diff --git a/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/wrapper/ConsoleReaderWrapper1_20_R2.java b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/wrapper/ConsoleReaderWrapper1_20_R2.java new file mode 100644 index 0000000..373c5ec --- /dev/null +++ b/vcompat-1_20_R2/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R2/wrapper/ConsoleReaderWrapper1_20_R2.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R2.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_20_R2.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_20_R2 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_20_R2 INSTANCE = new ConsoleReaderWrapper1_20_R2(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_20_R2() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-1_20_R3/.gitignore b/vcompat-1_20_R3/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_20_R3/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_20_R3/pom.xml b/vcompat-1_20_R3/pom.xml new file mode 100644 index 0000000..3ace614 --- /dev/null +++ b/vcompat-1_20_R3/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_20_R3 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.4 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R3/pom.xml.versionsBackup b/vcompat-1_20_R3/pom.xml.versionsBackup new file mode 100644 index 0000000..980867f --- /dev/null +++ b/vcompat-1_20_R3/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_20_R3 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.4 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/BukkitConversion1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/BukkitConversion1_20_R3.java new file mode 100644 index 0000000..d48dcf1 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/BukkitConversion1_20_R3.java @@ -0,0 +1,209 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3; + +import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.BukkitContext1_20_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.BukkitType1_20_R3; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_20_R3 extends BukkitConversion { + + protected BukkitConversion1_20_R3(VersionControl1_20_R3 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.of(toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_20_R3(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_20_R3<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/EntityProvider1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/EntityProvider1_20_R3.java new file mode 100644 index 0000000..b7625c1 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/EntityProvider1_20_R3.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.utils.EntityConstructors1_20_R3; + +public class EntityProvider1_20_R3 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_20_R3(VersionControl1_20_R3 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_20_R3.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/PlayerProvider1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/PlayerProvider1_20_R3.java new file mode 100644 index 0000000..b77b28f --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/PlayerProvider1_20_R3.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.entity.Player1_20_R3; + +public class PlayerProvider1_20_R3 extends PlayerProvider { + + protected PlayerProvider1_20_R3(VersionControl1_20_R3 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_20_R3(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/TextureProvider1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/TextureProvider1_20_R3.java new file mode 100644 index 0000000..ad73a03 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/TextureProvider1_20_R3.java @@ -0,0 +1,111 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_20_R3.block.CraftSkull; +import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_20_R3 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_20_R3(VersionControl1_20_R3 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull") + .searchField("serialized", "serializedProfile").searchField("profile", "profile"); + + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner; + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + CompoundTag compound = (CompoundTag) craftMetaSkullRef.getFieldValue(meta, "serialized"); + if (compound == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + CompoundTag stackTag = stack.getOrCreateTag(); + if (stackTag.contains("SkullOwner", 10)) { + compound = stackTag.getCompound("SkullOwner"); + } else if (stackTag.contains("SkullProfile", 10)) { + compound = stackTag.getCompound("SkullProfile"); + } + } + if (compound == null) { + return null; + } + profile = NbtUtils.readGameProfile(compound); + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(profile); + return true; + } + +} diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/ToolProvider1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/ToolProvider1_20_R3.java new file mode 100644 index 0000000..db11094 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/ToolProvider1_20_R3.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.tools.BlockTools1_20_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.tools.ServerTools1_20_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.tools.SkinTools1_20_R3; + +public class ToolProvider1_20_R3 extends ToolProvider { + + private final BlockTools1_20_R3 blockTools = new BlockTools1_20_R3(); + private final SkinTools1_20_R3 skinTools = new SkinTools1_20_R3(); + private final ServerTools1_20_R3 serverTools = new ServerTools1_20_R3(); + + protected ToolProvider1_20_R3(VersionControl1_20_R3 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_20_R3 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_20_R3 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_20_R3 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/VersionControl1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/VersionControl1_20_R3.java new file mode 100644 index 0000000..f181633 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/VersionControl1_20_R3.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.hook.BukkitContainerAdapterHook1_20_R3; + +public class VersionControl1_20_R3 extends VersionControl { + + public static VersionControl1_20_R3 INSTANCE; + + public static VersionControl1_20_R3 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_20_R3()); + } + + private final ToolProvider1_20_R3 toolProvider = new ToolProvider1_20_R3(this); + private final TextureProvider1_20_R3 textureProvider = new TextureProvider1_20_R3(this); + private final EntityProvider1_20_R3 entityProvider = new EntityProvider1_20_R3(this); + private final PlayerProvider1_20_R3 playerProvider = new PlayerProvider1_20_R3(this); + private final BukkitConversion1_20_R3 bukkitConversion = new BukkitConversion1_20_R3(this); + + private VersionControl1_20_R3() { + BukkitContainerAdapterHook1_20_R3.hookEntity(); + } + + @Override + public ToolProvider1_20_R3 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_20_R3 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_20_R3 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_20_R3 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_20_R3 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_20_R3.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitContainer1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitContainer1_20_R3.java new file mode 100644 index 0000000..612675c --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitContainer1_20_R3.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_20_R3 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_20_R3(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_20_R3(key), WrappedType1_20_R3.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_20_R3(key), WrappedType1_20_R3.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_20_R3(key), value, WrappedType1_20_R3.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_20_R3(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_20_R3::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_20_R3 getWrapContext() { + return new BukkitContext1_20_R3(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitContext1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitContext1_20_R3.java new file mode 100644 index 0000000..7ce94ea --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitContext1_20_R3.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_20_R3 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_20_R3(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_20_R3 newWrapContainer() { + return new BukkitContainer1_20_R3(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitKey1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitKey1_20_R3.java new file mode 100644 index 0000000..c221ef8 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitKey1_20_R3.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_20_R3 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_20_R3(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_20_R3(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_20_R3(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_20_R3(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitType1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitType1_20_R3.java new file mode 100644 index 0000000..5830f09 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/BukkitType1_20_R3.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_20_R3 extends WrappedType1_20_R3, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_20_R3(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_20_R3(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_20_R3(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SimpleBukkitType1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SimpleBukkitType1_20_R3.java new file mode 100644 index 0000000..9f0fcbf --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SimpleBukkitType1_20_R3.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_20_R3 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_20_R3(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_20_R3(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_20_R3(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxContainer1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxContainer1_20_R3.java new file mode 100644 index 0000000..2ed6bf9 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxContainer1_20_R3.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_20_R3 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_20_R3(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_20_R3(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_20_R3.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_20_R3.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_20_R3.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_20_R3.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_20_R3::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_20_R3 getWrapContext() { + return new SyntaxContext1_20_R3(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_20_R3.asBukkit(key), new SimpleBukkitType1_20_R3<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_20_R3.asBukkit(key), new SimpleBukkitType1_20_R3<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_20_R3.asBukkit(key), new SimpleBukkitType1_20_R3<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_20_R3.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxContext1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxContext1_20_R3.java new file mode 100644 index 0000000..822e12a --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxContext1_20_R3.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_20_R3 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_20_R3(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_20_R3 newWrapContainer() { + return new SyntaxContainer1_20_R3(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxType1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxType1_20_R3.java new file mode 100644 index 0000000..7be3cd2 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/SyntaxType1_20_R3.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_20_R3 extends WrappedType1_20_R3, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_20_R3(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_20_R3(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_20_R3(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/WrappedType1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/WrappedType1_20_R3.java new file mode 100644 index 0000000..5b984d7 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/WrappedType1_20_R3.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_20_R3 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_20_R3(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_20_R3.internalState(primitive); + this.complexWrap = WrappedType1_20_R3.internalState(complex); + this.primitiveType = (Class) WrappedType1_20_R3.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_20_R3.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_20_R3((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R3::new) + .toArray(SyntaxContainer1_20_R3[]::new); + case 3: + return (P0) new BukkitContainer1_20_R3((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R3::new) + .toArray(BukkitContainer1_20_R3[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_20_R3((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R3::new).toArray(SyntaxContainer1_20_R3[]::new); + case 3: + return (C0) new BukkitContainer1_20_R3((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R3::new).toArray(BukkitContainer1_20_R3[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_20_R3((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R3::new) + .toArray(BukkitContainer1_20_R3[]::new); + case 3: + return (P1) new SyntaxContainer1_20_R3((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R3::new) + .toArray(SyntaxContainer1_20_R3[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_20_R3((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R3::new).toArray(BukkitContainer1_20_R3[]::new); + case 3: + return (C1) new SyntaxContainer1_20_R3((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R3::new).toArray(SyntaxContainer1_20_R3[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_20_R3.class; + case 2: + return SyntaxContainer1_20_R3[].class; + case 3: + return BukkitContainer1_20_R3.class; + case 4: + return BukkitContainer1_20_R3[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_20_R3 wrap(IDataType type) { + return new BukkitType1_20_R3<>(type); + } + + public static SyntaxType1_20_R3 wrap(PersistentDataType type) { + return new SyntaxType1_20_R3<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/hook/BukkitContainerAdapterHook1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/hook/BukkitContainerAdapterHook1_20_R3.java new file mode 100644 index 0000000..c2e644e --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/data/hook/BukkitContainerAdapterHook1_20_R3.java @@ -0,0 +1,140 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_20_R3.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.BukkitContainer1_20_R3; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.SyntaxContainer1_20_R3; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_20_R3 { + + private static final BukkitContainerAdapterHook1_20_R3 HOOK = new BukkitContainerAdapterHook1_20_R3(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_20_R3() { + if (HOOK != null) { + throw new UnsupportedOperationException(); + } + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_20_R3.class); + adapters.remove(SyntaxContainer1_20_R3.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_20_R3.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_20_R3.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_20_R3.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_20_R3.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_20_R3 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_20_R3(container); + } + + private SyntaxContainer1_20_R3 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_20_R3(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/ArmorStand1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/ArmorStand1_20_R3.java new file mode 100644 index 0000000..543b624 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/ArmorStand1_20_R3.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_20_R3 extends EntityLiving1_20_R3 implements NmsArmorStand { + + public ArmorStand1_20_R3(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/Entity1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/Entity1_20_R3.java new file mode 100644 index 0000000..0ff5d4f --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/Entity1_20_R3.java @@ -0,0 +1,220 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R3.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_20_R3 implements NmsEntity { + + private static final ClassLookup ENTITY_REF = VersionCompatProvider.get().getLookupProvider().createLookup("Entity", Entity.class).searchMethodsByArguments("setLevel", Level.class); + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_20_R3(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + ENTITY_REF.execute(handle, "setLevel", ((CraftWorld) location.getWorld()).getHandle()); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/EntityLiving1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/EntityLiving1_20_R3.java new file mode 100644 index 0000000..630ce7f --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/EntityLiving1_20_R3.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_20_R3 extends Entity1_20_R3 implements NmsEntityLiving { + + public EntityLiving1_20_R3(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/Player1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/Player1_20_R3.java new file mode 100644 index 0000000..ae5c28c --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/entity/Player1_20_R3.java @@ -0,0 +1,293 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R3.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.data.SyntaxContainer1_20_R3; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_20_R3 extends EntityLiving1_20_R3 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_20_R3(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_20_R3(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.connection.latency(); + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level(); + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(handle.createCommonSpawnInfo(world), ClientboundRespawnPacket.KEEP_ALL_DATA); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/BlockTools1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/BlockTools1_20_R3.java new file mode 100644 index 0000000..f8d866b --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/BlockTools1_20_R3.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R3.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_20_R3 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_20_R3() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.getProperties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.getProperties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/ServerTools1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/ServerTools1_20_R3.java new file mode 100644 index 0000000..59dac7f --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/ServerTools1_20_R3.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_20_R3.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.wrapper.ConsoleReaderWrapper1_20_R3; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_20_R3 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_20_R3 getConsole() { + return ConsoleReaderWrapper1_20_R3.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/SkinTools1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/SkinTools1_20_R3.java new file mode 100644 index 0000000..75b9dd7 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/tools/SkinTools1_20_R3.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.tools; + +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_20_R3 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/utils/EntityConstructors1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/utils/EntityConstructors1_20_R3.java new file mode 100644 index 0000000..d6e749a --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/utils/EntityConstructors1_20_R3.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.entity.ArmorStand1_20_R3; + +public final class EntityConstructors1_20_R3 { + + private EntityConstructors1_20_R3() { + throw new UnsupportedOperationException(); + } + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_20_R3(world)); + +} \ No newline at end of file diff --git a/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/wrapper/ConsoleReaderWrapper1_20_R3.java b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/wrapper/ConsoleReaderWrapper1_20_R3.java new file mode 100644 index 0000000..22d1955 --- /dev/null +++ b/vcompat-1_20_R3/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R3/wrapper/ConsoleReaderWrapper1_20_R3.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R3.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_20_R3.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_20_R3 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_20_R3 INSTANCE = new ConsoleReaderWrapper1_20_R3(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_20_R3() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-1_20_R4/.gitignore b/vcompat-1_20_R4/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_20_R4/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_20_R4/pom.xml b/vcompat-1_20_R4/pom.xml new file mode 100644 index 0000000..23ea8fb --- /dev/null +++ b/vcompat-1_20_R4/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_20_R4 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.6 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R4/pom.xml.versionsBackup b/vcompat-1_20_R4/pom.xml.versionsBackup new file mode 100644 index 0000000..8a46c31 --- /dev/null +++ b/vcompat-1_20_R4/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_20_R4 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.20.6 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/BukkitConversion1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/BukkitConversion1_20_R4.java new file mode 100644 index 0000000..7fbf350 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/BukkitConversion1_20_R4.java @@ -0,0 +1,214 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_20_R4.CraftServer; +import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.core.RegistryAccess.Frozen; +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.BukkitContext1_20_R4; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.BukkitType1_20_R4; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_20_R4 extends BukkitConversion { + + private final Frozen registry = ((CraftServer) Bukkit.getServer()).getServer().registryAccess(); + + protected BukkitConversion1_20_R4(VersionControl1_20_R4 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.parseOptional(registry, toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(registry, new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_20_R4(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_20_R4<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/EntityProvider1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/EntityProvider1_20_R4.java new file mode 100644 index 0000000..70a9cf5 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/EntityProvider1_20_R4.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R4.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.utils.EntityConstructors1_20_R4; + +public class EntityProvider1_20_R4 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_20_R4(VersionControl1_20_R4 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_20_R4.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/PlayerProvider1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/PlayerProvider1_20_R4.java new file mode 100644 index 0000000..6774418 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/PlayerProvider1_20_R4.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.entity.Player1_20_R4; + +public class PlayerProvider1_20_R4 extends PlayerProvider { + + protected PlayerProvider1_20_R4(VersionControl1_20_R4 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_20_R4(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/TextureProvider1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/TextureProvider1_20_R4.java new file mode 100644 index 0000000..759ac85 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/TextureProvider1_20_R4.java @@ -0,0 +1,100 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R4.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_20_R4.block.CraftSkull; +import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ResolvableProfile; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_20_R4 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_20_R4(VersionControl1_20_R4 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull").searchField("profile", "profile"); + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.gameProfile(); + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + ResolvableProfile resolved = stack.get(DataComponents.PROFILE); + if (resolved != null) { + profile = resolved.gameProfile(); + } + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(new ResolvableProfile(profile)); + return true; + } + +} diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/ToolProvider1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/ToolProvider1_20_R4.java new file mode 100644 index 0000000..85f2cf2 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/ToolProvider1_20_R4.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.tools.BlockTools1_20_R4; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.tools.ServerTools1_20_R4; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.tools.SkinTools1_20_R4; + +public class ToolProvider1_20_R4 extends ToolProvider { + + private final BlockTools1_20_R4 blockTools = new BlockTools1_20_R4(); + private final SkinTools1_20_R4 skinTools = new SkinTools1_20_R4(); + private final ServerTools1_20_R4 serverTools = new ServerTools1_20_R4(); + + protected ToolProvider1_20_R4(VersionControl1_20_R4 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_20_R4 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_20_R4 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_20_R4 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/VersionControl1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/VersionControl1_20_R4.java new file mode 100644 index 0000000..32028a1 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/VersionControl1_20_R4.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.hook.BukkitContainerAdapterHook1_20_R4; + +public class VersionControl1_20_R4 extends VersionControl { + + public static VersionControl1_20_R4 INSTANCE; + + public static VersionControl1_20_R4 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_20_R4()); + } + + private final ToolProvider1_20_R4 toolProvider = new ToolProvider1_20_R4(this); + private final TextureProvider1_20_R4 textureProvider = new TextureProvider1_20_R4(this); + private final EntityProvider1_20_R4 entityProvider = new EntityProvider1_20_R4(this); + private final PlayerProvider1_20_R4 playerProvider = new PlayerProvider1_20_R4(this); + private final BukkitConversion1_20_R4 bukkitConversion = new BukkitConversion1_20_R4(this); + + private VersionControl1_20_R4() { + BukkitContainerAdapterHook1_20_R4.hookEntity(); + } + + @Override + public ToolProvider1_20_R4 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_20_R4 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_20_R4 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_20_R4 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_20_R4 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_20_R4.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitContainer1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitContainer1_20_R4.java new file mode 100644 index 0000000..7840f0a --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitContainer1_20_R4.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_20_R4 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_20_R4(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_20_R4(key), WrappedType1_20_R4.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_20_R4(key), WrappedType1_20_R4.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_20_R4(key), value, WrappedType1_20_R4.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_20_R4(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_20_R4::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_20_R4 getWrapContext() { + return new BukkitContext1_20_R4(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitContext1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitContext1_20_R4.java new file mode 100644 index 0000000..5986601 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitContext1_20_R4.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_20_R4 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_20_R4(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_20_R4 newWrapContainer() { + return new BukkitContainer1_20_R4(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitKey1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitKey1_20_R4.java new file mode 100644 index 0000000..e7df194 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitKey1_20_R4.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_20_R4 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_20_R4(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_20_R4(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_20_R4(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_20_R4(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitType1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitType1_20_R4.java new file mode 100644 index 0000000..56b3b82 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/BukkitType1_20_R4.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_20_R4 extends WrappedType1_20_R4, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_20_R4(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_20_R4(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_20_R4(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SimpleBukkitType1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SimpleBukkitType1_20_R4.java new file mode 100644 index 0000000..3d183b7 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SimpleBukkitType1_20_R4.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_20_R4 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_20_R4(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_20_R4(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_20_R4(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxContainer1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxContainer1_20_R4.java new file mode 100644 index 0000000..6b93fe4 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxContainer1_20_R4.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_20_R4 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_20_R4(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_20_R4(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_20_R4.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_20_R4.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_20_R4.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_20_R4.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_20_R4::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_20_R4 getWrapContext() { + return new SyntaxContext1_20_R4(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_20_R4.asBukkit(key), new SimpleBukkitType1_20_R4<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_20_R4.asBukkit(key), new SimpleBukkitType1_20_R4<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_20_R4.asBukkit(key), new SimpleBukkitType1_20_R4<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_20_R4.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxContext1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxContext1_20_R4.java new file mode 100644 index 0000000..38b479a --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxContext1_20_R4.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_20_R4 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_20_R4(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_20_R4 newWrapContainer() { + return new SyntaxContainer1_20_R4(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxType1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxType1_20_R4.java new file mode 100644 index 0000000..39e7c5d --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/SyntaxType1_20_R4.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_20_R4 extends WrappedType1_20_R4, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_20_R4(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_20_R4(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_20_R4(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/WrappedType1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/WrappedType1_20_R4.java new file mode 100644 index 0000000..966146a --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/WrappedType1_20_R4.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_20_R4 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_20_R4(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_20_R4.internalState(primitive); + this.complexWrap = WrappedType1_20_R4.internalState(complex); + this.primitiveType = (Class) WrappedType1_20_R4.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_20_R4.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_20_R4((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R4::new) + .toArray(SyntaxContainer1_20_R4[]::new); + case 3: + return (P0) new BukkitContainer1_20_R4((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R4::new) + .toArray(BukkitContainer1_20_R4[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_20_R4((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R4::new).toArray(SyntaxContainer1_20_R4[]::new); + case 3: + return (C0) new BukkitContainer1_20_R4((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R4::new).toArray(BukkitContainer1_20_R4[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_20_R4((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_20_R4::new) + .toArray(BukkitContainer1_20_R4[]::new); + case 3: + return (P1) new SyntaxContainer1_20_R4((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_20_R4::new) + .toArray(SyntaxContainer1_20_R4[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_20_R4((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_20_R4::new).toArray(BukkitContainer1_20_R4[]::new); + case 3: + return (C1) new SyntaxContainer1_20_R4((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_20_R4::new).toArray(SyntaxContainer1_20_R4[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_20_R4.class; + case 2: + return SyntaxContainer1_20_R4[].class; + case 3: + return BukkitContainer1_20_R4.class; + case 4: + return BukkitContainer1_20_R4[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_20_R4 wrap(IDataType type) { + return new BukkitType1_20_R4<>(type); + } + + public static SyntaxType1_20_R4 wrap(PersistentDataType type) { + return new SyntaxType1_20_R4<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/hook/BukkitContainerAdapterHook1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/hook/BukkitContainerAdapterHook1_20_R4.java new file mode 100644 index 0000000..204542e --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/data/hook/BukkitContainerAdapterHook1_20_R4.java @@ -0,0 +1,140 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_20_R4.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_20_R4.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.BukkitContainer1_20_R4; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.SyntaxContainer1_20_R4; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_20_R4 { + + private static final BukkitContainerAdapterHook1_20_R4 HOOK = new BukkitContainerAdapterHook1_20_R4(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_20_R4() { + if (HOOK != null) { + throw new UnsupportedOperationException(); + } + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_20_R4.class); + adapters.remove(SyntaxContainer1_20_R4.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_20_R4.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_20_R4.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_20_R4.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_20_R4.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_20_R4 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_20_R4(container); + } + + private SyntaxContainer1_20_R4 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_20_R4(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/ArmorStand1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/ArmorStand1_20_R4.java new file mode 100644 index 0000000..7bc9768 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/ArmorStand1_20_R4.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_20_R4 extends EntityLiving1_20_R4 implements NmsArmorStand { + + public ArmorStand1_20_R4(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/Entity1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/Entity1_20_R4.java new file mode 100644 index 0000000..fb10e19 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/Entity1_20_R4.java @@ -0,0 +1,220 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_20_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R4.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_20_R4 implements NmsEntity { + + private static final ClassLookup ENTITY_REF = VersionCompatProvider.get().getLookupProvider().createLookup("Entity", Entity.class).searchMethodsByArguments("setLevel", Level.class); + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_20_R4(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + ENTITY_REF.execute(handle, "setLevel", ((CraftWorld) location.getWorld()).getHandle()); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/EntityLiving1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/EntityLiving1_20_R4.java new file mode 100644 index 0000000..599ad89 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/EntityLiving1_20_R4.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_20_R4 extends Entity1_20_R4 implements NmsEntityLiving { + + public EntityLiving1_20_R4(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/Player1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/Player1_20_R4.java new file mode 100644 index 0000000..9ed9947 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/entity/Player1_20_R4.java @@ -0,0 +1,293 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R4.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.data.SyntaxContainer1_20_R4; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_20_R4 extends EntityLiving1_20_R4 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_20_R4(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_20_R4(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.connection.latency(); + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level(); + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(handle.createCommonSpawnInfo(world), ClientboundRespawnPacket.KEEP_ALL_DATA); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/BlockTools1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/BlockTools1_20_R4.java new file mode 100644 index 0000000..fb35d14 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/BlockTools1_20_R4.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_20_R4.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_20_R4 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_20_R4() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.properties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.properties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/ServerTools1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/ServerTools1_20_R4.java new file mode 100644 index 0000000..f01e770 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/ServerTools1_20_R4.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_20_R4.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.wrapper.ConsoleReaderWrapper1_20_R4; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_20_R4 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_20_R4 getConsole() { + return ConsoleReaderWrapper1_20_R4.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/SkinTools1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/SkinTools1_20_R4.java new file mode 100644 index 0000000..71a8ab5 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/tools/SkinTools1_20_R4.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.tools; + +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_20_R4 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/utils/EntityConstructors1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/utils/EntityConstructors1_20_R4.java new file mode 100644 index 0000000..5494cbe --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/utils/EntityConstructors1_20_R4.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.entity.ArmorStand1_20_R4; + +public final class EntityConstructors1_20_R4 { + + private EntityConstructors1_20_R4() { + throw new UnsupportedOperationException(); + } + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_20_R4(world)); + +} \ No newline at end of file diff --git a/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/wrapper/ConsoleReaderWrapper1_20_R4.java b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/wrapper/ConsoleReaderWrapper1_20_R4.java new file mode 100644 index 0000000..4cdd665 --- /dev/null +++ b/vcompat-1_20_R4/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_20_R4/wrapper/ConsoleReaderWrapper1_20_R4.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_20_R4.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_20_R4.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_20_R4 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_20_R4 INSTANCE = new ConsoleReaderWrapper1_20_R4(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_20_R4() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-1_21_R1/.gitignore b/vcompat-1_21_R1/.gitignore new file mode 100644 index 0000000..00d2ab7 --- /dev/null +++ b/vcompat-1_21_R1/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/.apt_generated_tests/ diff --git a/vcompat-1_21_R1/pom.xml b/vcompat-1_21_R1/pom.xml new file mode 100644 index 0000000..f1877f2 --- /dev/null +++ b/vcompat-1_21_R1/pom.xml @@ -0,0 +1,109 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.7 + + vcompat-1_21_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.21 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + ${specialsource.version} + + false + + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_21_R1/pom.xml.versionsBackup b/vcompat-1_21_R1/pom.xml.versionsBackup new file mode 100644 index 0000000..ae137f6 --- /dev/null +++ b/vcompat-1_21_R1/pom.xml.versionsBackup @@ -0,0 +1,106 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-1_21_R1 + + + ${project.basedir}/../libraries/mapping + ${project.basedir}/../libraries/spigot + 1.21 + + + + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + spigot + remapped + 0.1 + system + ${spigot.libPath}/spigot-${minecraft.version}.jar + + + it.unimi.dsi + fastutil + 8.5.6 + provided + + + com.mojang + datafixerupper + 1.0.20 + provided + + + jline + jline + 2.12.1 + provided + + + org.slf4j + slf4j-api + 2.0.0-alpha1 + provided + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${minecraft.version}-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:${minecraft.version}-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/BukkitConversion1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/BukkitConversion1_21_R1.java new file mode 100644 index 0000000..dfa3296 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/BukkitConversion1_21_R1.java @@ -0,0 +1,214 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_21_R1.CraftServer; +import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; + +import net.minecraft.core.RegistryAccess.Frozen; +import net.minecraft.nbt.ByteArrayTag; +import net.minecraft.nbt.ByteTag; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.DoubleTag; +import net.minecraft.nbt.EndTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.IntArrayTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongArrayTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.ShortTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.BukkitConversion; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.BukkitContext1_21_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.BukkitType1_21_R1; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByte; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtByteArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtDouble; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtEnd; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtFloat; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtInt; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtIntArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtList; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLong; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtLongArray; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtShort; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtString; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtTag; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtType; + +public class BukkitConversion1_21_R1 extends BukkitConversion { + + private final Frozen registry = ((CraftServer) Bukkit.getServer()).getServer().registryAccess(); + + protected BukkitConversion1_21_R1(VersionControl1_21_R1 versionControl) { + super(versionControl); + } + + @Override + public EntityType toEntityType(NmsEntityType type) { + try { + return EntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public NmsEntityType fromEntityType(EntityType type) { + try { + return NmsEntityType.valueOf(type.name()); + } catch (IllegalArgumentException ignore) { + return null; + } + } + + @Override + public Tag toMinecraftTag(NbtTag tag) { + switch (tag.getType()) { + case END: + return EndTag.INSTANCE; + case BYTE: + return ByteTag.valueOf(((NbtByte) tag).getValue()); + case BYTE_ARRAY: + return new ByteArrayTag(((NbtByteArray) tag).getValue()); + case DOUBLE: + return DoubleTag.valueOf(((NbtDouble) tag).getValue()); + case FLOAT: + return FloatTag.valueOf(((NbtFloat) tag).getValue()); + case INT: + return IntTag.valueOf(((NbtInt) tag).getValue()); + case INT_ARRAY: + return new IntArrayTag(((NbtIntArray) tag).getValue()); + case LONG: + return LongTag.valueOf(((NbtLong) tag).getValue()); + case LONG_ARRAY: + return new LongArrayTag(((NbtLongArray) tag).getValue()); + case SHORT: + return ShortTag.valueOf(((NbtShort) tag).getValue()); + case STRING: + return StringTag.valueOf(((NbtString) tag).getValue()); + case LIST: + return toMinecraftList((NbtList) tag); + case COMPOUND: + return toMinecraftCompound((NbtCompound) tag); + default: + return null; + } + } + + @Override + public NbtTag fromMinecraftTag(Object tag) { + if (tag != null && tag instanceof Tag) { + return fromMinecraftTag0((Tag) tag); + } + return null; + } + + public NbtTag fromMinecraftTag0(Tag tag) { + switch (NbtType.getById(tag.getId())) { + case END: + return NbtEnd.INSTANCE; + case BYTE: + return new NbtByte(((ByteTag) tag).getAsByte()); + case BYTE_ARRAY: + return new NbtByteArray(((ByteArrayTag) tag).getAsByteArray()); + case DOUBLE: + return new NbtDouble(((DoubleTag) tag).getAsDouble()); + case FLOAT: + return new NbtFloat(((FloatTag) tag).getAsFloat()); + case INT: + return new NbtInt(((IntTag) tag).getAsInt()); + case INT_ARRAY: + return new NbtIntArray(((IntArrayTag) tag).getAsIntArray()); + case LONG: + return new NbtLong(((LongTag) tag).getAsLong()); + case LONG_ARRAY: + return new NbtLongArray(((LongArrayTag) tag).getAsLongArray()); + case SHORT: + return new NbtShort(((ShortTag) tag).getAsShort()); + case STRING: + return new NbtString(((StringTag) tag).getAsString()); + case LIST: + return fromMinecraftList(tag); + case COMPOUND: + return fromMinecraftCompound(tag); + default: + return null; + } + } + + @Override + public ListTag toMinecraftList(NbtList list) { + ListTag output = new ListTag(); + for (NbtTag tag : list) { + output.add(toMinecraftTag(tag)); + } + return output; + } + + @Override + public NbtList fromMinecraftList(Object raw) { + if (!(raw instanceof ListTag)) { + return null; + } + ListTag list = (ListTag) raw; + NbtList output = new NbtList<>(NbtType.getById(list.getElementType())); + for (Tag base : list) { + output.add(fromMinecraftTag(base)); + } + return output; + } + + @Override + public CompoundTag toMinecraftCompound(NbtCompound compound) { + NbtCompound compoundTag = compound; + CompoundTag targetCompound = new CompoundTag(); + for (String key : compoundTag.getKeys()) { + targetCompound.put(key, toMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public NbtCompound fromMinecraftCompound(Object raw) { + if (!(raw instanceof CompoundTag)) { + return null; + } + CompoundTag compoundTag = (CompoundTag) raw; + NbtCompound targetCompound = new NbtCompound(); + for (String key : compoundTag.getAllKeys()) { + targetCompound.set(key, fromMinecraftTag(compoundTag.get(key))); + } + return targetCompound; + } + + @Override + public org.bukkit.inventory.ItemStack itemFromCompound(NbtCompound compound) { + return CraftItemStack.asBukkitCopy(ItemStack.parseOptional(registry, toMinecraftCompound(compound))); + } + + @Override + public NbtCompound itemToCompound(org.bukkit.inventory.ItemStack itemStack) { + return fromMinecraftCompound(CraftItemStack.asNMSCopy(itemStack).save(registry, new CompoundTag())); + } + + @Override + public WrappedContext createContext(IDataAdapterContext context) { + return new BukkitContext1_21_R1(context); + } + + @Override + public WrapType wrap(IDataType dataType) { + return new BukkitType1_21_R1<>(dataType); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/EntityProvider1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/EntityProvider1_21_R1.java new file mode 100644 index 0000000..b475c43 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/EntityProvider1_21_R1.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1; + +import java.util.EnumMap; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_21_R1.CraftWorld; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.EntityProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityType; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.utils.EntityConstructors1_21_R1; + +public class EntityProvider1_21_R1 extends EntityProvider { + + private final EnumMap> entityMap = new EnumMap<>(NmsEntityType.class); + + protected EntityProvider1_21_R1(VersionControl1_21_R1 versionControl) { + super(versionControl); + } + + @SuppressWarnings("unchecked") + private final Function searchConstructor(NmsEntityType type) { + try { + return (Function) EntityConstructors1_21_R1.class.getField(type.name()).get(null); + } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignore) { + return null; + } + } + + private final Function getConstructor(NmsEntityType type) { + return entityMap.computeIfAbsent(type, (key -> searchConstructor(key))); + } + + @Override + public NmsEntity createEntity(org.bukkit.World world, NmsEntityType type) { + if (!(world instanceof CraftWorld)) { + return null; + } + Function function; + if ((function = getConstructor(type)) == null) { + return null; + } + return function.apply(((CraftWorld) world).getHandle()); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/PlayerProvider1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/PlayerProvider1_21_R1.java new file mode 100644 index 0000000..62c8d47 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/PlayerProvider1_21_R1.java @@ -0,0 +1,20 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1; + +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.PlayerProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.entity.Player1_21_R1; + +public class PlayerProvider1_21_R1 extends PlayerProvider { + + protected PlayerProvider1_21_R1(VersionControl1_21_R1 versionControl) { + super(versionControl); + } + + @Override + protected NmsPlayer createPlayer(Player player) { + return new Player1_21_R1(player); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/TextureProvider1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/TextureProvider1_21_R1.java new file mode 100644 index 0000000..7ce0f72 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/TextureProvider1_21_R1.java @@ -0,0 +1,100 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_21_R1.block.CraftBlockEntityState; +import org.bukkit.craftbukkit.v1_21_R1.block.CraftSkull; +import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.mojang.authlib.GameProfile; + +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ResolvableProfile; +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.provider.TextureProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; + +public class TextureProvider1_21_R1 extends TextureProvider { + + private final ClassLookup craftEntityStateRef; + private final ClassLookup craftItemStackRef; + private final ClassLookup craftMetaSkullRef; + + protected TextureProvider1_21_R1(VersionControl1_21_R1 versionControl) { + super(versionControl); + ClassLookupProvider provider = versionControl.getLookupProvider(); + craftEntityStateRef = provider.createLookup("CraftBlockEntityState", CraftBlockEntityState.class).searchField("tileEntity", + "tileEntity"); + craftItemStackRef = provider.createLookup("CraftItemStack", CraftItemStack.class).searchField("handle", "handle"); + craftMetaSkullRef = provider.createCBLookup("CraftMetaSkull", "inventory.CraftMetaSkull").searchField("profile", "profile"); + } + + @Override + public GameProfile profileFromBlock(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.gameProfile(); + } + + @Override + public GameProfile profileFromItem(org.bukkit.inventory.ItemStack itemStack) { + if (!(itemStack.getItemMeta() instanceof SkullMeta)) { + return null; + } + SkullMeta meta = (SkullMeta) itemStack.getItemMeta(); + GameProfile profile = (GameProfile) craftMetaSkullRef.getFieldValue(meta, "profile"); + if (profile == null) { + ItemStack stack = null; + if (itemStack instanceof CraftItemStack) { + stack = (ItemStack) craftItemStackRef.getFieldValue(itemStack, "handle"); + } + if (stack == null) { + stack = CraftItemStack.asNMSCopy(itemStack); + } + ResolvableProfile resolved = stack.get(DataComponents.PROFILE); + if (resolved != null) { + profile = resolved.gameProfile(); + } + } + return profile; + } + + @Override + public org.bukkit.inventory.ItemStack getItem(GameProfile profile) { + org.bukkit.inventory.ItemStack craftStack = CraftItemStack.asCraftCopy(new org.bukkit.inventory.ItemStack(Material.PLAYER_HEAD)); + applyItem(craftStack, profile); + return craftStack; + } + + @Override + public boolean applyItem(org.bukkit.inventory.ItemStack itemStack, GameProfile profile) { + ItemMeta meta = itemStack.getItemMeta(); + if (!(meta instanceof SkullMeta)) { + return false; + } + SkullMeta skullMeta = (SkullMeta) meta; + craftMetaSkullRef.setFieldValue(meta, "profile", profile); + itemStack.setItemMeta(skullMeta); + return true; + } + + @Override + public boolean applyBlock(Block block, GameProfile profile) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return false; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + entitySkull.setOwner(new ResolvableProfile(profile)); + return true; + } + +} diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/ToolProvider1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/ToolProvider1_21_R1.java new file mode 100644 index 0000000..eed1379 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/ToolProvider1_21_R1.java @@ -0,0 +1,33 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1; + +import net.sourcewriters.minecraft.vcompat.provider.ToolProvider; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.tools.BlockTools1_21_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.tools.ServerTools1_21_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.tools.SkinTools1_21_R1; + +public class ToolProvider1_21_R1 extends ToolProvider { + + private final BlockTools1_21_R1 blockTools = new BlockTools1_21_R1(); + private final SkinTools1_21_R1 skinTools = new SkinTools1_21_R1(); + private final ServerTools1_21_R1 serverTools = new ServerTools1_21_R1(); + + protected ToolProvider1_21_R1(VersionControl1_21_R1 versionControl) { + super(versionControl); + } + + @Override + public SkinTools1_21_R1 getSkinTools() { + return skinTools; + } + + @Override + public ServerTools1_21_R1 getServerTools() { + return serverTools; + } + + @Override + public BlockTools1_21_R1 getBlockTools() { + return blockTools; + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/VersionControl1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/VersionControl1_21_R1.java new file mode 100644 index 0000000..d6496bf --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/VersionControl1_21_R1.java @@ -0,0 +1,55 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1; + +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.hook.BukkitContainerAdapterHook1_21_R1; + +public class VersionControl1_21_R1 extends VersionControl { + + public static VersionControl1_21_R1 INSTANCE; + + public static VersionControl1_21_R1 init() { + return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionControl1_21_R1()); + } + + private final ToolProvider1_21_R1 toolProvider = new ToolProvider1_21_R1(this); + private final TextureProvider1_21_R1 textureProvider = new TextureProvider1_21_R1(this); + private final EntityProvider1_21_R1 entityProvider = new EntityProvider1_21_R1(this); + private final PlayerProvider1_21_R1 playerProvider = new PlayerProvider1_21_R1(this); + private final BukkitConversion1_21_R1 bukkitConversion = new BukkitConversion1_21_R1(this); + + private VersionControl1_21_R1() { + BukkitContainerAdapterHook1_21_R1.hookEntity(); + } + + @Override + public ToolProvider1_21_R1 getToolProvider() { + return toolProvider; + } + + @Override + public EntityProvider1_21_R1 getEntityProvider() { + return entityProvider; + } + + @Override + public PlayerProvider1_21_R1 getPlayerProvider() { + return playerProvider; + } + + @Override + public TextureProvider1_21_R1 getTextureProvider() { + return textureProvider; + } + + @Override + public BukkitConversion1_21_R1 getBukkitConversion() { + return bukkitConversion; + } + + @Override + public void shutdown() { + dataProvider.getDefaultDistributor().shutdown(); + BukkitContainerAdapterHook1_21_R1.unhookAll(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitContainer1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitContainer1_21_R1.java new file mode 100644 index 0000000..318addb --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitContainer1_21_R1.java @@ -0,0 +1,160 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.NamespacedKey; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; + +public final class BukkitContainer1_21_R1 extends WrappedContainer implements PersistentDataContainer { + + private final IDataContainer container; + + public BukkitContainer1_21_R1(IDataContainer container) { + this.container = container; + } + + @Override + public IDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return container; + } + + /* + * + */ + + @Override + public boolean has(NamespacedKey key, PersistentDataType type) { + return has(new BukkitKey1_21_R1(key), WrappedType1_21_R1.wrap(type)); + } + + @Override + public Z get(NamespacedKey key, PersistentDataType type) { + return get(new BukkitKey1_21_R1(key), WrappedType1_21_R1.wrap(type)); + } + + @Override + public Z getOrDefault(NamespacedKey key, PersistentDataType type, Z value) { + return Optional.ofNullable(get(key, type)).orElse(value); + } + + @Override + public void set(NamespacedKey key, PersistentDataType type, Z value) { + set(new BukkitKey1_21_R1(key), value, WrappedType1_21_R1.wrap(type)); + } + + @Override + public void remove(NamespacedKey key) { + remove(new BukkitKey1_21_R1(key)); + } + + @Override + public Set getKeys() { + return Arrays.stream(container.getKeys()).map(SyntaxKey::new).map(BukkitKey1_21_R1::asBukkit).collect(Collectors.toSet()); + } + + @Override + public PersistentDataAdapterContext getAdapterContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public BukkitContext1_21_R1 getWrapContext() { + return new BukkitContext1_21_R1(container.getContext()); + } + + @Override + public boolean has(String key) { + return has(wrappedKey(key)); + } + + @Override + public boolean has(WrappedKey key) { + return container.has(key.getNamespacedKey()); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public Object get(String key) { + return get(wrappedKey(key)); + } + + @Override + public Object get(WrappedKey key) { + return container.get(key.getNamespacedKey()); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(key.getNamespacedKey(), type.syntaxType()); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(key.getNamespacedKey(), value, type.syntaxType()); + } + + @Override + public boolean remove(String key) { + return false; + } + + @Override + public boolean remove(WrappedKey key) { + return container.remove(key.getNamespacedKey()); + } + + @Override + public Set keySet() { + return container.getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitContext1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitContext1_21_R1.java new file mode 100644 index 0000000..2e01dd2 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitContext1_21_R1.java @@ -0,0 +1,38 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class BukkitContext1_21_R1 extends WrappedContext implements PersistentDataAdapterContext { + + private final IDataAdapterContext context; + + public BukkitContext1_21_R1(IDataAdapterContext context) { + this.context = context; + } + + @Override + public IDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return newWrapContainer(); + } + + @Override + public IDataContainer newContainer() { + return context.newContainer(); + } + + @Override + public BukkitContainer1_21_R1 newWrapContainer() { + return new BukkitContainer1_21_R1(context.newContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitKey1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitKey1_21_R1.java new file mode 100644 index 0000000..e27125f --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitKey1_21_R1.java @@ -0,0 +1,52 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import org.bukkit.NamespacedKey; +import org.bukkit.plugin.Plugin; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; + +public final class BukkitKey1_21_R1 extends WrappedKey { + + private final NamespacedKey key; + + public BukkitKey1_21_R1(Plugin plugin, String key) { + this.key = new NamespacedKey(plugin, key); + } + + @SuppressWarnings("deprecation") + public BukkitKey1_21_R1(String name, String key) { + this.key = new NamespacedKey(name, key); + } + + public BukkitKey1_21_R1(NamespacedKey key) { + this.key = key; + } + + @Override + public NamespacedKey getHandle() { + return key; + } + + @Override + public String getName() { + return key.getNamespace(); + } + + @Override + public String getKey() { + return key.getKey(); + } + + @Override + public String toString() { + return key.toString(); + } + + public static NamespacedKey asBukkit(WrappedKey key) { + if (key.getHandle() instanceof NamespacedKey) { + return (NamespacedKey) key.getHandle(); + } + return new BukkitKey1_21_R1(key.getName(), key.getKey()).getHandle(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitType1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitType1_21_R1.java new file mode 100644 index 0000000..c6eb59c --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/BukkitType1_21_R1.java @@ -0,0 +1,68 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class BukkitType1_21_R1 extends WrappedType1_21_R1, P0, P1, C0, C1> + implements PersistentDataType { + + private final IDataType type; + + public BukkitType1_21_R1(IDataType type) { + super(type.getPrimitive(), type.getComplex()); + this.type = type; + } + + @Override + public IDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitive(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplex(); + } + + /* + * + */ + + @Override + public Class getComplexType() { + return complexType; + } + + @Override + public Class getPrimitiveType() { + return primitiveType; + } + + @Override + public P0 toPrimitive(C0 complex, PersistentDataAdapterContext context) { + return wrapToPrimitive(complex, new SyntaxContext1_21_R1(context)); + } + + @Override + public C0 fromPrimitive(P0 primitive, PersistentDataAdapterContext context) { + return wrapToComplex(primitive, new SyntaxContext1_21_R1(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + return toPrimitiveWrapped(type.toPrimitive(context, toComplexOriginal(complex))); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + return toComplexWrapped(type.fromPrimitive(context, toPrimitiveOriginal(primitive))); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SimpleBukkitType1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SimpleBukkitType1_21_R1.java new file mode 100644 index 0000000..d148cc4 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SimpleBukkitType1_21_R1.java @@ -0,0 +1,36 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public class SimpleBukkitType1_21_R1 implements PersistentDataType { + + private final WrapType type; + + public SimpleBukkitType1_21_R1(WrapType type) { + this.type = type; + } + + @Override + public Class getComplexType() { + return type.getComplexWrapped(); + } + + @Override + public Class

getPrimitiveType() { + return type.getPrimitiveWrapped(); + } + + @Override + public P toPrimitive(C complex, PersistentDataAdapterContext context) { + return type.wrapToPrimitive(complex, new SyntaxContext1_21_R1(context)); + } + + @Override + public C fromPrimitive(P primitive, PersistentDataAdapterContext context) { + return type.wrapToComplex(primitive, new SyntaxContext1_21_R1(context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxContainer1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxContainer1_21_R1.java new file mode 100644 index 0000000..6744ef9 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxContainer1_21_R1.java @@ -0,0 +1,191 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterRegistry; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedKey; +import net.sourcewriters.minecraft.vcompat.provider.data.wrap.SyntaxKey; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.utils.key.IKey; + +public final class SyntaxContainer1_21_R1 extends WrappedContainer implements IDataContainer { + + private final PersistentDataContainer container; + + public SyntaxContainer1_21_R1(PersistentDataContainer container) { + this.container = container; + } + + @Override + public PersistentDataContainer getHandle() { + return container; + } + + @Override + public IDataContainer getAsSyntaxContainer() { + return new SyntaxContainer1_21_R1(container); + } + + @Override + public IDataAdapterRegistry getRegistry() { + return VersionCompatProvider.get().getControl().getDataProvider().getRegistry(); + } + + /* + * + */ + + @Override + public boolean has(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, IDataType type) { + return has(syntaxKey(key), type); + } + + @Override + public boolean has(IKey key, IDataType type) { + return has(new SyntaxKey(key), WrappedType1_21_R1.wrap(type)); + } + + @Override + public C get(String key, IDataType type) { + return get(syntaxKey(key), type); + } + + @Override + public C get(IKey key, IDataType type) { + return get(new SyntaxKey(key), WrappedType1_21_R1.wrap(type)); + } + + @Override + public Object get(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public Object get(IKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public void set(String key, E value, IDataType type) { + set(wrappedKey(key), value, WrappedType1_21_R1.wrap(type)); + } + + @Override + public void set(IKey key, E value, IDataType type) { + set(new SyntaxKey(key), value, WrappedType1_21_R1.wrap(type)); + } + + @Override + public boolean remove(String key) { + return remove(wrappedKey(key)); + } + + @Override + public boolean remove(IKey key) { + return remove(new SyntaxKey(key)); + } + + @Override + public IKey[] getKeys() { + return container.getKeys().stream().map(BukkitKey1_21_R1::new).map(WrappedKey::getNamespacedKey).toArray(IKey[]::new); + } + + @Override + public Set getKeyspaces() { + return container.getKeys().stream().map(org.bukkit.NamespacedKey::toString).collect(Collectors.toSet()); + } + + @Override + public IDataAdapterContext getContext() { + return getWrapContext(); + } + + /* + * + */ + + @Override + public SyntaxContext1_21_R1 getWrapContext() { + return new SyntaxContext1_21_R1(container.getAdapterContext()); + } + + @Override + public boolean has(String key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public boolean has(String key, WrapType type) { + return has(wrappedKey(key), type); + } + + @Override + public boolean has(WrappedKey key, WrapType type) { + return container.has(BukkitKey1_21_R1.asBukkit(key), new SimpleBukkitType1_21_R1<>(type)); + } + + @Override + public Object get(WrappedKey key) { + throw new UnsupportedOperationException("Can't be used with PersistentDataContainer of Bukkit"); + } + + @Override + public C get(String key, WrapType type) { + return get(wrappedKey(key), type); + } + + @Override + public C get(WrappedKey key, WrapType type) { + return container.get(BukkitKey1_21_R1.asBukkit(key), new SimpleBukkitType1_21_R1<>(type)); + } + + @Override + public void set(String key, B value, WrapType type) { + set(wrappedKey(key), value, type); + } + + @Override + public void set(WrappedKey key, B value, WrapType type) { + container.set(BukkitKey1_21_R1.asBukkit(key), new SimpleBukkitType1_21_R1<>(type), value); + } + + @Override + public boolean remove(WrappedKey key) { + container.remove(BukkitKey1_21_R1.asBukkit(key)); + return true; // Will always return true as we don't know if it contained it + } + + @Override + public Set keySet() { + return getKeyspaces(); + } + + @Override + public boolean isEmpty() { + return container.isEmpty(); + } + + @Override + public int size() { + return container.getKeys().size(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxContext1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxContext1_21_R1.java new file mode 100644 index 0000000..7667a94 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxContext1_21_R1.java @@ -0,0 +1,37 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataContainer; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public final class SyntaxContext1_21_R1 extends WrappedContext implements PersistentDataAdapterContext { + + private final PersistentDataAdapterContext context; + + public SyntaxContext1_21_R1(PersistentDataAdapterContext context) { + this.context = context; + } + + @Override + public PersistentDataAdapterContext getHandle() { + return context; + } + + @Override + public PersistentDataContainer newPersistentDataContainer() { + return context.newPersistentDataContainer(); + } + + @Override + public IDataContainer newContainer() { + return newWrapContainer(); + } + + @Override + public SyntaxContainer1_21_R1 newWrapContainer() { + return new SyntaxContainer1_21_R1(context.newPersistentDataContainer()); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxType1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxType1_21_R1.java new file mode 100644 index 0000000..8588c82 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/SyntaxType1_21_R1.java @@ -0,0 +1,75 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataAdapterContext; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContext; + +public class SyntaxType1_21_R1 extends WrappedType1_21_R1, P0, P1, C0, C1> + implements IDataType { + + private final PersistentDataType type; + + public SyntaxType1_21_R1(PersistentDataType type) { + super(type.getPrimitiveType(), type.getComplexType()); + this.type = type; + } + + @Override + public PersistentDataType getHandle() { + return type; + } + + @Override + public Class getPrimitiveOriginal() { + return type.getPrimitiveType(); + } + + @Override + public Class getComplexOriginal() { + return type.getComplexType(); + } + + /* + * + */ + + @Override + public Class getComplex() { + return complexType; + } + + @Override + public Class getPrimitive() { + return primitiveType; + } + + @Override + public P0 toPrimitive(IDataAdapterContext context, C0 complex) { + return wrapToPrimitive(complex, new BukkitContext1_21_R1(context)); + } + + @Override + public C0 fromPrimitive(IDataAdapterContext context, P0 primitive) { + return wrapToComplex(primitive, new BukkitContext1_21_R1(context)); + } + + @Override + public P0 wrapToPrimitive(C0 complex, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toPrimitiveWrapped(type.toPrimitive(toComplexOriginal(complex), (PersistentDataAdapterContext) context)); + } + + @Override + public C0 wrapToComplex(P0 primitive, WrappedContext context) { + if (!(context instanceof PersistentDataAdapterContext)) { + return null; + } + return toComplexWrapped(type.fromPrimitive(toPrimitiveOriginal(primitive), (PersistentDataAdapterContext) context)); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/WrappedType1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/WrappedType1_21_R1.java new file mode 100644 index 0000000..a106eec --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/WrappedType1_21_R1.java @@ -0,0 +1,149 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data; + +import java.util.Arrays; + +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.api.IDataType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; + +public abstract class WrappedType1_21_R1 implements WrapType { + + protected final Class primitiveType; + protected final Class complexType; + + private final int primitiveWrap; + private final int complexWrap; + + @SuppressWarnings("unchecked") + protected WrappedType1_21_R1(Class primitive, Class complex) { + this.primitiveWrap = WrappedType1_21_R1.internalState(primitive); + this.complexWrap = WrappedType1_21_R1.internalState(complex); + this.primitiveType = (Class) WrappedType1_21_R1.internalWrap(primitive, primitiveWrap); + this.complexType = (Class) WrappedType1_21_R1.internalWrap(complex, complexWrap); + } + + public abstract H getHandle(); + + public Class getPrimitiveWrapped() { + return primitiveType; + } + + public Class getComplexWrapped() { + return complexType; + } + + public abstract Class getPrimitiveOriginal(); + + public abstract Class getComplexOriginal(); + + @SuppressWarnings("unchecked") + public P0 toPrimitiveWrapped(P1 primitive) { + switch (primitiveWrap) { + case 1: + return (P0) new SyntaxContainer1_21_R1((PersistentDataContainer) primitive); + case 2: + return (P0) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_21_R1::new) + .toArray(SyntaxContainer1_21_R1[]::new); + case 3: + return (P0) new BukkitContainer1_21_R1((IDataContainer) primitive); + case 4: + return (P0) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_21_R1::new) + .toArray(BukkitContainer1_21_R1[]::new); + default: + return (P0) primitive; + } + } + + @SuppressWarnings("unchecked") + public C0 toComplexWrapped(C1 complex) { + switch (complexWrap) { + case 1: + return (C0) new SyntaxContainer1_21_R1((PersistentDataContainer) complex); + case 2: + return (C0) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_21_R1::new).toArray(SyntaxContainer1_21_R1[]::new); + case 3: + return (C0) new BukkitContainer1_21_R1((IDataContainer) complex); + case 4: + return (C0) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_21_R1::new).toArray(BukkitContainer1_21_R1[]::new); + default: + return (C0) complex; + } + } + + @SuppressWarnings("unchecked") + public P1 toPrimitiveOriginal(P0 primitive) { + switch (primitiveWrap) { + case 1: + return (P1) new BukkitContainer1_21_R1((IDataContainer) primitive); + case 2: + return (P1) Arrays.stream((IDataContainer[]) primitive).map(BukkitContainer1_21_R1::new) + .toArray(BukkitContainer1_21_R1[]::new); + case 3: + return (P1) new SyntaxContainer1_21_R1((PersistentDataContainer) primitive); + case 4: + return (P1) Arrays.stream((PersistentDataContainer[]) primitive).map(SyntaxContainer1_21_R1::new) + .toArray(SyntaxContainer1_21_R1[]::new); + default: + return (P1) primitive; + } + } + + @SuppressWarnings("unchecked") + public C1 toComplexOriginal(C0 complex) { + switch (complexWrap) { + case 1: + return (C1) new BukkitContainer1_21_R1((IDataContainer) complex); + case 2: + return (C1) Arrays.stream((IDataContainer[]) complex).map(BukkitContainer1_21_R1::new).toArray(BukkitContainer1_21_R1[]::new); + case 3: + return (C1) new SyntaxContainer1_21_R1((PersistentDataContainer) complex); + case 4: + return (C1) Arrays.stream((PersistentDataContainer[]) complex).map(SyntaxContainer1_21_R1::new).toArray(SyntaxContainer1_21_R1[]::new); + default: + return (C1) complex; + } + } + + protected static Class internalWrap(Class clazz, int state) { + switch (state) { + case 1: + return SyntaxContainer1_21_R1.class; + case 2: + return SyntaxContainer1_21_R1[].class; + case 3: + return BukkitContainer1_21_R1.class; + case 4: + return BukkitContainer1_21_R1[].class; + default: + return clazz; + } + } + + protected static int internalState(Class clazz) { + if (clazz.isAssignableFrom(PersistentDataContainer.class)) { + return 1; + } + if (clazz.isAssignableFrom(PersistentDataContainer[].class)) { + return 2; + } + if (clazz.isAssignableFrom(IDataContainer.class)) { + return 3; + } + if (clazz.isAssignableFrom(IDataContainer[].class)) { + return 4; + } + return 0; + } + + public static BukkitType1_21_R1 wrap(IDataType type) { + return new BukkitType1_21_R1<>(type); + } + + public static SyntaxType1_21_R1 wrap(PersistentDataType type) { + return new SyntaxType1_21_R1<>(type); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/hook/BukkitContainerAdapterHook1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/hook/BukkitContainerAdapterHook1_21_R1.java new file mode 100644 index 0000000..00802c8 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/data/hook/BukkitContainerAdapterHook1_21_R1.java @@ -0,0 +1,140 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.hook; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +import org.bukkit.craftbukkit.v1_21_R1.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_21_R1.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.v1_21_R1.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.persistence.PersistentDataContainer; + +import net.minecraft.nbt.CompoundTag; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.data.api.IDataContainer; +import net.sourcewriters.minecraft.vcompat.data.nbt.NbtContainer; +import net.sourcewriters.minecraft.vcompat.provider.VersionControl; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.BukkitContainer1_21_R1; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.SyntaxContainer1_21_R1; +import net.sourcewriters.minecraft.vcompat.provider.lookup.ClassLookupProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.shaded.syntaxapi.nbt.NbtCompound; + +@SuppressWarnings({ + "rawtypes", + "unchecked" +}) +public final class BukkitContainerAdapterHook1_21_R1 { + + private static final BukkitContainerAdapterHook1_21_R1 HOOK = new BukkitContainerAdapterHook1_21_R1(); + + private final ClassLookup registryRef; + private final ClassLookup entityRef; + + private BukkitContainerAdapterHook1_21_R1() { + if (HOOK != null) { + throw new UnsupportedOperationException(); + } + ClassLookupProvider provider = VersionCompatProvider.get().getLookupProvider(); + registryRef = provider.createLookup("CraftPersistentDataTypeRegistry", CraftPersistentDataTypeRegistry.class) + .searchMethod("create", "createAdapter", Class.class, Class.class, Function.class, Function.class) + .searchField("adapters", "adapters").searchField("function", "CREATE_ADAPTER"); + entityRef = provider.createLookup("CraftEntity", CraftEntity.class).searchField("registry", "DATA_TYPE_REGISTRY"); + } + + private final HashMap map = new HashMap<>(); + + private CraftPersistentDataTypeRegistry getEntityRegistry() { + return (CraftPersistentDataTypeRegistry) entityRef.getFieldValue("registry"); + } + + private void uninjectAll() { + for (CraftPersistentDataTypeRegistry registry : map.keySet()) { + Map adapters = (Map) registryRef.getFieldValue(registry, "adapters"); + adapters.remove(BukkitContainer1_21_R1.class); + adapters.remove(SyntaxContainer1_21_R1.class); + registryRef.setFieldValue(registry, "function", map.get(registry)); + } + map.clear(); + } + + private void inject(CraftPersistentDataTypeRegistry registry) { + if (map.containsKey(registry)) { + return; + } + map.put(registry, (Function) registryRef.getFieldValue(registry, "function")); + Function function = clazz -> createAdapter(registry, registryRef.getMethod("create").getReturnType(), (Class) clazz); + registryRef.setFieldValue(registry, "function", function); + } + + private E createAdapter(CraftPersistentDataTypeRegistry registry, Class adapterType, Class type) { + if (Objects.equals(BukkitContainer1_21_R1.class, type)) { + return (E) buildAdapter(registry, BukkitContainer1_21_R1.class, tag -> fromPrimitiveSyntax(tag)); + } + if (Objects.equals(SyntaxContainer1_21_R1.class, type)) { + return (E) buildAdapter(registry, SyntaxContainer1_21_R1.class, tag -> fromPrimitiveBukkit(registry, tag)); + } + return (E) map.get(registry).apply(type); + } + + private Object buildAdapter(Object handle, Class type, Function function) { + return registryRef.run(handle, "create", type, CompoundTag.class, (Function) input -> toPrimitive(input), function); + } + + private CompoundTag toPrimitive(WrappedContainer input) { + Object handle = findFinalContainer(input).getHandle(); + if (handle instanceof PersistentDataContainer) { + if (handle instanceof CraftPersistentDataContainer) { + return ((CraftPersistentDataContainer) handle).toTagCompound(); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + if (handle instanceof IDataContainer) { + if (handle instanceof NbtContainer) { + return (CompoundTag) VersionCompatProvider.get().getControl().getBukkitConversion() + .toMinecraftCompound(((NbtContainer) handle).asNbt()); + } + throw new IllegalArgumentException( + "Expected 'CraftPersistentDataContainer' got '" + handle.getClass().getSimpleName() + " instead'!"); + } + throw new IllegalArgumentException("Unknown WrappedContainer implementation!"); + } + + private BukkitContainer1_21_R1 fromPrimitiveSyntax(CompoundTag data) { + VersionControl control = VersionCompatProvider.get().getControl(); + NbtContainer container = new NbtContainer(control.getDataProvider().getRegistry()); + NbtCompound compound = control.getBukkitConversion().fromMinecraftCompound(data); + container.fromNbt(compound); + return new BukkitContainer1_21_R1(container); + } + + private SyntaxContainer1_21_R1 fromPrimitiveBukkit(CraftPersistentDataTypeRegistry registry, CompoundTag data) { + CraftPersistentDataContainer container = new CraftPersistentDataContainer(registry); + container.putAll(data); + return new SyntaxContainer1_21_R1(container); + } + + private WrappedContainer findFinalContainer(WrappedContainer container) { + WrappedContainer output = container; + while (output.getHandle() instanceof WrappedContainer) { + output = (WrappedContainer) output.getHandle(); + } + return output; + } + + public static void unhookAll() { + HOOK.uninjectAll(); + } + + public static void hookEntity() { + HOOK.inject(HOOK.getEntityRegistry()); + } + + public static void hook(CraftPersistentDataTypeRegistry registry) { + HOOK.inject(registry); + } + +} diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/ArmorStand1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/ArmorStand1_21_R1.java new file mode 100644 index 0000000..deed17f --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/ArmorStand1_21_R1.java @@ -0,0 +1,24 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.entity; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsArmorStand; + +public class ArmorStand1_21_R1 extends EntityLiving1_21_R1 implements NmsArmorStand { + + public ArmorStand1_21_R1(Level world) { + super(new ArmorStand(EntityType.ARMOR_STAND, world)); + } + + @Override + public void setSmall(boolean small) { + handle.setSmall(small); + } + + @Override + public boolean isSmall() { + return handle.isSmall(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/Entity1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/Entity1_21_R1.java new file mode 100644 index 0000000..2fa5033 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/Entity1_21_R1.java @@ -0,0 +1,220 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_21_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_21_R1.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntity; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.utils.NmsBoundingBox; + +public abstract class Entity1_21_R1 implements NmsEntity { + + private static final ClassLookup ENTITY_REF = VersionCompatProvider.get().getLookupProvider().createLookup("Entity", Entity.class).searchMethodsByArguments("setLevel", Level.class); + + protected final E handle; + + protected final List visible = Collections.synchronizedList(new ArrayList<>()); + + public Entity1_21_R1(E handle) { + this.handle = handle; + } + + @Override + public final E getHandle() { + return handle; + } + + @Override + public int getId() { + return handle.getId(); + } + + @Override + public UUID getUniqueId() { + return handle.getUUID(); + } + + @Override + public NmsBoundingBox getBoundingBox() { + AABB box = handle.getBoundingBox(); + return new NmsBoundingBox(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ); + } + + @Override + public void setCustomName(String name) { + handle.setCustomName(CraftChatMessage.fromStringOrNull(name)); + updateVisibility(); + } + + @Override + public String getCustomName() { + return CraftChatMessage.fromComponent(handle.getCustomName()); + } + + @Override + public void setGravity(boolean gravity) { + handle.setNoGravity(!gravity); + } + + @Override + public boolean hasGravity() { + return !handle.isNoGravity(); + } + + @Override + public void setCustomNameVisible(boolean visible) { + handle.setCustomNameVisible(visible); + } + + @Override + public boolean isCustomNameVisible() { + return handle.isCustomNameVisible(); + } + + @Override + public void setInvisible(boolean invisible) { + handle.setInvisible(invisible); + } + + @Override + public boolean isInvisible() { + return handle.isInvisible(); + } + + @Override + public boolean isInteractable() { + return handle.isPushable(); + } + + @Override + public boolean isCollidable() { + return handle.canBeCollidedWith(); + } + + @Override + public void setInvulnerable(boolean invulnerable) { + handle.setInvulnerable(invulnerable); + } + + @Override + public boolean isInvulnerable() { + return handle.isInvulnerable(); + } + + @Override + public void setLocation(Location location) { + handle.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + if (location.getWorld() == null || handle.getCommandSenderWorld().getWorld() == location.getWorld()) { + updateVisibility(); + return; + } + ENTITY_REF.execute(handle, "setLevel", ((CraftWorld) location.getWorld()).getHandle()); + updateVisibility(); + } + + @Override + public Location getLocation() { + Vec3 vector = handle.position(); + return new Location(handle.getCommandSenderWorld().getWorld(), vector.x, vector.y, vector.z); + } + + @Override + public void updateVisibility() { + if (visible.isEmpty()) { + return; + } + Player[] players; + synchronized (visible) { + players = visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + hide(players); + show(players); + } + + @Override + public boolean isShown(Player player) { + synchronized (visible) { + return visible.contains(player.getUniqueId()); + } + } + + @Override + public void hide(Player... players) { + if (players.length == 0) { + return; + } + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(handle.getId()); + for (Player player : players) { + if (!isShown(player)) { + continue; + } + ((CraftPlayer) player).getHandle().connection.send(packet); + synchronized (visible) { + visible.remove(player.getUniqueId()); + } + } + } + + @Override + public void show(Player... players) { + if (players.length == 0) { + return; + } + ClientboundAddEntityPacket packet = new ClientboundAddEntityPacket(handle, 0, handle.blockPosition()); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + ServerGamePacketListenerImpl connection; + for (Player player : players) { + if (isShown(player)) { + continue; + } + connection = ((CraftPlayer) player).getHandle().connection; + connection.send(packet); + connection.send(metadataPacket); + synchronized (visible) { + visible.add(player.getUniqueId()); + } + } + } + + @Override + public UUID[] getVisible() { + synchronized (visible) { + return visible.toArray(new UUID[0]); + } + } + + @Override + public Player[] getVisibleAsPlayer() { + synchronized (visible) { + return visible.stream().map(Bukkit::getOfflinePlayer).filter(OfflinePlayer::isOnline).map(OfflinePlayer::getPlayer) + .toArray(Player[]::new); + } + } + + @Override + public void kill() { + hide(getVisibleAsPlayer()); + handle.kill(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/EntityLiving1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/EntityLiving1_21_R1.java new file mode 100644 index 0000000..b110ef1 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/EntityLiving1_21_R1.java @@ -0,0 +1,17 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.entity; + +import net.minecraft.world.entity.LivingEntity; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsEntityLiving; + +public abstract class EntityLiving1_21_R1 extends Entity1_21_R1 implements NmsEntityLiving { + + public EntityLiving1_21_R1(E handle) { + super(handle); + } + + @Override + public void setCollidable(boolean collidable) { + handle.collides = collidable; + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/Player1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/Player1_21_R1.java new file mode 100644 index 0000000..9edd285 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/entity/Player1_21_R1.java @@ -0,0 +1,293 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.entity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_21_R1.util.CraftChatMessage; +import org.bukkit.entity.Player; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; +import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; +import net.minecraft.network.protocol.game.ClientboundTabListPacket; +import net.minecraft.network.protocol.game.ServerboundClientCommandPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.data.WrapType; +import net.sourcewriters.minecraft.vcompat.provider.data.WrappedContainer; +import net.sourcewriters.minecraft.vcompat.provider.data.type.SkinDataType; +import net.sourcewriters.minecraft.vcompat.provider.entity.NmsPlayer; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.data.SyntaxContainer1_21_R1; +import net.sourcewriters.minecraft.vcompat.util.bukkit.Players; +import net.sourcewriters.minecraft.vcompat.util.minecraft.MojangProfileServer; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; +import net.sourcewriters.minecraft.vcompat.util.thread.PostAsync; + +public class Player1_21_R1 extends EntityLiving1_21_R1 implements NmsPlayer { + + private String realName; + private Skin realSkin; + + private final WrappedContainer dataAdapter; + + public Player1_21_R1(Player player) { + super(((CraftPlayer) player).getHandle()); + dataAdapter = new SyntaxContainer1_21_R1(getBukkitPlayer().getPersistentDataContainer()); + update(false); + } + + @Override + public CraftPlayer getBukkitPlayer() { + return handle.getBukkitEntity(); + } + + @Override + public WrappedContainer getDataAdapter() { + return dataAdapter; + } + + @Override + public void setSkin(Skin skin) { + if (skin == null) { + return; + } + dataAdapter.set("skin", skin, SkinDataType.WRAPPED_INSTANCE); + } + + @Override + public Skin getSkin() { + return dataAdapter.getOrDefault("skin", SkinDataType.WRAPPED_INSTANCE, realSkin); + } + + @Override + public Skin getRealSkin() { + return realSkin; + } + + @Override + public void setName(String name) { + if (getName().equals(name)) { + return; + } + if (name == null) { + dataAdapter.remove("name"); + return; + } + dataAdapter.set("name", name, WrapType.STRING); + } + + @Override + public String getName() { + return dataAdapter.getOrDefault("name", WrapType.STRING, realName); + } + + @Override + public String getRealName() { + return realName; + } + + @Override + public void setPlayerListHeader(String text) { + setPlayerListHeaderAndFooter(text, getPlayerListFooter()); + } + + @Override + public String getPlayerListHeader() { + return dataAdapter.getOrDefault("header", WrapType.STRING, ""); + } + + @Override + public void setPlayerListFooter(String text) { + setPlayerListHeaderAndFooter(getPlayerListHeader(), text); + } + + @Override + public String getPlayerListFooter() { + return dataAdapter.getOrDefault("footer", WrapType.STRING, ""); + } + + @Override + public int getPing() { + return handle.connection.latency(); + } + + @Override + public void setPlayerListHeaderAndFooter(String header, String footer) { + dataAdapter.set("header", header, WrapType.STRING); + dataAdapter.set("footer", footer, WrapType.STRING); + sendPlayerListInfo(header, footer); + } + + private final void sendPlayerListInfo(String header, String footer) { + if (handle.hasDisconnected()) { + return; + } + + Component headerComponent = header.isEmpty() ? null : CraftChatMessage.fromStringOrNull(header, true); + Component footerComponent = footer.isEmpty() ? null : CraftChatMessage.fromStringOrNull(footer, true); + + handle.connection.send(new ClientboundTabListPacket(headerComponent, footerComponent)); + } + + @Override + public void setTitleTimes(int fadeIn, int stay, int fadeOut) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitlesAnimationPacket(fadeIn, stay, fadeOut)); + } + + @Override + public void sendSubtitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetSubtitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendTitle(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetTitleTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void sendActionBar(String text) { + if (handle.hasDisconnected()) { + return; + } + handle.connection.send(new ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(text))); + } + + @Override + public void fakeRespawn() { + if (handle.hasDisconnected()) { + return; + } + ClientboundPlayerInfoRemovePacket remInfoPacket = new ClientboundPlayerInfoRemovePacket(Arrays.asList(handle.getUUID())); + ClientboundPlayerInfoUpdatePacket addInfoPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Arrays.asList(handle)); + + ClientboundRemoveEntitiesPacket destroyPacket = new ClientboundRemoveEntitiesPacket(handle.getId()); + + ClientboundRotateHeadPacket rotationPacket = new ClientboundRotateHeadPacket(handle, + (byte) Mth.floor(handle.getYHeadRot() * 256F / 360F)); + ClientboundMoveEntityPacket.Rot moreRotationPacket = new ClientboundMoveEntityPacket.Rot(handle.getId(), + (byte) (handle.getYHeadRot() * 256 / 360), (byte) (handle.getXRot() * 256 / 360), true); + + ArrayList> list = new ArrayList<>(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + list.add(Pair.of(slot, handle.getItemBySlot(slot))); + } + ClientboundSetEquipmentPacket equipmentPacket = new ClientboundSetEquipmentPacket(handle.getId(), list); + ClientboundSetEntityDataPacket metadataPacket = new ClientboundSetEntityDataPacket(handle.getId(), handle.getEntityData().getNonDefaultValues()); + + Player self = getBukkitPlayer(); + Player[] players = Players.getOnlineWithout(getUniqueId()); + for (Player player : players) { + if (!player.canSee(self)) { + continue; + } + ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(destroyPacket); + connection.send(rotationPacket); + connection.send(moreRotationPacket); + connection.send(equipmentPacket); + connection.send(metadataPacket); + } + + ServerLevel world = (ServerLevel) handle.level(); + ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(handle.createCommonSpawnInfo(world), ClientboundRespawnPacket.KEEP_ALL_DATA); + ClientboundPlayerPositionPacket positionPacket = new ClientboundPlayerPositionPacket(handle.getX(), handle.getY(), handle.getZ(), + handle.xRotO, handle.yRotO, Collections.emptySet(), 0); + ClientboundSetCarriedItemPacket itemPacket = new ClientboundSetCarriedItemPacket(handle.getInventory().selected); + ClientboundEntityEventPacket statusPacket = new ClientboundEntityEventPacket(handle, (byte) 28); + + ServerGamePacketListenerImpl connection = handle.connection; + connection.send(remInfoPacket); + connection.send(addInfoPacket); + connection.send(respawnPacket); + connection.send(positionPacket); + connection.send(itemPacket); + connection.send(statusPacket); + connection.send(metadataPacket); + + handle.onUpdateAbilities(); + handle.resetSentInfo(); + handle.inventoryMenu.broadcastChanges(); + handle.inventoryMenu.sendAllDataToRemote(); + if (handle.containerMenu != handle.inventoryMenu) { + handle.containerMenu.broadcastChanges(); + handle.containerMenu.sendAllDataToRemote(); + } + self.recalculatePermissions(); + } + + @Override + public void respawn() { + if (handle.connection.isDisconnected()) { + return; + } + handle.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN)); + } + + @Override + public void update() { + update(true); + } + + private final void update(boolean flag) { + PostAsync.forcePost(() -> { + realName = MojangProfileServer.getName(getUniqueId()); + realSkin = MojangProfileServer.getSkin(realName, getUniqueId()); + }); + if (flag) { + GameProfile profile = handle.getGameProfile(); + + Skin skin = getSkin(); + if (skin != null) { + PropertyMap properties = profile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + } + + String name = dataAdapter.get("name", WrapType.STRING); + if (name != null && !name.isBlank()) { + VersionCompatProvider.get().getLookupProvider().getLookup("mjGameProfile").setFieldValue(profile, "name", name); + } + + if (!(name == null && skin == null)) { + fakeRespawn(); + } + } + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/BlockTools1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/BlockTools1_21_R1.java new file mode 100644 index 0000000..5955fc5 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/BlockTools1_21_R1.java @@ -0,0 +1,47 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.tools; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.v1_21_R1.block.CraftSkull; + +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; + +import net.minecraft.world.level.block.entity.SkullBlockEntity; +import net.sourcewriters.minecraft.vcompat.VersionCompatProvider; +import net.sourcewriters.minecraft.vcompat.provider.lookup.handle.ClassLookup; +import net.sourcewriters.minecraft.vcompat.provider.tools.BlockTools; +import net.sourcewriters.minecraft.vcompat.util.constants.MinecraftConstants; + +public class BlockTools1_21_R1 extends BlockTools { + + private final ClassLookup craftEntityStateRef; + + public BlockTools1_21_R1() { + craftEntityStateRef = VersionCompatProvider.get().getLookupProvider().createLookup("CraftSkull", CraftSkull.class) + .searchField("tileEntity", "tileEntity"); + } + + @Override + public void setHeadTexture(Block block, String texture) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + PropertyMap map = entitySkull.owner.properties(); + map.removeAll("textures"); + map.put("textures", new Property("textures", MinecraftConstants.TEXTURE_SIGNATURE, texture)); + } + + @Override + public String getHeadTexture(Block block) { + BlockState state = block.getState(); + if (!(state instanceof CraftSkull)) { + return null; + } + SkullBlockEntity entitySkull = (SkullBlockEntity) craftEntityStateRef.getFieldValue(state, "tileEntity"); + return entitySkull.owner.properties().get("textures").iterator().next().getValue(); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/ServerTools1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/ServerTools1_21_R1.java new file mode 100644 index 0000000..5f7dbcc --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/ServerTools1_21_R1.java @@ -0,0 +1,31 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.tools; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_21_R1.CraftServer; + +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.wrapper.ConsoleReaderWrapper1_21_R1; +import net.sourcewriters.minecraft.vcompat.provider.tools.ServerTools; + +public class ServerTools1_21_R1 extends ServerTools { + + @Override + public void setMotd(String text) { + ((CraftServer) Bukkit.getServer()).getServer().setMotd(text); + } + + @Override + public String getMotd() { + return ((CraftServer) Bukkit.getServer()).getServer().getMotd(); + } + + @Override + public String getLevelName() { + return ((CraftServer) Bukkit.getServer()).getServer().getProperties().levelName; + } + + @Override + public ConsoleReaderWrapper1_21_R1 getConsole() { + return ConsoleReaderWrapper1_21_R1.INSTANCE; + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/SkinTools1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/SkinTools1_21_R1.java new file mode 100644 index 0000000..502295c --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/tools/SkinTools1_21_R1.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.tools; + +import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import net.sourcewriters.minecraft.vcompat.provider.tools.SkinTools; +import net.sourcewriters.minecraft.vcompat.util.minecraft.Skin; + +public class SkinTools1_21_R1 extends SkinTools { + + @Override + public Skin skinFromPlayer(Player player) { + return skinFromGameProfile(((CraftPlayer) player).getHandle().getGameProfile()); + } + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/utils/EntityConstructors1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/utils/EntityConstructors1_21_R1.java new file mode 100644 index 0000000..037ecf3 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/utils/EntityConstructors1_21_R1.java @@ -0,0 +1,16 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.utils; + +import java.util.function.Function; + +import net.minecraft.world.level.Level; +import net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.entity.ArmorStand1_21_R1; + +public final class EntityConstructors1_21_R1 { + + private EntityConstructors1_21_R1() { + throw new UnsupportedOperationException(); + } + + public static final Function ARMOR_STAND = (world -> new ArmorStand1_21_R1(world)); + +} \ No newline at end of file diff --git a/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/wrapper/ConsoleReaderWrapper1_21_R1.java b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/wrapper/ConsoleReaderWrapper1_21_R1.java new file mode 100644 index 0000000..4a7f7d0 --- /dev/null +++ b/vcompat-1_21_R1/src/main/java/net/sourcewriters/minecraft/vcompat/provider/impl/v1_21_R1/wrapper/ConsoleReaderWrapper1_21_R1.java @@ -0,0 +1,51 @@ +package net.sourcewriters.minecraft.vcompat.provider.impl.v1_21_R1.wrapper; + +import java.io.IOException; +import java.io.Writer; + +import org.bukkit.Bukkit; + +import net.sourcewriters.minecraft.vcompat.provider.wrapper.ConsoleReaderWrapper; + +import org.bukkit.craftbukkit.Main; +import org.bukkit.craftbukkit.v1_21_R1.CraftServer; + +import jline.console.ConsoleReader; + +public final class ConsoleReaderWrapper1_21_R1 extends ConsoleReaderWrapper { + + public static final ConsoleReaderWrapper1_21_R1 INSTANCE = new ConsoleReaderWrapper1_21_R1(); + + private final ConsoleReader reader; + + @SuppressWarnings("resource") + private ConsoleReaderWrapper1_21_R1() { + this.reader = ((CraftServer) Bukkit.getServer()).getServer().reader; + } + + @Override + public Writer getOutput() { + return reader.getOutput(); + } + + @Override + public boolean isAnsiSupported() { + return reader.getTerminal().isAnsiSupported(); + } + + @Override + public void flush() throws IOException { + reader.flush(); + } + + @Override + public void drawLine() throws IOException { + reader.drawLine(); + } + + @Override + public boolean isJLineSupported() { + return Main.useJline; + } + +} diff --git a/vcompat-api/pom.xml b/vcompat-api/pom.xml index 36a2d67..cd998a2 100644 --- a/vcompat-api/pom.xml +++ b/vcompat-api/pom.xml @@ -3,7 +3,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat-api diff --git a/vcompat-api/pom.xml.versionsBackup b/vcompat-api/pom.xml.versionsBackup new file mode 100644 index 0000000..36a2d67 --- /dev/null +++ b/vcompat-api/pom.xml.versionsBackup @@ -0,0 +1,94 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-api + + + + + + + com.syntaxphoenix.syntaxapi + java + 2.0.14 + + + com.syntaxphoenix.syntaxapi + nbt + 2.0.12 + + + com.syntaxphoenix.syntaxapi + version + 2.0.12 + + + com.syntaxphoenix.syntaxapi + key + 2.0.11 + + + com.syntaxphoenix.syntaxapi + random + 2.0.11 + + + com.syntaxphoenix.syntaxapi + logging + 2.0.11 + + + com.syntaxphoenix.syntaxapi + json-lib + 2.0.11 + + + + + + jline + jline + 2.12.1 + provided + + + + + + + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + com.syntaxphoenix.syntaxapi + net.sourcewriters.minecraft.vcompat.shaded.syntaxapi + + + + + + + \ No newline at end of file diff --git a/vcompat-core/pom.xml b/vcompat-core/pom.xml index f1705c4..207cf96 100644 --- a/vcompat-core/pom.xml +++ b/vcompat-core/pom.xml @@ -3,7 +3,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat @@ -44,6 +44,41 @@ vcompat-1_19_R1 ${project.parent.version} + + net.sourcewriters.minecraft + vcompat-1_19_R2 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_19_R3 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_20_R1 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_20_R2 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_20_R3 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_20_R4 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_21_R1 + ${project.parent.version} + diff --git a/vcompat-core/pom.xml.versionsBackup b/vcompat-core/pom.xml.versionsBackup new file mode 100644 index 0000000..f1705c4 --- /dev/null +++ b/vcompat-core/pom.xml.versionsBackup @@ -0,0 +1,91 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat + + + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + + + + + + net.sourcewriters.minecraft + vcompat-legacy + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_17_R1 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_18_R1 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_18_R2 + ${project.parent.version} + + + net.sourcewriters.minecraft + vcompat-1_19_R1 + ${project.parent.version} + + + + + + + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + com.syntaxphoenix.syntaxapi + net.sourcewriters.minecraft.vcompat.shaded.syntaxapi + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.0.0-M2 + + false + + + + + \ No newline at end of file diff --git a/vcompat-legacy/pom.xml b/vcompat-legacy/pom.xml index 1c40646..2221b6a 100644 --- a/vcompat-legacy/pom.xml +++ b/vcompat-legacy/pom.xml @@ -3,7 +3,7 @@ net.sourcewriters.minecraft vcompat-parent - 3.0.6 + 3.0.7 vcompat-legacy diff --git a/vcompat-legacy/pom.xml.versionsBackup b/vcompat-legacy/pom.xml.versionsBackup new file mode 100644 index 0000000..1c40646 --- /dev/null +++ b/vcompat-legacy/pom.xml.versionsBackup @@ -0,0 +1,130 @@ + + 4.0.0 + + net.sourcewriters.minecraft + vcompat-parent + 3.0.6 + + vcompat-legacy + + + ${project.basedir}/../libraries/spigot + + + + + net.sourcewriters.minecraft + vcompat-api + ${project.parent.version} + provided + + + + + + bukkit + spigot-1.16.4 + 0.1 + system + ${spigot.libPath}/spigot-1.16.4.jar + + + bukkit + spigot-1.16.3 + 0.1 + system + ${spigot.libPath}/spigot-1.16.3.jar + + + bukkit + spigot-1.16.1 + 0.1 + system + ${spigot.libPath}/spigot-1.16.1.jar + + + bukkit + spigot-1.15.2 + 0.1 + system + ${spigot.libPath}/spigot-1.15.2.jar + + + bukkit + spigot-1.14.2 + 0.1 + system + ${spigot.libPath}/spigot-1.14.2.jar + + + bukkit + spigot-1.13.2 + 0.1 + system + ${spigot.libPath}/spigot-1.13.2.jar + + + bukkit + spigot-1.13 + 0.1 + system + ${spigot.libPath}/spigot-1.13.jar + + + bukkit + spigot-1.12.2 + 0.1 + system + ${spigot.libPath}/spigot-1.12.2.jar + + + bukkit + spigot-1.11 + 0.1 + system + ${spigot.libPath}/spigot-1.11.jar + + + bukkit + spigot-1.10.2 + 0.1 + system + ${spigot.libPath}/spigot-1.10.2.jar + + + bukkit + spigot-1.9.4 + 0.1 + system + ${spigot.libPath}/spigot-1.9.4.jar + + + bukkit + spigot-1.9 + 0.1 + system + ${spigot.libPath}/spigot-1.9.jar + + + bukkit + spigot-1.8.8 + 0.1 + system + ${spigot.libPath}/spigot-1.8.8.jar + + + bukkit + spigot-1.8.3 + 0.1 + system + ${spigot.libPath}/spigot-1.8.3.jar + + + bukkit + spigot-1.8 + 0.1 + system + ${spigot.libPath}/spigot-1.8.jar + + + \ No newline at end of file