From b4d8df9e8e4fbdadcd66e5449ac47e67c383dbed Mon Sep 17 00:00:00 2001 From: skippyall <> Date: Sun, 1 Sep 2024 18:49:33 +0200 Subject: [PATCH] Merge spawnMinion and spawnMinionAt --- .../io/github/skippyall/minions/Minions.java | 2 +- .../minions/fakeplayer/MinionFakePlayer.java | 103 ++++-------------- .../skippyall/minions/minion/MinionData.java | 36 ++++++ .../skippyall/minions/minion/MinionItem.java | 14 +-- .../minions/minion/MinionPersistentState.java | 56 ---------- .../minions/mixins/PlayerListMixin.java | 5 +- 6 files changed, 67 insertions(+), 149 deletions(-) create mode 100644 src/main/java/io/github/skippyall/minions/minion/MinionData.java diff --git a/src/main/java/io/github/skippyall/minions/Minions.java b/src/main/java/io/github/skippyall/minions/Minions.java index 3b793cc..57aa27f 100644 --- a/src/main/java/io/github/skippyall/minions/Minions.java +++ b/src/main/java/io/github/skippyall/minions/Minions.java @@ -33,7 +33,7 @@ public class Minions implements ModInitializer { MinionPersistentState.create(server); MinionPersistentState.INSTANCE.getMinionData().forEach(data -> { System.out.println("spawn Minion " + data.name); - MinionFakePlayer.spawnMinion(data, server.getOverworld()); + MinionFakePlayer.spawnMinionAt(data, server.getOverworld(), null, null); }); }); ServerTickEvents.START_SERVER_TICK.register(server -> { diff --git a/src/main/java/io/github/skippyall/minions/fakeplayer/MinionFakePlayer.java b/src/main/java/io/github/skippyall/minions/fakeplayer/MinionFakePlayer.java index 34c7d80..1292383 100644 --- a/src/main/java/io/github/skippyall/minions/fakeplayer/MinionFakePlayer.java +++ b/src/main/java/io/github/skippyall/minions/fakeplayer/MinionFakePlayer.java @@ -3,14 +3,10 @@ package io.github.skippyall.minions.fakeplayer; import com.mojang.authlib.GameProfile; import com.mojang.authlib.yggdrasil.ProfileResult; import io.github.skippyall.minions.Minions; -import io.github.skippyall.minions.minion.MinionInventory; -import io.github.skippyall.minions.minion.MinionItem; -import io.github.skippyall.minions.minion.MinionPersistentState; -import io.github.skippyall.minions.minion.ModuleInventory; +import io.github.skippyall.minions.minion.*; import io.github.skippyall.minions.mixins.GameProfileMixin; import io.github.skippyall.minions.program.runtime.MinionRuntime; import net.minecraft.block.BlockState; -import net.minecraft.component.ComponentType; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Entity; import net.minecraft.entity.EquipmentSlot; @@ -27,7 +23,6 @@ import net.minecraft.network.packet.c2s.common.SyncedClientOptions; import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket; import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket; import net.minecraft.network.packet.s2c.play.EntitySetHeadYawS2CPacket; -import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerTask; import net.minecraft.server.network.ConnectedClientData; @@ -38,16 +33,16 @@ import net.minecraft.text.TranslatableTextContent; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec2f; import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameMode; import net.minecraft.world.TeleportTarget; +import org.jetbrains.annotations.Nullable; -import java.util.Optional; import java.util.UUID; public class MinionFakePlayer extends ServerPlayerEntity { public Runnable fixStartingPosition = () -> {}; - public boolean isAShadow; private float moveForward; private float moveSideways; @@ -76,7 +71,8 @@ public class MinionFakePlayer extends ServerPlayerEntity { GameProfile finalProfile = newProfile; ((GameProfileMixin)finalProfile).setId(UUID.randomUUID()); Minions.addExecuteOnNextTick(() -> { - MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault(), false, canProgram); + MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault()); + instance.programmable = canProgram; instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), instance, new ConnectedClientData(finalProfile, 0, instance.getClientOptions(), false)); instance.teleport(level, pos.x, pos.y, pos.z, (float) yaw, (float) pitch); @@ -97,7 +93,7 @@ public class MinionFakePlayer extends ServerPlayerEntity { }); } - public static void spawnMinion(MinionPersistentState.MinionData data, ServerWorld level) { + public static void spawnMinionAt(MinionData data, ServerWorld level, @Nullable Vec3d pos, @Nullable Vec2f rot) { MinecraftServer server = level.getServer(); server.getUserCache().findByNameAsync(data.name).thenAcceptAsync((optional) -> { GameProfile profile = null; @@ -115,46 +111,16 @@ public class MinionFakePlayer extends ServerPlayerEntity { GameProfile finalProfile = newProfile; ((GameProfileMixin)finalProfile).setId(data.uuid); Minions.addExecuteOnNextTick(() -> { - MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault(), false, data.programmable); - System.out.println(instance.getPos()); - server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), instance, new ConnectedClientData(finalProfile, 0, instance.getClientOptions(), false)); - System.out.println(instance.getPos()); - instance.setHealth(20.0F); - instance.unsetRemoved(); - instance.interactionManager.changeGameMode(GameMode.SURVIVAL); - server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), level.getRegistryKey());//instance.dimension); - server.getPlayerManager().sendToDimension(new EntityPositionS2CPacket(instance), level.getRegistryKey());//instance.dimension); - //instance.world.getChunkManager(). updatePosition(instance); - instance.dataTracker.set(PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes) - instance.getAbilities().flying = false; - }); - }); - } - - public static void spawnMinionAt(MinionPersistentState.MinionData data, ServerWorld level, Vec3d pos, double yaw, double pitch) { - MinecraftServer server = level.getServer(); - server.getUserCache().findByNameAsync(data.name).thenAcceptAsync((optional) -> { - GameProfile profile = null; - if (optional.isPresent()) { - ProfileResult result = server.getSessionService().fetchProfile(optional.get().getId(), true); - if (result != null) { - profile = result.profile(); + MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault()); + if(pos != null && rot != null) { + instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(pos.x, pos.y, pos.z, rot.x, rot.y); } - } - if (profile == null) { - profile = new GameProfile(new UUID(0, 0), data.name); - } - GameProfile newProfile = new GameProfile(data.uuid, data.name); - newProfile.getProperties().putAll(profile.getProperties()); - GameProfile finalProfile = newProfile; - ((GameProfileMixin)finalProfile).setId(data.uuid); - Minions.addExecuteOnNextTick(() -> { - MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault(), false, data.programmable); - instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); System.out.println(instance.getPos()); server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), instance, new ConnectedClientData(finalProfile, 0, instance.getClientOptions(), false)); System.out.println(instance.getPos()); - instance.teleport(level, pos.x, pos.y, pos.z, (float) yaw, (float) pitch); + if(pos != null && rot != null) { + instance.teleport(level, pos.x, pos.y, pos.z, rot.x, rot.y); + } instance.setVelocity(0,0,0); instance.setHealth(20.0F); instance.unsetRemoved(); @@ -168,47 +134,24 @@ public class MinionFakePlayer extends ServerPlayerEntity { }); } - @SuppressWarnings("unused") //Don't know if I'll need this - public static MinionFakePlayer createShadow(MinecraftServer server, ServerPlayerEntity player) + public static MinionFakePlayer respawnFake(MinecraftServer server, ServerWorld level, GameProfile profile, SyncedClientOptions cli) { - player.getServer().getPlayerManager().remove(player); - player.networkHandler.disconnect(Text.translatable("multiplayer.disconnect.duplicate_login")); - ServerWorld worldIn = player.getServerWorld();//.getWorld(player.dimension); - GameProfile gameprofile = player.getGameProfile(); - MinionFakePlayer playerShadow = new MinionFakePlayer(server, worldIn, gameprofile, player.getClientOptions(), true, false); - playerShadow.setSession(player.getSession()); - server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), playerShadow, new ConnectedClientData(gameprofile, 0, player.getClientOptions(), false)); - - playerShadow.setHealth(player.getHealth()); - playerShadow.networkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch()); - playerShadow.interactionManager.changeGameMode(player.interactionManager.getGameMode()); - ((ServerPlayerInterface) playerShadow).getActionPack().copyFrom(((ServerPlayerInterface) player).getActionPack()); - playerShadow.dataTracker.set(PLAYER_MODEL_PARTS, player.getDataTracker().get(PLAYER_MODEL_PARTS)); - - - server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(playerShadow, (byte) (player.headYaw * 256 / 360)), playerShadow.getWorld().getRegistryKey()); - server.getPlayerManager().sendToAll(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, playerShadow)); - //player.world.getChunkManager().updatePosition(playerShadow); - playerShadow.getAbilities().flying = player.getAbilities().flying; - return playerShadow; + return new MinionFakePlayer(server, level, profile, cli); } - public static MinionFakePlayer respawnFake(MinecraftServer server, ServerWorld level, GameProfile profile, SyncedClientOptions cli, boolean programmable) - { - return new MinionFakePlayer(server, level, profile, cli, false, programmable); - } - - private MinionFakePlayer(MinecraftServer server, ServerWorld worldIn, GameProfile profile, SyncedClientOptions cli, boolean shadow, boolean programmable) + private MinionFakePlayer(MinecraftServer server, ServerWorld worldIn, GameProfile profile, SyncedClientOptions cli) { super(server, worldIn, profile, cli); - isAShadow = shadow; - this.programmable = programmable; } public boolean isProgrammable() { return programmable; } + public void setProgrammable(boolean programmable) { + this.programmable = programmable; + } + public ModuleInventory getModuleInventory() { return moduleInventory; } @@ -377,15 +320,11 @@ public class MinionFakePlayer extends ServerPlayerEntity { protected void drop(ServerWorld world, DamageSource damageSource) { super.drop(world, damageSource); dropItem(toItemStack(), true, false); - for(ItemStack item : moduleInventory.getItems()) { - dropItem(item, true, false); - } - moduleInventory.clear(); } private ItemStack toItemStack() { ItemStack stack = new ItemStack(Minions.MINION_ITEM); - MinionItem.setData(MinionPersistentState.MinionData.fromMinion(this), stack); + MinionItem.setData(MinionData.fromMinion(this), stack); if (!getMinionName().equals("Minion")) { stack.set(DataComponentTypes.CUSTOM_NAME, Text.of(getMinionName())); } @@ -396,12 +335,14 @@ public class MinionFakePlayer extends ServerPlayerEntity { public void writeCustomDataToNbt(NbtCompound nbt) { super.writeCustomDataToNbt(nbt); nbt.put("modules", moduleInventory.writeNbt(new NbtCompound(), getRegistryManager())); + nbt.putBoolean("programmable", programmable); } @Override public void readCustomDataFromNbt(NbtCompound nbt) { super.readCustomDataFromNbt(nbt); moduleInventory.readNbt(nbt.getCompound("modules"), getRegistryManager()); + programmable = nbt.getBoolean("programmable"); } public String getMinionName() { diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionData.java b/src/main/java/io/github/skippyall/minions/minion/MinionData.java new file mode 100644 index 0000000..4e8bc4c --- /dev/null +++ b/src/main/java/io/github/skippyall/minions/minion/MinionData.java @@ -0,0 +1,36 @@ +package io.github.skippyall.minions.minion; + +import io.github.skippyall.minions.fakeplayer.MinionFakePlayer; +import net.minecraft.nbt.NbtCompound; + +import java.util.UUID; + +public class MinionData { + public UUID uuid; + public String name; + + public MinionData(UUID uuid, String name) { + this.uuid = uuid; + this.name = name; + } + + public NbtCompound writeNbt() { + NbtCompound nbt = new NbtCompound(); + + nbt.putUuid("uuid", uuid); + nbt.putString("name", name); + + return nbt; + } + + public static MinionData readNbt(NbtCompound nbt) { + UUID uuid = nbt.getUuid("uuid"); + String name = nbt.getString("name"); + + return new MinionData(uuid, name); + } + + public static MinionData fromMinion(MinionFakePlayer minion) { + return new MinionData(minion.getUuid(), minion.getMinionName()); + } +} diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionItem.java b/src/main/java/io/github/skippyall/minions/minion/MinionItem.java index d385fdc..e5c1c31 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionItem.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionItem.java @@ -3,8 +3,6 @@ package io.github.skippyall.minions.minion; import eu.pb4.polymer.core.api.item.PolymerItem; import eu.pb4.polymer.core.api.item.PolymerItemUtils; import io.github.skippyall.minions.fakeplayer.MinionFakePlayer; -import net.minecraft.client.render.VertexFormatElement; -import net.minecraft.component.ComponentType; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.NbtComponent; import net.minecraft.item.*; @@ -15,6 +13,7 @@ import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; +import net.minecraft.util.math.Vec2f; import org.jetbrains.annotations.Nullable; public class MinionItem extends Item implements PolymerItem { @@ -46,28 +45,29 @@ public class MinionItem extends Item implements PolymerItem { name = "Minion"; } if(!context.getWorld().isClient) { - MinionPersistentState.MinionData data = getData(context.getStack()); + MinionData data = getData(context.getStack()); if (data == null) { MinionFakePlayer.createMinion(name, (ServerWorld) context.getWorld(), (ServerPlayerEntity) context.getPlayer(), canProgram, context.getBlockPos().toCenterPos().add(0,0.5,0), 0, 0); }else { - MinionFakePlayer.spawnMinionAt(data, (ServerWorld) context.getWorld(), context.getBlockPos().toCenterPos().add(0,0.5,0), 0, 0); + MinionFakePlayer.spawnMinionAt(data, (ServerWorld) context.getWorld(), context.getBlockPos().toCenterPos().add(0,0.5,0), new Vec2f(0, 0)); MinionPersistentState.INSTANCE.addMinion(data); } } + context.getStack().decrement(1); return ActionResult.SUCCESS; } - public static void setData(MinionPersistentState.MinionData data, ItemStack item) { + public static void setData(MinionData data, ItemStack item) { NbtCompound nbt = item.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).copyNbt(); nbt.put("data", data.writeNbt()); item.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(nbt)); } @Nullable - public static MinionPersistentState.MinionData getData(ItemStack item) { + public static MinionData getData(ItemStack item) { NbtCompound nbt = item.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).copyNbt(); if (nbt.getType("data") == NbtElement.COMPOUND_TYPE) { - return MinionPersistentState.MinionData.readNbt(nbt.getCompound("data")); + return MinionData.readNbt(nbt.getCompound("data")); } return null; } diff --git a/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java b/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java index 2548902..1c6b590 100644 --- a/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java +++ b/src/main/java/io/github/skippyall/minions/minion/MinionPersistentState.java @@ -71,60 +71,4 @@ public class MinionPersistentState extends PersistentState { public static void create(MinecraftServer server) { INSTANCE = server.getWorld(World.OVERWORLD).getPersistentStateManager().getOrCreate(TYPE, "minion"); } - - public static class MinionData { - public UUID uuid; - public String name; - public boolean programmable; - - public MinionData(UUID uuid, String name, boolean programmable) { - this.uuid = uuid; - this.name = name; - this.programmable = programmable; - } - - public NbtCompound writeNbt() { - NbtCompound nbt = new NbtCompound(); - - /*NbtList posList = new NbtList(); - posList.add(NbtDouble.of(pos.getX())); - posList.add(NbtDouble.of(pos.getY())); - posList.add(NbtDouble.of(pos.getZ())); - nbt.put("pos", posList); - - NbtList rotList = new NbtList(); - rotList.add(NbtFloat.of(rot.x)); - rotList.add(NbtFloat.of(rot.y)); - nbt.put("rotation", rotList);*/ - - nbt.putUuid("uuid", uuid); - nbt.putString("name", name); - nbt.putBoolean("programmable", programmable); - - return nbt; - } - - public static MinionData readNbt(NbtCompound nbt) { - /*NbtList posList = nbt.getList("pos", NbtElement.DOUBLE_TYPE); - double x = posList.getDouble(0); - double y = posList.getDouble(1); - double z = posList.getDouble(2); - Vec3d pos = new Vec3d(x, y, z); - - NbtList rotList = nbt.getList("rotation", NbtElement.FLOAT_TYPE); - float yaw = rotList.getFloat(0); - float pitch = rotList.getFloat(1); - Vec2f rot = new Vec2f(yaw, pitch);*/ - - UUID uuid = nbt.getUuid("uuid"); - String name = nbt.getString("name"); - boolean programmable = nbt.getBoolean("programmable"); - - return new MinionData(uuid, name, programmable); - } - - public static MinionData fromMinion(MinionFakePlayer minion) { - return new MinionData(minion.getUuid(), minion.getMinionName(), minion.isProgrammable()); - } - } } diff --git a/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java b/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java index 60c8be2..37baf7f 100644 --- a/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java +++ b/src/main/java/io/github/skippyall/minions/mixins/PlayerListMixin.java @@ -16,10 +16,7 @@ import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; -import org.apache.logging.log4j.core.jmx.Server; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -49,7 +46,7 @@ public class PlayerListMixin { @WrapOperation(method = "respawnPlayer", at = @At(value = "NEW", target = "(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/server/world/ServerWorld;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/network/packet/c2s/common/SyncedClientOptions;)Lnet/minecraft/server/network/ServerPlayerEntity;")) public ServerPlayerEntity makePlayerForRespawn(MinecraftServer minecraftServer, ServerWorld serverLevel, GameProfile gameProfile, SyncedClientOptions clientInformation, Operation original, ServerPlayerEntity serverPlayer, boolean bl) { if (serverPlayer instanceof MinionFakePlayer minion) { - return MinionFakePlayer.respawnFake(minecraftServer, serverLevel, gameProfile, clientInformation, minion.isProgrammable()); + return MinionFakePlayer.respawnFake(minecraftServer, serverLevel, gameProfile, clientInformation); } return original.call(minecraftServer, serverLevel, gameProfile, clientInformation); }