Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI with Gradle
name: Build and Upload Artifact

on:
push:
Expand All @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 21
- name: Set up JDK 25
uses: actions/setup-java@v4.2.1
with:
java-version: '21'
Expand Down
41 changes: 26 additions & 15 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
plugins {
id("java")
id("com.gradleup.shadow") version "8.3.6"
id("com.gradleup.shadow") version "9.3.0"
}
// Version of HungerGames
val projectVersion = "5.0.0-beta4"
// Minimum version of Minecraft that HungerGames supports
val apiVersion = "1.21.10"
// Where this builds on the server
val serverLocation = "1-21-5"
val serverLocation = "26-1"
// Minecraft version to build against
val minecraftVersion = "1.21.10"
val minecraftVersion = "26.1.2"

java.sourceCompatibility = JavaVersion.VERSION_21
java.sourceCompatibility = JavaVersion.VERSION_25

repositories {
mavenCentral()
Expand All @@ -26,7 +28,7 @@ repositories {

// MythicMobs
maven("https://mvn.lumine.io/repository/maven-public/") {
content { includeGroup("io.lumine") }
content { includeGroup("io.lumine") }
}

// Papi
Expand All @@ -38,22 +40,22 @@ repositories {

dependencies {
// Paper
compileOnly("io.papermc.paper:paper-api:${minecraftVersion}-R0.1-SNAPSHOT")
compileOnly("io.papermc.paper:paper-api:${minecraftVersion}.build.+")

// Command Api
implementation("dev.jorel:commandapi-paper-shade:11.0.1-SNAPSHOT")
implementation("dev.jorel:commandapi-paper-shade:11.2.0")

// bStats
implementation("org.bstats:bstats-bukkit:3.1.0")
implementation("org.bstats:bstats-bukkit:3.2.0")

// MythicMobs
compileOnly("io.lumine:Mythic-Dist:5.6.1")

// Papi
compileOnly("me.clip:placeholderapi:2.11.6")
compileOnly("me.clip:placeholderapi:2.12.2")

// NBT-API
implementation("de.tr7zw:item-nbt-api:2.15.3") {
implementation("de.tr7zw:item-nbt-api:2.15.7") {
isTransitive = false
}

Expand All @@ -71,18 +73,20 @@ tasks {
dependsOn("shadowJar")
from("build/libs") {
include("HungerGames-*.jar")
destinationDir = file("/Users/ShaneBee/Desktop/Server/${serverLocation}/plugins/")
destinationDir = file("/Users/ShaneBee/Desktop/Server/Minecraft/${serverLocation}/plugins/")
}

}
processResources {
val prop = ("version" to projectVersion)
val prop2 = ("apiversion" to apiVersion)
filesMatching("paper-plugin.yml") {
expand(prop)
expand(prop, prop2)
}

}
compileJava {
options.release = 21
options.release = 25
options.compilerArgs.add("-Xlint:unchecked")
options.compilerArgs.add("-Xlint:deprecation")
}
Expand All @@ -98,14 +102,21 @@ tasks {

}
shadowJar {
archiveFileName = "HungerGames-${projectVersion}.jar"
archiveClassifier.set("")
relocate("fr.mrmicky.fastboard", "com.shanebeestudios.hg.shaded-api.fastboard")
relocate("dev.jorel.commandapi", "com.shanebeestudios.hg.shaded-api.commandapi")
relocate("de.tr7zw.changeme.nbtapi", "com.shanebeestudios.hg.shaded-api.nbt")
relocate("org.bstats", "com.shanebeestudios.hg.api.metrics")
archiveFileName = "HungerGames-${projectVersion}.jar"
}
jar {
enabled = false
dependsOn(shadowJar)
archiveFileName.set("HungerGames.jar")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(25))
}
withSourcesJar()
}
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
9 changes: 3 additions & 6 deletions gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import org.jetbrains.annotations.ApiStatus;

import java.util.List;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;

public abstract class CustomArg {
Expand Down Expand Up @@ -46,7 +45,7 @@ public static void init(HungerGames plugin, GameManager gameManager) {
@Override
public Argument<?> get(String name) {
return new CustomArgument<>(new StringArgument(name), info -> {
String gameName = info.input().toLowerCase(Locale.ROOT);
String gameName = info.input();
Game game = GAME_MANAGER.getGame(gameName);
if (game == null) {
String msg = LANG.command_base_invalid_game.replace("<arena>", gameName);
Expand Down
112 changes: 91 additions & 21 deletions src/main/java/com/shanebeestudios/hg/api/util/NBTApi.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package com.shanebeestudios.hg.api.util;

import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* NBT class for adding NBT to items
* <p>(Mainly for internal use)</p>
*/
@SuppressWarnings("CallToPrintStackTrace")
@SuppressWarnings({"CallToPrintStackTrace", "DataFlowIssue"})
public class NBTApi {

private static boolean ENABLED;
Expand Down Expand Up @@ -100,52 +104,118 @@ public static void applyNBTToEntity(Entity entity, String nbtString) {
}
}

// Cache these classes/methods to prevent retrieving them too often
private static final Class<?> ICHAT_BASE_COMPONENT_CLASS = ReflectionUtils.getNMSClass("net.minecraft.network.chat.IChatBaseComponent");
// Classes
private static Class<?> CRAFT_ITEM_STACK_CLASS;
private static final Class<?> NMS_COMPONENT_CLASS = ReflectionUtils.getNMSClass("net.minecraft.network.chat.Component");
private static final Class<?> CRAFT_CHAT_MESSAGE_CLASS = ReflectionUtils.getOBCClass("util.CraftChatMessage");
private static final Class<?> TEXT_TAG_VISITOR_CLASS;
private static final Class<?> NBT_BASE_CLASS = ReflectionUtils.getNMSClass("net.minecraft.nbt.NBTBase");
private static final Class<?> TEXT_TAG_VISITOR_CLASS = ReflectionUtils.getNMSClass("net.minecraft.nbt.TextComponentTagVisitor");
private static final Class<?> NBT_TAG_CLASS = ReflectionUtils.getNMSClass("net.minecraft.nbt.Tag");

// Fields/Objects
private static Object CODEC;
private static Object REGISTRY_ACCESS;
private static Object NBT_OPS_INSTANCE;

// Methods
private static Method GET_COMPONENTS_METHOD;
private static Method ENCODE_METHOD;
private static Method GET_OR_ELSE;
private static Method CREATE_SERIALIZER_METHOD;
private static final Method FROM_COMPONENT;
private static final Method VISIT_METHOD;
private static final boolean IS_RUNNING_1_20_5 = Util.isRunningMinecraft(1, 20, 5);

// Constructors
private static Constructor<?> NBT_COMPOUND_CONSTRUCTOR;

static {
TEXT_TAG_VISITOR_CLASS = ReflectionUtils.getNMSClass("net.minecraft.nbt.TextComponentTagVisitor");
try {
// Classes
CRAFT_ITEM_STACK_CLASS = ReflectionUtils.getOBCClass("inventory.CraftItemStack");
Class<?> compoundTag = ReflectionUtils.getNMSClass("net.minecraft.nbt.CompoundTag");
Class<?> craftWorld = ReflectionUtils.getOBCClass("CraftWorld");
Class<?> dataComponentMap = ReflectionUtils.getNMSClass("net.minecraft.core.component.DataComponentMap");
Class<?> dataResult = ReflectionUtils.getNMSClass("com.mojang.serialization.DataResult");
Class<?> dynamicOps = ReflectionUtils.getNMSClass("com.mojang.serialization.DynamicOps");
Class<?> encoder = ReflectionUtils.getNMSClass("com.mojang.serialization.Encoder");
Class<?> holderLookup = ReflectionUtils.getNMSClass("net.minecraft.core.HolderLookup$Provider");
Class<?> itemStack = ReflectionUtils.getNMSClass("net.minecraft.world.item.ItemStack");
Class<?> level = ReflectionUtils.getNMSClass("net.minecraft.world.level.Level");
Class<?> nbtOps = ReflectionUtils.getNMSClass("net.minecraft.nbt.NbtOps");

// Fields/Objects
CODEC = ReflectionUtils.getField("CODEC", dataComponentMap, null);
Object nmsWorld = craftWorld.getDeclaredMethod("getHandle").invoke(Bukkit.getWorlds().get(0));
REGISTRY_ACCESS = level.getDeclaredMethod("registryAccess").invoke(nmsWorld);
NBT_OPS_INSTANCE = ReflectionUtils.getField("INSTANCE", nbtOps, null);

// Methods
GET_COMPONENTS_METHOD = itemStack.getDeclaredMethod("getComponents");
ENCODE_METHOD = encoder.getMethod("encode", Object.class, dynamicOps, Object.class);
GET_OR_ELSE = dataResult.getDeclaredMethod("getOrThrow");
CREATE_SERIALIZER_METHOD = holderLookup.getDeclaredMethod("createSerializationContext", dynamicOps);

// Constructors
NBT_COMPOUND_CONSTRUCTOR = compoundTag.getDeclaredConstructor();

} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}

Method from_comp = null;
Method visit = null;
try {
assert TEXT_TAG_VISITOR_CLASS != null;
assert CRAFT_CHAT_MESSAGE_CLASS != null;
visit = TEXT_TAG_VISITOR_CLASS.getDeclaredMethod("visit", NBT_BASE_CLASS);
from_comp = CRAFT_CHAT_MESSAGE_CLASS.getMethod("fromComponent", ICHAT_BASE_COMPONENT_CLASS);
visit = TEXT_TAG_VISITOR_CLASS.getDeclaredMethod("visit", NBT_TAG_CLASS);
from_comp = CRAFT_CHAT_MESSAGE_CLASS.getMethod("fromComponent", NMS_COMPONENT_CLASS);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
FROM_COMPONENT = from_comp;
VISIT_METHOD = visit;
}

/**
* Get the vanilla version of NBT of an item
* <br>This will show components which don't normally show in NBT
*
* @param itemStack Item to grab NBT from
* @return Vanilla NBT of item
*/
@SuppressWarnings({"deprecation"})
public static NBTCompound getVanillaNBT(ItemStack itemStack) {
try {
Object nmsItem = ReflectionUtils.getField("handle", CRAFT_ITEM_STACK_CLASS, itemStack);
Object components = GET_COMPONENTS_METHOD.invoke(nmsItem);
Object serial = CREATE_SERIALIZER_METHOD.invoke(REGISTRY_ACCESS, NBT_OPS_INSTANCE);
Object newNBTCompound = NBT_COMPOUND_CONSTRUCTOR.newInstance();

Object encoded = ENCODE_METHOD.invoke(CODEC, components, serial, newNBTCompound);
Object nmsNbt = GET_OR_ELSE.invoke(encoded);
NBTCompound itemNbt = NBTItem.convertItemtoNBT(itemStack);
itemNbt.getOrCreateCompound("components").mergeCompound(new NBTContainer(nmsNbt));
return itemNbt;
} catch (IllegalAccessException | InvocationTargetException | InstantiationException ignore) {
return new NBTContainer();
}
}

/**
* Get a pretty NBT string
* <p>This is the same as what vanilla Minecraft outputs when using the '/data' command</p>
*
* @param nbtString NBT string to convert to pretty
* @param split When null NBT will print on one long line, if not null NBT compound will be
* split into lines with JSON style, and this string will start each line off
* (usually spaces)
* @param compound Compound to convert to pretty
* @param split When null NBT will print on one long line, if not null NBT compound will be
* split into lines with JSON style, and this string will start each line off
* (usually spaces)
* @return Pretty string of NBTCompound
*/
@SuppressWarnings("deprecation")
public static @Nullable String getPrettyNBT(String nbtString, String split) {
Object nmsNBT = new NBTContainer(nbtString).getCompound();
public static @Nullable String getPrettyNBT(NBTCompound compound, String split) {
Object nmsNBT = new NBTContainer(compound.toString()).getCompound();
String s = split != null ? split : "";
try {
Object tagVisitorInstance;
if (IS_RUNNING_1_20_5) {
tagVisitorInstance = TEXT_TAG_VISITOR_CLASS.getConstructor(String.class).newInstance(s);
} else {
tagVisitorInstance = TEXT_TAG_VISITOR_CLASS.getConstructor(String.class, int.class).newInstance(s, 0);
}
Object tagVisitorInstance = TEXT_TAG_VISITOR_CLASS.getConstructor(String.class).newInstance(s);
Object prettyComponent = VISIT_METHOD.invoke(tagVisitorInstance, nmsNBT);
return ((String) FROM_COMPONENT.invoke(CRAFT_CHAT_MESSAGE_CLASS, prettyComponent));
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.shanebeestudios.hg.plugin.HungerGames;
import com.shanebeestudios.hg.plugin.permission.Permissions;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import dev.jorel.commandapi.arguments.Argument;
import dev.jorel.commandapi.arguments.LiteralArgument;
Expand Down Expand Up @@ -38,7 +39,7 @@ protected Argument<?> register() {
NBT.getComponents(itemStack, readableNBT -> {
Util.sendPrefixedMessage(player, "NBT of held item sent to console!");
Util.log("NBT: %s", readableNBT.toString());
String pretty = NBTApi.getPrettyNBT(readableNBT.toString(), " ");
String pretty = NBTApi.getPrettyNBT((NBTCompound) readableNBT, " ");
if (pretty != null) {
Util.log("Pretty NBT:");
Bukkit.getConsoleSender().sendMessage(System.lineSeparator() + pretty);
Expand All @@ -59,7 +60,7 @@ protected Argument<?> register() {
ReadWriteNBT nbtCopy = NBT.parseNBT(snapshot.getAsString());
Util.sendPrefixedMessage(player, "NBT of target entity sent to console!");
Util.log("NBT: %s", nbtCopy.toString());
String pretty = NBTApi.getPrettyNBT(nbtCopy.toString(), " ");
String pretty = NBTApi.getPrettyNBT((NBTCompound) nbtCopy, " ");
if (pretty != null) {
Util.log("Pretty NBT:");
Bukkit.getConsoleSender().sendMessage(System.lineSeparator() + pretty);
Expand Down
Loading
Loading