My idea here is being able to spawn a MobEntity in the World that the player is in when a certain client-side Event is triggered. Specifically, I need to be able to encode the MobEntity Object (or at least the EntityType Object with the position coordinates) as well as the AbstractSpawner and SpawnReason Objects through a packet to be spawned server-side (I might also need to pass in a World object since I'm not sure if MobEntity.getEntityWorld() would work server-side). As of now, I am only able to send primitive data-types or serializable non-vanilla Objects. I know that encoding non-serializable Objects such as Entity and World is not secure (and it gets an error if I try it anyway), but I'm not sure what else I could do. Thanks in advance!
PacketSpawnFearMod.java (running this would get a java.io.NotSerializableException when I attempt to convert the MobEntity, AbstractSpawner, and SpawnReason fields of the PacketSpawnFearMod Object to byte arrays)
package com.junferno.fearmod.packets;
import com.junferno.fearmod.FearMod;
import net.minecraft.entity.MobEntity;
import net.minecraft.entity.SpawnReason;
import net.minecraft.network.PacketBuffer;
import net.minecraft.world.spawner.AbstractSpawner;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
import net.minecraftforge.fml.network.NetworkEvent;
import java.io.*;
import java.util.function.Supplier;
public class PacketSpawnFearMod implements Serializable {
private MobEntity entity;
private AbstractSpawner spawner;
private SpawnReason spawnReason;
public PacketSpawnFearMod(MobEntity entity, AbstractSpawner spawner, SpawnReason spawnReason) {
this.entity = entity;
this.spawner = spawner;
this.spawnReason = spawnReason;
}
public static byte[] objToByte(PacketSpawnFearMod packet) throws IOException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
objStream.writeObject(packet);
return byteStream.toByteArray();
}
public static Object byteToObj(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
ObjectInputStream objStream = new ObjectInputStream(byteStream);
return objStream.readObject();
}
public PacketSpawnFearMod(PacketBuffer buf) {
try {
PacketSpawnFearMod packet = (PacketSpawnFearMod) byteToObj(buf.readByteArray());
this.entity = packet.entity;
this.spawner = packet.spawner;
this.spawnReason = packet.spawnReason;
}
catch (IOException | ClassNotFoundException e) {
FearMod.LOGGER.error("Failed to read packet");
FearMod.LOGGER.error(e.toString());
}
}
public static void encode(PacketSpawnFearMod packet, PacketBuffer buf) {
try {
buf.writeByteArray(objToByte(packet));
}
catch (IOException e) {
FearMod.LOGGER.error("Failed to encode packet"); // java.io.NotSerializableException
FearMod.LOGGER.error(e.toString());
}
}
public static void handle(final PacketSpawnFearMod packet, Supplier<NetworkEvent.Context> context) {
NetworkEvent.Context ctx = context.get();
ctx.enqueueWork(() -> {
MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(
packet.entity,
packet.entity.getEntityWorld(),
packet.entity.getPosX(),
packet.entity.getPosY(),
packet.entity.getPosZ(),
packet.spawner,
packet.spawnReason
));
});
ctx.setPacketHandled(true);
}
}
I am using Forge 1.16.4 with Java 1.8.0, Gradle 4.10.3, and IntelliJ IDEA Community Edition 2020 on Windows 10