Преглед изворни кода

complete player invisibility by faking spectator

Kajetan Johannes Hammerle пре 5 година
родитељ
комит
3591af0d9d

+ 26 - 0
src/main/java/me/km/snuviscript/commands/PlayerCommands.java

@@ -27,6 +27,7 @@ import net.minecraft.nbt.NBTUtil;
 import net.minecraft.network.ThreadQuickExitException;
 import net.minecraft.network.play.client.CChatMessagePacket;
 import net.minecraft.network.play.client.CClientStatusPacket;
+import net.minecraft.network.play.server.SPlayerListItemPacket;
 import net.minecraft.network.play.server.SSpawnPositionPacket;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.tileentity.SkullTileEntity;
@@ -276,6 +277,31 @@ public class PlayerCommands {
         sm.registerConsumer("player.setdisplayname", (sc, in) -> {
             ((ModEntityPlayerMP) in[0].get(sc)).setTabListDisplayName(in[1].getString(sc), scheduler);
         });
+        sm.registerConsumer("player.hide", (sc, in) -> {
+            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
+            GameType type = p.interactionManager.getGameType();
+            ReflectionUtils.setGameType(p.interactionManager, GameType.SPECTATOR);
+            SPlayerListItemPacket packet = new SPlayerListItemPacket(SPlayerListItemPacket.Action.UPDATE_GAME_MODE, p);
+            ReflectionUtils.setGameType(p.interactionManager, type);
+            for(ServerPlayerEntity other : server.getPlayerList().getPlayers()) {
+                if(other == p) {
+                    continue;
+                }
+                other.connection.sendPacket(packet);
+            }
+            p.setInvisible(true);
+        });
+        sm.registerConsumer("player.show", (sc, in) -> {
+            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
+            p.setInvisible(false);
+            SPlayerListItemPacket packet = new SPlayerListItemPacket(SPlayerListItemPacket.Action.UPDATE_GAME_MODE, p);
+            for(ServerPlayerEntity other : server.getPlayerList().getPlayers()) {
+                if(other == p) {
+                    continue;
+                }
+                other.connection.sendPacket(packet);
+            }
+        });
         sm.registerFunction("players.getamount", (sc, in) -> (double) server.getCurrentPlayerCount());
         sm.registerFunction("players.tolist", (sc, in) -> new ArrayList(server.getPlayerList().getPlayers()));
         sm.registerFunction("players.toworldlist", (sc, in) -> new ArrayList(((World) in[0].get(sc)).getPlayers()));

+ 11 - 0
src/main/java/me/km/utils/ReflectionUtils.java

@@ -13,11 +13,13 @@ import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.player.PlayerAbilities;
 import net.minecraft.entity.player.ServerPlayerEntity;
 import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.management.PlayerInteractionManager;
 import net.minecraft.server.management.PlayerList;
 import net.minecraft.util.FoodStats;
 import net.minecraft.util.ResourceLocation;
 import net.minecraft.world.Explosion;
 import net.minecraft.world.GameRules;
+import net.minecraft.world.GameType;
 import net.minecraft.world.IWorld;
 import net.minecraft.world.World;
 import net.minecraft.world.biome.provider.BiomeProvider;
@@ -252,4 +254,13 @@ public class ReflectionUtils {
             return null;
         }
     }
+
+    // -----------------------------------------------------------------------------------
+    // game type setter without update for dirty hack
+    // -----------------------------------------------------------------------------------
+    private final static Field GAME_TYPE = getField(PlayerInteractionManager.class, "field_73091_c");
+
+    public static void setGameType(PlayerInteractionManager m, GameType type) {
+        setFieldValue(m, GAME_TYPE, type);
+    }
 }