diff --git a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java index 61b2588..9c8ce6e 100644 --- a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java +++ b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java @@ -56,14 +56,14 @@ public class SFCraftInitializer extends GuiceModInitializer { protected void onReady(MinecraftServer minecraftServer) { log.info("SFCraft is loading"); SFCraft.server = minecraftServer; - SFCraft.injector = getInjector(); getModuleManager().switchGlobalState(Lifecycle.State.ENABLED); log.info("Load completed! " + getModuleManager().getModules().size() + " modules were loaded."); } @Override protected Injector onInit() { - return Guice.createInjector( + SFEntityType.registerEntities(); + return SFCraft.injector = Guice.createInjector( new SFCraft(), this ); diff --git a/src/main/java/io/ib67/sfcraft/SFEntityType.java b/src/main/java/io/ib67/sfcraft/SFEntityType.java new file mode 100644 index 0000000..1844615 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/SFEntityType.java @@ -0,0 +1,52 @@ +package io.ib67.sfcraft; + +import io.ib67.sfcraft.entity.SFGuiderEntity; +import lombok.experimental.UtilityClass; +import lombok.extern.log4j.Log4j2; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry; +import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Log4j2 +public class SFEntityType { + public final EntityType GUIDER = Registry.register( + Registries.ENTITY_TYPE, + Identifier.of("sfcraft", "guider"), + EntityType.Builder.create(SFGuiderEntity::new, SpawnGroup.CREATURE) + .dimensions(0.35F, 0.6F) + .eyeHeight(0.36F) + .vehicleAttachment(0.04F) + .maxTrackingRange(8) + .trackingTickInterval(2).build() + ); + private static SFEntityType registry; + private final Map, EntityType> mappedEntityTypes = new ConcurrentHashMap<>(); + + private void init() { + register(GUIDER, EntityType.ALLAY, SFGuiderEntity.createAllayAttributes().build()); + } + + private void register(EntityType custom, EntityType origin, DefaultAttributeContainer attr) { + FabricDefaultAttributeRegistry.register(custom, attr); + mappedEntityTypes.put(custom, origin); + } + + static void registerEntities() { + registry = new SFEntityType(); + registry.init(); + } + + public static EntityType mapToVanilla(EntityType type) { + return (EntityType) registry.mappedEntityTypes.getOrDefault(type, type); + } +} diff --git a/src/main/java/io/ib67/sfcraft/entity/SFGuiderEntity.java b/src/main/java/io/ib67/sfcraft/entity/SFGuiderEntity.java new file mode 100644 index 0000000..8968e00 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/entity/SFGuiderEntity.java @@ -0,0 +1,30 @@ +package io.ib67.sfcraft.entity; + +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.passive.AllayEntity; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; +import net.minecraft.world.World; + +public class SFGuiderEntity extends AllayEntity { + public SFGuiderEntity(EntityType entityEntityType, World world) { + super(entityEntityType, world); + } + + @Override + public Text getName() { + return Text.of("guider"); + } + + @Override + public void tick() { + super.tick(); + var nearbyPlayer = PlayerLookup.around((ServerWorld) getWorld(), getPos(), 20D); + for (ServerPlayerEntity serverPlayerEntity : nearbyPlayer) { + this.navigation.startMovingTo(serverPlayerEntity, 2f); + break; + } + } +} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java index f792eb0..7231b08 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java @@ -4,7 +4,11 @@ import io.ib67.sfcraft.SFCraft; import io.ib67.sfcraft.callback.SFCallbacks; import io.ib67.sfcraft.mixin.server.bridge.ServerPlayerBridge; import io.ib67.sfcraft.registry.chat.SimpleMessageDecorator; +import net.minecraft.entity.EntityType; +import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.message.MessageDecorator; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.text.Text; diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java new file mode 100644 index 0000000..4ea274b --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/mixin/server/hack/EntitySpawnS2CPacketMixin.java @@ -0,0 +1,17 @@ +package io.ib67.sfcraft.mixin.server.hack; + +import io.ib67.sfcraft.SFCraftInitializer; +import io.ib67.sfcraft.SFEntityType; +import net.minecraft.entity.EntityType; +import net.minecraft.network.packet.s2c.play.EntitySpawnS2CPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(EntitySpawnS2CPacket.class) +public class EntitySpawnS2CPacketMixin { + @ModifyArg(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/codec/PacketCodec;encode(Ljava/lang/Object;Ljava/lang/Object;)V"), index = 1) + public Object mapModType(Object type) { + return SFEntityType.mapToVanilla((EntityType) type); + } +} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java new file mode 100644 index 0000000..2546341 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/mixin/server/hack/HoverEntityContentMixin.java @@ -0,0 +1,18 @@ +package io.ib67.sfcraft.mixin.server.hack; + +import io.ib67.sfcraft.SFCraftInitializer; +import io.ib67.sfcraft.SFEntityType; +import net.minecraft.entity.EntityType; +import net.minecraft.text.HoverEvent; +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; + +@Mixin(HoverEvent.EntityContent.class) +public class HoverEntityContentMixin { + @Inject(method = "method_54198", at = @At("HEAD"), cancellable = true) + private static void sf$mapToVanilla(HoverEvent.EntityContent content, CallbackInfoReturnable cir) { + cir.setReturnValue(SFEntityType.mapToVanilla(content.entityType)); + } +} diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java new file mode 100644 index 0000000..5b4f2d6 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/mixin/server/hack/RegistryHandlerMixin.java @@ -0,0 +1,21 @@ +package io.ib67.sfcraft.mixin.server.hack; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; +import net.minecraft.util.Identifier; +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; + +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +@Mixin(DirectRegistryPacketHandler.class) +public abstract class RegistryHandlerMixin { + @Inject(method = "sendPacket", at = @At("HEAD"), remap = false) + public void sf$removeRegistry(Consumer sender, Map> registryMap, CallbackInfo ci) { + registryMap.clear(); + } +} diff --git a/src/main/resources/sfcraft.mixins.json b/src/main/resources/sfcraft.mixins.json index 8ddbe6f..ee36b78 100644 --- a/src/main/resources/sfcraft.mixins.json +++ b/src/main/resources/sfcraft.mixins.json @@ -8,21 +8,24 @@ "client": [ ], "server": [ - "server.fixes.EndermanEntityMixin$ChaseGoalMixin", - "server.bridge.ServerWorldBridge", - "server.bridge.ServerPlayerBridge", - "server.bridge.EntityBridge", - "server.MinecraftServerMixin", - "server.ServerPlayNetworkHandlerMixin", - "server.SleepManagerMixin", - "server.ServerWorldMixin", - "server.EntityMixin", "server.AbstractFurnaceBlockMixin", - "server.ServerHandshakeNetworkHandlerMixin", + "server.EntityMixin", "server.LegacyQueryHandlerMixin", - "server.ServerPlayerEntityMixin", + "server.MinecraftServerMixin", "server.PlayerEntityMixin", - "server.ServerLoginNetworkHandlerMixin" + "server.ServerHandshakeNetworkHandlerMixin", + "server.ServerLoginNetworkHandlerMixin", + "server.ServerPlayerEntityMixin", + "server.ServerPlayNetworkHandlerMixin", + "server.ServerWorldMixin", + "server.SleepManagerMixin", + "server.bridge.EntityBridge", + "server.bridge.ServerPlayerBridge", + "server.bridge.ServerWorldBridge", + "server.fixes.EndermanEntityMixin$ChaseGoalMixin", + "server.hack.EntitySpawnS2CPacketMixin", + "server.hack.RegistryHandlerMixin", + "server.hack.HoverEntityContentMixin" ], "injectors": { "defaultRequire": 1