Merge pull request #1 from Mineattack-Foxgalaxy/master

ErfinderLabyrinth's changes
This commit was merged in pull request #1.
This commit is contained in:
skippyall
2024-09-01 17:35:12 +02:00
committed by GitHub
11 changed files with 382 additions and 36 deletions
@@ -1,9 +1,12 @@
package io.github.skippyall.minions; package io.github.skippyall.minions;
import eu.pb4.polymer.core.api.entity.PolymerEntityUtils; import eu.pb4.polymer.core.api.entity.PolymerEntityUtils;
import io.github.skippyall.minions.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.minion.MinionItem; import io.github.skippyall.minions.minion.MinionItem;
import io.github.skippyall.minions.minion.MinionPersistentState;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@@ -11,16 +14,45 @@ import net.minecraft.util.Identifier;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
public class Minions implements ModInitializer { public class Minions implements ModInitializer {
public static final String MOD_ID = "minions"; public static final String MOD_ID = "minions";
public static final MinionItem MINION_ITEM = Registry.register(Registries.ITEM, Identifier.of(MOD_ID, "minion"), new MinionItem(false)); public static final MinionItem MINION_ITEM = Registry.register(Registries.ITEM, Identifier.of(MOD_ID, "minion"), new MinionItem(false));
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
private static final List<Runnable> executeOnNextTick = new ArrayList<>();
@Override @Override
public void onInitialize() { public void onInitialize() {
LOGGER.debug("Add Customthing");
PolymerEntityUtils.registerType(); PolymerEntityUtils.registerType();
ServerLifecycleEvents.SERVER_STARTED.register(server -> { ServerLifecycleEvents.SERVER_STARTED.register(server -> {
MinionPersistentState.create(server);
MinionPersistentState.INSTANCE.getMinionData().forEach(data -> {
System.out.println("spawn Minion " + data.name);
MinionFakePlayer.spawnMinion(data, server.getOverworld());
});
});
ServerTickEvents.START_SERVER_TICK.register(server -> {
exec(() -> {
for (Runnable run:executeOnNextTick) {
run.run();
}
executeOnNextTick.clear();
});
});
}
private static synchronized void exec(Runnable run) {
run.run();
}
public static void addExecuteOnNextTick(Runnable run) {
exec(() -> {
executeOnNextTick.add(run);
}); });
} }
} }
@@ -4,9 +4,14 @@ import com.mojang.authlib.GameProfile;
import com.mojang.authlib.yggdrasil.ProfileResult; import com.mojang.authlib.yggdrasil.ProfileResult;
import io.github.skippyall.minions.Minions; import io.github.skippyall.minions.Minions;
import io.github.skippyall.minions.minion.MinionInventory; 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.ModuleInventory;
import io.github.skippyall.minions.mixins.GameProfileMixin;
import io.github.skippyall.minions.program.runtime.MinionRuntime; import io.github.skippyall.minions.program.runtime.MinionRuntime;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.component.ComponentType;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.MovementType; import net.minecraft.entity.MovementType;
@@ -18,13 +23,11 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.DisconnectionInfo; import net.minecraft.network.DisconnectionInfo;
import net.minecraft.network.NetworkSide; import net.minecraft.network.NetworkSide;
import net.minecraft.network.packet.StatusPackets;
import net.minecraft.network.packet.c2s.common.SyncedClientOptions; import net.minecraft.network.packet.c2s.common.SyncedClientOptions;
import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket; import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket;
import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket; import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket;
import net.minecraft.network.packet.s2c.play.EntitySetHeadYawS2CPacket; import net.minecraft.network.packet.s2c.play.EntitySetHeadYawS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.network.packet.s2c.query.PingResultS2CPacket;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerTask; import net.minecraft.server.ServerTask;
import net.minecraft.server.network.ConnectedClientData; import net.minecraft.server.network.ConnectedClientData;
@@ -34,12 +37,12 @@ import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent; import net.minecraft.text.TranslatableTextContent;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Uuids;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameMode; import net.minecraft.world.GameMode;
import net.minecraft.world.TeleportTarget; import net.minecraft.world.TeleportTarget;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public class MinionFakePlayer extends ServerPlayerEntity { public class MinionFakePlayer extends ServerPlayerEntity {
@@ -56,30 +59,112 @@ public class MinionFakePlayer extends ServerPlayerEntity {
public static void createMinion(String username, ServerWorld level, ServerPlayerEntity owner, boolean canProgram, Vec3d pos, double yaw, double pitch) { public static void createMinion(String username, ServerWorld level, ServerPlayerEntity owner, boolean canProgram, Vec3d pos, double yaw, double pitch) {
MinecraftServer server = level.getServer(); MinecraftServer server = level.getServer();
server.getUserCache().findByNameAsync(username).thenAcceptAsync((optional) -> { server.getUserCache().findByNameAsync(username).thenAcceptAsync((optional) -> {
try {
GameProfile profile = null;
if(optional.isPresent()){
UUID uuid = optional.get().getId();
ProfileResult result = server.getSessionService().fetchProfile(uuid, true);
if(result != null) {
profile = result.profile();
}
}
if(profile == null) {
profile = new GameProfile(new UUID(0,0), username);
}
GameProfile newProfile = new GameProfile(UUID.randomUUID(), username);
newProfile.getProperties().putAll(profile.getProperties());
GameProfile finalProfile = newProfile;
((GameProfileMixin)finalProfile).setId(UUID.randomUUID());
Minions.addExecuteOnNextTick(() -> {
MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault(), false, 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);
instance.setHealth(20.0F);
instance.unsetRemoved();
instance.getAttributeInstance(EntityAttributes.GENERIC_STEP_HEIGHT).setBaseValue(0.6F);
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;
MinionPersistentState.INSTANCE.addMinion(instance);
});
}catch (Throwable ex) {
ex.printStackTrace();
}
});
}
public static void spawnMinion(MinionPersistentState.MinionData data, ServerWorld level) {
MinecraftServer server = level.getServer();
server.getUserCache().findByNameAsync(data.name).thenAcceptAsync((optional) -> {
GameProfile profile = null; GameProfile profile = null;
if(optional.isPresent()){ if (optional.isPresent()) {
UUID uuid = optional.get().getId(); ProfileResult result = server.getSessionService().fetchProfile(optional.get().getId(), true);
ProfileResult result = server.getSessionService().fetchProfile(uuid, true); if (result != null) {
if(result != null) {
profile = result.profile(); profile = result.profile();
} }
} }
if(profile == null) { if (profile == null) {
profile = new GameProfile(Uuids.getOfflinePlayerUuid(username), username); profile = new GameProfile(new UUID(0, 0), data.name);
} }
MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, SyncedClientOptions.createDefault(), false, canProgram); GameProfile newProfile = new GameProfile(data.uuid, data.name);
instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(pos.x, pos.y, pos.z, (float) yaw, (float) pitch); newProfile.getProperties().putAll(profile.getProperties());
server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), instance, new ConnectedClientData(profile, 0, instance.getClientOptions(), false)); GameProfile finalProfile = newProfile;
instance.teleport(level, pos.x, pos.y, pos.z, (float) yaw, (float) pitch); ((GameProfileMixin)finalProfile).setId(data.uuid);
instance.setHealth(20.0F); Minions.addExecuteOnNextTick(() -> {
instance.unsetRemoved(); MinionFakePlayer instance = new MinionFakePlayer(server, level, finalProfile, SyncedClientOptions.createDefault(), false, data.programmable);
instance.getAttributeInstance(EntityAttributes.GENERIC_STEP_HEIGHT).setBaseValue(0.6F); System.out.println(instance.getPos());
instance.interactionManager.changeGameMode(GameMode.SURVIVAL); server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), instance, new ConnectedClientData(finalProfile, 0, instance.getClientOptions(), false));
server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), level.getRegistryKey());//instance.dimension); System.out.println(instance.getPos());
server.getPlayerManager().sendToDimension(new EntityPositionS2CPacket(instance), level.getRegistryKey());//instance.dimension); instance.setHealth(20.0F);
//instance.world.getChunkManager(). updatePosition(instance); instance.unsetRemoved();
instance.dataTracker.set(PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes) instance.interactionManager.changeGameMode(GameMode.SURVIVAL);
instance.getAbilities().flying = false; 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();
}
}
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);
instance.setVelocity(0,0,0);
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;
});
}); });
} }
@@ -117,7 +202,7 @@ public class MinionFakePlayer extends ServerPlayerEntity {
{ {
super(server, worldIn, profile, cli); super(server, worldIn, profile, cli);
isAShadow = shadow; isAShadow = shadow;
this.programmable = programmable;
} }
public boolean isProgrammable() { public boolean isProgrammable() {
@@ -155,11 +240,11 @@ public class MinionFakePlayer extends ServerPlayerEntity {
if (!isUsingItem()) super.onEquipStack(slot, previous, stack); if (!isUsingItem()) super.onEquipStack(slot, previous, stack);
} }
@Override /*@Override
public void kill() public void kill()
{ {
kill(Text.literal("Killed")); kill(Text.literal("Killed"));
} }*/
public void kill(Text reason) public void kill(Text reason)
{ {
@@ -172,6 +257,8 @@ public class MinionFakePlayer extends ServerPlayerEntity {
this.networkHandler.onDisconnected(new DisconnectionInfo(reason)); this.networkHandler.onDisconnected(new DisconnectionInfo(reason));
})); }));
} }
MinionPersistentState.INSTANCE.removeMinion(this);
} }
@Override @Override
@@ -269,14 +356,14 @@ public class MinionFakePlayer extends ServerPlayerEntity {
float newForward = (float) (moveForward - movement.z); float newForward = (float) (moveForward - movement.z);
float newSideways = (float) (moveSideways - movement.x); float newSideways = (float) (moveSideways - movement.x);
Vec3d newMovement = movement; Vec3d newMovement = movement;
if ((newForward < 0 && moveForward >= 0) || (newForward > 0 && moveForward <= 0)) { if ((newForward < 0 && moveForward > 0) || (newForward > 0 && moveForward < 0)) {
newMovement = new Vec3d(newMovement.x, newMovement.y, moveForward); newMovement = new Vec3d(newMovement.x, newMovement.y, moveForward);
moveForward = 0; moveForward = 0;
getMinionActionPack().setForward(0); getMinionActionPack().setForward(0);
}else { }else {
moveForward = newForward; moveForward = newForward;
} }
if ((newSideways < 0 && moveSideways >= 0) || (newSideways > 0 && moveSideways <= 0)) { if ((newSideways < 0 && moveSideways > 0) || (newSideways > 0 && moveSideways < 0)) {
newMovement = new Vec3d(newMovement.x, newMovement.y, moveSideways); newMovement = new Vec3d(newMovement.x, newMovement.y, moveSideways);
moveSideways = 0; moveSideways = 0;
getMinionActionPack().setStrafing(0); getMinionActionPack().setStrafing(0);
@@ -289,13 +376,22 @@ public class MinionFakePlayer extends ServerPlayerEntity {
@Override @Override
protected void drop(ServerWorld world, DamageSource damageSource) { protected void drop(ServerWorld world, DamageSource damageSource) {
super.drop(world, damageSource); super.drop(world, damageSource);
dropItem(new ItemStack(Minions.MINION_ITEM), true, false); dropItem(toItemStack(), true, false);
for(ItemStack item : moduleInventory.getItems()) { for(ItemStack item : moduleInventory.getItems()) {
dropItem(item, true, false); dropItem(item, true, false);
} }
moduleInventory.clear(); moduleInventory.clear();
} }
private ItemStack toItemStack() {
ItemStack stack = new ItemStack(Minions.MINION_ITEM);
MinionItem.setData(MinionPersistentState.MinionData.fromMinion(this), stack);
if (!getMinionName().equals("Minion")) {
stack.set(DataComponentTypes.CUSTOM_NAME, Text.of(getMinionName()));
}
return stack;
}
@Override @Override
public void writeCustomDataToNbt(NbtCompound nbt) { public void writeCustomDataToNbt(NbtCompound nbt) {
super.writeCustomDataToNbt(nbt); super.writeCustomDataToNbt(nbt);
@@ -307,4 +403,8 @@ public class MinionFakePlayer extends ServerPlayerEntity {
super.readCustomDataFromNbt(nbt); super.readCustomDataFromNbt(nbt);
moduleInventory.readNbt(nbt.getCompound("modules"), getRegistryManager()); moduleInventory.readNbt(nbt.getCompound("modules"), getRegistryManager());
} }
public String getMinionName() {
return getGameProfile().getName();
}
} }
@@ -3,9 +3,14 @@ package io.github.skippyall.minions.minion;
import eu.pb4.polymer.core.api.item.PolymerItem; import eu.pb4.polymer.core.api.item.PolymerItem;
import eu.pb4.polymer.core.api.item.PolymerItemUtils; import eu.pb4.polymer.core.api.item.PolymerItemUtils;
import io.github.skippyall.minions.fakeplayer.MinionFakePlayer; 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.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.item.tooltip.TooltipType; import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.RegistryWrapper;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
@@ -41,8 +46,37 @@ public class MinionItem extends Item implements PolymerItem {
name = "Minion"; name = "Minion";
} }
if(!context.getWorld().isClient) { if(!context.getWorld().isClient) {
MinionFakePlayer.createMinion(name, (ServerWorld) context.getWorld(), (ServerPlayerEntity) context.getPlayer(), canProgram, context.getBlockPos().toCenterPos().add(0,0.5,0), 0, 0); MinionPersistentState.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);
MinionPersistentState.INSTANCE.addMinion(data);
}
} }
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
public static void setData(MinionPersistentState.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) {
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 null;
}
public static boolean containsData(ItemStack item) {
NbtComponent nbt = item.get(DataComponentTypes.CUSTOM_DATA);
if (nbt == null) {
return false;
}
return nbt.copyNbt().contains("data");
}
} }
@@ -16,7 +16,7 @@ public class MinionPersistentState extends PersistentState {
public static MinionPersistentState INSTANCE; public static MinionPersistentState INSTANCE;
public static List<MinionData> minionData = new ArrayList<>(); private List<MinionData> minionData = new ArrayList<>();
@Override @Override
public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
@@ -30,10 +30,42 @@ public class MinionPersistentState extends PersistentState {
public static MinionPersistentState read(NbtCompound compound, RegistryWrapper.WrapperLookup lookup) { public static MinionPersistentState read(NbtCompound compound, RegistryWrapper.WrapperLookup lookup) {
NbtList list = compound.getList("minions", NbtElement.COMPOUND_TYPE); NbtList list = compound.getList("minions", NbtElement.COMPOUND_TYPE);
MinionPersistentState instance = new MinionPersistentState();
for(NbtElement element : list) { for(NbtElement element : list) {
minionData.add(MinionData.readNbt((NbtCompound) element)); instance.addMinion(MinionData.readNbt((NbtCompound) element));
} }
return new MinionPersistentState(); return instance;
}
public void addMinion(MinionFakePlayer minion) {
addMinion(MinionData.fromMinion(minion));
}
public void addMinion(MinionData data) {
System.out.println("add Minion " + data.name);
minionData.add(data);
markDirty();
}
public void removeMinion(MinionFakePlayer minionData) {
removeMinion(minionData.getUuid());
}
public void removeMinion(UUID minionUUID) {
MinionData removal = null;
for (MinionData data : minionData) {
if (data.uuid.equals(minionUUID)) {
removal = data;
}
}
if (removal != null) {
minionData.remove(removal);
}
markDirty();
}
public List<MinionData> getMinionData() {
return minionData;
} }
public static void create(MinecraftServer server) { public static void create(MinecraftServer server) {
@@ -42,9 +74,13 @@ public class MinionPersistentState extends PersistentState {
public static class MinionData { public static class MinionData {
public UUID uuid; public UUID uuid;
public String name;
public boolean programmable;
public MinionData(UUID uuid) { public MinionData(UUID uuid, String name, boolean programmable) {
this.uuid = uuid; this.uuid = uuid;
this.name = name;
this.programmable = programmable;
} }
public NbtCompound writeNbt() { public NbtCompound writeNbt() {
@@ -62,6 +98,8 @@ public class MinionPersistentState extends PersistentState {
nbt.put("rotation", rotList);*/ nbt.put("rotation", rotList);*/
nbt.putUuid("uuid", uuid); nbt.putUuid("uuid", uuid);
nbt.putString("name", name);
nbt.putBoolean("programmable", programmable);
return nbt; return nbt;
} }
@@ -79,12 +117,14 @@ public class MinionPersistentState extends PersistentState {
Vec2f rot = new Vec2f(yaw, pitch);*/ Vec2f rot = new Vec2f(yaw, pitch);*/
UUID uuid = nbt.getUuid("uuid"); UUID uuid = nbt.getUuid("uuid");
String name = nbt.getString("name");
boolean programmable = nbt.getBoolean("programmable");
return new MinionData(uuid); return new MinionData(uuid, name, programmable);
} }
public static MinionData fromMinion(MinionFakePlayer minion) { public static MinionData fromMinion(MinionFakePlayer minion) {
return new MinionData(minion.getUuid()); return new MinionData(minion.getUuid(), minion.getMinionName(), minion.isProgrammable());
} }
} }
} }
@@ -0,0 +1,29 @@
package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.server.world.ChunkTicketManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(value = ChunkTicketManager.class, remap = false)
public class ChunkTicketManagerFixMixin {
@WrapOperation(method = "handleChunkLeave", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z"))
public boolean filterIfNull(ObjectSet instance, Object o, Operation<Boolean> original) {
if (instance != null) {
return original.call(instance, o);
}
return false;//Unused
}
@WrapOperation(method = "handleChunkLeave", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;isEmpty()Z"))
public boolean filterIfNull(ObjectSet instance, Operation<Boolean> original) {
if (instance != null) {
return original.call(instance);
}
return true;//Unused
}
}
@@ -0,0 +1,24 @@
package io.github.skippyall.minions.mixins;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.world.PlayerSaveHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(PlayerSaveHandler.class)
public class Debug2Mixin {
@Inject(method = "method_55788", at = @At("HEAD"))
public void debug(PlayerEntity playerEntity, NbtCompound nbt, CallbackInfoReturnable<NbtCompound> cir) {
System.out.println("loadPlayerData " + playerEntity.getNameForScoreboard());
}
@Inject(method = "loadPlayerData(Lnet/minecraft/entity/player/PlayerEntity;Ljava/lang/String;)Ljava/util/Optional;", at = @At("RETURN"))
public void debug(PlayerEntity player, String extension, CallbackInfoReturnable<Optional<NbtCompound>> cir) {
System.out.println(cir.getReturnValue().isEmpty() + player.getUuidAsString());
}
}
@@ -0,0 +1,32 @@
package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.sugar.Local;
import io.github.skippyall.minions.fakeplayer.MinionFakePlayer;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NbtCompound;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
//@Mixin(SectionedEntityCache.class)
@Mixin(Entity.class)
public class DebugMixin {
/*@Inject(method = "forEachInBox", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/ChunkSectionPos;asLong(III)J", shift = At.Shift.BEFORE, ordinal = 0))
private void debug(Box box, LazyIterationConsumer<EntityTrackingSection<?>> consumer, CallbackInfo ci) {
System.out.println("call");
}*/
@Inject(method = "readNbt", at = @At("HEAD"))
public void debug(NbtCompound nbt, CallbackInfo ci) {
if ((Object) this instanceof MinionFakePlayer) {
System.out.println("readNBT");
}
}
@Inject(method = "setPos", at = @At("HEAD"))
public void debug(double x, double y, double z, CallbackInfo ci) {
if ((Object) this instanceof MinionFakePlayer) {
System.out.println("Set Minion Pos to " + x + " " + y + " " + z);
}
}
}
@@ -0,0 +1,15 @@
package io.github.skippyall.minions.mixins;
import com.mojang.authlib.GameProfile;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.UUID;
@Mixin(value = GameProfile.class, remap = false)
public interface GameProfileMixin{
@Mutable
@Accessor("id")
void setId(UUID id);
}
@@ -2,6 +2,7 @@ package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import io.github.skippyall.minions.fakeplayer.MinionFakePlayer; import io.github.skippyall.minions.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.fakeplayer.NetHandlerPlayServerFake; import io.github.skippyall.minions.fakeplayer.NetHandlerPlayServerFake;
@@ -14,6 +15,8 @@ import net.minecraft.server.network.ConnectedClientData;
import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; 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.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@@ -50,4 +53,11 @@ public class PlayerListMixin {
} }
return original.call(minecraftServer, serverLevel, gameProfile, clientInformation); return original.call(minecraftServer, serverLevel, gameProfile, clientInformation);
} }
@WrapOperation(method = "onPlayerConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V"))
public void noLoginMessage(PlayerManager instance, Text message, boolean overlay, Operation<Void> original, @Local(argsOnly = true) ServerPlayerEntity player) {
if(!(player instanceof MinionFakePlayer)) {
original.call(instance, message, overlay);
}
}
} }
@@ -0,0 +1,25 @@
package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.skippyall.minions.fakeplayer.MinionFakePlayer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(ServerPlayNetworkHandler.class)
public class ServerPlayNetworkHandlerMixin {
@Shadow
public ServerPlayerEntity player;
@WrapOperation(method = "cleanUp", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V"))
public void noLogoutMessage(PlayerManager instance, Text message, boolean overlay, Operation<Void> original) {
if(!(player instanceof MinionFakePlayer)) {
original.call(instance, message, overlay);
}
}
}
+6 -1
View File
@@ -4,11 +4,16 @@
"package": "io.github.skippyall.minions.mixins", "package": "io.github.skippyall.minions.mixins",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"mixins": [ "mixins": [
"ChunkTicketManagerFixMixin",
"ConnectionMixin", "ConnectionMixin",
"Debug2Mixin",
"DebugMixin",
"GameProfileMixin",
"MinecraftServerMixin", "MinecraftServerMixin",
"PlayerListEntryS2CPacket$EntryMixin", "PlayerListEntryS2CPacket$EntryMixin",
"PlayerListMixin", "PlayerListMixin",
"ServerPlayerMixin" "ServerPlayerMixin",
"ServerPlayNetworkHandlerMixin"
], ],
"client": [], "client": [],
"server": [], "server": [],