diff --git a/README.md b/README.md index b3955e82..c27169cf 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ [![Hangar](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/available/hangar_vector.svg)](https://hangar.papermc.io/Oliver) [![Unsupported spigot](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/unsupported/spigot_vector.svg)]() -[![Website](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/documentation/website_vector.svg)](https://fancyplugins.de) -[![Documentation](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/documentation/ghpages_vector.svg)](https://docs.fancyplugins.de) +[![Website](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/documentation/website_vector.svg)](https://fancyinnovations.com) +[![Documentation](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/documentation/ghpages_vector.svg)](https://docs.fancyinnovations.com) [![discord-plural](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/discord-plural_46h.png)](https://discord.gg/ZUgYCEJUEx) diff --git a/build.gradle.kts b/build.gradle.kts index e974c180..6b3e943f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,8 @@ plugins { - id("com.gradleup.shadow") version "9.0.0-beta17" apply false - id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false - id("xyz.jpenilla.run-paper") version "2.3.1" apply false - id("de.eldoria.plugin-yml.paper") version "0.7.1" apply false - id("io.papermc.hangar-publish-plugin") version "0.1.3" apply false - id("com.modrinth.minotaur") version "2.+" apply false + id("com.gradleup.shadow") version "9.2.2" apply false + id("io.papermc.paperweight.userdev") version "2.0.0-beta.19" apply false + id("xyz.jpenilla.run-paper") version "3.0.2" apply false + id("de.eldoria.plugin-yml.paper") version "0.8.0" apply false } allprojects { @@ -17,5 +15,12 @@ allprojects { maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.fancyinnovations.com/releases") maven(url = "https://jitpack.io") + maven("https://maven-prs.papermc.io/Paper/pr13194") { + name = "Maven for PR #13194" // https://github.com/PaperMC/Paper/pull/13194 + mavenContent { + includeModule("io.papermc.paper", "dev-bundle") + includeModule("io.papermc.paper", "paper-api") + } + } } } diff --git a/docs/src/fancyholograms/changelog/v2.md b/docs/src/fancyholograms/changelog/v2.md index 1f9dddee..5e105511 100644 --- a/docs/src/fancyholograms/changelog/v2.md +++ b/docs/src/fancyholograms/changelog/v2.md @@ -7,6 +7,15 @@ order: 2 # +## v2.8.0 [!badge variant="info" text="2025-10-10"] + +- Added support for 1.21.9 and 1.21.10 +- Added support for MiniPlaceholders v3 +- Improved performance by running more tasks asynchronously +- Improved logging +- Added HologramManager#isLoaded method +- Regular dev builds are now published to the BETA channel + ## v2.7.0 [!badge variant="info" text="2025-07-18"] - Added support for 1.21.7 and 1.21.8 diff --git a/docs/src/fancynpcs/changelog/v2.md b/docs/src/fancynpcs/changelog/v2.md index a4258c9c..e4739821 100644 --- a/docs/src/fancynpcs/changelog/v2.md +++ b/docs/src/fancynpcs/changelog/v2.md @@ -7,6 +7,17 @@ order: 2 # +## v2.8.0 [!badge variant="info" text="2025-10-10"] + +- Added support for 1.21.9 and 1.21.10 +- Added support for MiniPlaceholders v3 +- Added permissions for each action type +- Improved logging +- Fixed various bugs for the player-npcs fflag +- Added an optional flag to disable arm swinging in Npc#update +- Added NpcManager#isLoaded method +- Regular dev builds are now published to the BETA channel + ## v2.7.1 [!badge variant="info" text="2025-08-07"] - Fixed placeholder skins not refreshing diff --git a/docs/src/fancynpcs/commands/npc.md b/docs/src/fancynpcs/commands/npc.md index 390b8f84..188aee85 100644 --- a/docs/src/fancynpcs/commands/npc.md +++ b/docs/src/fancynpcs/commands/npc.md @@ -177,6 +177,13 @@ Teleports NPC to specified location. - **Syntax**: `/npc move_to (npc) (x) (y) (z) [world] [--look-in-my-direction]` - **Permissions**: `fancynpcs.command.npc.move_to` +### Rotate npc + +Sets the yaw and pitch of the specified NPC. + +- **Syntax**: `/npc rotate (npc) (yaw) (pitch)` +- **Permissions**: `fancynpcs.command.npc.rotate` + ### Center npc location Centers the NPC to the specified location. diff --git a/docs/src/fancynpcs/tutorials/action-system.md b/docs/src/fancynpcs/tutorials/action-system.md index 7ab623ee..f7f6a54c 100644 --- a/docs/src/fancynpcs/tutorials/action-system.md +++ b/docs/src/fancynpcs/tutorials/action-system.md @@ -73,6 +73,10 @@ Syntax: `send_to_server (server name)` Example: `/npc action (npc) (trigger) add send_to_server skyblock` +!!!info +Make sure to set `bungee-plugin-message-channel` to `true` in the velocity.toml config file. Otherwise, this action might not work properly. +!!! + ### execute_random_action Picks a random action from the remaining actions in the list and executes it. This action is useful for creating random behavior in NPCs. @@ -118,6 +122,10 @@ Syntax: `need_permission (permission)` Example: `/npc action (npc) (trigger) add need_permission my.cool.permission` +!!!info +If you add the `!` prefix to the permission, the action will be inverted. This means that the action list will be canceled if the player has the permission. +!!! + ### play_sound Plays a sound to the player. This action is useful for creating audio feedback for the player when interacting with the NPC. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 002b867c..bad7c246 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/libraries/common/src/main/java/de/oliver/fancylib/translations/Translator.java b/libraries/common/src/main/java/de/oliver/fancylib/translations/Translator.java index 1504e39b..c12dbc34 100644 --- a/libraries/common/src/main/java/de/oliver/fancylib/translations/Translator.java +++ b/libraries/common/src/main/java/de/oliver/fancylib/translations/Translator.java @@ -57,6 +57,13 @@ public class Translator { } for (File langFile : langFiles) { + if (!langFile.isFile()) { + continue; + } + if (!langFile.getName().endsWith(".yml")) { + continue; + } + languages.add(loadLanguageFile(langFile)); } diff --git a/libraries/config/build.gradle.kts b/libraries/config/build.gradle.kts index 70eb501b..8c6bb6c0 100644 --- a/libraries/config/build.gradle.kts +++ b/libraries/config/build.gradle.kts @@ -14,7 +14,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") compileOnly("org.jetbrains:annotations:26.0.2") diff --git a/libraries/packets/build.gradle.kts b/libraries/packets/build.gradle.kts index 5b63b4ff..468d38a4 100644 --- a/libraries/packets/build.gradle.kts +++ b/libraries/packets/build.gradle.kts @@ -18,9 +18,10 @@ allprojects { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") implementation(project(":libraries:packets:packets-api")) + implementation(project(":libraries:packets:implementations:1_21_11")) implementation(project(":libraries:packets:implementations:1_21_9")) implementation(project(":libraries:packets:implementations:1_21_6")) implementation(project(":libraries:packets:implementations:1_21_5")) diff --git a/libraries/packets/implementations/1_21_11/build.gradle.kts b/libraries/packets/implementations/1_21_11/build.gradle.kts new file mode 100644 index 00000000..87087bfa --- /dev/null +++ b/libraries/packets/implementations/1_21_11/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + id("java-library") + id("io.papermc.paperweight.userdev") +} + +paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION + +dependencies { + paperweight.paperDevBundle("25w45a-R0.1-SNAPSHOT") + compileOnly(project(":libraries:packets:packets-api")) + + testImplementation(project(":libraries:packets")) + testImplementation(project(":libraries:packets:packets-api")) + testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2") + testImplementation("org.junit.jupiter:junit-jupiter-engine:5.12.2") + testImplementation("org.junit.platform:junit-platform-console-standalone:1.12.2") +} + +tasks { + test { + useJUnitPlatform() + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundAddEntityPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundAddEntityPacketImpl.java new file mode 100644 index 00000000..f4ca9230 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundAddEntityPacketImpl.java @@ -0,0 +1,48 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundAddEntityPacket; +import de.oliver.fancysitula.api.utils.AngelConverter; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.phys.Vec3; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.EntityType; + +import java.util.UUID; + +public class ClientboundAddEntityPacketImpl extends FS_ClientboundAddEntityPacket { + + public ClientboundAddEntityPacketImpl(int entityId, UUID entityUUID, EntityType entityType, double x, double y, double z, float yaw, float pitch, float headYaw, int velocityX, int velocityY, int velocityZ, int data) { + super(entityId, entityUUID, entityType, x, y, z, yaw, pitch, headYaw, velocityX, velocityY, velocityZ, data); + } + + @Override + public Object createPacket() { + net.minecraft.world.entity.EntityType vanillaType = BuiltInRegistries.ENTITY_TYPE.getValue(CraftNamespacedKey.toMinecraft(entityType.getKey())); + + return new ClientboundAddEntityPacket( + entityId, + entityUUID, + x, + y, + z, + AngelConverter.degreesToVanillaByte(pitch), + AngelConverter.degreesToVanillaByte(yaw), + vanillaType, + data, + new Vec3(velocityX, velocityY, velocityZ), + AngelConverter.degreesToVanillaByte(headYaw) + ); + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundAddEntityPacket packet = (ClientboundAddEntityPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundClearDialogPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundClearDialogPacketImpl.java new file mode 100644 index 00000000..5fb79a62 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundClearDialogPacketImpl.java @@ -0,0 +1,22 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundClearDialogPacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.common.ClientboundClearDialogPacket; +import net.minecraft.server.level.ServerPlayer; + +public class ClientboundClearDialogPacketImpl extends FS_ClientboundClearDialogPacket { + @Override + public Object createPacket() { + return ClientboundClearDialogPacket.INSTANCE; + } + + @Override + protected void sendPacketTo(FS_RealPlayer player) { + ClientboundClearDialogPacket packet = (ClientboundClearDialogPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundCreateOrUpdateTeamPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundCreateOrUpdateTeamPacketImpl.java new file mode 100644 index 00000000..3694e322 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundCreateOrUpdateTeamPacketImpl.java @@ -0,0 +1,128 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundCreateOrUpdateTeamPacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import io.papermc.paper.adventure.PaperAdventure; +import net.minecraft.ChatFormatting; +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.scores.PlayerTeam; +import net.minecraft.world.scores.Scoreboard; +import net.minecraft.world.scores.Team; + +public class ClientboundCreateOrUpdateTeamPacketImpl extends FS_ClientboundCreateOrUpdateTeamPacket { + + private static final Scoreboard SCOREBOARD = new Scoreboard(); + + public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, CreateTeam createTeam) { + super(teamName, createTeam); + } + + public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, RemoveTeam removeTeam) { + super(teamName, removeTeam); + } + + public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, UpdateTeam updateTeam) { + super(teamName, updateTeam); + } + + public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, AddEntity addEntity) { + super(teamName, addEntity); + } + + public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, RemoveEntity removeEntity) { + super(teamName, removeEntity); + } + + @Override + public Object createPacket() { + return switch (method) { + case CREATE_TEAM -> createCreateTeamPacket(); + case REMOVE_TEAM -> createRemoveTeamPacket(); + case UPDATE_TEAM -> createUpdateTeamPacket(); + case ADD_ENTITY -> createAddEntityPacket(); + case REMOVE_ENTITY -> createRemoveEntityPacket(); + }; + } + + private Object createCreateTeamPacket() { + if (createTeam == null) { + return null; + } + + PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName); + playerTeam.setDisplayName(PaperAdventure.asVanilla(createTeam.getDisplayName())); + playerTeam.setAllowFriendlyFire(createTeam.isAllowFriendlyFire()); + playerTeam.setSeeFriendlyInvisibles(createTeam.isCanSeeFriendlyInvisibles()); + playerTeam.setNameTagVisibility(Team.Visibility.valueOf(createTeam.getNameTagVisibility().getName())); + playerTeam.setCollisionRule(PlayerTeam.CollisionRule.valueOf(createTeam.getCollisionRule().getName())); + playerTeam.setColor(ChatFormatting.getById(createTeam.getColor().getId())); + playerTeam.setPlayerPrefix(PaperAdventure.asVanilla(createTeam.getPrefix())); + playerTeam.setPlayerSuffix(PaperAdventure.asVanilla(createTeam.getSuffix())); + for (String entity : createTeam.getEntities()) { + playerTeam.getPlayers().add(entity); + } + + return ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, true); + } + + private Object createRemoveTeamPacket() { + if (removeTeam == null) { + return null; + } + + PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName); + return ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam); + } + + private Object createUpdateTeamPacket() { + if (updateTeam == null) { + return null; + } + + PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName); + playerTeam.setDisplayName(PaperAdventure.asVanilla(updateTeam.getDisplayName())); + playerTeam.setAllowFriendlyFire(updateTeam.isAllowFriendlyFire()); + playerTeam.setSeeFriendlyInvisibles(updateTeam.isCanSeeFriendlyInvisibles()); + playerTeam.setNameTagVisibility(Team.Visibility.valueOf(updateTeam.getNameTagVisibility().getName())); + playerTeam.setCollisionRule(PlayerTeam.CollisionRule.valueOf(updateTeam.getCollisionRule().getName())); + playerTeam.setColor(ChatFormatting.getById(updateTeam.getColor().getId())); + playerTeam.setPlayerPrefix(PaperAdventure.asVanilla(updateTeam.getPrefix())); + playerTeam.setPlayerSuffix(PaperAdventure.asVanilla(updateTeam.getSuffix())); + + return ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, true); + } + + private Object createAddEntityPacket() { + if (addEntity == null) { + return null; + } + + PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName); + for (String entity : addEntity.getEntities()) { + playerTeam.getPlayers().add(entity); + } + return ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(playerTeam, addEntity.getEntities(), ClientboundSetPlayerTeamPacket.Action.ADD); + } + + private Object createRemoveEntityPacket() { + if (removeEntity == null) { + return null; + } + + PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName); + for (String entity : removeEntity.getEntities()) { + playerTeam.getPlayers().add(entity); + } + return ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(playerTeam, removeEntity.getEntities(), ClientboundSetPlayerTeamPacket.Action.REMOVE); + } + + @Override + protected void sendPacketTo(FS_RealPlayer player) { + ClientboundSetPlayerTeamPacket packet = (ClientboundSetPlayerTeamPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundPlayerInfoRemovePacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundPlayerInfoRemovePacketImpl.java new file mode 100644 index 00000000..c4e6a6e1 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundPlayerInfoRemovePacketImpl.java @@ -0,0 +1,30 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoRemovePacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.server.level.ServerPlayer; + +import java.util.List; +import java.util.UUID; + +public class ClientboundPlayerInfoRemovePacketImpl extends FS_ClientboundPlayerInfoRemovePacket { + + public ClientboundPlayerInfoRemovePacketImpl(List uuids) { + super(uuids); + } + + @Override + public Object createPacket() { + return new ClientboundPlayerInfoRemovePacket(uuids); + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundPlayerInfoRemovePacket packet = (ClientboundPlayerInfoRemovePacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundPlayerInfoUpdatePacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundPlayerInfoUpdatePacketImpl.java new file mode 100644 index 00000000..b707f60e --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundPlayerInfoUpdatePacketImpl.java @@ -0,0 +1,54 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoUpdatePacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.GameProfileImpl; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import io.papermc.paper.adventure.PaperAdventure; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.level.GameType; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public class ClientboundPlayerInfoUpdatePacketImpl extends FS_ClientboundPlayerInfoUpdatePacket { + + public ClientboundPlayerInfoUpdatePacketImpl(EnumSet actions, List entries) { + super(actions, entries); + } + + @Override + public Object createPacket() { + EnumSet vanillaActions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class); + for (FS_ClientboundPlayerInfoUpdatePacket.Action action : actions) { + vanillaActions.add(ClientboundPlayerInfoUpdatePacket.Action.valueOf(action.name())); + } + + List entries = new ArrayList<>(); + for (Entry entry : this.entries) { + entries.add(new ClientboundPlayerInfoUpdatePacket.Entry( + entry.uuid(), + GameProfileImpl.asVanilla(entry.profile()), + entry.listed(), + entry.latency(), + GameType.byId(entry.gameMode().getId()), + PaperAdventure.asVanilla(entry.displayName()), + true, + -1, + null // TODO: Add ChatSession support + )); + } + + return new ClientboundPlayerInfoUpdatePacket(vanillaActions, entries); + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundRemoveEntitiesPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundRemoveEntitiesPacketImpl.java new file mode 100644 index 00000000..7aca5733 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundRemoveEntitiesPacketImpl.java @@ -0,0 +1,37 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundRemoveEntitiesPacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.server.level.ServerPlayer; + +import java.util.List; + +public class ClientboundRemoveEntitiesPacketImpl extends FS_ClientboundRemoveEntitiesPacket { + + /** + * @param entityIds IDs of the entities to remove + */ + public ClientboundRemoveEntitiesPacketImpl(List entityIds) { + super(entityIds); + } + + @Override + public Object createPacket() { + int[] ids = new int[this.entityIds.size()]; + for (int i = 0; i < this.entityIds.size(); i++) { + ids[i] = this.entityIds.get(i); + } + + return new ClientboundRemoveEntitiesPacket(ids); + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundRemoveEntitiesPacket packet = (ClientboundRemoveEntitiesPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundRotateHeadPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundRotateHeadPacketImpl.java new file mode 100644 index 00000000..240d3068 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundRotateHeadPacketImpl.java @@ -0,0 +1,38 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundRotateHeadPacket; +import de.oliver.fancysitula.api.utils.AngelConverter; +import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import net.minecraft.server.level.ServerPlayer; + +public class ClientboundRotateHeadPacketImpl extends FS_ClientboundRotateHeadPacket { + + public ClientboundRotateHeadPacketImpl(int entityId, float headYaw) { + super(entityId, headYaw); + } + + @Override + public Object createPacket() { + ClientboundRotateHeadPacket packet = null; + + try { + packet = ReflectionUtils.createUnsafeInstance(ClientboundRotateHeadPacket.class); + ReflectionUtils.setFinalField(packet, "entityId", entityId); + ReflectionUtils.setFinalField(packet, "yHeadRot", AngelConverter.degreesToVanillaByte(headYaw)); + } catch (Exception e) { + e.printStackTrace(); + } + return packet; + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundRotateHeadPacket packet = (ClientboundRotateHeadPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetEntityDataPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetEntityDataPacketImpl.java new file mode 100644 index 00000000..a011e10c --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetEntityDataPacketImpl.java @@ -0,0 +1,67 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundSetEntityDataPacket; +import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerPlayer; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class ClientboundSetEntityDataPacketImpl extends FS_ClientboundSetEntityDataPacket { + + public ClientboundSetEntityDataPacketImpl(int entityId, List entityData) { + super(entityId, entityData); + } + + @Override + public Object createPacket() { + List> dataValues = new ArrayList<>(); + for (EntityData data : entityData) { + try { + Class entityClass = Class.forName(data.getAccessor().entityClassName()); + net.minecraft.network.syncher.EntityDataAccessor accessor = ReflectionUtils.getStaticField(entityClass, data.getAccessor().accessorFieldName()); + + Object vanillaValue = data.getValue(); + + if (data.getValue() == null) { + continue; + } + + if (data.getValue() instanceof Component c) { + vanillaValue = PaperAdventure.asVanilla(c); + } + + if (data.getValue() instanceof ItemStack i) { + vanillaValue = net.minecraft.world.item.ItemStack.fromBukkitCopy(i); + } + + if (data.getValue() instanceof BlockState b) { + vanillaValue = ((CraftBlockState) b).getHandle(); + } + + dataValues.add(SynchedEntityData.DataValue.create(accessor, vanillaValue)); + } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + } + } + + return new ClientboundSetEntityDataPacket(entityId, dataValues); + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundSetEntityDataPacket packet = (ClientboundSetEntityDataPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetEquipmentPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetEquipmentPacketImpl.java new file mode 100644 index 00000000..0530362f --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetEquipmentPacketImpl.java @@ -0,0 +1,45 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import com.mojang.datafixers.util.Pair; +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundSetEquipmentPacket; +import de.oliver.fancysitula.api.utils.FS_EquipmentSlot; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.EquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ClientboundSetEquipmentPacketImpl extends FS_ClientboundSetEquipmentPacket { + + public ClientboundSetEquipmentPacketImpl(int entityId, Map equipment) { + super(entityId, equipment); + } + + @Override + public Object createPacket() { + List> slots = new ArrayList<>(); + + for (Map.Entry entry : equipment.entrySet()) { + EquipmentSlot equipmentSlot = net.minecraft.world.entity.EquipmentSlot.byName(entry.getKey().name().toLowerCase()); + net.minecraft.world.item.ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue()); + + slots.add(Pair.of(equipmentSlot, itemStack)); + } + + return new ClientboundSetEquipmentPacket(entityId, slots); + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundSetEquipmentPacket packet = (ClientboundSetEquipmentPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetPassengersPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetPassengersPacketImpl.java new file mode 100644 index 00000000..689f7081 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundSetPassengersPacketImpl.java @@ -0,0 +1,45 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundSetPassengersPacket; +import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; +import net.minecraft.server.level.ServerPlayer; + +import java.util.List; + +public class ClientboundSetPassengersPacketImpl extends FS_ClientboundSetPassengersPacket { + + public ClientboundSetPassengersPacketImpl(int entityId, List passengers) { + super(entityId, passengers); + } + + + @Override + public Object createPacket() { + int[] passengers = new int[this.passengers.size()]; + for (int i = 0; i < this.passengers.size(); i++) { + passengers[i] = this.passengers.get(i); + } + + try { + ClientboundSetPassengersPacket packet = ReflectionUtils.createUnsafeInstance(ClientboundSetPassengersPacket.class); + ReflectionUtils.setFinalField(packet, "vehicle", entityId); + ReflectionUtils.setFinalField(packet, "passengers", passengers); + return packet; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundSetPassengersPacket packet = (ClientboundSetPassengersPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundShowDialogPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundShowDialogPacketImpl.java new file mode 100644 index 00000000..998d048d --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundShowDialogPacketImpl.java @@ -0,0 +1,276 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.dialogs.FS_CommonDialogData; +import de.oliver.fancysitula.api.dialogs.FS_Dialog; +import de.oliver.fancysitula.api.dialogs.FS_DialogAction; +import de.oliver.fancysitula.api.dialogs.actions.FS_CommonButtonData; +import de.oliver.fancysitula.api.dialogs.actions.FS_DialogActionButton; +import de.oliver.fancysitula.api.dialogs.actions.FS_DialogCustomAction; +import de.oliver.fancysitula.api.dialogs.body.FS_DialogBody; +import de.oliver.fancysitula.api.dialogs.body.FS_DialogItemBody; +import de.oliver.fancysitula.api.dialogs.body.FS_DialogTextBody; +import de.oliver.fancysitula.api.dialogs.inputs.*; +import de.oliver.fancysitula.api.dialogs.types.FS_ConfirmationDialog; +import de.oliver.fancysitula.api.dialogs.types.FS_DialogListDialog; +import de.oliver.fancysitula.api.dialogs.types.FS_MultiActionDialog; +import de.oliver.fancysitula.api.dialogs.types.FS_NoticeDialog; +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundShowDialogPacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.common.ClientboundShowDialogPacket; +import net.minecraft.resources.Identifier; +import net.minecraft.server.dialog.*; +import net.minecraft.server.dialog.action.Action; +import net.minecraft.server.dialog.action.CustomAll; +import net.minecraft.server.dialog.body.DialogBody; +import net.minecraft.server.dialog.body.ItemBody; +import net.minecraft.server.dialog.body.PlainMessage; +import net.minecraft.server.dialog.input.*; +import net.minecraft.server.level.ServerPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class ClientboundShowDialogPacketImpl extends FS_ClientboundShowDialogPacket { + + public ClientboundShowDialogPacketImpl(FS_Dialog dialog) { + super(dialog); + } + + @Override + public Object createPacket() { + Holder holder = Holder.direct(toNms(dialog)); + return new ClientboundShowDialogPacket(holder); + } + + @Override + protected void sendPacketTo(FS_RealPlayer player) { + ClientboundShowDialogPacket packet = (ClientboundShowDialogPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } + + private Dialog toNms(FS_Dialog dialog) { + if (dialog instanceof FS_NoticeDialog notice) { + return noticeToNms(notice); + } else if (dialog instanceof FS_ConfirmationDialog confirmation) { + return confirmationToNms(confirmation); + } else if (dialog instanceof FS_DialogListDialog dialogList) { + return dialogListToNms(dialogList); + } else if (dialog instanceof FS_MultiActionDialog multiActionDialog) { + return multiActionDialogToNms(multiActionDialog); + } + + return null; + } + + private Dialog noticeToNms(FS_NoticeDialog notice) { + CommonDialogData common = commonToNms(notice.getDialogData()); + ActionButton actionButton = actionButtonToNms(notice.getActionButton()); + + return new NoticeDialog(common, actionButton); + } + + private Dialog confirmationToNms(FS_ConfirmationDialog notice) { + CommonDialogData common = commonToNms(notice.getDialogData()); + ActionButton yes = actionButtonToNms(notice.getYesButton()); + ActionButton no = actionButtonToNms(notice.getNoButton()); + + return new ConfirmationDialog(common, yes, no); + } + + private Dialog dialogListToNms(FS_DialogListDialog dialogList) { + CommonDialogData common = commonToNms(dialogList.getDialogData()); + List> dialogs = new ArrayList<>(); + + for (FS_Dialog dialog : dialogList.getDialogs()) { + dialogs.add(Holder.direct(toNms(dialog))); + } + + HolderSet dialogSet = HolderSet.direct(dialogs); + + Optional exitButton = dialogList.getExitButton() != null ? + Optional.of(actionButtonToNms(dialogList.getExitButton())) : + Optional.empty(); + + return new DialogListDialog(common, dialogSet, exitButton, dialogList.getColumns(), dialogList.getButtonWidth()); + } + + private Dialog multiActionDialogToNms(FS_MultiActionDialog multiActionDialog) { + CommonDialogData common = commonToNms(multiActionDialog.getDialogData()); + List actionButtons = new ArrayList<>(); + + for (FS_DialogActionButton actionButton : multiActionDialog.getActions()) { + actionButtons.add(actionButtonToNms(actionButton)); + } + + Optional exitAction = multiActionDialog.getExitAction() != null ? + Optional.of(actionButtonToNms(multiActionDialog.getExitAction())) : + Optional.empty(); + + return new MultiActionDialog(common, actionButtons, exitAction, multiActionDialog.getColumns()); + } + + private CommonDialogData commonToNms(FS_CommonDialogData dialogData) { + Component title = PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(dialogData.getTitle())); + + Optional externalTitle = dialogData.getExternalTitle() != null ? + Optional.of(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(dialogData.getExternalTitle()))) : + Optional.empty(); + + return new CommonDialogData( + title, + externalTitle, + dialogData.isCanCloseWithEscape(), + dialogData.isPause(), + actionToNms(dialogData.getAfterAction()), + bodyToNms(dialogData.getBody()), + inputsToNms(dialogData.getInputs()) + ); + } + + private DialogAction actionToNms(FS_DialogAction dialogAction) { + return switch (dialogAction) { + case CLOSE -> DialogAction.CLOSE; + case NONE -> DialogAction.NONE; + case WAIT_FOR_RESPONSE -> DialogAction.WAIT_FOR_RESPONSE; + }; + } + + private List bodyToNms(List bodies) { + List nmsBodies = new ArrayList<>(); + + for (FS_DialogBody body : bodies) { + if (body instanceof FS_DialogTextBody textBody) { + nmsBodies.add(new PlainMessage( + PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(textBody.getText())), + textBody.getWidth() + )); + } else if (body instanceof FS_DialogItemBody itemBody) { + Optional description = itemBody.getDescription() != null ? + Optional.of(new PlainMessage( + PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(itemBody.getDescription().getText())), + itemBody.getDescription().getWidth() + )) : + Optional.empty(); + + nmsBodies.add(new ItemBody( + CraftItemStack.asNMSCopy(itemBody.getItem()), + description, + itemBody.isShowDecorations(), + itemBody.isShowTooltip(), + itemBody.getWidth(), + itemBody.getHeight() + )); + } + } + + return nmsBodies; + } + + private List inputsToNms(List inputs) { + List nmsInputs = new ArrayList<>(); + + for (FS_DialogInput input : inputs) { + String key = input.getKey(); + + InputControl control = null; + if (input.getControl() instanceof FS_DialogBooleanInput booleanInput) { + control = new BooleanInput( + PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(booleanInput.getLabel())), + booleanInput.isInitial(), + booleanInput.getOnTrue(), + booleanInput.getOnFalse() + ); + } else if (input.getControl() instanceof FS_DialogNumberRangeInput numberRangeInput) { + control = new NumberRangeInput( + numberRangeInput.getWidth(), + PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(numberRangeInput.getLabel())), + numberRangeInput.getLabelFormat(), + new NumberRangeInput.RangeInfo( + numberRangeInput.getStart(), + numberRangeInput.getEnd(), + numberRangeInput.getInitial() != null ? Optional.of(numberRangeInput.getInitial()) : Optional.empty(), + numberRangeInput.getStep() != null ? Optional.of(numberRangeInput.getStep()) : Optional.empty() + ) + ); + } else if (input.getControl() instanceof FS_DialogSingleOptionInput singleOptionInput) { + List nmsEntries = new ArrayList<>(); + for (FS_DialogSingleOptionInput.Entry entry : singleOptionInput.getEntries()) { + nmsEntries.add(new SingleOptionInput.Entry( + entry.getId(), + entry.getDisplay() != null ? Optional.of(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(entry.getDisplay()))) : Optional.empty(), + entry.isInitial() + )); + } + + control = new SingleOptionInput( + singleOptionInput.getWidth(), + nmsEntries, + PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(singleOptionInput.getLabel())), + singleOptionInput.isLabelVisible() + ); + } else if (input.getControl() instanceof FS_DialogTextInput textInput) { + control = new TextInput( + textInput.getWidth(), + PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(textInput.getLabel())), + textInput.isLabelVisible(), + textInput.getInitial(), + textInput.getMaxLength(), + Optional.empty() + ); + } + + nmsInputs.add(new Input(key, control)); + } + + return nmsInputs; + } + + private ActionButton actionButtonToNms(FS_DialogActionButton actionButton) { + CommonButtonData buttonData = commonButtonDataToNms(actionButton.getButtonData()); + + Action action = null; + if (actionButton.getAction() instanceof FS_DialogCustomAction customAction) { + Key idKey = Key.key("fancysitula", customAction.getId()); + Identifier idLocation = PaperAdventure.asVanilla(idKey); + + Optional additions; + if (customAction.getAdditions() != null) { + CompoundTag tag = new CompoundTag(); + customAction.getAdditions().forEach(tag::putString); + additions = Optional.of(tag); + } else { + additions = Optional.empty(); + } + + action = new CustomAll(idLocation, additions); + } + + Optional optionalAction = action != null ? + Optional.of(action) : + Optional.empty(); + + return new ActionButton(buttonData, optionalAction); + } + + private CommonButtonData commonButtonDataToNms(FS_CommonButtonData commonButtonData) { + Component label = PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(commonButtonData.getLabel())); + Optional tooltip = commonButtonData.getTooltip() != null ? + Optional.of(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(commonButtonData.getTooltip()))) : + Optional.empty(); + int width = commonButtonData.getWidth(); + + return new CommonButtonData(label, tooltip, width); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundTeleportEntityPacketImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundTeleportEntityPacketImpl.java new file mode 100644 index 00000000..51c62161 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/packets/ClientboundTeleportEntityPacketImpl.java @@ -0,0 +1,43 @@ +package de.oliver.fancysitula.versions.v1_21_11.packets; + +import de.oliver.fancysitula.api.entities.FS_RealPlayer; +import de.oliver.fancysitula.api.packets.FS_ClientboundTeleportEntityPacket; +import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter; +import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.PositionMoveRotation; +import net.minecraft.world.phys.Vec3; + +import java.util.Set; + +public class ClientboundTeleportEntityPacketImpl extends FS_ClientboundTeleportEntityPacket { + + public ClientboundTeleportEntityPacketImpl(int entityId, double x, double y, double z, float yaw, float pitch, boolean onGround) { + super(entityId, x, y, z, yaw, pitch, onGround); + } + + @Override + public Object createPacket() { + ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket( + entityId, + new PositionMoveRotation( + new Vec3(x, y, z), + Vec3.ZERO, + yaw, + pitch + ), + Set.of(), + onGround + ); + + return packet; + } + + @Override + public void sendPacketTo(FS_RealPlayer player) { + ClientboundTeleportEntityPacket packet = (ClientboundTeleportEntityPacket) createPacket(); + + ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer()); + vanillaPlayer.connection.send(packet); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/GameProfileImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/GameProfileImpl.java new file mode 100644 index 00000000..39b7332c --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/GameProfileImpl.java @@ -0,0 +1,33 @@ +package de.oliver.fancysitula.versions.v1_21_11.utils; + +import com.mojang.authlib.GameProfile; +import de.oliver.fancysitula.api.utils.FS_GameProfile; + +import java.util.Map; + +public class GameProfileImpl { + + public static GameProfile asVanilla(FS_GameProfile gameProfile) { + GameProfile gf = new GameProfile(gameProfile.getUUID(), gameProfile.getName()); + + for (Map.Entry entry : gameProfile.getProperties().entrySet()) { + FS_GameProfile.Property property = entry.getValue(); + + gf.properties().put(entry.getKey(), new com.mojang.authlib.properties.Property(property.name(), property.value(), property.signature())); + } + + return gf; + } + + public static FS_GameProfile fromVanilla(GameProfile gameProfile) { + FS_GameProfile fsGameProfile = new FS_GameProfile(gameProfile.id(), gameProfile.name()); + + for (Map.Entry entry : gameProfile.properties().entries()) { + com.mojang.authlib.properties.Property property = entry.getValue(); + + fsGameProfile.getProperties().put(entry.getKey(), new FS_GameProfile.Property(property.name(), property.value(), property.signature())); + } + + return fsGameProfile; + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/PacketListenerImpl.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/PacketListenerImpl.java new file mode 100644 index 00000000..9e626b3f --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/PacketListenerImpl.java @@ -0,0 +1,110 @@ +package de.oliver.fancysitula.versions.v1_21_11.utils; + +import de.oliver.fancysitula.api.packets.FS_ServerboundCustomClickActionPacket; +import de.oliver.fancysitula.api.packets.FS_ServerboundPacket; +import de.oliver.fancysitula.api.utils.FS_PacketListener; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.papermc.paper.adventure.PaperAdventure; +import net.minecraft.nbt.StringTag; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.ServerboundCustomClickActionPacket; +import net.minecraft.server.level.ServerPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PacketListenerImpl extends FS_PacketListener { + + private static final String PIPELINE_NAME = "fancysitula-packet-injector"; + + public PacketListenerImpl(FS_ServerboundPacket.Type packet) { + super(packet); + } + + @Override + public void inject(Player player) { + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + Channel channel = serverPlayer.connection.connection.channel; + + if (channel.pipeline().get(PIPELINE_NAME) != null) { + return; + } + + channel.pipeline().addAfter("decoder", PIPELINE_NAME, new MessageToMessageDecoder>() { + @Override + protected void decode(ChannelHandlerContext ctx, Packet msg, List out) { + out.add(msg); + + FS_ServerboundPacket.Type packetType = getPacketType(msg); + if (packetType == null) { + return; // Unsupported packet type + } + + if (packet == FS_ServerboundPacket.Type.ALL) { + FS_ServerboundPacket fsPacket = convert(packetType, msg); + PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(fsPacket, player); + listeners.forEach(listener -> listener.accept(packetReceivedEvent)); + return; + } + + if (packet == packetType) { + FS_ServerboundPacket fsPacket = convert(packetType, msg); + PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(fsPacket, player); + listeners.forEach(listener -> listener.accept(packetReceivedEvent)); + } + } + }); + } + + private FS_ServerboundPacket.Type getPacketType(Packet packet) { + String className = packet.getClass().getSimpleName(); + for (FS_ServerboundPacket.Type type : FS_ServerboundPacket.Type.values()) { + if (type.getPacketClassName().equalsIgnoreCase(className)) { + return type; + } + } + + return null; + } + + private FS_ServerboundPacket convert(FS_ServerboundPacket.Type type, Packet packet) { + switch (type) { + case CUSTOM_CLICK_ACTION -> { + ServerboundCustomClickActionPacket customClickActionPacket = (ServerboundCustomClickActionPacket) packet; + + Map payload = new HashMap<>(); + if (customClickActionPacket.payload().isPresent() && customClickActionPacket.payload().get().asCompound().isPresent()) { + customClickActionPacket.payload().get().asCompound().get().forEach((k, v) -> { + if (v.getType().getName().equals(StringTag.TYPE.getName())) { + if (v.asString().isPresent()) { + payload.put(k, v.asString().get()); + } + } else if (v.getType().getName().equals(net.minecraft.nbt.ByteTag.TYPE.getName())) { + if (v.asBoolean().isPresent()) { + payload.put(k, String.valueOf(v.asBoolean().get())); + } else if (v.asByte().isPresent()) { + payload.put(k, String.valueOf(v.asByte().get())); + } + } else { + payload.put(k, v.toString()); + } + }); + } + + return new FS_ServerboundCustomClickActionPacket( + type, + PaperAdventure.asAdventure(customClickActionPacket.id()), + payload + ); + } + // Add more cases for other packet types as needed + default -> throw new IllegalArgumentException("Unsupported packet type: " + type); + } + } +} diff --git a/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/VanillaPlayerAdapter.java b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/VanillaPlayerAdapter.java new file mode 100644 index 00000000..ab2780e0 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/main/java/de/oliver/fancysitula/versions/v1_21_11/utils/VanillaPlayerAdapter.java @@ -0,0 +1,12 @@ +package de.oliver.fancysitula.versions.v1_21_11.utils; + +import net.minecraft.server.level.ServerPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class VanillaPlayerAdapter { + + public static ServerPlayer asVanilla(Player p) { + return ((CraftPlayer) p).getHandle(); + } +} diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundAddEntityPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundAddEntityPacketImplTest.java new file mode 100644 index 00000000..bd429275 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundAddEntityPacketImplTest.java @@ -0,0 +1,65 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.api.utils.AngelConverter; +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundAddEntityPacketImpl; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import org.bukkit.entity.EntityType; + +import java.util.UUID; + +class ClientboundAddEntityPacketImplTest { + + //TODO: Fix this test (registry problems) + // @Test + void createPacket() { + int entityId = 10000; + UUID entityUUID = UUID.randomUUID(); + EntityType entityType = EntityType.PIG; + + double x = 5; + double y = 57; + double z = 203; + + float yaw = 142; + float pitch = 247; + float headYaw = 90; + + int velocityX = 0; + int velocityY = 0; + int velocityZ = 0; + + int data = 0; + + ClientboundAddEntityPacketImpl packet = new ClientboundAddEntityPacketImpl( + entityId, + entityUUID, + entityType, + x, + y, + z, + yaw, + pitch, + headYaw, + velocityX, + velocityY, + velocityZ, + data + ); + + ClientboundAddEntityPacket createdPacket = (ClientboundAddEntityPacket) packet.createPacket(); + + assert createdPacket.getId() == entityId; + assert createdPacket.getUUID().equals(entityUUID); + assert createdPacket.getType().getDescriptionId().equals(entityType.getKey().getKey()); + assert createdPacket.getX() == x; + assert createdPacket.getY() == y; + assert createdPacket.getZ() == z; + assert createdPacket.getYRot() == AngelConverter.degreesToVanillaByte(yaw); + assert createdPacket.getXRot() == AngelConverter.degreesToVanillaByte(pitch); + assert createdPacket.getYHeadRot() == AngelConverter.degreesToVanillaByte(headYaw); + assert createdPacket.getMovement().x == velocityX; + assert createdPacket.getMovement().y == velocityY; + assert createdPacket.getMovement().z == velocityZ; + assert createdPacket.getData() == data; + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundClearDialogPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundClearDialogPacketImplTest.java new file mode 100644 index 00000000..2c00dfbc --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundClearDialogPacketImplTest.java @@ -0,0 +1,15 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundClearDialogPacketImpl; +import org.junit.jupiter.api.Test; + +public class ClientboundClearDialogPacketImplTest { + + @Test + void createPacket() { + ClientboundClearDialogPacketImpl packet = new ClientboundClearDialogPacketImpl(); + assert packet.createPacket() != null : "Packet creation failed"; +// assert packet.equals(ClientboundClearDialogPacket.INSTANCE); + } + +} diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoRemovePacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoRemovePacketImplTest.java new file mode 100644 index 00000000..6a9cad4c --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoRemovePacketImplTest.java @@ -0,0 +1,23 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoRemovePacketImpl; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.UUID; + +class ClientboundPlayerInfoRemovePacketImplTest { + + @Test + void createPacket() { + List uuids = List.of(UUID.randomUUID(), UUID.randomUUID()); + + ClientboundPlayerInfoRemovePacketImpl packet = new ClientboundPlayerInfoRemovePacketImpl(uuids); + ClientboundPlayerInfoRemovePacket vanillaPacket = (ClientboundPlayerInfoRemovePacket) packet.createPacket(); + + for (UUID uuid : uuids) { + assert vanillaPacket.profileIds().contains(uuid); + } + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoUpdatePacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoUpdatePacketImplTest.java new file mode 100644 index 00000000..5a3b3971 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoUpdatePacketImplTest.java @@ -0,0 +1,62 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoUpdatePacket; +import de.oliver.fancysitula.api.utils.FS_GameProfile; +import de.oliver.fancysitula.api.utils.FS_GameType; +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoUpdatePacketImpl; +import net.kyori.adventure.text.Component; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.UUID; + +class ClientboundPlayerInfoUpdatePacketImplTest { + + @Test + void createPacket() { + // Setup packet + EnumSet actions = EnumSet.noneOf(FS_ClientboundPlayerInfoUpdatePacket.Action.class); + actions.add(FS_ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER); + actions.add(FS_ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); + actions.add(FS_ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); + + FS_GameProfile gameProfile = new FS_GameProfile(UUID.randomUUID(), "Test name"); + boolean listed = true; + int latency = 42; + FS_GameType gameMode = FS_GameType.SURVIVAL; + Component displayName = Component.text("Test displayname"); + + List entries = new ArrayList<>(); + entries.add(new FS_ClientboundPlayerInfoUpdatePacket.Entry( + gameProfile.getUUID(), + gameProfile, + listed, + latency, + gameMode, + displayName + )); + + ClientboundPlayerInfoUpdatePacketImpl packet = new ClientboundPlayerInfoUpdatePacketImpl(actions, entries); + + ClientboundPlayerInfoUpdatePacket createdPacket = (ClientboundPlayerInfoUpdatePacket) packet.createPacket(); + + assert createdPacket.entries().size() == 1; + assert createdPacket.actions().size() == 3; + + // check entry + ClientboundPlayerInfoUpdatePacket.Entry entry = createdPacket.entries().getFirst(); + assert entry.profile().id().equals(gameProfile.getUUID()); + assert entry.profile().name().equals(gameProfile.getName()); + assert entry.listed() == listed; + assert entry.latency() == latency; + assert entry.gameMode().getId() == gameMode.getId(); + + // check actions + assert createdPacket.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER); + assert createdPacket.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); + assert createdPacket.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRemoveEntitiesPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRemoveEntitiesPacketImplTest.java new file mode 100644 index 00000000..846f45cb --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRemoveEntitiesPacketImplTest.java @@ -0,0 +1,21 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRemoveEntitiesPacketImpl; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import org.junit.jupiter.api.Test; + +import java.util.List; + +class ClientboundRemoveEntitiesPacketImplTest { + + @Test + void createPacket() { + List entityIds = List.of(95, 120, 154, 187); + + ClientboundRemoveEntitiesPacketImpl packet = new ClientboundRemoveEntitiesPacketImpl(entityIds); + ClientboundRemoveEntitiesPacket createdPacket = (ClientboundRemoveEntitiesPacket) packet.createPacket(); + + assert createdPacket.getEntityIds().size() == entityIds.size(); + assert createdPacket.getEntityIds().containsAll(entityIds); + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRotateHeadPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRotateHeadPacketImplTest.java new file mode 100644 index 00000000..f6f38409 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRotateHeadPacketImplTest.java @@ -0,0 +1,21 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils; +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRotateHeadPacketImpl; +import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; +import org.junit.jupiter.api.Test; + +class ClientboundRotateHeadPacketImplTest { + + @Test + void createPacket() throws Exception { + int entityId = 184; + float headYaw = 45; + + ClientboundRotateHeadPacketImpl packet = new ClientboundRotateHeadPacketImpl(entityId, (byte) headYaw); + ClientboundRotateHeadPacket createdPacket = (ClientboundRotateHeadPacket) packet.createPacket(); + + assert ReflectionUtils.getField(createdPacket, "entityId").equals(entityId); + assert createdPacket.getYHeadRot() == headYaw; + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEntityDataPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEntityDataPacketImplTest.java new file mode 100644 index 00000000..ce7358f1 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEntityDataPacketImplTest.java @@ -0,0 +1,29 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.api.packets.FS_ClientboundSetEntityDataPacket; +import de.oliver.fancysitula.api.utils.entityData.FS_TextDisplayData; +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEntityDataPacketImpl; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; + +import java.util.List; + +class ClientboundSetEntityDataPacketImplTest { + + //TODO: Fix this test (using registry) +// @Test + void createPacket() { + int entityId = 712; + List entityData = List.of( + new FS_ClientboundSetEntityDataPacket.EntityData( + FS_TextDisplayData.TEXT, + "Hello, World!" + ) + ); + + ClientboundSetEntityDataPacketImpl packet = new ClientboundSetEntityDataPacketImpl(entityId, entityData); + ClientboundSetEntityDataPacket createdPacket = (ClientboundSetEntityDataPacket) packet.createPacket(); + + assert createdPacket.id() == entityId; + assert createdPacket.packedItems().size() == 1; + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEquipmentPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEquipmentPacketImplTest.java new file mode 100644 index 00000000..7f736f56 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEquipmentPacketImplTest.java @@ -0,0 +1,29 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.api.utils.FS_EquipmentSlot; +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEquipmentPacketImpl; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +class ClientboundSetEquipmentPacketImplTest { + + //TODO: Fix this test (registry problems) + // @Test + void createPacket() { + // Setup packet + Map equipment = Map.of( + FS_EquipmentSlot.MAINHAND, new ItemStack(Material.DIAMOND_SWORD), + FS_EquipmentSlot.OFFHAND, new ItemStack(Material.SHIELD), + FS_EquipmentSlot.HEAD, new ItemStack(Material.DIAMOND_HELMET) + ); + + ClientboundSetEquipmentPacketImpl packet = new ClientboundSetEquipmentPacketImpl(42, equipment); + ClientboundSetEquipmentPacket createdPacket = (ClientboundSetEquipmentPacket) packet.createPacket(); + + assert createdPacket.getEntity() == 42; + assert createdPacket.getSlots().size() == 3; + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetPassengersPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetPassengersPacketImplTest.java new file mode 100644 index 00000000..61d42019 --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetPassengersPacketImplTest.java @@ -0,0 +1,29 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetPassengersPacketImpl; +import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +public class ClientboundSetPassengersPacketImplTest { + + @Test + void createPacket() { + // Setup packet + int vehicleID = 712; + List passengers = new ArrayList<>(); + passengers.add(571); + passengers.add(572); + + ClientboundSetPassengersPacketImpl packet = new ClientboundSetPassengersPacketImpl(vehicleID, passengers); + ClientboundSetPassengersPacket createdPacket = (ClientboundSetPassengersPacket) packet.createPacket(); + + // Check packet + assert createdPacket.getVehicle() == vehicleID; + assert createdPacket.getPassengers().length == 2; + assert createdPacket.getPassengers()[0] == 571; + assert createdPacket.getPassengers()[1] == 572; + } +} diff --git a/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundTeleportEntityPacketImplTest.java b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundTeleportEntityPacketImplTest.java new file mode 100644 index 00000000..f1d19cbc --- /dev/null +++ b/libraries/packets/implementations/1_21_11/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundTeleportEntityPacketImplTest.java @@ -0,0 +1,31 @@ +package de.oliver.fancysitula.versions.v1_21_9.packets; + +import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundTeleportEntityPacketImpl; +import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; +import org.junit.jupiter.api.Test; + +class ClientboundTeleportEntityPacketImplTest { + + @Test + void createPacket() { + int entityId = 4313; + double x = 15.0; + double y = 57.0; + double z = -27.0; + float yaw = 90.0f; + float pitch = 45.0f; + boolean onGround = true; + + ClientboundTeleportEntityPacketImpl packet = new ClientboundTeleportEntityPacketImpl(entityId, x, y, z, yaw, pitch, onGround); + ClientboundTeleportEntityPacket createdPacket = (ClientboundTeleportEntityPacket) packet.createPacket(); + + assert createdPacket != null; + assert createdPacket.id() == entityId; + assert createdPacket.change().position().x == x; + assert createdPacket.change().position().y == y; + assert createdPacket.change().position().z == z; + assert createdPacket.change().xRot() == pitch; + assert createdPacket.change().yRot() == yaw; + assert createdPacket.onGround() == onGround; + } +} \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundAddEntityPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundAddEntityPacketImplTest.java similarity index 88% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundAddEntityPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundAddEntityPacketImplTest.java index 1d960809..7d57ba34 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundAddEntityPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundAddEntityPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import de.oliver.fancysitula.api.utils.AngelConverter; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; @@ -56,9 +56,9 @@ class ClientboundAddEntityPacketImplTest { assert createdPacket.getYRot() == AngelConverter.degreesToVanillaByte(yaw); assert createdPacket.getXRot() == AngelConverter.degreesToVanillaByte(pitch); assert createdPacket.getYHeadRot() == AngelConverter.degreesToVanillaByte(headYaw); - assert createdPacket.getXa() == velocityX; - assert createdPacket.getYa() == velocityY; - assert createdPacket.getZa() == velocityZ; + assert createdPacket.getMovement().x == velocityX; + assert createdPacket.getMovement().y == velocityY; + assert createdPacket.getMovement().z == velocityZ; assert createdPacket.getData() == data; } } \ No newline at end of file diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundClearDialogPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundClearDialogPacketImplTest.java similarity index 86% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundClearDialogPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundClearDialogPacketImplTest.java index 5496c66d..832bacf7 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundClearDialogPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundClearDialogPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import org.junit.jupiter.api.Test; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundPlayerInfoRemovePacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoRemovePacketImplTest.java similarity index 92% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundPlayerInfoRemovePacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoRemovePacketImplTest.java index 697ed995..75839343 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundPlayerInfoRemovePacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoRemovePacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; import org.junit.jupiter.api.Test; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundPlayerInfoUpdatePacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoUpdatePacketImplTest.java similarity index 92% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundPlayerInfoUpdatePacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoUpdatePacketImplTest.java index fae3abba..bb5e1723 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundPlayerInfoUpdatePacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundPlayerInfoUpdatePacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoUpdatePacket; import de.oliver.fancysitula.api.utils.FS_GameProfile; @@ -47,8 +47,8 @@ class ClientboundPlayerInfoUpdatePacketImplTest { // check entry ClientboundPlayerInfoUpdatePacket.Entry entry = createdPacket.entries().getFirst(); - assert entry.profile().getId().equals(gameProfile.getUUID()); - assert entry.profile().getName().equals(gameProfile.getName()); + assert entry.profile().id().equals(gameProfile.getUUID()); + assert entry.profile().name().equals(gameProfile.getName()); assert entry.listed() == listed; assert entry.latency() == latency; assert entry.gameMode().getId() == gameMode.getId(); diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundRemoveEntitiesPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRemoveEntitiesPacketImplTest.java similarity index 92% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundRemoveEntitiesPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRemoveEntitiesPacketImplTest.java index 71cee44b..5de06317 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundRemoveEntitiesPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRemoveEntitiesPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; import org.junit.jupiter.api.Test; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundRotateHeadPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRotateHeadPacketImplTest.java similarity index 92% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundRotateHeadPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRotateHeadPacketImplTest.java index 749d1f0f..7e48115f 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundRotateHeadPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundRotateHeadPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetEntityDataPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEntityDataPacketImplTest.java similarity index 94% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetEntityDataPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEntityDataPacketImplTest.java index ac55023b..1823e768 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetEntityDataPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEntityDataPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import de.oliver.fancysitula.api.packets.FS_ClientboundSetEntityDataPacket; import de.oliver.fancysitula.api.utils.entityData.FS_TextDisplayData; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetEquipmentPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEquipmentPacketImplTest.java similarity index 94% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetEquipmentPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEquipmentPacketImplTest.java index 64784728..2b56d469 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetEquipmentPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetEquipmentPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import de.oliver.fancysitula.api.utils.FS_EquipmentSlot; import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetPassengersPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetPassengersPacketImplTest.java similarity index 94% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetPassengersPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetPassengersPacketImplTest.java index 03ee3a01..6a384f1c 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundSetPassengersPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundSetPassengersPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; import org.junit.jupiter.api.Test; diff --git a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundTeleportEntityPacketImplTest.java b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundTeleportEntityPacketImplTest.java similarity index 95% rename from libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundTeleportEntityPacketImplTest.java rename to libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundTeleportEntityPacketImplTest.java index 215e51d8..b866856f 100644 --- a/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundTeleportEntityPacketImplTest.java +++ b/libraries/packets/implementations/1_21_9/src/test/java/de/oliver/fancysitula/versions/v1_21_9/packets/ClientboundTeleportEntityPacketImplTest.java @@ -1,4 +1,4 @@ -package de.oliver.fancysitula.versions.v1_21_6.packets; +package de.oliver.fancysitula.versions.v1_21_9.packets; import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; import org.junit.jupiter.api.Test; diff --git a/libraries/packets/packets-api/build.gradle.kts b/libraries/packets/packets-api/build.gradle.kts index c371236d..4bd5c6e5 100644 --- a/libraries/packets/packets-api/build.gradle.kts +++ b/libraries/packets/packets-api/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") } diff --git a/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/ServerVersion.java b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/ServerVersion.java index d9211930..07e418aa 100644 --- a/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/ServerVersion.java +++ b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/ServerVersion.java @@ -7,7 +7,8 @@ import java.util.List; public enum ServerVersion { - v1_21_10("1.21.10", 774), + v1_21_11("1.21.11", 774), + v1_21_10("1.21.10", 773), v1_21_9("1.21.9", 773), v1_21_8("1.21.8", 772), v1_21_7("1.21.7", 772), diff --git a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketFactory.java b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketFactory.java index cedd8bfd..3797c19e 100644 --- a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketFactory.java +++ b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketFactory.java @@ -28,6 +28,9 @@ public class PacketFactory { List entries ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoUpdatePacketImpl(actions, entries); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundPlayerInfoUpdatePacketImpl(actions, entries); } @@ -73,6 +76,9 @@ public class PacketFactory { int velocityZ, int data) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundAddEntityPacketImpl(entityId, entityUUID, entityType, x, y, z, yaw, pitch, headYaw, velocityX, velocityY, velocityZ, data); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundAddEntityPacketImpl(entityId, entityUUID, entityType, x, y, z, yaw, pitch, headYaw, velocityX, velocityY, velocityZ, data); } @@ -105,6 +111,9 @@ public class PacketFactory { List uuids ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoRemovePacketImpl(uuids); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundPlayerInfoRemovePacketImpl(uuids); } @@ -137,6 +146,9 @@ public class PacketFactory { List entityIds ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRemoveEntitiesPacketImpl(entityIds); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundRemoveEntitiesPacketImpl(entityIds); } @@ -181,6 +193,9 @@ public class PacketFactory { boolean onGround ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundTeleportEntityPacketImpl(entityId, x, y, z, yaw, pitch, onGround); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundTeleportEntityPacketImpl(entityId, x, y, z, yaw, pitch, onGround); } @@ -215,6 +230,9 @@ public class PacketFactory { float headYaw ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRotateHeadPacketImpl(entityId, headYaw); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundRotateHeadPacketImpl(entityId, headYaw); } @@ -249,6 +267,9 @@ public class PacketFactory { List entityData ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEntityDataPacketImpl(entityId, entityData); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundSetEntityDataPacketImpl(entityId, entityData); } @@ -283,6 +304,9 @@ public class PacketFactory { Map equipment ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEquipmentPacketImpl(entityId, equipment); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundSetEquipmentPacketImpl(entityId, equipment); } @@ -317,6 +341,9 @@ public class PacketFactory { List passengers ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetPassengersPacketImpl(entityId, passengers); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundSetPassengersPacketImpl(entityId, passengers); } @@ -354,6 +381,9 @@ public class PacketFactory { FS_ClientboundCreateOrUpdateTeamPacket.CreateTeam createTeam ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, createTeam); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, createTeam); } @@ -390,6 +420,9 @@ public class PacketFactory { FS_ClientboundCreateOrUpdateTeamPacket.RemoveTeam removeTeam ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeTeam); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeTeam); } @@ -426,6 +459,9 @@ public class PacketFactory { FS_ClientboundCreateOrUpdateTeamPacket.UpdateTeam updateTeam ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, updateTeam); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, updateTeam); } @@ -462,6 +498,9 @@ public class PacketFactory { FS_ClientboundCreateOrUpdateTeamPacket.AddEntity addEntity ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, addEntity); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, addEntity); } @@ -498,6 +537,9 @@ public class PacketFactory { FS_ClientboundCreateOrUpdateTeamPacket.RemoveEntity removeEntity ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeEntity); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeEntity); } @@ -531,6 +573,9 @@ public class PacketFactory { FS_Dialog dialog ) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundShowDialogPacketImpl(dialog); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundShowDialogPacketImpl(dialog); } @@ -549,6 +594,9 @@ public class PacketFactory { */ public FS_ClientboundClearDialogPacket createClearDialogPacket() { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundClearDialogPacketImpl(); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundClearDialogPacketImpl(); } diff --git a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java index 5744a164..657844f7 100644 --- a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java +++ b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java @@ -8,6 +8,9 @@ public class PacketListenerFactory { public FS_PacketListener createPacketListener(FS_ServerboundPacket.Type packet) { switch (ServerVersion.getCurrentVersion()) { + case v1_21_11 -> { + return new de.oliver.fancysitula.versions.v1_21_11.utils.PacketListenerImpl(packet); + } case v1_21_9, v1_21_10 -> { return new de.oliver.fancysitula.versions.v1_21_9.utils.PacketListenerImpl(packet); } diff --git a/libraries/packets/test-plugin/build.gradle.kts b/libraries/packets/test-plugin/build.gradle.kts index a542b6af..5a398149 100644 --- a/libraries/packets/test-plugin/build.gradle.kts +++ b/libraries/packets/test-plugin/build.gradle.kts @@ -17,7 +17,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") implementation(project(":libraries:packets")) implementation(project(":libraries:packets:packets-api")) @@ -39,7 +39,7 @@ paper { tasks { runServer { - minecraftVersion("1.21.9") + minecraftVersion("1.21.10") } shadowJar { diff --git a/libraries/plugin-tests/build.gradle.kts b/libraries/plugin-tests/build.gradle.kts index c496efbb..95615f4a 100644 --- a/libraries/plugin-tests/build.gradle.kts +++ b/libraries/plugin-tests/build.gradle.kts @@ -19,7 +19,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") compileOnly("com.google.code.gson:gson:2.13.1") implementation("org.jetbrains:annotations:26.0.2") diff --git a/plugins/fancydialogs/VERSION b/plugins/fancydialogs/VERSION index 9c2a0970..f9d08f8f 100644 --- a/plugins/fancydialogs/VERSION +++ b/plugins/fancydialogs/VERSION @@ -1 +1 @@ -0.0.24 \ No newline at end of file +0.0.32 \ No newline at end of file diff --git a/plugins/fancydialogs/build.gradle.kts b/plugins/fancydialogs/build.gradle.kts index e42f37bb..b67a0c2e 100644 --- a/plugins/fancydialogs/build.gradle.kts +++ b/plugins/fancydialogs/build.gradle.kts @@ -8,19 +8,10 @@ plugins { id("xyz.jpenilla.run-paper") id("com.gradleup.shadow") id("de.eldoria.plugin-yml.paper") - id("io.papermc.hangar-publish-plugin") - id("com.modrinth.minotaur") } runPaper.folia.registerTask() -val supportedVersions = - listOf( - "1.21.6", - "1.21.7", - "1.21.8", - ) - allprojects { group = "de.oliver" version = getFDVersion() @@ -42,7 +33,7 @@ allprojects { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") implementation(project(":plugins:fancydialogs:fd-api")) @@ -59,7 +50,7 @@ dependencies { implementation("de.oliver.FancyAnalytics:logger:0.0.8") compileOnly(project(":plugins:fancynpcs:fn-api")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") implementation("io.github.revxrsal:lamp.common:4.0.0-rc.12") implementation("io.github.revxrsal:lamp.bukkit:4.0.0-rc.12") @@ -94,10 +85,10 @@ paper { tasks { runServer { - minecraftVersion("1.21.9") + minecraftVersion("1.21.10") downloadPlugins { - modrinth("fancynpcs", "2.6.0.283") + modrinth("fancynpcs", "2.8.0") // hangar("ViaVersion", "5.3.2") // hangar("ViaBackwards", "5.3.2") // modrinth("multiverse-core", "4.3.11") @@ -146,14 +137,6 @@ tasks { } } -tasks.publishAllPublicationsToHangar { - dependsOn("shadowJar") -} - -tasks.modrinth { - dependsOn("shadowJar") -} - java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } @@ -168,35 +151,4 @@ val gitCommitMessage: Provider = providers.exec { fun getFDVersion(): String { return file("VERSION").readText() -} - -hangarPublish { - publications.register("plugin") { - version = project.version as String - id = "FancyDialogs" - channel = "Alpha" - - apiKey.set(System.getenv("HANGAR_PUBLISH_API_TOKEN")) - - platforms { - paper { - jar = tasks.shadowJar.flatMap { it.archiveFile } - platformVersions = supportedVersions - } - } - - changelog = gitCommitMessage.get() - } -} - -modrinth { - token.set(System.getenv("MODRINTH_PUBLISH_API_TOKEN")) - projectId.set("FancyDialogs") - versionNumber.set(getFDVersion()) - versionType.set("alpha") - uploadFile.set(file("build/libs/${project.name}-${getFDVersion()}.jar")) - gameVersions.addAll(supportedVersions) - loaders.add("paper") - loaders.add("folia") - changelog.set(gitCommitMessage.get()) } \ No newline at end of file diff --git a/plugins/fancydialogs/fd-api/build.gradle.kts b/plugins/fancydialogs/fd-api/build.gradle.kts index f48e1a4c..4d5b6bcc 100644 --- a/plugins/fancydialogs/fd-api/build.gradle.kts +++ b/plugins/fancydialogs/fd-api/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(project(":libraries:common")) compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") - implementation("org.lushplugins:ChatColorHandler:6.0.2") + implementation("org.lushplugins:ChatColorHandler:6.0.0") implementation("org.jetbrains:annotations:24.0.0") } diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/Dialog.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/Dialog.java index 0a7c329a..a2074a98 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/Dialog.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/Dialog.java @@ -4,6 +4,7 @@ import com.fancyinnovations.fancydialogs.api.data.DialogData; import org.bukkit.entity.Player; import org.jetbrains.annotations.ApiStatus; +import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -12,12 +13,12 @@ public abstract class Dialog { protected String id; protected DialogData data; - protected Set viewers; + protected Map viewers; // uuid, time opened public Dialog(String id, DialogData data) { this.id = id; this.data = data; - this.viewers = ConcurrentHashMap.newKeySet(); + this.viewers = new ConcurrentHashMap<>(); } public Dialog() { @@ -49,7 +50,7 @@ public abstract class Dialog { * @return a set of UUIDs of players who have this dialog opened */ public Set getViewers() { - return Set.copyOf(viewers); + return Set.copyOf(viewers.keySet()); } /** @@ -58,13 +59,7 @@ public abstract class Dialog { * @param uuid of the player to check * @return true if the dialog is opened for the player, false otherwise */ - public boolean isOpenedFor(UUID uuid) { - if (uuid == null) { - return false; - } - - return viewers.contains(uuid); - } + public abstract boolean isOpenedFor(UUID uuid); /*** * Checks if the dialog is opened for a specific player. @@ -85,7 +80,8 @@ public abstract class Dialog { if (player == null) { return; } - viewers.add(player.getUniqueId()); + + viewers.put(player.getUniqueId(), System.currentTimeMillis()); } @ApiStatus.Internal @@ -93,6 +89,7 @@ public abstract class Dialog { if (player == null) { return; } + viewers.remove(player.getUniqueId()); } } diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/dialogs/ConfirmationDialog.java similarity index 77% rename from plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java rename to plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/dialogs/ConfirmationDialog.java index 312594ff..86606d56 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/ConfirmationDialog.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/dialogs/ConfirmationDialog.java @@ -1,9 +1,12 @@ -package com.fancyinnovations.fancydialogs.api; +package com.fancyinnovations.fancydialogs.api.dialogs; +import com.fancyinnovations.fancydialogs.api.Dialog; +import com.fancyinnovations.fancydialogs.api.FancyDialogs; import com.fancyinnovations.fancydialogs.api.data.DialogBodyData; import com.fancyinnovations.fancydialogs.api.data.DialogButton; import com.fancyinnovations.fancydialogs.api.data.DialogData; import com.fancyinnovations.fancydialogs.api.data.inputs.DialogInputs; +import com.fancyinnovations.fancydialogs.api.data.inputs.DialogTextField; import org.bukkit.entity.Player; import java.util.List; @@ -19,6 +22,7 @@ public class ConfirmationDialog { private String title = "Confirmation"; private String confirmText = "Yes"; private String cancelText = "No"; + private String expectedUserInput = ""; private Dialog dialog; private String confirmButtonId; @@ -28,7 +32,7 @@ public class ConfirmationDialog { private Runnable onCancel = () -> { }; - public ConfirmationDialog(String title, String question, String confirmText, String cancelText, Runnable onConfirm, Runnable onCancel) { + public ConfirmationDialog(String title, String question, String confirmText, String cancelText, String expectedUserInput, Runnable onConfirm, Runnable onCancel) { this.title = title; this.question = question; this.confirmText = confirmText; @@ -56,6 +60,11 @@ public class ConfirmationDialog { return this; } + public ConfirmationDialog withExpectedUserInput(String expectedUserInput) { + this.expectedUserInput = expectedUserInput; + return this; + } + public ConfirmationDialog withOnConfirm(Runnable onConfirm) { this.onConfirm = onConfirm; return this; @@ -103,18 +112,31 @@ public class ConfirmationDialog { ); this.cancelButtonId = cancelBtn.id(); + List textFields = null; + if (expectedUserInput != null && !expectedUserInput.isEmpty()) { + textFields = List.of( + new DialogTextField("confirmation_user_input", "Type '" + expectedUserInput + "' to confirm", 0, "", expectedUserInput.length(), 1) + ); + } + + DialogInputs inputs = new DialogInputs(textFields, null, null); + DialogData dialogData = new DialogData( "confirmation_dialog_" + UUID.randomUUID(), title, false, List.of(new DialogBodyData(question)), - DialogInputs.EMPTY, // TODO add support for confirmation phrases + inputs, List.of(confirmBtn, cancelBtn) ); this.dialog = FancyDialogs.get().createDialog(dialogData); } + public String getExpectedUserInput() { + return expectedUserInput; + } + public String getConfirmButtonId() { return confirmButtonId; } diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/NoticeDialog.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/dialogs/NoticeDialog.java similarity index 91% rename from plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/NoticeDialog.java rename to plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/dialogs/NoticeDialog.java index 8f224a10..1fe91101 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/NoticeDialog.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/dialogs/NoticeDialog.java @@ -1,5 +1,6 @@ -package com.fancyinnovations.fancydialogs.api; +package com.fancyinnovations.fancydialogs.api.dialogs; +import com.fancyinnovations.fancydialogs.api.FancyDialogs; import com.fancyinnovations.fancydialogs.api.data.DialogBodyData; import com.fancyinnovations.fancydialogs.api.data.DialogData; import com.fancyinnovations.fancydialogs.api.data.inputs.DialogInputs; diff --git a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java index b97d01f9..3ed4b0b8 100644 --- a/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java +++ b/plugins/fancydialogs/fd-api/src/main/java/com/fancyinnovations/fancydialogs/api/events/DialogButtonClickedEvent.java @@ -6,6 +6,8 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +import java.util.Map; + public class DialogButtonClickedEvent extends Event { private static final HandlerList handlerList = new HandlerList(); @@ -13,12 +15,14 @@ public class DialogButtonClickedEvent extends Event { private final Player player; private final String dialogId; private final String buttonId; + private final Map payload; - public DialogButtonClickedEvent(@NotNull Player player, @NotNull String dialogId, @NotNull String buttonId) { + public DialogButtonClickedEvent(@NotNull Player player, @NotNull String dialogId, @NotNull String buttonId, @NotNull Map payload) { super(!Bukkit.isPrimaryThread()); this.player = player; this.dialogId = dialogId; this.buttonId = buttonId; + this.payload = payload; } public static HandlerList getHandlerList() { @@ -37,6 +41,10 @@ public class DialogButtonClickedEvent extends Event { return buttonId; } + public Map getPayload() { + return payload; + } + @Override public @NotNull HandlerList getHandlers() { return handlerList; diff --git a/plugins/fancydialogs/release_deployment_config.json b/plugins/fancydialogs/release_deployment_config.json index 3b362b3b..2eafea5d 100644 --- a/plugins/fancydialogs/release_deployment_config.json +++ b/plugins/fancydialogs/release_deployment_config.json @@ -8,7 +8,9 @@ "1.21.6", "1.21.7", "1.21.8", - "1.21.9" + "1.21.9", + "1.21.10", + "1.21.11" ], "channel": "RELEASE", "loaders": [ diff --git a/plugins/fancydialogs/snapshot_deployment_config.json b/plugins/fancydialogs/snapshot_deployment_config.json index 04c7fc6c..a3d065cd 100644 --- a/plugins/fancydialogs/snapshot_deployment_config.json +++ b/plugins/fancydialogs/snapshot_deployment_config.json @@ -8,7 +8,8 @@ "1.21.6", "1.21.7", "1.21.8", - "1.21.9" + "1.21.9", + "1.21.10" ], "channel": "BETA", "loaders": [ diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java index a9df77da..b7d0f682 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/FancyDialogsPlugin.java @@ -9,7 +9,6 @@ import com.fancyinnovations.fancydialogs.api.data.DialogData; import com.fancyinnovations.fancydialogs.commands.DialogCMD; import com.fancyinnovations.fancydialogs.commands.FancyDialogsCMD; import com.fancyinnovations.fancydialogs.commands.QuickActionsCMD; -import com.fancyinnovations.fancydialogs.commands.TutorialCMD; import com.fancyinnovations.fancydialogs.commands.types.DialogCommandType; import com.fancyinnovations.fancydialogs.config.FDFeatureFlags; import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig; @@ -243,7 +242,6 @@ public class FancyDialogsPlugin extends JavaPlugin implements FancyDialogs { lamp.register(FancyDialogsCMD.INSTANCE); lamp.register(DialogCMD.INSTANCE); - lamp.register(TutorialCMD.INSTANCE); if (!FDFeatureFlags.DISABLE_QUICK_ACTIONS_DIALOG.isEnabled()) { lamp.register(QuickActionsCMD.INSTANCE); } diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java index 5881330d..29f027d9 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/FancyDialogsCMD.java @@ -1,9 +1,9 @@ package com.fancyinnovations.fancydialogs.commands; import com.fancyinnovations.fancydialogs.FancyDialogsPlugin; -import com.fancyinnovations.fancydialogs.api.ConfirmationDialog; import com.fancyinnovations.fancydialogs.api.Dialog; import com.fancyinnovations.fancydialogs.api.data.DialogData; +import com.fancyinnovations.fancydialogs.api.dialogs.ConfirmationDialog; import com.fancyinnovations.fancydialogs.config.FancyDialogsConfig; import com.fancyinnovations.fancydialogs.dialog.DialogImpl; import de.oliver.fancyanalytics.logger.LogLevel; diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/TutorialCMD.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/TutorialCMD.java deleted file mode 100644 index b971feb0..00000000 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/commands/TutorialCMD.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.fancyinnovations.fancydialogs.commands; - -import com.fancyinnovations.fancydialogs.FancyDialogsPlugin; -import de.oliver.fancylib.translations.Translator; -import revxrsal.commands.annotation.Command; -import revxrsal.commands.annotation.Description; -import revxrsal.commands.bukkit.actor.BukkitCommandActor; -import revxrsal.commands.bukkit.annotation.CommandPermission; - -public final class TutorialCMD { - - public static final TutorialCMD INSTANCE = new TutorialCMD(); - - private final FancyDialogsPlugin plugin = FancyDialogsPlugin.get(); - private final Translator translator = FancyDialogsPlugin.get().getTranslator(); - - private TutorialCMD() { - } - - @Command("tutorial open ") - @Description("Opens a specific tutorial dialog") - @CommandPermission("fancydialogs.commands.tutorial") - public void onTutorialOpen( - final BukkitCommandActor actor, - final String tutorial - ) { - actor.requirePlayer().sendMessage("Opening tutorial: " + tutorial); - } -} diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/config/FancyDialogsConfig.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/config/FancyDialogsConfig.java index 09dde53c..27c6af24 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/config/FancyDialogsConfig.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/config/FancyDialogsConfig.java @@ -12,6 +12,7 @@ public class FancyDialogsConfig { private String logLevel; private String welcomeDialogID; private String quickActionsDialogID; + private int closeTimeout; public void load() { FancyDialogsPlugin.get().reloadConfig(); @@ -29,6 +30,9 @@ public class FancyDialogsConfig { quickActionsDialogID = (String) ConfigHelper.getOrDefault(config, "quick_actions_dialog_id", "quick_actions"); config.setInlineComments("quick_actions_dialog_id", List.of("The ID of the dialog which will be shown to the player when they click on the quick actions key ('G' by default).")); + closeTimeout = (int) ConfigHelper.getOrDefault(config, "close_timeout", 1000 * 60 * 2); + config.setInlineComments("close_timeout", List.of("The time in milliseconds after which a dialog will be considered closed if the player does not respond. 0 means no timeout.")); + FancyDialogsPlugin.get().saveConfig(); } @@ -47,4 +51,8 @@ public class FancyDialogsConfig { public String getQuickActionsDialogID() { return quickActionsDialogID; } + + public int getCloseTimeout() { + return closeTimeout; + } } diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/dialog/DialogImpl.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/dialog/DialogImpl.java index fb4b0384..aba2f12a 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/dialog/DialogImpl.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/dialog/DialogImpl.java @@ -27,6 +27,7 @@ import org.lushplugins.chatcolorhandler.parsers.ParserTypes; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.UUID; public class DialogImpl extends Dialog { @@ -177,7 +178,7 @@ public class DialogImpl extends Dialog { .createShowDialogPacket(buildForPlayer(player)) .send(new FS_RealPlayer(player)); - viewers.add(player.getUniqueId()); + addViewer(player); FancyDialogsPlugin.get().getFancyLogger().debug("Opened dialog " + id + " for player " + player.getName()); } @@ -188,9 +189,29 @@ public class DialogImpl extends Dialog { .createClearDialogPacket() .send(new FS_RealPlayer(player)); - viewers.remove(player.getUniqueId()); + removeViewer(player); FancyDialogsPlugin.get().getFancyLogger().debug("Closed dialog " + id + " for player " + player.getName()); } + @Override + public boolean isOpenedFor(UUID uuid) { + if (uuid == null) { + return false; + } + + if (!viewers.containsKey(uuid)) { + return false; + } + + long openedAt = viewers.get(uuid); + long now = System.currentTimeMillis(); + if (now - openedAt > FancyDialogsPlugin.get().getFancyDialogsConfig().getCloseTimeout()) { + viewers.remove(uuid); + return false; + } + + return true; + } + } diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java index 774a0bd1..f1b369a8 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/CustomClickActionPacketListener.java @@ -46,7 +46,7 @@ public class CustomClickActionPacketListener { String dialogId = packet.getPayload().get("dialog_id"); String buttonId = packet.getPayload().get("button_id"); - new DialogButtonClickedEvent(event.player(), dialogId, buttonId).callEvent(); + new DialogButtonClickedEvent(event.player(), dialogId, buttonId, packet.getPayload()).callEvent(); if (dialogId.startsWith("confirmation_dialog_")) { return; // Ignore confirmation dialog actions, handled separately diff --git a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java index b1a406aa..f82e5f69 100644 --- a/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java +++ b/plugins/fancydialogs/src/main/java/com/fancyinnovations/fancydialogs/listener/DialogButtonClickedListener.java @@ -1,6 +1,7 @@ package com.fancyinnovations.fancydialogs.listener; -import com.fancyinnovations.fancydialogs.api.ConfirmationDialog; +import com.fancyinnovations.fancydialogs.FancyDialogsPlugin; +import com.fancyinnovations.fancydialogs.api.dialogs.ConfirmationDialog; import com.fancyinnovations.fancydialogs.api.events.DialogButtonClickedEvent; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -16,6 +17,21 @@ public class DialogButtonClickedListener implements Listener { } if (event.getButtonId().equals(dialog.getConfirmButtonId())) { + if (dialog.getExpectedUserInput() != null && !dialog.getExpectedUserInput().isEmpty()) { + if (!event.getPayload().containsKey("confirmation_user_input")) { + FancyDialogsPlugin.get().getFancyLogger().warn("Confirmation dialog expected user input but none was provided."); + return; + } + + String userInput = event.getPayload().get("confirmation_user_input"); + if (!userInput.equals(dialog.getExpectedUserInput())) { + FancyDialogsPlugin.get().getTranslator() + .translate("confirmation_dialog.input_mismatch") + .send(event.getPlayer()); + return; + } + } + dialog.getOnConfirm().run(); ConfirmationDialog.CACHE.remove(event.getDialogId()); } else if (event.getButtonId().equals(dialog.getCancelButtonId())) { diff --git a/plugins/fancydialogs/src/main/resources/languages/default.yml b/plugins/fancydialogs/src/main/resources/languages/default.yml index fecae7cb..efb95eab 100644 --- a/plugins/fancydialogs/src/main/resources/languages/default.yml +++ b/plugins/fancydialogs/src/main/resources/languages/default.yml @@ -2,6 +2,8 @@ language_name: default messages: dialog: not_found: "Dialog {warningColor}{id} is not registered." + confirmation_dialog: + input_mismatch: "Your input does not match the expected phrase." commands: dialog: open: diff --git a/plugins/fancyholograms-v2/CHANGELOG.md b/plugins/fancyholograms-v2/CHANGELOG.md index 28d5ca42..35e1f627 100644 --- a/plugins/fancyholograms-v2/CHANGELOG.md +++ b/plugins/fancyholograms-v2/CHANGELOG.md @@ -1,3 +1 @@ -- Improved performance by running more tasks asynchronously -- Improved logging -- Added HologramManager#isLoaded method \ No newline at end of file +- Added support for 1.21.11 \ No newline at end of file diff --git a/plugins/fancyholograms-v2/VERSION b/plugins/fancyholograms-v2/VERSION index 9df8bcae..8d1338f0 100644 --- a/plugins/fancyholograms-v2/VERSION +++ b/plugins/fancyholograms-v2/VERSION @@ -1 +1 @@ -2.7.0.154 \ No newline at end of file +2.8.0.158 \ No newline at end of file diff --git a/plugins/fancyholograms-v2/api/build.gradle.kts b/plugins/fancyholograms-v2/api/build.gradle.kts index 64405108..9eed58fb 100644 --- a/plugins/fancyholograms-v2/api/build.gradle.kts +++ b/plugins/fancyholograms-v2/api/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(project(":libraries:common")) compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") - implementation("org.lushplugins:ChatColorHandler:6.0.2") + implementation("org.lushplugins:ChatColorHandler:6.0.0") } tasks { diff --git a/plugins/fancyholograms-v2/build.gradle.kts b/plugins/fancyholograms-v2/build.gradle.kts index f836abe3..7ac9bacd 100644 --- a/plugins/fancyholograms-v2/build.gradle.kts +++ b/plugins/fancyholograms-v2/build.gradle.kts @@ -8,33 +8,10 @@ plugins { id("xyz.jpenilla.run-paper") id("com.gradleup.shadow") id("de.eldoria.plugin-yml.paper") - id("io.papermc.hangar-publish-plugin") - id("com.modrinth.minotaur") } runPaper.folia.registerTask() -val supportedVersions = - listOf( - "1.19.4", - "1.20", - "1.20.1", - "1.20.2", - "1.20.3", - "1.20.4", - "1.20.5", - "1.20.6", - "1.21", - "1.21.1", - "1.21.2", - "1.21.3", - "1.21.4", - "1.21.5", - "1.21.6", - "1.21.7", - "1.21.8", - ) - allprojects { group = "de.oliver" version = getFHVersion() @@ -56,7 +33,7 @@ allprojects { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") implementation(project(":plugins:fancyholograms-v2:api")) implementation(project(":plugins:fancyholograms-v2:implementation_1_20_4", configuration = "reobf")) @@ -77,7 +54,7 @@ dependencies { implementation("de.oliver.FancyAnalytics:logger:0.0.8") compileOnly(project(":plugins:fancynpcs:fn-api")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT") } @@ -114,7 +91,7 @@ paper { tasks { runServer { - minecraftVersion("1.21.9") + minecraftVersion("1.21.10") downloadPlugins { // modrinth("fancynpcs", "2.5.2") @@ -167,14 +144,6 @@ tasks { } } -tasks.publishAllPublicationsToHangar { - dependsOn("shadowJar") -} - -tasks.modrinth { - dependsOn("shadowJar") -} - java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } @@ -190,34 +159,3 @@ val gitCommitMessage: Provider = providers.exec { fun getFHVersion(): String { return file("VERSION").readText() } - -hangarPublish { - publications.register("plugin") { - version = project.version as String - id = "FancyHolograms" - channel = "Alpha" - - apiKey.set(System.getenv("HANGAR_PUBLISH_API_TOKEN")) - - platforms { - paper { - jar = tasks.shadowJar.flatMap { it.archiveFile } - platformVersions = supportedVersions - } - } - - changelog = gitCommitMessage.get() - } -} - -modrinth { - token.set(System.getenv("MODRINTH_PUBLISH_API_TOKEN")) - projectId.set("fancyholograms") - versionNumber.set(getFHVersion()) - versionType.set("alpha") - uploadFile.set(file("build/libs/${project.name}-${getFHVersion()}.jar")) - gameVersions.addAll(supportedVersions) - loaders.add("paper") - loaders.add("folia") - changelog.set(gitCommitMessage.get()) -} \ No newline at end of file diff --git a/plugins/fancyholograms-v2/release_deployment_config.json b/plugins/fancyholograms-v2/release_deployment_config.json index 0dcba9b9..301b23d9 100644 --- a/plugins/fancyholograms-v2/release_deployment_config.json +++ b/plugins/fancyholograms-v2/release_deployment_config.json @@ -22,7 +22,9 @@ "1.21.6", "1.21.7", "1.21.8", - "1.21.9" + "1.21.9", + "1.21.10", + "1.21.11" ], "channel": "RELEASE", "loaders": [ diff --git a/plugins/fancyholograms-v2/snapshot_deployment_config.json b/plugins/fancyholograms-v2/snapshot_deployment_config.json index aa790cca..2baa09f6 100644 --- a/plugins/fancyholograms-v2/snapshot_deployment_config.json +++ b/plugins/fancyholograms-v2/snapshot_deployment_config.json @@ -22,7 +22,8 @@ "1.21.6", "1.21.7", "1.21.8", - "1.21.9" + "1.21.9", + "1.21.10" ], "channel": "BETA", "loaders": [ diff --git a/plugins/fancyholograms-v2/src/main/java/de/oliver/fancyholograms/FancyHolograms.java b/plugins/fancyholograms-v2/src/main/java/de/oliver/fancyholograms/FancyHolograms.java index ab8fa58a..88b2ce3d 100644 --- a/plugins/fancyholograms-v2/src/main/java/de/oliver/fancyholograms/FancyHolograms.java +++ b/plugins/fancyholograms-v2/src/main/java/de/oliver/fancyholograms/FancyHolograms.java @@ -292,7 +292,7 @@ public final class FancyHolograms extends JavaPlugin implements FancyHologramsPl private void registerListeners() { getServer().getPluginManager().registerEvents(new PlayerListener(this), this); getServer().getPluginManager().registerEvents(new WorldListener(), this); - if (Bukkit.getMinecraftVersion().equals("1.21.4") || Bukkit.getMinecraftVersion().equals("1.21.5") || Bukkit.getMinecraftVersion().equals("1.21.6") || Bukkit.getMinecraftVersion().equals("1.21.7") || Bukkit.getMinecraftVersion().equals("1.21.8")) { + if (Set.of("1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8").contains(Bukkit.getMinecraftVersion())) { getServer().getPluginManager().registerEvents(new PlayerLoadedListener(), this); } diff --git a/plugins/fancyholograms/CHANGELOG-SNAPSHOT.md b/plugins/fancyholograms/CHANGELOG-SNAPSHOT.md index 8ff8b587..42ff7372 100644 --- a/plugins/fancyholograms/CHANGELOG-SNAPSHOT.md +++ b/plugins/fancyholograms/CHANGELOG-SNAPSHOT.md @@ -1,5 +1,6 @@ -**ATTENTION**: v3 is still in development and contains breaking changes and potential bugs. -Do not use this version in production at all, or you may lose data!! +**ATTENTION**: v3 is still in development and contains breaking changes and potential bugs. +Do not use this version in production at all, or you may lose data! +Once migrated to v3, you cannot go back to v2 without losing all your holograms and configurations! Commit hash: %COMMIT_HASH% diff --git a/plugins/fancyholograms/VERSION b/plugins/fancyholograms/VERSION index a26a84a5..fa310a86 100644 --- a/plugins/fancyholograms/VERSION +++ b/plugins/fancyholograms/VERSION @@ -1 +1 @@ -3.0.0-SNAPSHOT.6 \ No newline at end of file +3.0.0-SNAPSHOT.11 \ No newline at end of file diff --git a/plugins/fancyholograms/build.gradle.kts b/plugins/fancyholograms/build.gradle.kts index 64882491..9ed5ce14 100644 --- a/plugins/fancyholograms/build.gradle.kts +++ b/plugins/fancyholograms/build.gradle.kts @@ -8,27 +8,10 @@ plugins { id("xyz.jpenilla.run-paper") id("com.gradleup.shadow") id("de.eldoria.plugin-yml.paper") - id("io.papermc.hangar-publish-plugin") - id("com.modrinth.minotaur") } runPaper.folia.registerTask() -val supportedVersions = - listOf( - "1.20.5", - "1.20.6", - "1.21", - "1.21.1", - "1.21.2", - "1.21.3", - "1.21.4", - "1.21.5", - "1.21.6", - "1.21.7", - "1.21.8", - ) - allprojects { group = "de.oliver" version = getFHVersion() @@ -50,7 +33,7 @@ allprojects { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") implementation(project(":plugins:fancyholograms:fh-api")) @@ -70,7 +53,7 @@ dependencies { implementation("io.github.revxrsal:lamp.common:4.0.0-rc.12") implementation("io.github.revxrsal:lamp.bukkit:4.0.0-rc.12") compileOnly(project(":plugins:fancynpcs:fn-api")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") compileOnly("com.viaversion:viaversion-api:5.2.1") compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT") } @@ -113,7 +96,7 @@ paper { tasks { runServer { - minecraftVersion("1.21.9") + minecraftVersion("1.21.10") downloadPlugins { modrinth("fancynpcs", "2.7.0") @@ -162,14 +145,6 @@ tasks { } } -tasks.publishAllPublicationsToHangar { - dependsOn("shadowJar") -} - -tasks.modrinth { - dependsOn("shadowJar") -} - java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } @@ -185,34 +160,3 @@ fun getLastCommitMessage(): String { fun getFHVersion(): String { return file("VERSION").readText() } - -hangarPublish { - publications.register("plugin") { - version = getFHVersion() - id = "FancyHolograms" - channel = "Alpha" - - apiKey.set(System.getenv("HANGAR_PUBLISH_API_TOKEN")) - - platforms { - paper { - jar = tasks.shadowJar.flatMap { it.archiveFile } - platformVersions = supportedVersions - } - } - - changelog = getLastCommitMessage() - } -} - -modrinth { - token.set(System.getenv("MODRINTH_PUBLISH_API_TOKEN")) - projectId.set("fancyholograms") - versionNumber.set(getFHVersion()) - versionType.set("alpha") - uploadFile.set(file("build/libs/FancyHolograms-${getFHVersion()}.jar")) - gameVersions.addAll(supportedVersions) - loaders.add("paper") - loaders.add("folia") - changelog.set(getLastCommitMessage()) -} \ No newline at end of file diff --git a/plugins/fancyholograms/fh-api/build.gradle.kts b/plugins/fancyholograms/fh-api/build.gradle.kts index 53a05a92..73475050 100644 --- a/plugins/fancyholograms/fh-api/build.gradle.kts +++ b/plugins/fancyholograms/fh-api/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { compileOnly(project(":libraries:jdb")) compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") - implementation("org.lushplugins:ChatColorHandler:6.0.2") + implementation("org.lushplugins:ChatColorHandler:6.0.0") } tasks { diff --git a/plugins/fancyholograms/release_deployment_config.json b/plugins/fancyholograms/release_deployment_config.json index 9eb7de7a..f6515d94 100644 --- a/plugins/fancyholograms/release_deployment_config.json +++ b/plugins/fancyholograms/release_deployment_config.json @@ -16,7 +16,9 @@ "1.21.6", "1.21.7", "1.21.8", - "1.21.9" + "1.21.9", + "1.21.10", + "1.21.11" ], "channel": "RELEASE", "loaders": [ diff --git a/plugins/fancyholograms/snapshot_deployment_config.json b/plugins/fancyholograms/snapshot_deployment_config.json index b192bc03..793ce33f 100644 --- a/plugins/fancyholograms/snapshot_deployment_config.json +++ b/plugins/fancyholograms/snapshot_deployment_config.json @@ -16,7 +16,8 @@ "1.21.6", "1.21.7", "1.21.8", - "1.21.9" + "1.21.9", + "1.21.10" ], "channel": "ALPHA", "loaders": [ diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java index 233fea46..88922c2f 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/HologramCMD.java @@ -202,10 +202,6 @@ public final class HologramCMD extends Command { return Collections.emptyList(); } - if (args[2].equalsIgnoreCase("traits")) { - return new TraitsCMD().tabcompletion(sender, hologram, args); - } - // /holo edit [hologram] [option] {tab:contextual} if (args.length == 4) { final var suggestions = switch (args[2].toLowerCase(Locale.ROOT)) { @@ -354,9 +350,6 @@ public final class HologramCMD extends Command { } return switch (action) { - // hologram data - case "traits" -> new TraitsCMD().run(player, hologram, args); - // display data case "moveto" -> new MoveToCMD().run(player, hologram, args); case "rotate" -> new RotateCMD().run(player, hologram, args); diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/TraitsCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/TraitsCMD.java deleted file mode 100644 index 52c0719f..00000000 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/hologram/TraitsCMD.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.fancyinnovations.fancyholograms.commands.hologram; - -import com.fancyinnovations.fancyholograms.api.FancyHolograms; -import com.fancyinnovations.fancyholograms.api.hologram.Hologram; -import com.fancyinnovations.fancyholograms.api.trait.HologramTraitRegistry; -import com.fancyinnovations.fancyholograms.commands.Subcommand; -import de.oliver.fancylib.MessageHelper; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -public class TraitsCMD implements Subcommand { - - @Override - public List tabcompletion(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { - if (args.length == 4) { - return List.of("add", "remove"); - } else if (args.length == 5) { - return FancyHolograms.get().getTraitRegistry().getTraits() - .stream() - .filter(ti -> !ti.isDefault()) - .filter(ti -> { - if (args[3].equalsIgnoreCase("add")) { - return !hologram.getData().getTraitTrait().isTraitAttached(ti.clazz()); - } else if (args[3].equalsIgnoreCase("remove")) { - return hologram.getData().getTraitTrait().isTraitAttached(ti.clazz()); - } - - return true; - }) - .map(HologramTraitRegistry.TraitInfo::name) - .toList(); - } - - return List.of(); - } - - @Override - public boolean run(@NotNull CommandSender player, @Nullable Hologram hologram, @NotNull String[] args) { - if (!(player.hasPermission("fancyholograms.hologram.edit.traits"))) { - MessageHelper.error(player, "You don't have the required permission to change traits of a hologram."); - return false; - } - - // /hologram edit traits - - if (args.length < 5) { - MessageHelper.error(player, "Usage: /hologram edit traits "); - return false; - } - - String action = args[3]; - String traitName = args[4]; - if (traitName == null || traitName.isEmpty()) { - MessageHelper.error(player, "You must specify a trait name."); - return false; - } - - HologramTraitRegistry.TraitInfo traitInfo = FancyHolograms.get().getTraitRegistry().getTrait(traitName); - if (traitInfo == null) { - MessageHelper.error(player, "Trait '" + traitName + "' does not exist."); - return false; - } - - switch (action.toLowerCase()) { - case "add": { - if (hologram.getData().getTraitTrait().isTraitAttached(traitInfo.clazz())) { - MessageHelper.error(player, "Trait '" + traitName + "' is already attached to hologram '" + hologram.getData().getName() + "'."); - return false; - } - - hologram.getData().getTraitTrait().addTrait(traitInfo.clazz()); - MessageHelper.success(player, "Trait '" + traitName + "' has been added to hologram '" + hologram.getData().getName() + "'."); - return true; - } - case "remove": { - if (!hologram.getData().getTraitTrait().isTraitAttached(traitInfo.clazz())) { - MessageHelper.error(player, "Trait '" + traitName + "' is not attached to hologram '" + hologram.getData().getName() + "'."); - return false; - } - - hologram.getData().getTraitTrait().removeTrait(traitInfo.clazz()); - MessageHelper.success(player, "Trait '" + traitName + "' has been removed from hologram '" + hologram.getData().getName() + "'."); - return true; - } - default: { - MessageHelper.error(player, "Invalid action. Use 'add' or 'remove'."); - return false; - } - } - } -} diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/TraitCMD.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/TraitCMD.java index 0a61250c..db060e11 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/TraitCMD.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/commands/lampCommands/hologram/TraitCMD.java @@ -1,7 +1,9 @@ package com.fancyinnovations.fancyholograms.commands.lampCommands.hologram; import com.fancyinnovations.fancyholograms.api.hologram.Hologram; +import com.fancyinnovations.fancyholograms.api.trait.HologramTrait; import com.fancyinnovations.fancyholograms.api.trait.HologramTraitRegistry; +import com.fancyinnovations.fancyholograms.api.trait.HologramTraitTrait; import com.fancyinnovations.fancyholograms.commands.lampCommands.suggestions.AttachedTraitsSuggestion; import com.fancyinnovations.fancyholograms.commands.lampCommands.suggestions.DetachedTraitsSuggestion; import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; @@ -70,4 +72,30 @@ public final class TraitCMD { .replace("name", trait.name()) .send(actor.sender()); } + + @Command("hologram-new edit trait list") + @Description("Lists all attached traits of a hologram") + @CommandPermission("fancyholograms.commands.hologram.trait.list") + public void list( + final @NotNull BukkitCommandActor actor, + final @NotNull Hologram hologram + ) { + HologramTraitTrait traitTrait = hologram.getData().getTraitTrait(); + if (traitTrait.getTraits().isEmpty()) { + translator.translate("commands.hologram.edit.trait.list.no_traits") + .replace("hologram", hologram.getData().getName()) + .send(actor.sender()); + return; + } + + translator.translate("commands.hologram.edit.trait.list.header") + .replace("hologram", hologram.getData().getName()) + .send(actor.sender()); + + for (HologramTrait trait : traitTrait.getTraits()) { + translator.translate("commands.hologram.edit.trait.list.entry") + .replace("name", trait.getName()) + .send(actor.sender()); + } + } } diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java index 8c7a2df4..ac309d09 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/main/FancyHologramsPlugin.java @@ -212,6 +212,17 @@ public final class FancyHologramsPlugin extends JavaPlugin implements FancyHolog if (!configuration.areVersionNotificationsMuted()) { checkForNewerVersion(); } + if (versionConfig.isDevelopmentBuild()) { + fancyLogger.warn(""" + + -------------------------------------------------- + You are using a development build of FancyHolograms. + Please be aware that there might be bugs in this version. + If you find any bugs, please report them on our discord server (https://discord.gg/ZUgYCEJUEx). + Read more about the risks of using a development build here: https://docs.fancyinnovations.com/development-guidelines/versioning/#build + -------------------------------------------------- + """); + } metrics.register(); metrics.registerLegacy(); @@ -300,7 +311,7 @@ public final class FancyHologramsPlugin extends JavaPlugin implements FancyHolog getServer().getPluginManager().registerEvents(new PlayerListener(this), this); getServer().getPluginManager().registerEvents(new WorldLoadedListener(), this); - if (Bukkit.getMinecraftVersion().equals("1.21.4") || Bukkit.getMinecraftVersion().equals("1.21.5") || Bukkit.getMinecraftVersion().equals("1.21.6")) { + if (Set.of("1.21.4", "1.21.5", "1.21.6").contains(Bukkit.getMinecraftVersion())) { getServer().getPluginManager().registerEvents(new PlayerLoadedListener(), this); } diff --git a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/metrics/FHMetrics.java b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/metrics/FHMetrics.java index 93928173..b291de4f 100644 --- a/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/metrics/FHMetrics.java +++ b/plugins/fancyholograms/src/main/java/com/fancyinnovations/fancyholograms/metrics/FHMetrics.java @@ -1,6 +1,7 @@ package com.fancyinnovations.fancyholograms.metrics; import com.fancyinnovations.fancyholograms.api.HologramRegistry; +import com.fancyinnovations.fancyholograms.api.hologram.Hologram; import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; import de.oliver.fancyanalytics.api.FancyAnalyticsAPI; import de.oliver.fancyanalytics.api.metrics.MetricSupplier; @@ -74,6 +75,14 @@ public class FHMetrics { .toArray(String[]::new); })); + fancyAnalytics.registerNumberMetric(new MetricSupplier<>("total_amount_attached_traits", () -> { + double total = 0d; + for (Hologram hologram : registry.getAll()) { + total += hologram.getData().getTraitTrait().getTraits().size(); + } + return total; + })); + fancyAnalytics.initialize(); } diff --git a/plugins/fancyholograms/src/main/resources/languages/default.yml b/plugins/fancyholograms/src/main/resources/languages/default.yml index 708cd455..a0420d21 100644 --- a/plugins/fancyholograms/src/main/resources/languages/default.yml +++ b/plugins/fancyholograms/src/main/resources/languages/default.yml @@ -21,3 +21,7 @@ messages: detach: not_attached: "Hologram {warningColor}{hologram} does not have trait {warningColor}{name} attached." success: "Successfully detached trait {warningColor}{name} from hologram {warningColor}{hologram}." + list: + no_traits: "Hologram {warningColor}{hologram} does not have any traits attached." + header: "Hologram {warningColor}{hologram} has the following traits attached:" + entry: " - {warningColor}{name}" diff --git a/plugins/fancynpcs/CHANGELOG.md b/plugins/fancynpcs/CHANGELOG.md index e8aadb2f..d9c6b6fe 100644 --- a/plugins/fancynpcs/CHANGELOG.md +++ b/plugins/fancynpcs/CHANGELOG.md @@ -1,6 +1,6 @@ -- Added support for MiniPlaceholders v3 -- Added permissions for each action type -- Improved logging -- Fixed various bugs for the player-npcs fflag -- Added an optional flag to disable arm swinging in Npc#update -- Added NpcManager#isLoaded method \ No newline at end of file +- Added support for 1.21.11 +- Fixed skin mirroring for 1.21.9 +- Added inverted permission check for `need_permission` action (use prefix `!` to invert) +- Added `/npc rotate ` command to set NPC orientation +- Added `swing_arm_on_update` config option +- Added `use-minecraft-usercache` feature flag diff --git a/plugins/fancynpcs/README.md b/plugins/fancynpcs/README.md index 7e933f53..d0923c57 100644 --- a/plugins/fancynpcs/README.md +++ b/plugins/fancynpcs/README.md @@ -35,7 +35,7 @@ Check out **[images section](#images)** down below. ## Installation -Paper **1.19.4** - **1.21.8** with **Java 21** (or higher) is required. Plugin should also work on **Paper** forks. +Paper **1.19.4** - **1.21.11** with **Java 21** (or higher) is required. Plugin should also work on **Paper** forks. **Spigot** is **not** supported. diff --git a/plugins/fancynpcs/VERSION b/plugins/fancynpcs/VERSION index bf15e47d..e2b1107d 100644 --- a/plugins/fancynpcs/VERSION +++ b/plugins/fancynpcs/VERSION @@ -1 +1 @@ -2.7.1.299 \ No newline at end of file +2.8.0.308 \ No newline at end of file diff --git a/plugins/fancynpcs/build.gradle.kts b/plugins/fancynpcs/build.gradle.kts index 7b2f6833..2c03d76c 100644 --- a/plugins/fancynpcs/build.gradle.kts +++ b/plugins/fancynpcs/build.gradle.kts @@ -6,35 +6,10 @@ plugins { id("xyz.jpenilla.run-paper") id("com.gradleup.shadow") id("de.eldoria.plugin-yml.paper") - id("io.papermc.hangar-publish-plugin") - id("com.modrinth.minotaur") } runPaper.folia.registerTask() -val supportedVersions = - listOf( - "1.19.4", - "1.20", - "1.20.1", - "1.20.2", - "1.20.3", - "1.20.4", - "1.20.5", - "1.20.6", - "1.21", - "1.21.1", - "1.21.2", - "1.21.3", - "1.21.4", - "1.21.5", - "1.21.6", - "1.21.7", - "1.21.8", - "1.21.9", - "1.21.10" - ) - allprojects { group = "de.oliver" version = getFNVersion() @@ -53,9 +28,10 @@ allprojects { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") implementation(project(":plugins:fancynpcs:fn-api")) + implementation(project(":plugins:fancynpcs:implementation_1_21_11")) implementation(project(":plugins:fancynpcs:implementation_1_21_9")) implementation(project(":plugins:fancynpcs:implementation_1_21_6")) implementation(project(":plugins:fancynpcs:implementation_1_21_5")) @@ -78,12 +54,12 @@ dependencies { implementation(project(":libraries:jdb")) implementation(project(":libraries:plugin-tests")) implementation(project(":libraries:config")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") implementation("de.oliver.FancyAnalytics:java-sdk:0.0.4") implementation("de.oliver.FancyAnalytics:mc-api:0.1.11") implementation("de.oliver.FancyAnalytics:logger:0.0.8") implementation("org.incendo:cloud-core:2.0.0") - implementation("org.incendo:cloud-paper:2.0.0-beta.11") + implementation("org.incendo:cloud-paper:2.0.0-beta.13") implementation("org.incendo:cloud-annotations:2.0.0") annotationProcessor("org.incendo:cloud-annotations:2.0.0") implementation("org.mineskin:java-client-jsoup:3.0.3-SNAPSHOT") @@ -120,7 +96,7 @@ paper { tasks { runServer { - minecraftVersion("1.21.9") + minecraftVersion("1.21.10") downloadPlugins { // hangar("ViaVersion", "5.4.0") @@ -204,14 +180,6 @@ tasks { } } -tasks.publishAllPublicationsToHangar { - dependsOn(":plugins:fancynpcs:shadowJar") -} - -tasks.modrinth { - dependsOn(":plugins:fancynpcs:shadowJar") -} - java { toolchain.languageVersion.set(JavaLanguageVersion.of(21)) } @@ -227,34 +195,3 @@ val gitCommitMessage: Provider = providers.exec { fun getFNVersion(): String { return file("VERSION").readText() } - -hangarPublish { - publications.register("plugin") { - version = getFNVersion() - id = "FancyNpcs" - channel = "Alpha" - - apiKey.set(System.getenv("HANGAR_PUBLISH_API_TOKEN")) - - platforms { - paper { - jar = tasks.shadowJar.flatMap { it.archiveFile } - platformVersions.set(supportedVersions) - } - } - - changelog = gitCommitMessage.get() - } -} - -modrinth { - token.set(System.getenv("MODRINTH_PUBLISH_API_TOKEN")) - projectId.set("fancynpcs") - versionNumber.set(getFNVersion()) - versionType.set("alpha") - uploadFile.set(file("build/libs/${project.name}-${getFNVersion()}.jar")) - gameVersions.addAll(supportedVersions) - loaders.add("paper") - loaders.add("folia") - changelog.set(gitCommitMessage.get()) -} \ No newline at end of file diff --git a/plugins/fancynpcs/fn-api/build.gradle.kts b/plugins/fancynpcs/fn-api/build.gradle.kts index ba5b27d6..53b981e2 100644 --- a/plugins/fancynpcs/fn-api/build.gradle.kts +++ b/plugins/fancynpcs/fn-api/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { compileOnly(project(":libraries:config")) compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") - implementation("org.lushplugins:ChatColorHandler:6.0.2") + implementation("org.lushplugins:ChatColorHandler:6.0.0") } tasks { diff --git a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/FancyNpcsConfig.java b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/FancyNpcsConfig.java index b3409cda..65f4cf2f 100644 --- a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/FancyNpcsConfig.java +++ b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/FancyNpcsConfig.java @@ -35,6 +35,8 @@ public interface FancyNpcsConfig { int getRemoveNpcsFromPlayerlistDelay(); + boolean isSwingArmOnUpdate(); + String getMineSkinApiKey(); List getBlockedCommands(); diff --git a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/Npc.java b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/Npc.java index dcc5afee..25937559 100644 --- a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/Npc.java +++ b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/Npc.java @@ -132,7 +132,7 @@ public abstract class Npc { public abstract void update(Player player, boolean swingArm); public void update(Player player) { - update(player, true); + update(player, FancyNpcsPlugin.get().getFancyNpcConfig().isSwingArmOnUpdate()); } public void updateForAll(boolean swingArm) { @@ -142,13 +142,13 @@ public abstract class Npc { } public void updateForAll() { - updateForAll(true); + updateForAll(FancyNpcsPlugin.get().getFancyNpcConfig().isSwingArmOnUpdate()); } public abstract void move(Player player, boolean swingArm); public void move(Player player) { - move(player, true); + move(player, FancyNpcsPlugin.get().getFancyNpcConfig().isSwingArmOnUpdate()); } public void moveForAll(boolean swingArm) { @@ -158,7 +158,7 @@ public abstract class Npc { } public void moveForAll() { - moveForAll(true); + moveForAll(FancyNpcsPlugin.get().getFancyNpcConfig().isSwingArmOnUpdate()); } public void interact(Player player) { diff --git a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java index 1f57ffcb..0c3eaadb 100644 --- a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java +++ b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/actions/types/NeedPermissionAction.java @@ -20,7 +20,13 @@ public class NeedPermissionAction extends NpcAction { return; } - if (!context.getPlayer().hasPermission(value)) { + boolean invertCheck = value.startsWith("!"); + String permission = invertCheck ? value.substring(1) : value; + + boolean hasPermission = context.getPlayer().hasPermission(permission); + boolean passesCheck = invertCheck ? !hasPermission : hasPermission; + + if (!passesCheck) { FancyNpcsPlugin.get().getTranslator().translate("action_missing_permissions").send(context.getPlayer()); context.terminate(); } diff --git a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java index 202916d3..2e94499c 100644 --- a/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java +++ b/plugins/fancynpcs/fn-api/src/main/java/de/oliver/fancynpcs/api/events/NpcModifyEvent.java @@ -90,6 +90,7 @@ public class NpcModifyEvent extends Event implements Cancellable { LOCATION, MIRROR_SKIN, PLAYER_COMMAND, + ROTATION, SERVER_COMMAND, SHOW_IN_TAB, SKIN, diff --git a/plugins/fancynpcs/implementation_1_20/build.gradle.kts b/plugins/fancynpcs/implementation_1_20/build.gradle.kts index 6d748f26..fb03d1e6 100644 --- a/plugins/fancynpcs/implementation_1_20/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_20/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_20_1/build.gradle.kts b/plugins/fancynpcs/implementation_1_20_1/build.gradle.kts index 6c4e051d..89b4df3a 100644 --- a/plugins/fancynpcs/implementation_1_20_1/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_20_1/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_20_2/build.gradle.kts b/plugins/fancynpcs/implementation_1_20_2/build.gradle.kts index 0a736f4e..07c3c71d 100644 --- a/plugins/fancynpcs/implementation_1_20_2/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_20_2/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_20_4/build.gradle.kts b/plugins/fancynpcs/implementation_1_20_4/build.gradle.kts index 04d383a6..09f2750c 100644 --- a/plugins/fancynpcs/implementation_1_20_4/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_20_4/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_20_6/build.gradle.kts b/plugins/fancynpcs/implementation_1_20_6/build.gradle.kts index c323754d..6c7b3ae9 100644 --- a/plugins/fancynpcs/implementation_1_20_6/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_20_6/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_1/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_1/build.gradle.kts index 9c4b2793..5b343d8a 100644 --- a/plugins/fancynpcs/implementation_1_21_1/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_21_1/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_11/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_11/build.gradle.kts new file mode 100644 index 00000000..d9478088 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("java-library") + id("io.papermc.paperweight.userdev") +} + +paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION + +dependencies { + paperweight.paperDevBundle("25w45a-R0.1-SNAPSHOT") +// compileOnly("com.fancyinnovations:fancymc:1.21.6-pre2") + + compileOnly(project(":plugins:fancynpcs:fn-api")) + compileOnly(project(":libraries:common")) + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") +} + + +tasks { + javadoc { + options.encoding = Charsets.UTF_8.name() + } + + compileJava { + options.encoding = Charsets.UTF_8.name() + options.release = 21 + } +} \ No newline at end of file diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/FakeSynchronizer.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/FakeSynchronizer.java new file mode 100644 index 00000000..864a1e3a --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/FakeSynchronizer.java @@ -0,0 +1,31 @@ +package de.oliver.fancynpcs.v1_21_11; + +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.server.level.ServerEntity; +import net.minecraft.server.level.ServerPlayer; + +import java.util.function.Predicate; + +public class FakeSynchronizer implements ServerEntity.Synchronizer { + + public static final FakeSynchronizer INSTANCE = new FakeSynchronizer(); + + private FakeSynchronizer() { + } + + @Override + public void sendToTrackingPlayers(Packet packet) { + + } + + @Override + public void sendToTrackingPlayersAndSelf(Packet packet) { + + } + + @Override + public void sendToTrackingPlayersFiltered(Packet packet, Predicate predicate) { + + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/Npc_1_21_11.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/Npc_1_21_11.java new file mode 100644 index 00000000..e802286f --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/Npc_1_21_11.java @@ -0,0 +1,459 @@ +package de.oliver.fancynpcs.v1_21_11; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import com.mojang.datafixers.util.Pair; +import de.oliver.fancylib.ReflectionUtils; +import de.oliver.fancynpcs.api.FancyNpcsPlugin; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.api.NpcData; +import de.oliver.fancynpcs.api.events.NpcSpawnEvent; +import de.oliver.fancynpcs.api.utils.NpcEquipmentSlot; +import io.papermc.paper.adventure.PaperAdventure; +import net.minecraft.Optionull; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.RemoteChatSession; +import net.minecraft.network.protocol.game.*; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.resources.Identifier; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerEntity; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.scores.PlayerTeam; +import net.minecraft.world.scores.Scoreboard; +import net.minecraft.world.scores.Team; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.Player; +import org.lushplugins.chatcolorhandler.ModernChatColorHandler; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class Npc_1_21_11 extends Npc { + + private final String localName; + private final UUID uuid; + private Entity npc; + private Display.TextDisplay sittingVehicle; + + public Npc_1_21_11(NpcData data) { + super(data); + + this.localName = generateLocalName(); + this.uuid = UUID.randomUUID(); + } + + @Override + public void create() { + MinecraftServer minecraftServer = ((CraftServer) Bukkit.getServer()).getServer(); + ServerLevel serverLevel = ((CraftWorld) data.getLocation().getWorld()).getHandle(); + GameProfile gameProfile = new GameProfile(uuid, localName); + + if (data.getType() == org.bukkit.entity.EntityType.PLAYER) { + npc = new ServerPlayer(minecraftServer, serverLevel, new GameProfile(uuid, ""), ClientInformation.createDefault()); + ((ServerPlayer) npc).gameProfile = gameProfile; + } else { + Optional>> entityTypeReference = BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(data.getType().getKey())); + EntityType nmsType = entityTypeReference.get().value(); // TODO handle empty + EntityType.EntityFactory factory = (EntityType.EntityFactory) ReflectionUtils.getValue(nmsType, "factory"); // EntityType.factory + npc = factory.create(nmsType, serverLevel); + isTeamCreated.clear(); + } + } + + @Override + public void spawn(Player player) { + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + if (npc == null) { + return; + } + + if (!data.getLocation().getWorld().getName().equalsIgnoreCase(serverPlayer.level().getWorld().getName())) { + return; + } + + if (data.getSkinData() != null && data.getSkinData().hasTexture()) { + String value = data.getSkinData().getTextureValue(); + String signature = data.getSkinData().getTextureSignature(); + + PropertyMap propertyMap = new PropertyMap( + ImmutableMultimap.of( + "textures", + new Property("textures", value, signature) + ) + ); + ((ServerPlayer) npc).gameProfile = new GameProfile(uuid, localName, propertyMap); + } + + NpcSpawnEvent spawnEvent = new NpcSpawnEvent(this, player); + spawnEvent.callEvent(); + if (spawnEvent.isCancelled()) { + return; + } + + + if (npc instanceof ServerPlayer npcPlayer) { + EnumSet actions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class); + actions.add(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER); + actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); + if (data.isShowInTab()) { + actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); + } + + ClientboundPlayerInfoUpdatePacket playerInfoPacket = new ClientboundPlayerInfoUpdatePacket(actions, getEntry(npcPlayer, serverPlayer)); + serverPlayer.connection.send(playerInfoPacket); + + if (data.isSpawnEntity()) { + npc.setPos(data.getLocation().x(), data.getLocation().y(), data.getLocation().z()); + } + } + + ClientboundAddEntityPacket addEntityPacket = new ClientboundAddEntityPacket( + npc.getId(), + npc.getUUID(), + data.getLocation().x(), + data.getLocation().y(), + data.getLocation().z(), + data.getLocation().getPitch(), + data.getLocation().getYaw(), + npc.getType(), + 0, + Vec3.ZERO, + data.getLocation().getYaw() + ); + serverPlayer.connection.send(addEntityPacket); + + isVisibleForPlayer.put(player.getUniqueId(), true); + + + int removeNpcsFromPlayerlistDelay = FancyNpcsPlugin.get().getFancyNpcConfig().getRemoveNpcsFromPlayerlistDelay(); + if (!data.isShowInTab() && removeNpcsFromPlayerlistDelay > 0) { + FancyNpcsPlugin.get().getNpcThread().schedule(() -> { + ClientboundPlayerInfoRemovePacket playerInfoRemovePacket = new ClientboundPlayerInfoRemovePacket(List.of(npc.getUUID())); + serverPlayer.connection.send(playerInfoRemovePacket); + }, removeNpcsFromPlayerlistDelay, TimeUnit.MILLISECONDS); + } + + update(player); + } + + @Override + public void remove(Player player) { + if (npc == null) { + return; + } + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + if (npc instanceof ServerPlayer npcPlayer) { + ClientboundPlayerInfoRemovePacket playerInfoRemovePacket = new ClientboundPlayerInfoRemovePacket(List.of((npcPlayer.getUUID()))); + serverPlayer.connection.send(playerInfoRemovePacket); + } + + // remove entity + ClientboundRemoveEntitiesPacket removeEntitiesPacket = new ClientboundRemoveEntitiesPacket(npc.getId()); + serverPlayer.connection.send(removeEntitiesPacket); + + // remove sitting vehicle + if (sittingVehicle != null) { + ClientboundRemoveEntitiesPacket removeSittingVehiclePacket = new ClientboundRemoveEntitiesPacket(sittingVehicle.getId()); + serverPlayer.connection.send(removeSittingVehiclePacket); + } + + isVisibleForPlayer.put(serverPlayer.getUUID(), false); + } + + @Override + public void lookAt(Player player, Location location) { + if (npc == null) { + return; + } + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + npc.setRot(location.getYaw(), location.getPitch()); + npc.setYHeadRot(location.getYaw()); + npc.setXRot(location.getPitch()); + npc.setYRot(location.getYaw()); + + ClientboundTeleportEntityPacket teleportEntityPacket = new ClientboundTeleportEntityPacket( + npc.getId(), + new PositionMoveRotation( + new Vec3(data.getLocation().getX(), data.getLocation().getY(), data.getLocation().getZ()), + Vec3.ZERO, + location.getYaw(), + location.getPitch() + ), + Set.of(), + false + ); + serverPlayer.connection.send(teleportEntityPacket); + + float angelMultiplier = 256f / 360f; + ClientboundRotateHeadPacket rotateHeadPacket = new ClientboundRotateHeadPacket(npc, (byte) (location.getYaw() * angelMultiplier)); + serverPlayer.connection.send(rotateHeadPacket); + } + + @Override + public void update(Player player, boolean swingArm) { + if (npc == null) { + return; + } + + if (!isVisibleForPlayer.getOrDefault(player.getUniqueId(), false)) { + return; + } + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + PlayerTeam team = new PlayerTeam(new Scoreboard(), "npc-" + localName); + team.getPlayers().clear(); + team.getPlayers().add(npc instanceof ServerPlayer npcPlayer ? npcPlayer.getGameProfile().name() : npc.getStringUUID()); + team.setColor(PaperAdventure.asVanilla(data.getGlowingColor())); + if (!data.isCollidable()) { + team.setCollisionRule(Team.CollisionRule.NEVER); + } + + net.kyori.adventure.text.Component displayName = ModernChatColorHandler.translate(data.getDisplayName(), serverPlayer.getBukkitEntity()); + Component vanillaComponent = PaperAdventure.asVanilla(displayName); + if (!(npc instanceof ServerPlayer)) { + npc.setCustomName(vanillaComponent); + npc.setCustomNameVisible(true); + } else { + npc.setCustomName(null); + npc.setCustomNameVisible(false); + } + + if (data.getDisplayName().equalsIgnoreCase("")) { + team.setNameTagVisibility(Team.Visibility.NEVER); + npc.setCustomName(null); + npc.setCustomNameVisible(false); + } else { + team.setNameTagVisibility(Team.Visibility.ALWAYS); + } + + if (npc instanceof ServerPlayer npcPlayer) { + team.setPlayerPrefix(vanillaComponent); + npcPlayer.listName = vanillaComponent; + + EnumSet actions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class); + actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); + if (data.isShowInTab()) { + actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); + } + + ClientboundPlayerInfoUpdatePacket playerInfoPacket = new ClientboundPlayerInfoUpdatePacket(actions, getEntry(npcPlayer, serverPlayer)); + serverPlayer.connection.send(playerInfoPacket); + } + + boolean isTeamCreatedForPlayer = this.isTeamCreated.getOrDefault(player.getUniqueId(), false); + serverPlayer.connection.send(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, !isTeamCreatedForPlayer)); + isTeamCreated.put(player.getUniqueId(), true); + + npc.setGlowingTag(data.isGlowing()); + + data.applyAllAttributes(this); + + // Set equipment + List> equipmentList = new ArrayList<>(); + if (data.getEquipment() != null) { + for (NpcEquipmentSlot slot : data.getEquipment().keySet()) { + equipmentList.add(new Pair<>(EquipmentSlot.byName(slot.toNmsName()), CraftItemStack.asNMSCopy(data.getEquipment().get(slot)))); + } + } + + // Set body slot (from happy ghast harness attribute) + if (npc instanceof LivingEntity livingEntity) { + ItemStack bodySlot = livingEntity.getItemBySlot(EquipmentSlot.BODY); + if (!bodySlot.isEmpty()) { + equipmentList.add(new Pair<>(EquipmentSlot.BODY, bodySlot)); + } + } + + if (!equipmentList.isEmpty()) { + ClientboundSetEquipmentPacket setEquipmentPacket = new ClientboundSetEquipmentPacket(npc.getId(), equipmentList); + serverPlayer.connection.send(setEquipmentPacket); + } + + if (npc instanceof ServerPlayer) { + // Enable second layer of skin (https://wiki.vg/Entity_metadata#Player) + npc.getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, (byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40)); + } + + refreshEntityData(player); + + if (data.isSpawnEntity() && data.getLocation() != null) { + move(player, swingArm); + } + + NpcAttribute playerPoseAttr = FancyNpcsPlugin.get().getAttributeManager().getAttributeByName(org.bukkit.entity.EntityType.PLAYER, "pose"); + if (data.getAttributes().containsKey(playerPoseAttr)) { + String pose = data.getAttributes().get(playerPoseAttr); + + if (pose.equals("sitting")) { + setSitting(serverPlayer); + } else { + if (sittingVehicle != null) { + ClientboundRemoveEntitiesPacket removeSittingVehiclePacket = new ClientboundRemoveEntitiesPacket(sittingVehicle.getId()); + serverPlayer.connection.send(removeSittingVehiclePacket); + } + } + + } + + if (npc instanceof LivingEntity) { + Holder.Reference scaleAttribute = BuiltInRegistries.ATTRIBUTE.get(Identifier.parse("minecraft:scale")).get(); + AttributeInstance attributeInstance = new AttributeInstance(scaleAttribute, (a) -> { + }); + attributeInstance.setBaseValue(data.getScale()); + + ClientboundUpdateAttributesPacket updateAttributesPacket = new ClientboundUpdateAttributesPacket(npc.getId(), List.of(attributeInstance)); + serverPlayer.connection.send(updateAttributesPacket); + + } + } + + @Override + protected void refreshEntityData(Player player) { + if (!isVisibleForPlayer.getOrDefault(player.getUniqueId(), false)) { + return; + } + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + SynchedEntityData.DataItem[] itemsById = (SynchedEntityData.DataItem[]) ReflectionUtils.getValue(npc.getEntityData(), "itemsById"); // itemsById + List> entityData = new ArrayList<>(); + for (SynchedEntityData.DataItem dataItem : itemsById) { + entityData.add(dataItem.value()); + } + ClientboundSetEntityDataPacket setEntityDataPacket = new ClientboundSetEntityDataPacket(npc.getId(), entityData); + serverPlayer.connection.send(setEntityDataPacket); + } + + public void move(Player player, boolean swingArm) { + if (npc == null) { + return; + } + + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + npc.setPosRaw(data.getLocation().x(), data.getLocation().y(), data.getLocation().z()); + npc.setRot(data.getLocation().getYaw(), data.getLocation().getPitch()); + npc.setYHeadRot(data.getLocation().getYaw()); + npc.setXRot(data.getLocation().getPitch()); + npc.setYRot(data.getLocation().getYaw()); + + ClientboundTeleportEntityPacket teleportEntityPacket = new ClientboundTeleportEntityPacket( + npc.getId(), + new PositionMoveRotation( + new Vec3(data.getLocation().getX(), data.getLocation().getY(), data.getLocation().getZ()), + Vec3.ZERO, + data.getLocation().getYaw(), + data.getLocation().getPitch() + ), + Set.of(), + false + ); + serverPlayer.connection.send(teleportEntityPacket); + + float angelMultiplier = 256f / 360f; + ClientboundRotateHeadPacket rotateHeadPacket = new ClientboundRotateHeadPacket(npc, (byte) (data.getLocation().getYaw() * angelMultiplier)); + serverPlayer.connection.send(rotateHeadPacket); + + if (swingArm && npc instanceof ServerPlayer) { + ClientboundAnimatePacket animatePacket = new ClientboundAnimatePacket(npc, 0); + serverPlayer.connection.send(animatePacket); + } + } + + private ClientboundPlayerInfoUpdatePacket.Entry getEntry(ServerPlayer npcPlayer, ServerPlayer viewer) { + GameProfile profile; + if (!data.isMirrorSkin()) { + profile = npcPlayer.getGameProfile(); + } else { + Property textures = viewer.getGameProfile().properties().get("textures").iterator().next(); + + PropertyMap propertyMap = new PropertyMap( + ImmutableMultimap.of( + "textures", + new Property("textures", textures.value(), textures.signature()) + ) + ); + profile = new GameProfile(uuid, localName, propertyMap); + } + + return new ClientboundPlayerInfoUpdatePacket.Entry( + npcPlayer.getUUID(), + profile, + data.isShowInTab(), + 0, + npcPlayer.gameMode.getGameModeForPlayer(), + npcPlayer.getTabListDisplayName(), + true, + -1, + Optionull.map(npcPlayer.getChatSession(), RemoteChatSession::asData) + ); + } + + public void setSitting(ServerPlayer serverPlayer) { + if (npc == null) { + return; + } + + if (sittingVehicle == null) { + sittingVehicle = new Display.TextDisplay(EntityType.TEXT_DISPLAY, ((CraftWorld) data.getLocation().getWorld()).getHandle()); + } + + sittingVehicle.setPos(data.getLocation().x(), data.getLocation().y(), data.getLocation().z()); + + ServerEntity serverEntity = new ServerEntity( + serverPlayer.level(), + sittingVehicle, + 0, + false, + FakeSynchronizer.INSTANCE, + Set.of() + ); + ClientboundAddEntityPacket addEntityPacket = new ClientboundAddEntityPacket(sittingVehicle, serverEntity); + serverPlayer.connection.send(addEntityPacket); + + sittingVehicle.passengers = ImmutableList.of(npc); + + ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(sittingVehicle); + serverPlayer.connection.send(packet); + } + + @Override + public float getEyeHeight() { + return npc.getEyeHeight(); + } + + @Override + public int getEntityId() { + return npc.getId(); + } + + public Entity getNpc() { + return npc; + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/ReflectionHelper.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/ReflectionHelper.java new file mode 100644 index 00000000..e87d16a5 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/ReflectionHelper.java @@ -0,0 +1,13 @@ +package de.oliver.fancynpcs.v1_21_11; + +import de.oliver.fancylib.ReflectionUtils; +import de.oliver.fancynpcs.api.Npc; +import net.minecraft.world.entity.Entity; + +public class ReflectionHelper { + + public static T getEntity(Npc npc) { + return (T) ReflectionUtils.getValue(npc, "npc"); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AgeableMobAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AgeableMobAttributes.java new file mode 100644 index 00000000..b28f8ce2 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AgeableMobAttributes.java @@ -0,0 +1,38 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.AgeableMob; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AgeableMobAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "baby", + List.of("true", "false"), + Arrays.stream(EntityType.values()) + .filter(type -> type.getEntityClass() != null && Ageable.class.isAssignableFrom(type.getEntityClass())) + .toList(), + AgeableMobAttributes::setBaby + )); + + return attributes; + } + + private static void setBaby(Npc npc, String value) { + AgeableMob mob = ReflectionHelper.getEntity(npc); + + boolean isBaby = Boolean.parseBoolean(value); + + mob.setBaby(isBaby); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AllayAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AllayAttributes.java new file mode 100644 index 00000000..a84d599f --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AllayAttributes.java @@ -0,0 +1,34 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.allay.Allay; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class AllayAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "dancing", + List.of("true", "false"), + List.of(EntityType.ALLAY), + AllayAttributes::setDancing + )); + + return attributes; + } + + private static void setDancing(Npc npc, String value) { + Allay allay = ReflectionHelper.getEntity(npc); + + boolean dancing = Boolean.parseBoolean(value); + allay.setDancing(dancing); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ArmadilloAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ArmadilloAttributes.java new file mode 100644 index 00000000..cf9530ea --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ArmadilloAttributes.java @@ -0,0 +1,35 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.armadillo.Armadillo; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class ArmadilloAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "pose", + List.of("idle", "rolling", "unrolling", "scared"), + List.of(EntityType.ARMADILLO), + ArmadilloAttributes::setPose + )); + + return attributes; + } + + private static void setPose(Npc npc, String value) { + Armadillo armadillo = ReflectionHelper.getEntity(npc); + + Armadillo.ArmadilloState state = Armadillo.ArmadilloState.valueOf(value.toUpperCase()); + + armadillo.switchToState(state); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ArmorStandAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ArmorStandAttributes.java new file mode 100644 index 00000000..217ac5ec --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ArmorStandAttributes.java @@ -0,0 +1,35 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.decoration.ArmorStand; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class ArmorStandAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "show_arms", + List.of("true", "false"), + List.of(EntityType.ARMOR_STAND), + ArmorStandAttributes::setShowArms + )); + + return attributes; + } + + private static void setShowArms(Npc npc, String value) { + ArmorStand armorStand = ReflectionHelper.getEntity(npc); + + boolean showArms = Boolean.parseBoolean(value.toLowerCase()); + + armorStand.setShowArms(showArms); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/Attributes_1_21_11.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/Attributes_1_21_11.java new file mode 100644 index 00000000..fb88e8db --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/Attributes_1_21_11.java @@ -0,0 +1,56 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.NpcAttribute; + +import java.util.ArrayList; +import java.util.List; + +public class Attributes_1_21_11 { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.addAll(EntityAttributes.getAllAttributes()); + attributes.addAll(LivingEntityAttributes.getAllAttributes()); + attributes.addAll(AgeableMobAttributes.getAllAttributes()); + attributes.addAll(IllagerAttributes.getAllAttributes()); + attributes.addAll(SpellCasterAttributes.getAllAttributes()); + + attributes.addAll(PlayerAttributes.getAllAttributes()); + attributes.addAll(SheepAttributes.getAllAttributes()); + attributes.addAll(VillagerAttributes.getAllAttributes()); + attributes.addAll(FrogAttributes.getAllAttributes()); + attributes.addAll(HorseAttributes.getAllAttributes()); + attributes.addAll(ParrotAttributes.getAllAttributes()); + attributes.addAll(AxolotlAttributes.getAllAttributes()); + attributes.addAll(TropicalFishAttributes.getAllAttributes()); + attributes.addAll(FoxAttributes.getAllAttributes()); + attributes.addAll(PandaAttributes.getAllAttributes()); + attributes.addAll(GoatAttributes.getAllAttributes()); + attributes.addAll(AllayAttributes.getAllAttributes()); + attributes.addAll(CamelAttributes.getAllAttributes()); + attributes.addAll(RabbitAttributes.getAllAttributes()); + attributes.addAll(PiglinAttributes.getAllAttributes()); + attributes.addAll(CatAttributes.getAllAttributes()); + attributes.addAll(ShulkerAttributes.getAllAttributes()); + attributes.addAll(WolfAttributes.getAllAttributes()); + attributes.addAll(SlimeAttributes.getAllAttributes()); + attributes.addAll(PigAttributes.getAllAttributes()); + attributes.addAll(CowAttributes.getAllAttributes()); + attributes.addAll(ChickenAttributes.getAllAttributes()); + attributes.addAll(ArmorStandAttributes.getAllAttributes()); + attributes.addAll(BeeAttributes.getAllAttributes()); + attributes.addAll(VexAttributes.getAllAttributes()); + attributes.addAll(ArmadilloAttributes.getAllAttributes()); + attributes.addAll(HappyGhastAttributes.getAllAttributes()); + attributes.addAll(SnifferAttributes.getAllAttributes()); + + attributes.addAll(DisplayAttributes.getAllAttributes()); + attributes.addAll(TextDisplayAttributes.getAllAttributes()); + attributes.addAll(BlockDisplayAttributes.getAllAttributes()); + attributes.addAll(InteractionAttributes.getAllAttributes()); + + return attributes; + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AxolotlAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AxolotlAttributes.java new file mode 100644 index 00000000..16c3f944 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/AxolotlAttributes.java @@ -0,0 +1,51 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.axolotl.Axolotl; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AxolotlAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + Arrays.stream(Axolotl.Variant.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.AXOLOTL), + AxolotlAttributes::setVariant + )); + + attributes.add(new NpcAttribute( + "playing_dead", + List.of("true", "false"), + List.of(EntityType.AXOLOTL), + AxolotlAttributes::setPlayingDead + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + Axolotl axolotl = ReflectionHelper.getEntity(npc); + + Axolotl.Variant variant = Axolotl.Variant.valueOf(value.toUpperCase()); + axolotl.setVariant(variant); + } + + private static void setPlayingDead(Npc npc, String value) { + Axolotl axolotl = ReflectionHelper.getEntity(npc); + + boolean playingDead = Boolean.parseBoolean(value); + axolotl.setPlayingDead(playingDead); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/BeeAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/BeeAttributes.java new file mode 100644 index 00000000..fd78d69c --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/BeeAttributes.java @@ -0,0 +1,84 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.Bee; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class BeeAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "angry", + List.of("true", "false"), + List.of(EntityType.BEE), + BeeAttributes::setAngry + )); + + attributes.add(new NpcAttribute( + "sting", + List.of("true", "false"), + List.of(EntityType.BEE), + BeeAttributes::setSting + )); + + attributes.add(new NpcAttribute( + "nectar", + List.of("true", "false"), + List.of(EntityType.BEE), + BeeAttributes::setNectar + )); + + attributes.add(new NpcAttribute( + "rolling", + List.of("true", "false"), + List.of(EntityType.BEE), + BeeAttributes::setRolling + )); + + return attributes; + } + + private static void setAngry(Npc npc, String value) { + Bee bee = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "true" -> bee.setPersistentAngerEndTime(1); + case "false" -> bee.setPersistentAngerEndTime(0); + } + } + + private static void setSting(Npc npc, String value) { + Bee bee = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "true" -> bee.setHasStung(false); + case "false" -> bee.setHasStung(true); + } + } + + private static void setNectar(Npc npc, String value) { + Bee bee = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "true" -> bee.setHasNectar(true); + case "false" -> bee.setHasNectar(false); + } + } + + private static void setRolling(Npc npc, String value) { + Bee bee = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "true" -> bee.setRolling(true); + case "false" -> bee.setRolling(false); + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/BlockDisplayAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/BlockDisplayAttributes.java new file mode 100644 index 00000000..5b07921a --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/BlockDisplayAttributes.java @@ -0,0 +1,41 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.Identifier; +import net.minecraft.world.entity.Display; +import net.minecraft.world.level.block.Block; +import org.bukkit.Material; +import org.bukkit.Registry; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class BlockDisplayAttributes { + + private static final List BLOCKS = Registry.MATERIAL.stream().filter(Material::isBlock).map(it -> it.key().value()).toList(); + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "block", + BLOCKS, + List.of(EntityType.BLOCK_DISPLAY), + BlockDisplayAttributes::setBlock + )); + + return attributes; + } + + private static void setBlock(Npc npc, String value) { + Display.BlockDisplay display = ReflectionHelper.getEntity(npc); + + Block block = BuiltInRegistries.BLOCK.getValue(Identifier.parse(value.toLowerCase())); + + display.setBlockState(block.defaultBlockState()); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CamelAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CamelAttributes.java new file mode 100644 index 00000000..fe2e1338 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CamelAttributes.java @@ -0,0 +1,54 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.FancyNpcsPlugin; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.animal.camel.Camel; +import org.bukkit.Bukkit; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class CamelAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "sitting", "dashing"), + List.of(EntityType.CAMEL), + CamelAttributes::setPose + )); + + return attributes; + } + + private static void setPose(Npc npc, String value) { + Camel camel = ReflectionHelper.getEntity(npc); + + Bukkit.getScheduler().runTask(FancyNpcsPlugin.get().getPlugin(), () -> { + switch (value.toLowerCase()) { + case "standing" -> { + camel.setPose(Pose.STANDING); + camel.setDashing(false); + camel.resetLastPoseChangeTick(camel.level().getGameTime()); + } + case "sitting" -> { + camel.setPose(Pose.SITTING); + camel.setDashing(false); + camel.resetLastPoseChangeTick(-camel.level().getGameTime()); + } + case "dashing" -> { + camel.setPose(Pose.STANDING); + camel.setDashing(true); + camel.resetLastPoseChangeTick(camel.level().getGameTime()); + } + } + }); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CatAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CatAttributes.java new file mode 100644 index 00000000..ac2d6872 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CatAttributes.java @@ -0,0 +1,107 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.animal.Cat; +import net.minecraft.world.entity.animal.CatVariant; +import net.minecraft.world.item.DyeColor; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class CatAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + getCatVariantRegistry() + .listElementIds() + .map(id -> id.identifier().getPath()) + .toList(), + List.of(EntityType.CAT), + CatAttributes::setVariant + )); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "sleeping", "sitting"), + List.of(EntityType.CAT), + CatAttributes::setPose + )); + + attributes.add(new NpcAttribute( + "collar_color", + List.of("RED", "BLUE", "YELLOW", "GREEN", "PURPLE", "ORANGE", "LIME", "MAGENTA", "BROWN", "WHITE", "GRAY", "LIGHT_GRAY", "LIGHT_BLUE", "BLACK", "CYAN", "PINK", "NONE"), + List.of(EntityType.CAT), + CatAttributes::setCollarColor + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + final Cat cat = ReflectionHelper.getEntity(npc); + + Holder variant = getCatVariantRegistry() + .get(ResourceKey.create( + Registries.CAT_VARIANT, + Identifier.withDefaultNamespace(value.toLowerCase()) + )) + .orElseThrow(); + + cat.setVariant(variant); + } + + private static void setPose(Npc npc, String value) { + final Cat cat = ReflectionHelper.getEntity(npc); + switch (value.toLowerCase()) { + case "standing" -> { + cat.setInSittingPose(false, false); + cat.setLying(false); + } + case "sleeping" -> { + cat.setInSittingPose(false, false); + cat.setLying(true); + } + case "sitting" -> { + cat.setLying(false); + cat.setOrderedToSit(true); + cat.setInSittingPose(true, false); + } + } + } + + private static HolderLookup.RegistryLookup getCatVariantRegistry() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.CAT_VARIANT); + } + + private static void setCollarColor(Npc npc, String value) { + Cat cat = ReflectionHelper.getEntity(npc); + + if (value.equalsIgnoreCase("none") || value.isEmpty()) { + // Reset to no collar + cat.setTame(false, false); + return; + } + + try { + DyeColor color = DyeColor.valueOf(value.toUpperCase()); + if (!cat.isTame()) { + cat.setTame(true, false); + } + cat.setCollarColor(color); + } catch (IllegalArgumentException e) { + System.out.println("Invalid cat collar color: " + value); + } + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ChickenAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ChickenAttributes.java new file mode 100644 index 00000000..f9945c04 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ChickenAttributes.java @@ -0,0 +1,54 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.animal.Chicken; +import net.minecraft.world.entity.animal.ChickenVariant; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class ChickenAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + getChickenVariantRegistry() + .listElementIds() + .map(id -> id.identifier().getPath()) + .toList(), + List.of(EntityType.CHICKEN), + ChickenAttributes::setVariant + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + final Chicken cow = ReflectionHelper.getEntity(npc); + + Holder variant = getChickenVariantRegistry() + .get(ResourceKey.create( + Registries.CHICKEN_VARIANT, + Identifier.withDefaultNamespace(value.toLowerCase()) + )) + .orElseThrow(); + + cow.setVariant(variant); + } + + private static HolderLookup.RegistryLookup getChickenVariantRegistry() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.CHICKEN_VARIANT); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CowAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CowAttributes.java new file mode 100644 index 00000000..f4de238a --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/CowAttributes.java @@ -0,0 +1,54 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.animal.Cow; +import net.minecraft.world.entity.animal.CowVariant; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class CowAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + getCowVariantRegistry() + .listElementIds() + .map(id -> id.identifier().getPath()) + .toList(), + List.of(EntityType.COW), + CowAttributes::setVariant + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + final Cow cow = ReflectionHelper.getEntity(npc); + + Holder variant = getCowVariantRegistry() + .get(ResourceKey.create( + Registries.COW_VARIANT, + Identifier.withDefaultNamespace(value.toLowerCase()) + )) + .orElseThrow(); + + cow.setVariant(variant); + } + + private static HolderLookup.RegistryLookup getCowVariantRegistry() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.COW_VARIANT); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/DisplayAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/DisplayAttributes.java new file mode 100644 index 00000000..83c19aea --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/DisplayAttributes.java @@ -0,0 +1,37 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.Display; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DisplayAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "billboard", + Arrays.stream(org.bukkit.entity.Display.Billboard.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.TEXT_DISPLAY, EntityType.BLOCK_DISPLAY, EntityType.ITEM_DISPLAY), + DisplayAttributes::setBillboard + )); + + return attributes; + } + + private static void setBillboard(Npc npc, String value) { + Display display = ReflectionHelper.getEntity(npc); + + Display.BillboardConstraints billboard = Display.BillboardConstraints.valueOf(value.toUpperCase()); + display.setBillboardConstraints(billboard); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/EntityAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/EntityAttributes.java new file mode 100644 index 00000000..d9f74dd4 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/EntityAttributes.java @@ -0,0 +1,103 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.Entity; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class EntityAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "on_fire", + List.of("true", "false"), + Arrays.stream(EntityType.values()).toList(), + EntityAttributes::setOnFire + )); + + attributes.add(new NpcAttribute( + "invisible", + List.of("true", "false"), + Arrays.stream(EntityType.values()).toList(), + EntityAttributes::setInvisible + )); + + attributes.add(new NpcAttribute( + "silent", + List.of("true", "false"), + Arrays.stream(EntityType.values()).toList(), + EntityAttributes::setSilent + )); + + attributes.add(new NpcAttribute( + "shaking", + List.of("true", "false"), + Arrays.stream(EntityType.values()).toList(), + EntityAttributes::setShaking + )); + + attributes.add(new NpcAttribute( + "on_ground", + List.of("true", "false"), + Arrays.stream(EntityType.values()).toList(), + EntityAttributes::setOnGround + )); + + /*attributes.add(new NpcAttribute( + "entity_pose", + Arrays.stream(Pose.values()).map(Enum::toString).toList(), + Arrays.stream(EntityType.values()).toList(), + EntityAttributes::setEntityPose + ));*/ + + return attributes; + } + + private static void setOnFire(Npc npc, String value) { + Entity entity = ReflectionHelper.getEntity(npc); + + boolean onFire = Boolean.parseBoolean(value); + + entity.setSharedFlagOnFire(onFire); + + } + + private static void setInvisible(Npc npc, String value) { + Entity entity = ReflectionHelper.getEntity(npc); + + boolean invisible = Boolean.parseBoolean(value); + + entity.setInvisible(invisible); + } + + private static void setSilent(Npc npc, String value) { + Entity entity = ReflectionHelper.getEntity(npc); + + boolean silent = Boolean.parseBoolean(value); + + entity.setSilent(silent); + } + + private static void setShaking(Npc npc, String value) { + Entity entity = ReflectionHelper.getEntity(npc); + + boolean shaking = Boolean.parseBoolean(value); + + entity.setTicksFrozen(shaking ? entity.getTicksRequiredToFreeze() : 0); + } + + private static void setOnGround(Npc npc, String value) { + Entity entity = ReflectionHelper.getEntity(npc); + + boolean onGround = Boolean.parseBoolean(value); + + entity.setOnGround(onGround); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/FoxAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/FoxAttributes.java new file mode 100644 index 00000000..74b90668 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/FoxAttributes.java @@ -0,0 +1,66 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.Fox; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class FoxAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "type", + Arrays.stream(Fox.Variant.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.FOX), + FoxAttributes::setType + )); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "sleeping", "sitting"), + List.of(EntityType.FOX), + FoxAttributes::setPose + )); + + return attributes; + } + + private static void setType(Npc npc, String value) { + Fox fox = ReflectionHelper.getEntity(npc); + + Fox.Variant type = Fox.Variant.valueOf(value.toUpperCase()); + fox.setVariant(type); + } + + private static void setPose(Npc npc, String value) { + Fox fox = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "standing" -> { + fox.setIsCrouching(false); + fox.setSleeping(false); + fox.setSitting(false, false); + } + case "sleeping" -> { + fox.setSleeping(true); + fox.setSitting(false, false); + fox.setIsCrouching(false); + } + case "sitting" -> { + fox.setSitting(true, false); + fox.setSleeping(false); + fox.setIsCrouching(false); + } + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/FrogAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/FrogAttributes.java new file mode 100644 index 00000000..bdee1e40 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/FrogAttributes.java @@ -0,0 +1,53 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.animal.frog.Frog; +import net.minecraft.world.entity.animal.frog.FrogVariant; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class FrogAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + getFrogVariantRegistry() + .listElementIds() + .map(id -> id.identifier().getPath()) + .toList(), + List.of(EntityType.FROG), + FrogAttributes::setVariant + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + final Frog frog = ReflectionHelper.getEntity(npc); + + Holder variant = getFrogVariantRegistry() + .get(ResourceKey.create( + Registries.FROG_VARIANT, + Identifier.withDefaultNamespace(value.toLowerCase()) + )) + .orElseThrow(); + + frog.setVariant(variant); + } + + private static HolderLookup.RegistryLookup getFrogVariantRegistry() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.FROG_VARIANT); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/GoatAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/GoatAttributes.java new file mode 100644 index 00000000..ff354671 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/GoatAttributes.java @@ -0,0 +1,44 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.goat.Goat; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class GoatAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "horns", + List.of("none", "left", "right", "both"), + List.of(EntityType.GOAT), + GoatAttributes::setHorns + )); + + return attributes; + } + + private static void setHorns(Npc npc, String value) { + Goat goat = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "none" -> goat.removeHorns(); + case "both" -> goat.addHorns(); + case "left" -> { + goat.getEntityData().set(Goat.DATA_HAS_LEFT_HORN, true); + goat.getEntityData().set(Goat.DATA_HAS_RIGHT_HORN, false); + } + case "right" -> { + goat.getEntityData().set(Goat.DATA_HAS_RIGHT_HORN, true); + goat.getEntityData().set(Goat.DATA_HAS_LEFT_HORN, false); + } + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/HappyGhastAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/HappyGhastAttributes.java new file mode 100644 index 00000000..6c35cf41 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/HappyGhastAttributes.java @@ -0,0 +1,57 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.animal.HappyGhast; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class HappyGhastAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "harness", + List.of("white", "orange", "magenta", "light_blue", "yellow", "lime", "pink", "gray", "light_gray", "cyan", "purple", "blue", "brown", "green", "red", "black"), + List.of(EntityType.HAPPY_GHAST), + HappyGhastAttributes::setHarness + )); + + return attributes; + } + + private static void setHarness(Npc npc, String value) { + HappyGhast ghast = ReflectionHelper.getEntity(npc); + + ItemStack harnessItem = switch (value.toLowerCase()) { + case "white" -> Items.WHITE_HARNESS.getDefaultInstance(); + case "orange" -> Items.ORANGE_HARNESS.getDefaultInstance(); + case "magenta" -> Items.MAGENTA_HARNESS.getDefaultInstance(); + case "light_blue" -> Items.LIGHT_BLUE_HARNESS.getDefaultInstance(); + case "yellow" -> Items.YELLOW_HARNESS.getDefaultInstance(); + case "lime" -> Items.LIME_HARNESS.getDefaultInstance(); + case "pink" -> Items.PINK_HARNESS.getDefaultInstance(); + case "gray" -> Items.GRAY_HARNESS.getDefaultInstance(); + case "light_gray" -> Items.LIGHT_GRAY_HARNESS.getDefaultInstance(); + case "cyan" -> Items.CYAN_HARNESS.getDefaultInstance(); + case "purple" -> Items.PURPLE_HARNESS.getDefaultInstance(); + case "blue" -> Items.BLUE_HARNESS.getDefaultInstance(); + case "brown" -> Items.BROWN_HARNESS.getDefaultInstance(); + case "green" -> Items.GREEN_HARNESS.getDefaultInstance(); + case "red" -> Items.RED_HARNESS.getDefaultInstance(); + case "black" -> Items.BLACK_HARNESS.getDefaultInstance(); + default -> Items.AIR.getDefaultInstance(); + }; + + if (!harnessItem.isEmpty()) { + ghast.setItemSlot(EquipmentSlot.BODY, harnessItem); + } + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/HorseAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/HorseAttributes.java new file mode 100644 index 00000000..9a000564 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/HorseAttributes.java @@ -0,0 +1,84 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.horse.Horse; +import net.minecraft.world.entity.animal.horse.Markings; +import net.minecraft.world.entity.animal.horse.Variant; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class HorseAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + Arrays.stream(Variant.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.HORSE), + HorseAttributes::setVariant + )); + + attributes.add(new NpcAttribute( + "markings", + Arrays.stream(Markings.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.HORSE), + HorseAttributes::setMarkings + )); + + attributes.add(new NpcAttribute( + "pose", + List.of("eating", "rearing", "standing"), + Arrays.stream(EntityType.values()) + .filter(type -> type.getEntityClass() != null && (type == EntityType.HORSE || type == EntityType.DONKEY || + type == EntityType.MULE || type == EntityType.SKELETON_HORSE || type == EntityType.ZOMBIE_HORSE)) + .toList(), + HorseAttributes::setPose + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + Horse horse = ReflectionHelper.getEntity(npc); + + Variant variant = Variant.valueOf(value.toUpperCase()); + horse.setVariantAndMarkings(variant, horse.getMarkings()); + } + + private static void setMarkings(Npc npc, String value) { + Horse horse = ReflectionHelper.getEntity(npc); + + Markings markings = Markings.valueOf(value.toUpperCase()); + horse.setVariantAndMarkings(horse.getVariant(), markings); + } + + private static void setPose(Npc npc, String value) { + net.minecraft.world.entity.animal.horse.AbstractHorse horse = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "standing" -> { + horse.setEating(false); + horse.setStanding(0); + } + case "rearing" -> { + horse.setStanding(20); + horse.setEating(false); + } + case "eating" -> { + horse.setStanding(0); + horse.setEating(true); + } + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/IllagerAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/IllagerAttributes.java new file mode 100644 index 00000000..8b25982a --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/IllagerAttributes.java @@ -0,0 +1,39 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.raid.Raider; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Illager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class IllagerAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "celebrating", + List.of("true", "false"), + Arrays.stream(EntityType.values()) + .filter(type -> type.getEntityClass() != null && Illager.class.isAssignableFrom(type.getEntityClass())) + .toList(), + IllagerAttributes::setCelebrating + )); + + return attributes; + } + + private static void setCelebrating(Npc npc, String value) { + Raider raider = ReflectionHelper.getEntity(npc); + + boolean isCelebrating = Boolean.parseBoolean(value); + + raider.setCelebrating(isCelebrating); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/InteractionAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/InteractionAttributes.java new file mode 100644 index 00000000..ba0eb034 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/InteractionAttributes.java @@ -0,0 +1,60 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.Interaction; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class InteractionAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "height", + new ArrayList<>(), + List.of(EntityType.INTERACTION), + InteractionAttributes::setHeight + )); + + attributes.add(new NpcAttribute( + "width", + new ArrayList<>(), + List.of(EntityType.INTERACTION), + InteractionAttributes::setWidth + )); + + return attributes; + } + + private static void setHeight(Npc npc, String value) { + Interaction interaction = ReflectionHelper.getEntity(npc); + + float height; + try { + height = Float.parseFloat(value); + } catch (NumberFormatException e) { + return; + } + + interaction.setHeight(height); + } + + private static void setWidth(Npc npc, String value) { + Interaction interaction = ReflectionHelper.getEntity(npc); + + float width; + try { + width = Float.parseFloat(value); + } catch (NumberFormatException e) { + return; + } + + interaction.setWidth(width); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/LivingEntityAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/LivingEntityAttributes.java new file mode 100644 index 00000000..51da7145 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/LivingEntityAttributes.java @@ -0,0 +1,67 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.InteractionHand; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class LivingEntityAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + /*attributes.add(new NpcAttribute( + "hurt", + List.of("true", "false"), + Arrays.stream(EntityType.values()) + .filter(type -> type.getEntityClass() != null && LivingEntity.class.isAssignableFrom(type.getEntityClass())) + .toList(), + LivingEntityAttributes::setHurt + ));*/ + + attributes.add(new NpcAttribute( + "use_item", + List.of("main_hand", "off_hand", "none"), + Arrays.stream(EntityType.values()) + .filter(type -> type.getEntityClass() != null && LivingEntity.class.isAssignableFrom(type.getEntityClass())) + .toList(), + LivingEntityAttributes::setUseItem + )); + + return attributes; + } + + private static void setHurt(Npc npc, String value) { + net.minecraft.world.entity.LivingEntity livingEntity = ReflectionHelper.getEntity(npc); + + boolean isHurt = Boolean.parseBoolean(value); + + if (isHurt) { + livingEntity.hurtDuration = 1; + livingEntity.hurtTime = 1; + livingEntity.hurtMarked = true; + livingEntity.animateHurt(0); + } else { + livingEntity.hurtDuration = 0; + livingEntity.hurtTime = 0; + livingEntity.hurtMarked = false; + } + } + + private static void setUseItem(Npc npc, String value) { + net.minecraft.world.entity.LivingEntity livingEntity = ReflectionHelper.getEntity(npc); + + switch (value.toUpperCase()) { + case "NONE" -> livingEntity.stopUsingItem(); + case "MAIN_HAND" -> livingEntity.startUsingItem(InteractionHand.MAIN_HAND, true); + case "OFF_HAND" -> livingEntity.startUsingItem(InteractionHand.OFF_HAND, true); + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PandaAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PandaAttributes.java new file mode 100644 index 00000000..64c58194 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PandaAttributes.java @@ -0,0 +1,101 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancylib.ReflectionUtils; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.animal.Panda; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class PandaAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "gene", + Arrays.stream(Panda.Gene.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.PANDA), + PandaAttributes::setGene + )); + + attributes.add(new NpcAttribute( + "eating", + List.of("true", "false"), + List.of(EntityType.PANDA), + PandaAttributes::setEating + )); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "sitting", "onBack", "rolling"), + List.of(EntityType.PANDA), + PandaAttributes::setPose + )); + + return attributes; + } + + private static void setGene(Npc npc, String value) { + Panda panda = ReflectionHelper.getEntity(npc); + + Panda.Gene gene = Panda.Gene.valueOf(value.toUpperCase()); + panda.setMainGene(gene); + } + + private static void setPose(Npc npc, String value) { + Panda panda = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "standing" -> { + setFlag(panda, 8, false); //sitting + panda.roll(false); + panda.setOnBack(false); + } + case "sitting" -> { + panda.roll(false); + panda.setOnBack(false); + setFlag(panda, 8, true); //sitting + } + case "onback" -> { + setFlag(panda, 8, false); //sitting + panda.roll(false); + panda.setOnBack(true); + } + case "rolling" -> { + setFlag(panda, 8, false); //sitting + panda.setOnBack(false); + panda.roll(true); + } + } + } + + private static void setEating(Npc npc, String value) { + Panda panda = ReflectionHelper.getEntity(npc); + + boolean eating = Boolean.parseBoolean(value); + + panda.eat(eating); + } + + private static void setFlag(Panda panda, int mask, boolean value) { + EntityDataAccessor DATA_ID_FLAGS = (EntityDataAccessor) ReflectionUtils.getValue(panda, "DATA_ID_FLAGS"); + + byte b0 = panda.getEntityData().get(DATA_ID_FLAGS); + + if (value) { + panda.getEntityData().set(DATA_ID_FLAGS, (byte) (b0 | mask)); + } else { + panda.getEntityData().set(DATA_ID_FLAGS, (byte) (b0 & ~mask)); + } + + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ParrotAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ParrotAttributes.java new file mode 100644 index 00000000..09d8741b --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ParrotAttributes.java @@ -0,0 +1,59 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.Parrot; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ParrotAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + Arrays.stream(Parrot.Variant.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.PARROT), + ParrotAttributes::setVariant + )); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "sitting"), + List.of(EntityType.PARROT), + ParrotAttributes::setPose + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + Parrot parrot = ReflectionHelper.getEntity(npc); + + Parrot.Variant variant = Parrot.Variant.valueOf(value.toUpperCase()); + parrot.setVariant(variant); + } + + private static void setPose(Npc npc, String value) { + Parrot parrot = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "standing" -> { + parrot.setOrderedToSit(false); + parrot.setInSittingPose(false, false); + } + case "sitting" -> { + parrot.setOrderedToSit(true); + parrot.setInSittingPose(true, false); + } + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PigAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PigAttributes.java new file mode 100644 index 00000000..286bba0d --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PigAttributes.java @@ -0,0 +1,73 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.animal.Pig; +import net.minecraft.world.entity.animal.PigVariant; +import net.minecraft.world.item.Items; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class PigAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + getPigVariantRegistry() + .listElementIds() + .map(id -> id.identifier().getPath()) + .toList(), + List.of(EntityType.PIG), + PigAttributes::setVariant + )); + + attributes.add(new NpcAttribute( + "has_saddle", + List.of("true", "false"), + List.of(EntityType.PIG), + PigAttributes::setHasSaddle + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + final Pig pig = ReflectionHelper.getEntity(npc); + + Holder variant = getPigVariantRegistry() + .get(ResourceKey.create( + Registries.PIG_VARIANT, + Identifier.withDefaultNamespace(value.toLowerCase()) + )) + .orElseThrow(); + + pig.setVariant(variant); + } + + private static void setHasSaddle(Npc npc, String value) { + Pig pig = ReflectionHelper.getEntity(npc); + + boolean hasSaddle = Boolean.parseBoolean(value.toLowerCase()); + + if (hasSaddle) { + pig.setItemSlot(EquipmentSlot.SADDLE, Items.SADDLE.getDefaultInstance()); + } + } + + private static HolderLookup.RegistryLookup getPigVariantRegistry() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.PIG_VARIANT); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PiglinAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PiglinAttributes.java new file mode 100644 index 00000000..8321720d --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PiglinAttributes.java @@ -0,0 +1,34 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.monster.piglin.Piglin; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class PiglinAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "dancing", + List.of("true", "false"), + List.of(EntityType.PIGLIN), + PiglinAttributes::setDancing + )); + + return attributes; + } + + private static void setDancing(Npc npc, String value) { + Piglin piglin = ReflectionHelper.getEntity(npc); + + boolean dancing = Boolean.parseBoolean(value); + piglin.setDancing(dancing); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PlayerAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PlayerAttributes.java new file mode 100644 index 00000000..5a015ddb --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/PlayerAttributes.java @@ -0,0 +1,40 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancylib.ReflectionUtils; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.player.Player; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class PlayerAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "crouching", "sleeping", "swimming", "sitting"), + List.of(EntityType.PLAYER), + PlayerAttributes::setPose + )); + + return attributes; + } + + private static void setPose(Npc npc, String value) { + Player player = ReflectionHelper.getEntity(npc); + + Pose pose = Pose.valueOf(value.toUpperCase()); + + EntityDataAccessor DATA_POSE = (EntityDataAccessor) ReflectionUtils.getStaticValue(Entity.class, "DATA_POSE"); // DATA_POSE + player.getEntityData().set(DATA_POSE, pose); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/RabbitAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/RabbitAttributes.java new file mode 100644 index 00000000..b6c64a2d --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/RabbitAttributes.java @@ -0,0 +1,37 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.Rabbit; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class RabbitAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "variant", + Arrays.stream(Rabbit.Variant.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.RABBIT), + RabbitAttributes::setVariant + )); + + return attributes; + } + + private static void setVariant(Npc npc, String value) { + Rabbit rabbit = ReflectionHelper.getEntity(npc); + + Rabbit.Variant variant = Rabbit.Variant.valueOf(value.toUpperCase()); + rabbit.setVariant(variant); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SheepAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SheepAttributes.java new file mode 100644 index 00000000..654f0a35 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SheepAttributes.java @@ -0,0 +1,50 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.sheep.Sheep; +import net.minecraft.world.item.DyeColor; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SheepAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "wool_color", + Arrays.stream(DyeColor.values()).map(dyeColor -> dyeColor.name().toLowerCase()).toList(), + List.of(EntityType.SHEEP), + SheepAttributes::setColor + )); + + attributes.add(new NpcAttribute( + "sheared", + Arrays.asList("true", "false"), + List.of(EntityType.SHEEP), + SheepAttributes::setSheared + )); + + return attributes; + } + + private static void setColor(Npc npc, String value) { + Sheep sheep = ReflectionHelper.getEntity(npc); + + sheep.setColor(DyeColor.byName(value.toLowerCase(), DyeColor.WHITE)); + } + + private static void setSheared(Npc npc, String value) { + Sheep sheep = ReflectionHelper.getEntity(npc); + + boolean sheared = Boolean.parseBoolean(value); + + sheep.setSheared(sheared); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ShulkerAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ShulkerAttributes.java new file mode 100644 index 00000000..85eaa289 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/ShulkerAttributes.java @@ -0,0 +1,54 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.monster.Shulker; +import net.minecraft.world.item.DyeColor; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ShulkerAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "color", + Arrays.stream(DyeColor.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.SHULKER), + ShulkerAttributes::setColor + )); + + attributes.add(new NpcAttribute( + "shield", + List.of("open", "closed"), + List.of(EntityType.SHULKER), + ShulkerAttributes::setShield + )); + + return attributes; + } + + private static void setColor(Npc npc, String value) { + Shulker shulker = ReflectionHelper.getEntity(npc); + + DyeColor color = DyeColor.byName(value.toLowerCase(), DyeColor.PURPLE); + shulker.getEntityData().set(Shulker.DATA_COLOR_ID, (byte) color.getId()); + } + + private static void setShield(Npc npc, String value) { + Shulker shulker = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "closed" -> shulker.setRawPeekAmount(0); + case "open" -> shulker.setRawPeekAmount(Byte.MAX_VALUE); + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SlimeAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SlimeAttributes.java new file mode 100644 index 00000000..c6a2c0e5 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SlimeAttributes.java @@ -0,0 +1,40 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.monster.Slime; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class SlimeAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "size", + new ArrayList<>(), + List.of(EntityType.SLIME), + SlimeAttributes::setSize + )); + + return attributes; + } + + private static void setSize(Npc npc, String value) { + Slime slime = ReflectionHelper.getEntity(npc); + + int size; + try { + size = Integer.parseInt(value); + } catch (NumberFormatException e) { + return; + } + + slime.setSize(size, false); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SnifferAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SnifferAttributes.java new file mode 100644 index 00000000..faac16ba --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SnifferAttributes.java @@ -0,0 +1,36 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.sniffer.Sniffer; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SnifferAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "state", + Arrays.stream(Sniffer.State.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.SNIFFER), + SnifferAttributes::setState + )); + + return attributes; + } + + private static void setState(Npc npc, String value) { + final Sniffer sniffer = ReflectionHelper.getEntity(npc); + + Sniffer.State state = Sniffer.State.valueOf(value.toUpperCase()); + sniffer.transitionTo(state); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SpellCasterAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SpellCasterAttributes.java new file mode 100644 index 00000000..5327ec9c --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/SpellCasterAttributes.java @@ -0,0 +1,39 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.monster.SpellcasterIllager; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Spellcaster; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SpellCasterAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "casting", + Arrays.stream(SpellcasterIllager.IllagerSpell.values()).map(Enum::toString).toList(), + Arrays.stream(EntityType.values()) + .filter(type -> type.getEntityClass() != null && Spellcaster.class.isAssignableFrom(type.getEntityClass())) + .toList(), + SpellCasterAttributes::setPose + )); + + return attributes; + } + + private static void setPose(Npc npc, String value) { + SpellcasterIllager spellcasterIllager = ReflectionHelper.getEntity(npc); + + SpellcasterIllager.IllagerSpell spell = SpellcasterIllager.IllagerSpell.valueOf(value); + + spellcasterIllager.setIsCastingSpell(spell); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/TextDisplayAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/TextDisplayAttributes.java new file mode 100644 index 00000000..a110ddd5 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/TextDisplayAttributes.java @@ -0,0 +1,36 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.minecraft.world.entity.Display; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class TextDisplayAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "text", + new ArrayList<>(), + List.of(EntityType.TEXT_DISPLAY), + TextDisplayAttributes::setText + )); + + return attributes; + } + + private static void setText(Npc npc, String value) { + Display.TextDisplay display = ReflectionHelper.getEntity(npc); + + Component text = MiniMessage.miniMessage().deserialize(value); + display.setText(PaperAdventure.asVanilla(text)); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/TropicalFishAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/TropicalFishAttributes.java new file mode 100644 index 00000000..09b87aac --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/TropicalFishAttributes.java @@ -0,0 +1,72 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.animal.TropicalFish; +import net.minecraft.world.item.DyeColor; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TropicalFishAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "pattern", + Arrays.stream(TropicalFish.Pattern.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.TROPICAL_FISH), + TropicalFishAttributes::setPattern + )); + + attributes.add(new NpcAttribute( + "base_color", + Arrays.stream(DyeColor.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.TROPICAL_FISH), + TropicalFishAttributes::setBaseColor + )); + + attributes.add(new NpcAttribute( + "pattern_color", + Arrays.stream(DyeColor.values()) + .map(Enum::name) + .toList(), + List.of(EntityType.TROPICAL_FISH), + TropicalFishAttributes::setPatternColor + )); + + return attributes; + } + + private static void setPattern(Npc npc, String value) { + TropicalFish tropicalFish = ReflectionHelper.getEntity(npc); + + TropicalFish.Pattern pattern = TropicalFish.Pattern.valueOf(value.toUpperCase()); + tropicalFish.setPackedVariant(pattern.getPackedId()); + } + + private static void setBaseColor(Npc npc, String value) { + TropicalFish tropicalFish = ReflectionHelper.getEntity(npc); + + DyeColor color = DyeColor.byName(value.toLowerCase(), DyeColor.WHITE); + TropicalFish.Variant variant = new TropicalFish.Variant(tropicalFish.getPattern(), color, tropicalFish.getPatternColor()); + tropicalFish.setPackedVariant(variant.getPackedId()); + } + + private static void setPatternColor(Npc npc, String value) { + TropicalFish tropicalFish = ReflectionHelper.getEntity(npc); + + DyeColor color = DyeColor.byName(value.toLowerCase(), DyeColor.WHITE); + TropicalFish.Variant variant = new TropicalFish.Variant(tropicalFish.getPattern(), tropicalFish.getBaseColor(), color); + tropicalFish.setPackedVariant(variant.getPackedId()); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/VexAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/VexAttributes.java new file mode 100644 index 00000000..04b09b6c --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/VexAttributes.java @@ -0,0 +1,36 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.world.entity.monster.Vex; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class VexAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "charging", + List.of("true", "false"), + List.of(EntityType.VEX), + VexAttributes::setCharging + )); + + return attributes; + } + + private static void setCharging(Npc npc, String value) { + Vex vex = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "true" -> vex.setIsCharging(true); + case "false" -> vex.setIsCharging(false); + } + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/VillagerAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/VillagerAttributes.java new file mode 100644 index 00000000..9ff33fea --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/VillagerAttributes.java @@ -0,0 +1,55 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.Identifier; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.entity.npc.VillagerType; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class VillagerAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "profession", + BuiltInRegistries.VILLAGER_PROFESSION.keySet().stream().map(Identifier::getPath).toList(), + List.of(EntityType.VILLAGER), + VillagerAttributes::setProfession + )); + + attributes.add(new NpcAttribute( + "type", + BuiltInRegistries.VILLAGER_TYPE.keySet().stream().map(Identifier::getPath).toList(), + List.of(EntityType.VILLAGER), + VillagerAttributes::setType + )); + + return attributes; + } + + private static void setProfession(Npc npc, String value) { + Villager villager = ReflectionHelper.getEntity(npc); + + Holder profession = BuiltInRegistries.VILLAGER_PROFESSION.get(Identifier.tryParse(value)).orElseThrow(); + + villager.setVillagerData(villager.getVillagerData().withProfession(profession)); + } + + private static void setType(Npc npc, String value) { + Villager villager = ReflectionHelper.getEntity(npc); + + Holder type = BuiltInRegistries.VILLAGER_TYPE.get(Identifier.tryParse(value)).orElseThrow(); + + villager.setVillagerData(villager.getVillagerData().withType(type)); + } + +} diff --git a/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/WolfAttributes.java b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/WolfAttributes.java new file mode 100644 index 00000000..5762dca9 --- /dev/null +++ b/plugins/fancynpcs/implementation_1_21_11/src/main/java/de/oliver/fancynpcs/v1_21_11/attributes/WolfAttributes.java @@ -0,0 +1,127 @@ +package de.oliver.fancynpcs.v1_21_11.attributes; + +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.NpcAttribute; +import de.oliver.fancynpcs.v1_21_11.ReflectionHelper; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.animal.wolf.Wolf; +import net.minecraft.world.entity.animal.wolf.WolfVariant; +import net.minecraft.world.item.DyeColor; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.List; + +public class WolfAttributes { + + public static List getAllAttributes() { + List attributes = new ArrayList<>(); + + attributes.add(new NpcAttribute( + "pose", + List.of("standing", "sitting"), + List.of(EntityType.WOLF), + WolfAttributes::setPose + )); + + attributes.add(new NpcAttribute( + "angry", + List.of("true", "false"), + List.of(EntityType.WOLF), + WolfAttributes::setAngry + )); + + attributes.add(new NpcAttribute( + "variant", + getWolfVariantRegistry() + .listElementIds() + .map(id -> id.identifier().getPath()) + .toList(), + List.of(EntityType.WOLF), + WolfAttributes::setVariant + )); + + attributes.add(new NpcAttribute( + "collar_color", + List.of("RED", "BLUE", "YELLOW", "GREEN", "PURPLE", "ORANGE", "LIME", "MAGENTA", "BROWN", "WHITE", "GRAY", "LIGHT_GRAY", "LIGHT_BLUE", "BLACK", "CYAN", "PINK", "NONE"), + List.of(EntityType.WOLF), + WolfAttributes::setCollarColor + )); + + return attributes; + } + + private static void setPose(Npc npc, String value) { + Wolf wolf = ReflectionHelper.getEntity(npc); + + switch (value.toLowerCase()) { + case "standing" -> wolf.setInSittingPose(false, false); + case "sitting" -> wolf.setInSittingPose(true, false); + } + } + + private static void setAngry(Npc npc, String value) { + Wolf wolf = ReflectionHelper.getEntity(npc); + + boolean angry = Boolean.parseBoolean(value.toLowerCase()); + + wolf.setTimeToRemainAngry(angry ? 100 : 0); + } + + private static void setVariant(Npc npc, String value) { + Wolf wolf = ReflectionHelper.getEntity(npc); + + Registry registry = wolf.level().registryAccess().lookupOrThrow(Registries.WOLF_VARIANT); + + Identifier variantLocation = Identifier.tryParse("minecraft:" + value.toLowerCase()); + if (variantLocation == null) { + System.out.println("Invalid variant name: " + value); + return; + } + + WolfVariant variant = registry.getOptional(variantLocation).orElse(null); + if (variant == null) { + System.out.println("Wolf variant not found: " + variantLocation); + return; + } + + // Get the ResourceKey from the registry + registry.getResourceKey(variant).ifPresentOrElse( + key -> { + // Get the holder from the registry — this is properly bound + Holder holder = registry.wrapAsHolder(variant); + wolf.setVariant(holder); + }, + () -> System.out.println("Wolf variant not registered: " + variantLocation) + ); + } + + private static void setCollarColor(Npc npc, String value) { + Wolf wolf = ReflectionHelper.getEntity(npc); + + if (value.equalsIgnoreCase("none") || value.isEmpty()) { + // Reset to no collar + wolf.setTame(false, false); + return; + } + + try { + DyeColor color = DyeColor.valueOf(value.toUpperCase()); + if (!wolf.isTame()) { + wolf.setTame(true, false); + } + wolf.setCollarColor(color); + } catch (IllegalArgumentException e) { + System.out.println("Invalid wolf collar color: " + value); + } + } + + private static HolderLookup.RegistryLookup getWolfVariantRegistry() { + return MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.WOLF_VARIANT); + } +} diff --git a/plugins/fancynpcs/implementation_1_21_3/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_3/build.gradle.kts index eefc9c16..83bd12b8 100644 --- a/plugins/fancynpcs/implementation_1_21_3/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_21_3/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_4/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_4/build.gradle.kts index 4867177d..66c23e42 100644 --- a/plugins/fancynpcs/implementation_1_21_4/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_21_4/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_5/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_5/build.gradle.kts index e269e3c2..79bda8af 100644 --- a/plugins/fancynpcs/implementation_1_21_5/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_21_5/build.gradle.kts @@ -10,7 +10,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_6/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_6/build.gradle.kts index d6e512ad..6d2d239a 100644 --- a/plugins/fancynpcs/implementation_1_21_6/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_21_6/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_9/build.gradle.kts b/plugins/fancynpcs/implementation_1_21_9/build.gradle.kts index 55a910c5..fb69865b 100644 --- a/plugins/fancynpcs/implementation_1_21_9/build.gradle.kts +++ b/plugins/fancynpcs/implementation_1_21_9/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { compileOnly(project(":plugins:fancynpcs:fn-api")) compileOnly(project(":libraries:common")) - compileOnly("org.lushplugins:ChatColorHandler:6.0.2") + compileOnly("org.lushplugins:ChatColorHandler:6.0.0") } diff --git a/plugins/fancynpcs/implementation_1_21_9/src/main/java/de/oliver/fancynpcs/v1_21_9/Npc_1_21_9.java b/plugins/fancynpcs/implementation_1_21_9/src/main/java/de/oliver/fancynpcs/v1_21_9/Npc_1_21_9.java index 7b8c0763..d0b68858 100644 --- a/plugins/fancynpcs/implementation_1_21_9/src/main/java/de/oliver/fancynpcs/v1_21_9/Npc_1_21_9.java +++ b/plugins/fancynpcs/implementation_1_21_9/src/main/java/de/oliver/fancynpcs/v1_21_9/Npc_1_21_9.java @@ -387,11 +387,19 @@ public class Npc_1_21_9 extends Npc { } private ClientboundPlayerInfoUpdatePacket.Entry getEntry(ServerPlayer npcPlayer, ServerPlayer viewer) { - GameProfile profile = npcPlayer.getGameProfile(); - if (data.isMirrorSkin()) { - GameProfile newProfile = new GameProfile(profile.id(), profile.name()); - newProfile.properties().putAll(viewer.getGameProfile().properties()); - profile = newProfile; + GameProfile profile; + if (!data.isMirrorSkin()) { + profile = npcPlayer.getGameProfile(); + } else { + Property textures = viewer.getGameProfile().properties().get("textures").iterator().next(); + + PropertyMap propertyMap = new PropertyMap( + ImmutableMultimap.of( + "textures", + new Property("textures", textures.value(), textures.signature()) + ) + ); + profile = new GameProfile(uuid, localName, propertyMap); } return new ClientboundPlayerInfoUpdatePacket.Entry( diff --git a/plugins/fancynpcs/release_deployment_config.json b/plugins/fancynpcs/release_deployment_config.json index 622dabf3..b28d3190 100644 --- a/plugins/fancynpcs/release_deployment_config.json +++ b/plugins/fancynpcs/release_deployment_config.json @@ -23,7 +23,8 @@ "1.21.7", "1.21.8", "1.21.9", - "1.21.10" + "1.21.10", + "1.21.11" ], "channel": "RELEASE", "loaders": [ diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/AttributeManagerImpl.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/AttributeManagerImpl.java index 247adc9e..f78fb43c 100644 --- a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/AttributeManagerImpl.java +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/AttributeManagerImpl.java @@ -8,6 +8,7 @@ import de.oliver.fancynpcs.v1_20_2.attributes.Attributes_1_20_2; import de.oliver.fancynpcs.v1_20_4.attributes.Attributes_1_20_4; import de.oliver.fancynpcs.v1_20_6.attributes.Attributes_1_20_5; import de.oliver.fancynpcs.v1_21_1.attributes.Attributes_1_21_1; +import de.oliver.fancynpcs.v1_21_11.attributes.Attributes_1_21_11; import de.oliver.fancynpcs.v1_21_3.attributes.Attributes_1_21_3; import de.oliver.fancynpcs.v1_21_4.attributes.Attributes_1_21_4; import de.oliver.fancynpcs.v1_21_5.attributes.Attributes_1_21_5; @@ -31,6 +32,7 @@ public class AttributeManagerImpl implements AttributeManager { private void init() { String mcVersion = Bukkit.getMinecraftVersion(); switch (mcVersion) { + case "1.21.11" -> attributes = Attributes_1_21_11.getAllAttributes(); case "1.21.9", "1.21.10" -> attributes = Attributes_1_21_9.getAllAttributes(); case "1.21.6", "1.21.7", "1.21.8" -> attributes = Attributes_1_21_6.getAllAttributes(); case "1.21.5" -> attributes = Attributes_1_21_5.getAllAttributes(); diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcs.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcs.java index 0c1c11b1..3f62f30e 100644 --- a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcs.java +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcs.java @@ -53,6 +53,7 @@ import de.oliver.fancynpcs.v1_20_2.Npc_1_20_2; import de.oliver.fancynpcs.v1_20_4.Npc_1_20_4; import de.oliver.fancynpcs.v1_20_6.Npc_1_20_6; import de.oliver.fancynpcs.v1_21_1.Npc_1_21_1; +import de.oliver.fancynpcs.v1_21_11.Npc_1_21_11; import de.oliver.fancynpcs.v1_21_3.Npc_1_21_3; import de.oliver.fancynpcs.v1_21_4.Npc_1_21_4; import de.oliver.fancynpcs.v1_21_5.Npc_1_21_5; @@ -82,6 +83,7 @@ public class FancyNpcs extends JavaPlugin implements FancyNpcsPlugin { public static final FeatureFlag USE_NATIVE_THREADS_FEATURE_FLAG = new FeatureFlag("use-native-threads", "Use native threads instead of virtual threads.", false); public static final FeatureFlag ENABLE_DEBUG_MODE_FEATURE_FLAG = new FeatureFlag("enable-debug-mode", "Enable debug mode", false); public static final FeatureFlag ENABLE_FOLIA_VISIBILITY_FIX_FEATURE_FLAG = new FeatureFlag("enable-folia-visibility-fix", "When enabled, all npcs will respawn after 100ms when they should spawn", false); + public static final FeatureFlag USE_MINECRAFT_USERCACHE_FEATURE_FLAG = new FeatureFlag("use-minecraft-usercache", "Include the content of usercache.json to the username->uuid cache", false); private static FancyNpcs instance; private final ExtendedFancyLogger fancyLogger; @@ -163,6 +165,7 @@ public class FancyNpcs extends JavaPlugin implements FancyNpcsPlugin { String mcVersion = Bukkit.getMinecraftVersion(); switch (mcVersion) { + case "1.21.11" -> npcAdapter = Npc_1_21_11::new; case "1.21.9", "1.21.10" -> npcAdapter = Npc_1_21_9::new; case "1.21.6", "1.21.7", "1.21.8" -> npcAdapter = Npc_1_21_6::new; case "1.21.5" -> npcAdapter = Npc_1_21_5::new; @@ -190,7 +193,7 @@ public class FancyNpcs extends JavaPlugin implements FancyNpcsPlugin { fancyLogger.error("Unsupported minecraft server version."); getLogger().warning("--------------------------------------------------"); getLogger().warning("Unsupported minecraft server version."); - getLogger().warning("This plugin only supports 1.19.4 - 1.21.8"); + getLogger().warning("This plugin only supports 1.19.4 - 1.21.11"); getLogger().warning("Disabling the FancyNpcs plugin."); getLogger().warning("--------------------------------------------------"); pluginManager.disablePlugin(this); @@ -276,7 +279,7 @@ public class FancyNpcs extends JavaPlugin implements FancyNpcsPlugin { pluginManager.registerEvents(new PlayerTeleportListener(), instance); pluginManager.registerEvents(new PlayerChangedWorldListener(), instance); pluginManager.registerEvents(skinManager, instance); - if (Bukkit.getMinecraftVersion().equals("1.21.4") || Bukkit.getMinecraftVersion().equals("1.21.5") || Bukkit.getMinecraftVersion().equals("1.21.6") || Bukkit.getMinecraftVersion().equals("1.21.7") || Bukkit.getMinecraftVersion().equals("1.21.8") || Bukkit.getMinecraftVersion().equals("1.21.9") || Bukkit.getMinecraftVersion().equals("1.21.10")) { + if (Set.of("1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11").contains(Bukkit.getMinecraftVersion())) { getServer().getPluginManager().registerEvents(new PlayerLoadedListener(), this); } diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcsConfigImpl.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcsConfigImpl.java index c96f0486..59fba3ed 100644 --- a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcsConfigImpl.java +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/FancyNpcsConfigImpl.java @@ -78,6 +78,12 @@ public class FancyNpcsConfigImpl implements FancyNpcsConfig { */ private int removeNpcsFromPlayerlistDelay; + + /** + * Whether MPCs should swing arm on update. + */ + private boolean swingArmOnUpdate; + /** * The API key for the MineSkin API. */ @@ -139,6 +145,9 @@ public class FancyNpcsConfigImpl implements FancyNpcsConfig { removeNpcsFromPlayerlistDelay = (int) ConfigHelper.getOrDefault(config, "remove_npcs_from_playerlist_delay", 2000); config.setInlineComments("remove_npcs_from_playerlist_delay", List.of("The delay in milliseconds to remove NPCs from the player list. Increase this value if you have problems with skins not loading correctly when joining or switching worlds. You can set it to -1, if you don't have any npcs using the show_in_tab feature.")); + swingArmOnUpdate = (boolean) ConfigHelper.getOrDefault(config, "swing_arm_on_update", true); + config.setInlineComments("swing_arm_on_update", List.of("Whether NPCs should swing arm on update.")); + blockedCommands = (List) ConfigHelper.getOrDefault(config, "blocked_commands", Arrays.asList("op", "ban")); config.setInlineComments("blocked_commands", List.of("The commands that are blocked for NPCs in the message.")); @@ -231,6 +240,8 @@ public class FancyNpcsConfigImpl implements FancyNpcsConfig { return removeNpcsFromPlayerlistDelay; } + public boolean isSwingArmOnUpdate() { return swingArmOnUpdate; } + public String getMineSkinApiKey() { if (mineskinApiKey.isEmpty()) { return null; diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java index 15fcfde9..a439876a 100644 --- a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/CloudCommandManager.java @@ -33,6 +33,7 @@ import org.incendo.cloud.parser.standard.EnumParser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Set; import java.util.Optional; import static org.incendo.cloud.exception.handling.ExceptionHandler.unwrappingHandler; @@ -184,6 +185,7 @@ public final class CloudCommandManager { annotationParser.parse(NearbyCMD.INSTANCE); annotationParser.parse(HelpCMD.INSTANCE); annotationParser.parse(RemoveCMD.INSTANCE); + annotationParser.parse(RotateCMD.INSTANCE); annotationParser.parse(ShowInTabCMD.INSTANCE); annotationParser.parse(SkinCMD.INSTANCE); annotationParser.parse(TeleportCMD.INSTANCE); @@ -197,8 +199,7 @@ public final class CloudCommandManager { annotationParser.parse(FancyNpcsDebugCMD.INSTANCE); } - String mcVersion = Bukkit.getMinecraftVersion(); - if (mcVersion.equals("1.20.5") || mcVersion.equals("1.20.6") || mcVersion.equals("1.21") || mcVersion.equals("1.21.1") || mcVersion.equals("1.21.2") || mcVersion.equals("1.21.3") || mcVersion.equals("1.21.4") || mcVersion.equals("1.21.5") || mcVersion.equals("1.21.6") || mcVersion.equals("1.21.7") || Bukkit.getMinecraftVersion().equals("1.21.8") || Bukkit.getMinecraftVersion().equals("1.21.9") || Bukkit.getMinecraftVersion().equals("1.21.10")) { + if (Set.of("1.20.5", "1.20.6", "1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11").contains(Bukkit.getMinecraftVersion())) { annotationParser.parse(ScaleCMD.INSTANCE); } diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java new file mode 100644 index 00000000..31a804d5 --- /dev/null +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/commands/npc/RotateCMD.java @@ -0,0 +1,43 @@ +package de.oliver.fancynpcs.commands.npc; + +import de.oliver.fancylib.translations.Translator; +import de.oliver.fancynpcs.FancyNpcs; +import de.oliver.fancynpcs.api.Npc; +import de.oliver.fancynpcs.api.events.NpcModifyEvent; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.incendo.cloud.annotations.Command; +import org.incendo.cloud.annotations.Permission; +import org.jetbrains.annotations.NotNull; + +public enum RotateCMD { + INSTANCE; + + private final Translator translator = FancyNpcs.getInstance().getTranslator(); + + @Command("npc rotate ") + @Permission("fancynpcs.command.npc.rotate") + public void onRotate( + final @NotNull CommandSender sender, + final @NotNull Npc npc, + final float yaw, + final float pitch + ) { + final Location currentLocation = npc.getData().getLocation(); + final Location newLocation = currentLocation.clone(); + newLocation.setYaw(yaw); + newLocation.setPitch(pitch); + + if (new NpcModifyEvent(npc, NpcModifyEvent.NpcModification.ROTATION, new float[]{yaw, pitch}, sender).callEvent()) { + npc.getData().setLocation(newLocation); + npc.updateForAll(); + translator.translate("npc_rotate_set_success") + .replace("npc", npc.getData().getName()) + .replace("yaw", String.valueOf(yaw)) + .replace("pitch", String.valueOf(pitch)) + .send(sender); + } else { + translator.translate("command_npc_modification_cancelled").send(sender); + } + } +} \ No newline at end of file diff --git a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/skins/uuidcache/UUIDFileCache.java b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/skins/uuidcache/UUIDFileCache.java index f2ce0c94..f29ee148 100644 --- a/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/skins/uuidcache/UUIDFileCache.java +++ b/plugins/fancynpcs/src/main/java/de/oliver/fancynpcs/skins/uuidcache/UUIDFileCache.java @@ -55,6 +55,10 @@ public class UUIDFileCache implements UUIDCache { } private void loadMinecraftUsercache() { + if (!FancyNpcs.USE_MINECRAFT_USERCACHE_FEATURE_FLAG.isEnabled()) { + return; + } + if (!usercacheFile.exists()) { FancyNpcs.getInstance().getFancyLogger().debug("Minecraft usercache file does not exist, skipping load."); return; diff --git a/plugins/fancynpcs/src/main/resources/languages/default.yml b/plugins/fancynpcs/src/main/resources/languages/default.yml index 2563765d..d3e217e1 100644 --- a/plugins/fancynpcs/src/main/resources/languages/default.yml +++ b/plugins/fancynpcs/src/main/resources/languages/default.yml @@ -123,6 +123,7 @@ messages: npc_move_to: "Syntax: {primaryColor}/npc move_to {secondaryColor}(npc) (x) (y) (z) [world]" npc_nearby: "Syntax: {primaryColor}/npc nearby {secondaryColor}[filters...]" npc_remove: "Syntax: {primaryColor}/npc remove {secondaryColor}(npc)" + npc_rotate: "Syntax: {primaryColor}/npc rotate {secondaryColor}(npc) (yaw) (pitch)" npc_show_in_tab: "Syntax: {primaryColor}/npc show_in_tab {secondaryColor}(npc) (state)" npc_skin: "Syntax: {primaryColor}/npc skin {secondaryColor}(npc) (@none | @mirror | name | uuid | placeholder | url | file name) [--slim]" npc_teleport: "Syntax: {primaryColor}/npc teleport {secondaryColor}(npc)" @@ -176,6 +177,7 @@ messages: - "Teleports NPC to specified location.'>{primaryColor}/npc move_to {secondaryColor}(npc) (x) (y) (z) [world]" - "Lists all NPCs in your world. Can be filtered and sorted.'>{primaryColor}/npc nearby {secondaryColor}[--radius] [--type] [--sort]" - "Removes (deletes) specified NPC.'>{primaryColor}/npc remove {secondaryColor}(npc)" + - "Changes the rotation (yaw and pitch) of the NPC.'>{primaryColor}/npc rotate {secondaryColor}(npc) (yaw) (pitch)" - "Changes the scale of the size of the NPC.'>{primaryColor}/npc scale {secondaryColor}(npc) (factor)" - "Changes whether the NPC is shown in the player-list. This works only on NPCs of PLAYER type.{errorColor}Re-connecting to the server might be required for changes to take effect.'>{primaryColor}/npc show_in_tab {secondaryColor}(npc) (state)" - "Changes skin of the NPC.Supports PlaceholderAPI and MiniPlaceholders.{warningColor}@none - removes the skin{warningColor}@mirror - mirrors player skin{warningColor}(name) - name of any player{warningColor}(url) - url of the skin texture'>{primaryColor}/npc skin {secondaryColor}(npc) (@none | @mirror | name | url) [--slim]" @@ -302,6 +304,9 @@ messages: # Commands (npc remove) npc_remove_success: "NPC {warningColor}{npc} has been removed." + # Commands (npc rotate) + npc_rotate_set_success: "NPC {warningColor}{npc} has been rotated to yaw {warningColor}{yaw} and pitch {warningColor}{pitch}." + # Commands (scale) npc_scale_set_success: "NPC {warningColor}{npc} has been scaled to {warningColor}{scale}." diff --git a/plugins/fancyvisuals/build.gradle.kts b/plugins/fancyvisuals/build.gradle.kts index abaffa7d..f8fb6848 100644 --- a/plugins/fancyvisuals/build.gradle.kts +++ b/plugins/fancyvisuals/build.gradle.kts @@ -26,7 +26,7 @@ allprojects { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.9-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") rootProject.subprojects .filter { it.path.startsWith(":libraries:packets:implementations") } @@ -40,7 +40,7 @@ dependencies { compileOnly("de.oliver.FancyAnalytics:mc-api:0.1.11") // loaded in FancyVisualLoader compileOnly("de.oliver.FancyAnalytics:logger:0.0.8") // loaded in FancyVisualLoader - implementation("org.lushplugins:ChatColorHandler:6.0.2") + implementation("org.lushplugins:ChatColorHandler:6.0.0") compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") // commands @@ -81,7 +81,7 @@ paper { tasks { runServer { - minecraftVersion("1.21.9") + minecraftVersion("1.21.10") downloadPlugins { hangar("ViaVersion", "5.3.2") diff --git a/settings.gradle.kts b/settings.gradle.kts index e8eb2fad..1c69e4e9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,6 +2,7 @@ rootProject.name = "minecraft-plugins" include(":plugins:fancynpcs:") include(":plugins:fancynpcs:fn-api") +include(":plugins:fancynpcs:implementation_1_21_11") include(":plugins:fancynpcs:implementation_1_21_9") include(":plugins:fancynpcs:implementation_1_21_6") include(":plugins:fancynpcs:implementation_1_21_5") @@ -46,6 +47,7 @@ include(":libraries:packets:implementations:1_21_4") include(":libraries:packets:implementations:1_21_5") include(":libraries:packets:implementations:1_21_6") include(":libraries:packets:implementations:1_21_9") +include(":libraries:packets:implementations:1_21_11") include(":tools:deployment")