Mojang Mappings

This commit is contained in:
skippyall
2026-04-29 08:51:37 +02:00
parent cc9fedd63b
commit f5202a4264
140 changed files with 1646 additions and 1675 deletions
@@ -3,20 +3,20 @@ 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.ChunkLevelManager;
import net.minecraft.server.level.DistanceManager;
import org.slf4j.Logger;
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;
@Mixin(value = ChunkLevelManager.class)
@Mixin(value = DistanceManager.class)
public class ChunkTicketManagerFixMixin {
@Shadow
@Final
private static Logger LOGGER;
@WrapOperation(method = "handleChunkLeave", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z", remap = false))
@WrapOperation(method = "removePlayer", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z", remap = false))
public boolean filterIfNull(ObjectSet instance, Object o, Operation<Boolean> original) {
if (instance != null) {
return original.call(instance, o);
@@ -27,7 +27,7 @@ public class ChunkTicketManagerFixMixin {
return false;//Unused
}
@WrapOperation(method = "handleChunkLeave", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;isEmpty()Z", remap = false))
@WrapOperation(method = "removePlayer", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;isEmpty()Z", remap = false))
public boolean filterIfNull(ObjectSet instance, Operation<Boolean> original) {
if (instance != null) {
return original.call(instance);
@@ -0,0 +1,22 @@
package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.sugar.Local;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(ClientboundPlayerInfoUpdatePacket.Entry.class)
public class ClientboundPlayerInfoUpdatePacket$EntryMixin {
@ModifyArg(method = "<init>(Lnet/minecraft/server/level/ServerPlayer;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket$Entry;<init>(Ljava/util/UUID;Lcom/mojang/authlib/GameProfile;ZILnet/minecraft/world/level/GameType;Lnet/minecraft/network/chat/Component;ZILnet/minecraft/network/chat/RemoteChatSession$Data;)V"), index = 2)
private static boolean removeMinionFromTabList(boolean original, @Local(argsOnly = true) ServerPlayer player) {
if(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.showInTabList)) {
return false;
}
return original;
}
}
@@ -3,11 +3,11 @@ package io.github.skippyall.minions.mixins;
import io.github.skippyall.minions.minion.fakeplayer.ClientConnectionInterface;
import io.netty.channel.Channel;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Connection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientConnection.class)
@Mixin(Connection.class)
public abstract class ConnectionMixin implements ClientConnectionInterface {
@Override
@Accessor //Compat with adventure-platform-fabric
@@ -1,16 +1,16 @@
package io.github.skippyall.minions.mixins;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.stream.Stream;
import net.minecraft.world.entity.Entity;
@Mixin(Entity.class)
public interface EntityAccessor {
@Invoker("canAddPassenger")
boolean minions$canAddPassenger(Entity other);
@Invoker("streamIntoPassengers")
@Invoker("getIndirectPassengersStream")
Stream<Entity> minions$streamIntoPassengers();
}
@@ -1,18 +1,18 @@
package io.github.skippyall.minions.mixins;
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
import net.minecraft.entity.Entity;
import net.minecraft.world.EntityView;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import java.util.function.Predicate;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.EntityGetter;
@Mixin(EntityView.class)
public interface EntityViewMixin {
@ModifyArg(method = "getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/EntityView;getClosestPlayer(DDDDLjava/util/function/Predicate;)Lnet/minecraft/entity/player/PlayerEntity;"))
@Mixin(EntityGetter.class)
public interface EntityGetterMixin {
@ModifyArg(method = "getNearestPlayer(DDDDZ)Lnet/minecraft/world/entity/player/Player;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/EntityGetter;getNearestPlayer(DDDDLjava/util/function/Predicate;)Lnet/minecraft/world/entity/player/Player;"))
private @Nullable Predicate<Entity> addMinionPredicate(@Nullable Predicate<Entity> targetPredicate) {
Predicate<Entity> predicate = EntityViewMixinHelper.ADDITIONAL_PREDICATE.get();
if(targetPredicate != null) {
@@ -1,9 +1,9 @@
package io.github.skippyall.minions.mixins;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.world.World;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -17,11 +17,11 @@ public abstract class EntityMixin {
public abstract @Nullable LivingEntity getControllingPassenger();
@Shadow
private World world;
private Level level;
@Inject(method = "isLogicalSideForUpdatingMovement", at = @At("HEAD"), cancellable = true)
@Inject(method = "isLocalInstanceAuthoritative", at = @At("HEAD"), cancellable = true)
private void isFakePlayer(CallbackInfoReturnable<Boolean> cir)
{
if (getControllingPassenger() instanceof MinionFakePlayer) cir.setReturnValue(!world.isClient);
if (getControllingPassenger() instanceof MinionFakePlayer) cir.setReturnValue(!level.isClientSide);
}
}
@@ -4,10 +4,10 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.minion.skin.Base64SkinProvider;
import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -20,9 +20,8 @@ import java.util.stream.Collectors;
@Mixin(MinecraftServer.class)
public class MinecraftServerMixin {
@ModifyExpressionValue(method = "createMetadataPlayers", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;getPlayerList()Ljava/util/List;"))
public List<ServerPlayerEntity> ignoreFakePlayers(List<ServerPlayerEntity> original) {
@ModifyExpressionValue(method = "buildPlayerStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;getPlayers()Ljava/util/List;"))
public List<ServerPlayer> ignoreFakePlayers(List<ServerPlayer> original) {
return original.stream()
.filter(player -> !(player instanceof MinionFakePlayer minion
&& !minion.getData().config().getOption(MinionConfigOptions.showInServerList)))
@@ -30,7 +29,7 @@ public class MinecraftServerMixin {
}
@Inject(method = "handleCustomClickAction", at = @At("HEAD"), cancellable = true)
private void onCustomClickAction(Identifier id, Optional<NbtElement> payload, CallbackInfo ci) {
private void onCustomClickAction(ResourceLocation id, Optional<Tag> payload, CallbackInfo ci) {
if(id.equals(Base64SkinProvider.CUSTOM_DIALOG_ACTION)) {
Base64SkinProvider.onCustomDialogAction(payload);
ci.cancel();
@@ -4,17 +4,17 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(MobEntity.class)
public abstract class MobEntityMixin {
@WrapOperation(method = "checkDespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getClosestPlayer(Lnet/minecraft/entity/Entity;D)Lnet/minecraft/entity/player/PlayerEntity;"))
public PlayerEntity checkMobDespawningMinion(World instance, Entity entity, double maxDistance, Operation<PlayerEntity> original) {
@Mixin(Mob.class)
public abstract class MobMixin {
@WrapOperation(method = "checkDespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getNearestPlayer(Lnet/minecraft/world/entity/Entity;D)Lnet/minecraft/world/entity/player/Player;"))
public Player checkMobDespawningMinion(Level instance, Entity entity, double maxDistance, Operation<Player> original) {
EntityViewMixinHelper.ADDITIONAL_PREDICATE.set(entity2 -> {
if(entity2 instanceof MinionFakePlayer minion) {
return minion.canDespawnMobs();
@@ -22,7 +22,7 @@ public abstract class MobEntityMixin {
return true;
}
});
PlayerEntity player = original.call(instance, entity, maxDistance);
Player player = original.call(instance, entity, maxDistance);
EntityViewMixinHelper.ADDITIONAL_PREDICATE.remove();
return player;
}
@@ -0,0 +1,31 @@
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.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.NaturalSpawner;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(NaturalSpawner.class)
public class NaturalSpawnerMixin {
@WrapOperation(method = "spawnCategoryForPosition(Lnet/minecraft/world/entity/MobCategory;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ChunkAccess;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/NaturalSpawner$SpawnPredicate;Lnet/minecraft/world/level/NaturalSpawner$AfterSpawnCallback;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getNearestPlayer(DDDDZ)Lnet/minecraft/world/entity/player/Player;"))
private static Player checkMobSpawningMinion(ServerLevel world, double x, double y, double z, double maxDistance, boolean ignoreCreative, Operation<Player> original) {
EntityViewMixinHelper.ADDITIONAL_PREDICATE.set(entity -> {
if(entity instanceof ServerPlayer player) {
if(player instanceof MinionFakePlayer minion) {
return minion.canSpawnMobs();
}
return true;
}
return false;
});
Player player = original.call(world, x, y, z, maxDistance, ignoreCreative);
EntityViewMixinHelper.ADDITIONAL_PREDICATE.remove();
return player;
}
}
@@ -3,39 +3,39 @@ 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.minion.fakeplayer.MinionFakePlayer;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.PistonBlockEntity;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.piston.PistonMovingBlockEntity;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(PistonBlockEntity.class)
@Mixin(PistonMovingBlockEntity.class)
public abstract class PistonMovingBlockEntityMixin {
@WrapOperation(method = "pushEntities", at = @At(
@WrapOperation(method = "moveCollidedEntities", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/entity/Entity;getPistonBehavior()Lnet/minecraft/block/piston/PistonBehavior;"
target = "Lnet/minecraft/world/entity/Entity;getPistonPushReaction()Lnet/minecraft/world/level/material/PushReaction;"
))
private static PistonBehavior moveFakePlayers(Entity entity, Operation<PistonBehavior> original, World world, BlockPos pos, float f, PistonBlockEntity pistonBlockEntity)
private static PushReaction moveFakePlayers(Entity entity, Operation<PushReaction> original, Level world, BlockPos pos, float f, PistonMovingBlockEntity pistonBlockEntity)
{
if (entity instanceof MinionFakePlayer && pistonBlockEntity.getPushedBlock().isOf(Blocks.SLIME_BLOCK))
if (entity instanceof MinionFakePlayer && pistonBlockEntity.getMovedState().is(Blocks.SLIME_BLOCK))
{
Vec3d vec3d = entity.getVelocity();
Vec3 vec3d = entity.getDeltaMovement();
double x = vec3d.x;
double y = vec3d.y;
double z = vec3d.z;
Direction direction = pistonBlockEntity.getMovementDirection();
switch (direction.getAxis()) {
case X -> x = direction.getOffsetX();
case Y -> y = direction.getOffsetY();
case Z -> z = direction.getOffsetZ();
case X -> x = direction.getStepX();
case Y -> y = direction.getStepY();
case Z -> z = direction.getStepZ();
}
entity.setVelocity(x, y, z);
entity.setDeltaMovement(x, y, z);
}
return original.call(entity);
}
@@ -1,22 +0,0 @@
package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.sugar.Local;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(PlayerListS2CPacket.Entry.class)
public class PlayerListEntryS2CPacket$EntryMixin {
@ModifyArg(method = "<init>(Lnet/minecraft/server/network/ServerPlayerEntity;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/PlayerListS2CPacket$Entry;<init>(Ljava/util/UUID;Lcom/mojang/authlib/GameProfile;ZILnet/minecraft/world/GameMode;Lnet/minecraft/text/Text;ZILnet/minecraft/network/encryption/PublicPlayerSession$Serialized;)V"), index = 2)
private static boolean removeMinionFromTabList(boolean original, @Local(argsOnly = true) ServerPlayerEntity player) {
if(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.showInTabList)) {
return false;
}
return original;
}
}
@@ -9,17 +9,17 @@ import com.mojang.authlib.GameProfile;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.minion.fakeplayer.NetHandlerPlayServerFake;
import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.packet.c2s.common.SyncedClientOptions;
import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ConnectedClientData;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.storage.ReadView;
import net.minecraft.text.Text;
import net.minecraft.util.ErrorReporter;
import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.players.PlayerList;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.level.storage.ValueInput;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -30,11 +30,11 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Mixin(PlayerManager.class)
@Mixin(PlayerList.class)
public class PlayerListMixin {
@Inject(method = "loadPlayerData", at = @At(value = "RETURN", shift = At.Shift.BEFORE))
private void fixStartingPos(ServerPlayerEntity player, ErrorReporter errorReporter, CallbackInfoReturnable<Optional<ReadView>> cir)
@Inject(method = "load", at = @At(value = "RETURN", shift = At.Shift.BEFORE))
private void fixStartingPos(ServerPlayer player, ProblemReporter errorReporter, CallbackInfoReturnable<Optional<ValueInput>> cir)
{
if (player instanceof MinionFakePlayer)
{
@@ -42,8 +42,8 @@ public class PlayerListMixin {
}
}
@WrapOperation(method = "onPlayerConnect", at = @At(value = "NEW", target = "(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/network/ClientConnection;Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/server/network/ConnectedClientData;)Lnet/minecraft/server/network/ServerPlayNetworkHandler;"))
private ServerPlayNetworkHandler replaceNetworkHandler(MinecraftServer server, ClientConnection connection, ServerPlayerEntity serverPlayer, ConnectedClientData commonListenerCookie, Operation<ServerPlayNetworkHandler> original)
@WrapOperation(method = "placeNewPlayer", at = @At(value = "NEW", target = "(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/network/Connection;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/server/network/CommonListenerCookie;)Lnet/minecraft/server/network/ServerGamePacketListenerImpl;"))
private ServerGamePacketListenerImpl replaceNetworkHandler(MinecraftServer server, Connection connection, ServerPlayer serverPlayer, CommonListenerCookie commonListenerCookie, Operation<ServerGamePacketListenerImpl> original)
{
if (serverPlayer instanceof MinionFakePlayer fake) {
return new NetHandlerPlayServerFake(server, connection, fake, commonListenerCookie);
@@ -52,23 +52,23 @@ 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<ServerPlayerEntity> original, ServerPlayerEntity serverPlayer, boolean bl) {
@WrapOperation(method = "respawn", at = @At(value = "NEW", target = "(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/server/level/ServerLevel;Lcom/mojang/authlib/GameProfile;Lnet/minecraft/server/level/ClientInformation;)Lnet/minecraft/server/level/ServerPlayer;"))
public ServerPlayer makePlayerForRespawn(MinecraftServer minecraftServer, ServerLevel serverLevel, GameProfile gameProfile, ClientInformation clientInformation, Operation<ServerPlayer> original, ServerPlayer serverPlayer, boolean bl) {
if (serverPlayer instanceof MinionFakePlayer minion) {
return MinionFakePlayer.respawnFake(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) {
@WrapOperation(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"))
public void noLoginMessage(PlayerList instance, Component message, boolean overlay, Operation<Void> original, @Local(argsOnly = true) ServerPlayer player) {
if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLoginMessage))) {
original.call(instance, message, overlay);
}
}
@ModifyReceiver(method = "checkCanJoin", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"))
public List<ServerPlayerEntity> noMinionCounting(List<ServerPlayerEntity> instance) {
@ModifyReceiver(method = "canPlayerLogin", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"))
public List<ServerPlayer> noMinionCounting(List<ServerPlayer> instance) {
return instance.stream()
.filter(player -> !(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForPlayerLimit)))
.collect(Collectors.toCollection(ArrayList::new));
@@ -4,12 +4,13 @@ package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(PlayerEntity.class)
@Mixin(Player.class)
public abstract class PlayerMixin {
/**
* To make sure player attacks are able to knockback fake players
@@ -18,8 +19,9 @@ public abstract class PlayerMixin {
method = "attack",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/entity/Entity;velocityModified:Z",
ordinal = 0
target = "Lnet/minecraft/world/entity/Entity;hurtMarked:Z",
ordinal = 0,
opcode = Opcodes.GETFIELD
)
)
private boolean velocityModifiedAndNotCarpetFakePlayer(boolean value, @Local(argsOnly = true) Entity entity) {
@@ -4,21 +4,21 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.players.PlayerList;
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 {
@Mixin(ServerGamePacketListenerImpl.class)
public class ServerGamePacketListenerImplMixin {
@Shadow
public ServerPlayerEntity player;
public ServerPlayer 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) {
@WrapOperation(method = "removePlayerFromWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"))
public void noLogoutMessage(PlayerList instance, Component message, boolean overlay, Operation<Void> original) {
if(!(player instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.sendLogoutMessage))) {
original.call(instance, message, overlay);
}
@@ -4,15 +4,15 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.registration.MinionConfigOptions;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.SleepManager;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.SleepStatus;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(SleepManager.class)
public class SleepManagerMixin {
@WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;isSpectator()Z"))
public boolean excludeMinions(ServerPlayerEntity instance, Operation<Boolean> original) {
@Mixin(SleepStatus.class)
public class SleepStatusMixin {
@WrapOperation(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;isSpectator()Z"))
public boolean excludeMinions(ServerPlayer instance, Operation<Boolean> original) {
if (instance instanceof MinionFakePlayer minion && !minion.getData().config().getOption(MinionConfigOptions.countForSleeping)) {
return true;
} else {
@@ -1,31 +0,0 @@
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.minion.fakeplayer.MinionFakePlayer;
import io.github.skippyall.minions.mixinhelper.EntityViewMixinHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.SpawnHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(SpawnHelper.class)
public class SpawnHelperMixin {
@WrapOperation(method = "spawnEntitiesInChunk(Lnet/minecraft/entity/SpawnGroup;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/SpawnHelper$Checker;Lnet/minecraft/world/SpawnHelper$Runner;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ServerWorld;getClosestPlayer(DDDDZ)Lnet/minecraft/entity/player/PlayerEntity;"))
private static PlayerEntity checkMobSpawningMinion(ServerWorld world, double x, double y, double z, double maxDistance, boolean ignoreCreative, Operation<PlayerEntity> original) {
EntityViewMixinHelper.ADDITIONAL_PREDICATE.set(entity -> {
if(entity instanceof ServerPlayerEntity player) {
if(player instanceof MinionFakePlayer minion) {
return minion.canSpawnMobs();
}
return true;
}
return false;
});
PlayerEntity player = original.call(world, x, y, z, maxDistance, ignoreCreative);
EntityViewMixinHelper.ADDITIONAL_PREDICATE.remove();
return player;
}
}
@@ -2,23 +2,23 @@ package io.github.skippyall.minions.mixins;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.tick.TickManager;
import net.minecraft.world.TickRateManager;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(TickManager.class)
@Mixin(TickRateManager.class)
public abstract class TickRateManagerMixin {
@Shadow
public abstract boolean shouldTick();
public abstract boolean runsNormally();
@ModifyReturnValue(method = "shouldSkipTick", at = @At("TAIL"))
@ModifyReturnValue(method = "isEntityFrozen", at = @At("TAIL"))
private boolean handler(boolean alreadyFrozen, Entity entity) {
if (alreadyFrozen) return true;
if (shouldTick()) return false;
if (runsNormally()) return false;
return !isActualPlayer(entity) && // not carrying players
((EntityAccessor) entity)
@@ -28,6 +28,6 @@ public abstract class TickRateManagerMixin {
@Unique
private static boolean isActualPlayer(Entity e) {
return e instanceof PlayerEntity && !(e instanceof MinionFakePlayer);
return e instanceof Player && !(e instanceof MinionFakePlayer);
}
}
@@ -1,52 +0,0 @@
package io.github.skippyall.minions.mixins.antimobcap;
import com.llamalad7.mixinextras.sugar.Local;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ChunkLevelManager;
import net.minecraft.server.world.ChunkTicketManager;
import net.minecraft.util.math.ChunkSectionPos;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.Executor;
@Mixin(ChunkLevelManager.class)
public class ChunkLevelManagerMixin implements ChunkLevelManagerAccessor {
@Shadow @Final Long2ObjectMap<ObjectSet<ServerPlayerEntity>> playersByChunkPos;
@Shadow @Final private ChunkLevelManager.DistanceFromNearestPlayerTracker distanceFromNearestPlayerTracker;
@Unique
ChunkLevelManager.DistanceFromNearestPlayerTracker minionless;
@Inject(method = "<init>", at = @At("RETURN"))
public void createMinionlessClone(ChunkTicketManager ticketManager, Executor executor, Executor mainThreadExecutor, CallbackInfo ci) {
ChunkLevelManager manager = ((ChunkLevelManager)(Object)this);
minionless = manager.new DistanceFromNearestPlayerTracker(8);
((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)minionless).minions$markAsMinionless();
((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)distanceFromNearestPlayerTracker).minions$markAsTarget();
}
public ObjectSet<ServerPlayerEntity> minions$getPlayers(long chunkpos) {
return playersByChunkPos.get(chunkpos);
}
@Override
public ChunkLevelManager.DistanceFromNearestPlayerTracker minions$getMinionless() {
return minionless;
}
@Inject(method = "handleChunkLeave", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z", shift = At.Shift.AFTER, remap = false))
public void minion$updateMinionlessIfNoMinionInChunk(ChunkSectionPos pos, ServerPlayerEntity player, CallbackInfo ci, @Local long chunk) {
if (!((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)minionless).minions$isRealPlayerInChunk(chunk)) {
minionless.updateLevel(chunk, Integer.MAX_VALUE, false);
}
}
}
@@ -1,14 +1,14 @@
package io.github.skippyall.minions.mixins.antimobcap;
import net.minecraft.server.world.ChunkPosDistanceLevelPropagator;
import net.minecraft.server.level.ChunkTracker;
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(ChunkPosDistanceLevelPropagator.class)
public class ChunkPosDistanceLevelPropagatorMixin {
@Inject(method = "updateLevel", at = @At("HEAD"))
@Mixin(ChunkTracker.class)
public class ChunkTrackerMixin {
@Inject(method = "update", at = @At("HEAD"))
public void minions$updateLevel(long chunkPos, int distance, boolean decrease, CallbackInfo info) {
}
@@ -5,8 +5,8 @@ import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManager$Dist
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor;
import it.unimi.dsi.fastutil.longs.Long2ByteMap;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ChunkLevelManager;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -16,22 +16,22 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(value = ChunkLevelManager.DistanceFromNearestPlayerTracker.class)
public abstract class ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin extends ChunkPosDistanceLevelPropagatorMixin implements ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor {
@Mixin(value = DistanceManager.FixedPlayerDistanceChunkTracker.class)
public abstract class DistanceManager$FixedPlayerDistanceChunkTrackerMixin extends ChunkTrackerMixin implements ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor {
@Final
@Shadow
ChunkLevelManager field_17462;
DistanceManager field_17462;
@Shadow
@Final
protected Long2ByteMap distanceFromNearestPlayer;
protected Long2ByteMap chunks;
@Shadow protected abstract boolean isPlayerInChunk(long chunkPos);
@Shadow protected abstract boolean havePlayer(long chunkPos);
@Unique
boolean minions$minionless, minions$target;
@Inject(method = "isPlayerInChunk", at = @At("RETURN"), cancellable = true)
@Inject(method = "havePlayer", at = @At("RETURN"), cancellable = true)
public void minions$filterMinions(long chunkPos, CallbackInfoReturnable<Boolean> cir) {
if (minions$minionless) {
cir.setReturnValue(minions$isRealPlayerInChunk(chunkPos));
@@ -40,7 +40,7 @@ public abstract class ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin ex
@Override
public boolean minions$isRealPlayerInChunk(long chunkPos) {
ObjectSet<ServerPlayerEntity> players = ((ChunkLevelManagerAccessor)field_17462).minions$getPlayers(chunkPos);
ObjectSet<ServerPlayer> players = ((ChunkLevelManagerAccessor)field_17462).minions$getPlayers(chunkPos);
boolean contains = false;
if(players != null) {
contains = players.stream().anyMatch(player -> {
@@ -53,17 +53,17 @@ public abstract class ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin ex
return contains;
}
@Inject(method = "updateLevels", at = @At("HEAD"))
@Inject(method = "runAllUpdates", at = @At("HEAD"))
public void minions$sync(CallbackInfo info) {
if (minions$target) {
((ChunkLevelManagerAccessor)field_17462).minions$getMinionless().updateLevels();
((ChunkLevelManagerAccessor)field_17462).minions$getMinionless().runAllUpdates();
}
}
@Override
public void minions$updateLevel(long chunkPos, int distance, boolean decrease, CallbackInfo info) {
if (minions$target && (distance == Integer.MAX_VALUE || minions$isRealPlayerInChunk(chunkPos))) {
((ChunkLevelManagerAccessor)field_17462).minions$getMinionless().updateLevel(chunkPos, distance, decrease);
((ChunkLevelManagerAccessor)field_17462).minions$getMinionless().update(chunkPos, distance, decrease);
}
}
@@ -79,6 +79,6 @@ public abstract class ChunkLevelManager$DistanceFromNearestPlayerTrackerMixin ex
@Override
public int minions$getTickedChunkCount() {
return distanceFromNearestPlayer.size();
return chunks.size();
}
}
@@ -0,0 +1,52 @@
package io.github.skippyall.minions.mixins.antimobcap;
import com.llamalad7.mixinextras.sugar.Local;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.concurrent.Executor;
import net.minecraft.core.SectionPos;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.TicketStorage;
@Mixin(DistanceManager.class)
public class DistanceManagerMixin implements ChunkLevelManagerAccessor {
@Shadow @Final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerChunk;
@Shadow @Final private DistanceManager.FixedPlayerDistanceChunkTracker naturalSpawnChunkCounter;
@Unique
DistanceManager.FixedPlayerDistanceChunkTracker minionless;
@Inject(method = "<init>", at = @At("RETURN"))
public void createMinionlessClone(TicketStorage ticketManager, Executor executor, Executor mainThreadExecutor, CallbackInfo ci) {
DistanceManager manager = ((DistanceManager)(Object)this);
minionless = manager.new FixedPlayerDistanceChunkTracker(8);
((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)minionless).minions$markAsMinionless();
((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)naturalSpawnChunkCounter).minions$markAsTarget();
}
public ObjectSet<ServerPlayer> minions$getPlayers(long chunkpos) {
return playersPerChunk.get(chunkpos);
}
@Override
public DistanceManager.FixedPlayerDistanceChunkTracker minions$getMinionless() {
return minionless;
}
@Inject(method = "removePlayer", at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z", shift = At.Shift.AFTER, remap = false))
public void minion$updateMinionlessIfNoMinionInChunk(SectionPos pos, ServerPlayer player, CallbackInfo ci, @Local long chunk) {
if (!((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)minionless).minions$isRealPlayerInChunk(chunk)) {
minionless.update(chunk, Integer.MAX_VALUE, false);
}
}
}
@@ -0,0 +1,12 @@
package io.github.skippyall.minions.mixins.antimobcap;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerChunkCache;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ServerChunkCache.class)
public interface ServerChunkCacheAccessor {
@Accessor
DistanceManager getDistanceManager();
}
@@ -0,0 +1,23 @@
package io.github.skippyall.minions.mixins.antimobcap;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor;
import net.minecraft.server.level.DistanceManager;
import net.minecraft.server.level.ServerChunkCache;
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.ModifyArg;
@Mixin(ServerChunkCache.class)
public class ServerChunkCacheMixin {
@Shadow
@Final
private DistanceManager distanceManager;
@ModifyArg(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/NaturalSpawner;createState(ILjava/lang/Iterable;Lnet/minecraft/world/level/NaturalSpawner$ChunkGetter;Lnet/minecraft/world/level/LocalMobCapCalculator;)Lnet/minecraft/world/level/NaturalSpawner$SpawnState;"))
public int useMinionless(int spawningChunkCount) {
return ((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)((ChunkLevelManagerAccessor)distanceManager).minions$getMinionless()).minions$getTickedChunkCount();
}
}
@@ -1,12 +0,0 @@
package io.github.skippyall.minions.mixins.antimobcap;
import net.minecraft.server.world.ChunkLevelManager;
import net.minecraft.server.world.ServerChunkManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ServerChunkManager.class)
public interface ServerChunkManagerAccessor {
@Accessor
ChunkLevelManager getLevelManager();
}
@@ -1,23 +0,0 @@
package io.github.skippyall.minions.mixins.antimobcap;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor;
import io.github.skippyall.minions.mixinhelper.antimobcap.ChunkLevelManagerAccessor;
import net.minecraft.server.world.ChunkLevelManager;
import net.minecraft.server.world.ServerChunkManager;
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.ModifyArg;
@Mixin(ServerChunkManager.class)
public class ServerChunkManagerMixin {
@Shadow
@Final
private ChunkLevelManager levelManager;
@ModifyArg(method = "tickChunks(Lnet/minecraft/util/profiler/Profiler;J)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/SpawnHelper;setupSpawn(ILjava/lang/Iterable;Lnet/minecraft/world/SpawnHelper$ChunkSource;Lnet/minecraft/world/SpawnDensityCapper;)Lnet/minecraft/world/SpawnHelper$Info;"))
public int useMinionless(int spawningChunkCount) {
return ((ChunkLevelManager$DistanceFromNearestPlayerTrackerAccessor)((ChunkLevelManagerAccessor)levelManager).minions$getMinionless()).minions$getTickedChunkCount();
}
}
@@ -3,15 +3,15 @@ package io.github.skippyall.minions.mixins.compat.universal_graves;
import com.llamalad7.mixinextras.sugar.Local;
import eu.pb4.graves.grave.Grave;
import io.github.skippyall.minions.minion.fakeplayer.MinionFakePlayer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(Grave.class)
public class GraveMixin {
@ModifyArg(method = "createBlock", at = @At(value = "INVOKE", target = "Leu/pb4/graves/grave/Grave;<init>(JLcom/mojang/authlib/GameProfile;BLnet/minecraft/util/Arm;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Identifier;Leu/pb4/graves/grave/GraveType;JJILnet/minecraft/text/Text;Ljava/util/Collection;Ljava/util/Collection;ZI)V"))
private static boolean createGrave(boolean profile, @Local(argsOnly = true) ServerPlayerEntity player) {
@ModifyArg(method = "createBlock", at = @At(value = "INVOKE", target = "Leu/pb4/graves/grave/Grave;<init>(JLcom/mojang/authlib/GameProfile;BLnet/minecraft/world/entity/HumanoidArm;Lnet/minecraft/core/BlockPos;Lnet/minecraft/resources/ResourceLocation;Leu/pb4/graves/grave/GraveType;JJILnet/minecraft/network/chat/Component;Ljava/util/Collection;Ljava/util/Collection;ZI)V"))
private static boolean createGrave(boolean profile, @Local(argsOnly = true) ServerPlayer player) {
if(player instanceof MinionFakePlayer) {
return false;
}