diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..d60d8c3 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: shanebee +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..e4dfd3e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: 📝 Javadocs + url: https://shanebeee.github.io/docs/NMS-API/ + about: Get the docs! diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.yml b/.github/ISSUE_TEMPLATE/report-a-bug.yml new file mode 100644 index 0000000..0811ea1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/report-a-bug.yml @@ -0,0 +1,60 @@ +name: 🐞 Bug Report +description: Report an unexpected behaviour +title: "[BUG]" +body: + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Describe the observed behavior + placeholder: Tell us what you see! + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to reproduce + description: How do you reproduce this? Please provide as much step-by-step detail as possible. + value: | + 1. + 2. + 3. + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What did you expect to happen when the reproduce steps are followed? + placeholder: Tell us what you expected to see! + validations: + required: true + + - type: input + attributes: + label: NMS-API Version + description: Which version of NMS-API are you using? + placeholder: | + Ex: "1.7.2-1.21.1" + validations: + required: true + + - type: input + attributes: + label: Server Version/Software + description: Which version of the server and Minecraft are you using? + placeholder: | + Ex: "Paper 1.21.1" + validations: + required: true + + - type: textarea + attributes: + label: Additional Information + description: Any additional information that may help us solve the bug. + placeholder: | + Ex: "Using Spigot instead of Paper" + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/request-a-feature.yml b/.github/ISSUE_TEMPLATE/request-a-feature.yml new file mode 100644 index 0000000..7e5b9ea --- /dev/null +++ b/.github/ISSUE_TEMPLATE/request-a-feature.yml @@ -0,0 +1,33 @@ +name: 👷 Feature Request +description: Request an addition or change to NMS-API +title: "[SUGGESTION]" +body: + - type: textarea + id: suggestion + attributes: + label: Suggestion + description: What would you like to see improved? + placeholder: | + The more details, the better + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives + description: Describe alternatives you've considered + placeholder: | + The more details, the better + validations: + required: true + + - type: textarea + id: additional + attributes: + label: Additional Information + description: Any additional information that may help us out. + placeholder: | + Ex: "I know that Paper has API " + validations: + required: false diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..2eb2c84 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,42 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# 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 + +on: + push: + branches: [ '**' ] + pull_request: + branches: [ '**' ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 21 + uses: actions/setup-java@v4.2.1 + with: + java-version: '21' + distribution: 'temurin' + - name: Build with Gradle + uses: gradle/actions/setup-gradle@v3 + with: + arguments: build + - name: Upload a Build Artifact + uses: actions/upload-artifact@master + with: + # Artifact name + name: NMS-API-Artifact + # A file, directory or wildcard pattern that describes what to upload + path: build/libs/NMS-API*.jar + diff --git a/build.gradle b/build.gradle index 74cb238..fcff193 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ plugins { id 'java' id 'maven-publish' - id("io.papermc.paperweight.userdev") version "1.7.1" // the latest version can be found on the Gradle Plugin Portal + id("io.papermc.paperweight.userdev") version "1.7.7" // the latest version can be found on the Gradle Plugin Portal } // The Minecraft version we're currently building for -def minecraftVersion = '1.21.1' +def minecraftVersion = '1.21.4' // The Paper JavaDoc version to use -def javaDocVersion = '1.21.1' +def javaDocVersion = '1.21.4' // Where this builds on the server -def serverLocation = '1-21-1' +def serverLocation = '1-21-4' // Version of NMS-API def projectVersion = '1.7.2' diff --git a/src/main/java/com/shanebeestudios/nms/api/util/McUtils.java b/src/main/java/com/shanebeestudios/nms/api/util/McUtils.java index 29f3d3a..22dcf04 100644 --- a/src/main/java/com/shanebeestudios/nms/api/util/McUtils.java +++ b/src/main/java/com/shanebeestudios/nms/api/util/McUtils.java @@ -58,6 +58,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -207,7 +208,7 @@ public static LevelChunk getLevelChunk(Chunk chunk) { * @return Registry from key */ public static Registry getRegistry(ResourceKey> registry) { - return MinecraftServer.getServer().registryAccess().registryOrThrow(registry); + return MinecraftServer.getServer().registryAccess().lookupOrThrow(registry); } /** @@ -240,7 +241,11 @@ public static Entity getNMSEntity(org.bukkit.entity.Entity bukkitEntity) { public static EntityType getEntityType(org.bukkit.entity.EntityType bukkitType) { NamespacedKey key = bukkitType.getKey(); ResourceLocation resourceLocation = McUtils.getResourceLocation(key); - return BuiltInRegistries.ENTITY_TYPE.get(resourceLocation); + Optional>> ref = BuiltInRegistries.ENTITY_TYPE.get(resourceLocation); + if (ref.isEmpty()) { + throw new IllegalArgumentException("Unknown entity type " + resourceLocation); + } + return ref.get().value(); } /** @@ -290,7 +295,7 @@ public static Holder.Reference getHolderReference(Registry registry, N ResourceLocation resourceLocation = McUtils.getResourceLocation(key); ResourceKey resourceKey = ResourceKey.create(registry.key(), resourceLocation); try { - return registry.getHolderOrThrow(resourceKey); + return registry.getOrThrow(resourceKey); } catch (IllegalStateException ignore) { return null; } diff --git a/src/main/java/com/shanebeestudios/nms/api/world/WorldApi.java b/src/main/java/com/shanebeestudios/nms/api/world/WorldApi.java index d588c65..f088c88 100644 --- a/src/main/java/com/shanebeestudios/nms/api/world/WorldApi.java +++ b/src/main/java/com/shanebeestudios/nms/api/world/WorldApi.java @@ -86,7 +86,7 @@ public static void setBiome(@NotNull Location location, @NotNull NamespacedKey b LevelChunk chunk = serverLevel.getChunkAt(new BlockPos(x, y, z)); chunk.setBiome(x >> 2, y >> 2, z >> 2, biome); - chunk.setUnsaved(true); + chunk.markUnsaved(); } /** @@ -136,7 +136,7 @@ public static void fillBiome(@NotNull Location location, @NotNull Location locat for (ChunkAccess chunkAccess : chunkAccessList) { chunkAccess.fillBiomesFromNoise(McUtils.getBiomeResolver(new MutableInt(0), chunkAccess, box, biome, biomeHolder -> replaceBiome == null || biomeHolder.is(replaceBiome)), level.getChunkSource().randomState().sampler()); - chunkAccess.setUnsaved(true); + chunkAccess.markUnsaved(); } level.getChunkSource().chunkMap.resendBiomesForChunks(chunkAccessList); } diff --git a/src/main/java/com/shanebeestudios/nms/api/world/biome/BiomeDefinition.java b/src/main/java/com/shanebeestudios/nms/api/world/biome/BiomeDefinition.java index 3859567..6ca36a0 100644 --- a/src/main/java/com/shanebeestudios/nms/api/world/biome/BiomeDefinition.java +++ b/src/main/java/com/shanebeestudios/nms/api/world/biome/BiomeDefinition.java @@ -4,17 +4,14 @@ import com.shanebeestudios.nms.api.util.ReflectionUtils; import net.minecraft.core.Holder; import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeGenerationSettings; import net.minecraft.world.level.biome.BiomeSpecialEffects; import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier; import net.minecraft.world.level.biome.MobSpawnSettings; -import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.NamespacedKey; @@ -120,19 +117,17 @@ public Biome registerAndReturn() { this.biomeBuilder.generationSettings((new BiomeGenerationSettings.PlainBuilder()).build()); this.biomeBuilder.mobSpawnSettings((new MobSpawnSettings.Builder()).build()); Biome biome = this.biomeBuilder.build(); - DedicatedServer minecraftServer = McUtils.getMinecraftServer(Bukkit.getServer()); - RegistryAccess.Frozen registryAccess = minecraftServer.registryAccess(); - Registry biomeRegistry = registryAccess.registry(Registries.BIOME).orElseThrow(); + Registry biomeRegistry = McUtils.getRegistry(Registries.BIOME); ReflectionUtils.setField("frozen", biomeRegistry, false); ReflectionUtils.setField("unregisteredIntrusiveHolders", biomeRegistry, new IdentityHashMap<>()); Holder.Reference holder = biomeRegistry.createIntrusiveHolder(biome); ResourceKey resourceKey = ResourceKey.create(Registries.BIOME, this.key); - Registry.register(biomeRegistry, resourceKey, (Biome)holder.value()); + Registry.register(biomeRegistry, resourceKey, (Biome) holder.value()); biomeRegistry.freeze(); return biome; } - public static enum GrassModifier { + public enum GrassModifier { NONE(GrassColorModifier.NONE), DARK_FOREST(GrassColorModifier.DARK_FOREST), SWAMP(GrassColorModifier.SWAMP); diff --git a/src/main/java/com/shanebeestudios/nms/api/world/entity/FakePlayer.java b/src/main/java/com/shanebeestudios/nms/api/world/entity/FakePlayer.java index 528656c..8a99a13 100644 --- a/src/main/java/com/shanebeestudios/nms/api/world/entity/FakePlayer.java +++ b/src/main/java/com/shanebeestudios/nms/api/world/entity/FakePlayer.java @@ -1,6 +1,7 @@ package com.shanebeestudios.nms.api.world.entity; import com.shanebeestudios.nms.api.util.McUtils; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; @@ -47,7 +48,7 @@ public class FakePlayer { if (attachedEntity != null) serverPlayer.setId(attachedEntity.getId()); this.fakeServerPlayer = serverPlayer; this.fakePlayerEntry = new Entry(this.fakeServerPlayer.getUUID(), this.fakeServerPlayer.getGameProfile(), true, 0, - GameType.CREATIVE, this.fakeServerPlayer.getDisplayName(), null); + GameType.CREATIVE, this.fakeServerPlayer.getDisplayName(), true, /*Is 0 what we want?*/ 0,null); this.id = serverPlayer.getId(); this.attachedEntity = attachedEntity; } @@ -183,7 +184,9 @@ private void update(ServerPlayer serverPlayer) { connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER), this.fakePlayerEntry)); connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED), this.fakePlayerEntry)); ChunkMap.TrackedEntity trackedEntity = serverPlayer.serverLevel().getChunkSource().chunkMap.entityMap.get(serverPlayer.getId()); - connection.send(this.fakeServerPlayer.getAddEntityPacket(trackedEntity.serverEntity)); + + ClientboundAddEntityPacket addEntityPacket = new ClientboundAddEntityPacket(this.fakeServerPlayer, 0, this.fakeServerPlayer.blockPosition()); + connection.send(addEntityPacket); } /** diff --git a/src/main/java/com/shanebeestudios/nms/api/world/item/ItemApi.java b/src/main/java/com/shanebeestudios/nms/api/world/item/ItemApi.java index 1afa2dc..f70ddfd 100644 --- a/src/main/java/com/shanebeestudios/nms/api/world/item/ItemApi.java +++ b/src/main/java/com/shanebeestudios/nms/api/world/item/ItemApi.java @@ -6,13 +6,11 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TieredItem; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Api methods pertaining to an {@link org.bukkit.inventory.ItemStack} @@ -91,18 +89,6 @@ public static Item getItem(@NotNull Material bukkitMaterial) { return CraftMagicNumbers.getItem(bukkitMaterial); } - /** - * Get the {@link McTier Tier} from a Tiered Item - * - * @param item Tiered Item to get Tier from - * @return Tier of Item - */ - @Nullable - public static McTier getTier(@NotNull Item item) { - if (item instanceof TieredItem tieredItem) return McTier.wrap(tieredItem); - return null; - } - /** * Get a wrapped ItemStack for easy to use methods * diff --git a/src/main/java/com/shanebeestudios/nms/api/world/item/McItem.java b/src/main/java/com/shanebeestudios/nms/api/world/item/McItem.java index 78f1a43..847d26b 100644 --- a/src/main/java/com/shanebeestudios/nms/api/world/item/McItem.java +++ b/src/main/java/com/shanebeestudios/nms/api/world/item/McItem.java @@ -1,9 +1,9 @@ package com.shanebeestudios.nms.api.world.item; import net.minecraft.core.component.DataComponents; +import net.minecraft.tags.DamageTypeTags; import net.minecraft.world.item.Item; -import net.minecraft.world.item.TieredItem; -import org.jetbrains.annotations.Nullable; +import net.minecraft.world.item.component.DamageResistant; /** * Wrapper for Minecraft Item @@ -37,33 +37,28 @@ public Item getItem() { return this.item; } - /** - * Get the {@link McTier Tier} from a Tiered Item - * - * @return Tier of Item - */ - @Nullable - public McTier getTier() { - if (this.item instanceof TieredItem tieredItem) return McTier.wrap(tieredItem); - return null; - } - /** * Check if this item is fire-resistant * * @return True if fire-resistant else false */ public boolean isFireResistant() { - return this.item.components().has(DataComponents.FIRE_RESISTANT); + if (this.item.components().has(DataComponents.DAMAGE_RESISTANT)) { + DamageResistant data = this.item.components().get(DataComponents.DAMAGE_RESISTANT); + return data != null && data.types() == DamageTypeTags.IS_FIRE; + } + return false; } /** * Check if Item is complex * * @return True if complex else false + * @deprecated No longer a thing in MC */ + @Deprecated(since = "1.21.4") public boolean isComplex() { - return this.item.isComplex(); + return false; } } diff --git a/src/main/java/com/shanebeestudios/nms/api/world/item/McTier.java b/src/main/java/com/shanebeestudios/nms/api/world/item/McTier.java deleted file mode 100644 index 241973b..0000000 --- a/src/main/java/com/shanebeestudios/nms/api/world/item/McTier.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.shanebeestudios.nms.api.world.item; - -import net.minecraft.world.item.Tier; -import net.minecraft.world.item.TieredItem; -import net.minecraft.world.item.crafting.Ingredient; -import org.jetbrains.annotations.NotNull; - -/** - * Wrapper class for Minecraft {@link Tier Tier} - */ -public class McTier { - - /** - * Wrapper an NMS TieredItem for easy to use methods - * - * @param tieredItem NMS TieredItem to wrap - * @return Wrapped item - */ - public static McTier wrap(TieredItem tieredItem) { - return new McTier(tieredItem); - } - - private final Tier tier; - - private McTier(TieredItem tieredItem) { - this.tier = tieredItem.getTier(); - } - - /** - * Get the uses of this tier - * - * @return Uses of this tier - */ - public int getUses() { - return this.tier.getUses(); - } - - /** - * Get the speed of this tier - * - * @return Speed of this tier - */ - public float getSpeed() { - return this.tier.getSpeed(); - } - - /** - * Get the attack damage bonus of this tier - * - * @return Attack damage bonus of this tier - */ - public float getAttackDamageBonus() { - return this.tier.getAttackDamageBonus(); - } - - /** - * Get the level of this tier - * - * @return Level of this tier - * @deprecated Minecraft removed the tier level - */ - @Deprecated(forRemoval = true, since = "April 27/2023") - public int getLevel() { - throw new RuntimeException("no longer available"); - } - - /** - * Get the enchantment value of this tier - * - * @return Enchantment value of this tier - */ - public int getEnchantmentValue() { - return this.tier.getEnchantmentValue(); - } - - /** - * Get the repair ingredient of this tier - * - * @return Repair ingredient of this tier - */ - public @NotNull Ingredient getRepairIngredient() { - return this.tier.getRepairIngredient(); - } - -}