Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle the effect on packets exclusively #3

Open
TheMolkaPL opened this issue Jul 29, 2020 · 0 comments
Open

Handle the effect on packets exclusively #3

TheMolkaPL opened this issue Jul 29, 2020 · 0 comments

Comments

@TheMolkaPL
Copy link
Contributor

I've rewritten the effect to use packets exclusively in my project. This is safer, omits tons of Bukkit's unnecessary code and doesn't trigger events (which wasn't even compatible with other plugins). Feel free to implement this change into this plugin. Unfortunately it is only implemented for 1.16.

From 72e791b347210f8ce8d7109d9717d02d5f0f79d9 Mon Sep 17 00:00:00 2001
From: Aleksander Jagiello <[email protected]>
Date: Tue, 28 Jul 2020 23:57:10 +0200
Subject: [PATCH] Mob camera effect

---
 .../radiation/nms/V1_16NmsBridge.java         | 143 ++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 src/main/java/pl/craftserve/radiation/nms/V1_16NmsBridge.java

diff --git a/src/main/java/pl/craftserve/radiation/nms/V1_16NmsBridge.java b/src/main/java/pl/craftserve/radiation/nms/V1_16NmsBridge.java
new file mode 100644
index 0000000..5a2a270
--- /dev/null
+++ b/src/main/java/pl/craftserve/radiation/nms/V1_16NmsBridge.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2019 Aleksander Jagiełło <[email protected]>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package pl.craftserve.radiation.nms;
+
+import net.minecraft.server.v1_16_R1.BiomeManager;
+import net.minecraft.server.v1_16_R1.Container;
+import net.minecraft.server.v1_16_R1.DimensionManager;
+import net.minecraft.server.v1_16_R1.EntityLiving;
+import net.minecraft.server.v1_16_R1.EntityPlayer;
+import net.minecraft.server.v1_16_R1.EntityTypes;
+import net.minecraft.server.v1_16_R1.EnumGamemode;
+import net.minecraft.server.v1_16_R1.FoodMetaData;
+import net.minecraft.server.v1_16_R1.PacketPlayOutAbilities;
+import net.minecraft.server.v1_16_R1.PacketPlayOutCamera;
+import net.minecraft.server.v1_16_R1.PacketPlayOutEntityDestroy;
+import net.minecraft.server.v1_16_R1.PacketPlayOutGameStateChange;
+import net.minecraft.server.v1_16_R1.PacketPlayOutHeldItemSlot;
+import net.minecraft.server.v1_16_R1.PacketPlayOutPosition;
+import net.minecraft.server.v1_16_R1.PacketPlayOutRespawn;
+import net.minecraft.server.v1_16_R1.PacketPlayOutSpawnEntityLiving;
+import net.minecraft.server.v1_16_R1.PacketPlayOutUpdateHealth;
+import net.minecraft.server.v1_16_R1.PacketPlayOutWindowItems;
+import net.minecraft.server.v1_16_R1.PlayerConnection;
+import net.minecraft.server.v1_16_R1.PlayerInteractManager;
+import net.minecraft.server.v1_16_R1.ResourceKey;
+import net.minecraft.server.v1_16_R1.World;
+import net.minecraft.server.v1_16_R1.WorldServer;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
+public class V1_16NmsBridge extends V1_14ToV1_15NmsBridge {
+    private final Set<UUID> mobCameras = new HashSet<>(128);
+
+    public V1_16NmsBridge(String version) {
+        super(version);
+    }
+
+    @Override
+    public void playMobCameraEffect(Player player, EntityType entityType) {
+        Objects.requireNonNull(player, "player");
+        Objects.requireNonNull(entityType, "entityType");
+
+        if (!this.mobCameras.add(player.getUniqueId())) {
+            return;
+        }
+
+        EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
+        PlayerInteractManager interactManager = nmsPlayer.playerInteractManager;
+
+        PlayerConnection connection = nmsPlayer.playerConnection;
+        if (connection == null) {
+            return;
+        }
+
+        EntityTypes<?> nmsType = EntityTypes.a(entityType.getKey().getKey()).orElse(null);
+        if (nmsType == null) {
+            return;
+        }
+
+        EntityLiving nmsEntity = (EntityLiving) nmsType.a(nmsPlayer.world);
+        if (nmsEntity == null) {
+            return;
+        }
+
+        Location location = player.getLocation();
+        double x = location.getX();
+        double y = location.getY();
+        double z = location.getZ();
+        float yaw = location.getYaw();
+        float pitch = location.getPitch();
+
+        nmsEntity.setPosition(x, y, z);
+        nmsEntity.setPositionRotation(x, y, z, yaw, pitch);
+
+        PacketPlayOutGameStateChange.a gameModeState = PacketPlayOutGameStateChange.d;
+        int spectatorId = EnumGamemode.SPECTATOR.getId();
+
+        connection.sendPacket(new PacketPlayOutGameStateChange(gameModeState, spectatorId));
+        connection.sendPacket(new PacketPlayOutSpawnEntityLiving(nmsEntity));
+        connection.sendPacket(new PacketPlayOutCamera(nmsEntity));
+        connection.sendPacket(new PacketPlayOutEntityDestroy(nmsEntity.getId()));
+        connection.sendPacket(new PacketPlayOutUpdateHealth(0F, 0, 0F)); // kill
+
+        World world = nmsEntity.world;
+        WorldServer worldServer = nmsPlayer.getWorldServer();
+
+        ResourceKey<DimensionManager> typeKey = world.getTypeKey();
+        ResourceKey<World> dimensionKey = world.getDimensionKey();
+        long seed = BiomeManager.a(worldServer.getSeed());
+        EnumGamemode gameMode = interactManager.getGameMode();
+        EnumGamemode prevGameMode = interactManager.c();
+        boolean debug = world.isDebugWorld();
+        boolean flat = worldServer.isFlatWorld();
+
+        connection.sendPacket(new PacketPlayOutRespawn(typeKey, dimensionKey, seed, gameMode, prevGameMode, debug, flat, true));
+        connection.sendPacket(new PacketPlayOutAbilities(nmsPlayer.abilities));
+
+        Container container = nmsPlayer.activeContainer;
+        connection.sendPacket(new PacketPlayOutWindowItems(container.windowId, container.b()));
+        connection.sendPacket(new PacketPlayOutHeldItemSlot(nmsPlayer.inventory.itemInHandIndex));
+
+        FoodMetaData foodData = nmsPlayer.getFoodData();
+        connection.sendPacket(new PacketPlayOutUpdateHealth(nmsPlayer.getHealth(), foodData.foodLevel, foodData.saturationLevel));
+
+        connection.sendPacket(new PacketPlayOutPosition(x, y, z, yaw, pitch, Collections.emptySet(), -1));
+    }
+
+    @Override
+    public void pauseMobCameraEffect(Player player) {
+        Objects.requireNonNull(player, "player");
+
+        if (this.mobCameras.remove(player.getUniqueId())) {
+            EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
+            PlayerConnection connection = nmsPlayer.playerConnection;
+
+            if (connection != null) {
+                connection.sendPacket(new PacketPlayOutCamera(nmsPlayer));
+            }
+        }
+    }
+}
-- 
2.28.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant