Jump to content

[1.8.8] Updating a Packet System from 1.6.1, need help


Recommended Posts

Posted

First post, yeah, quit staring, you're making me nervous.

 

I've been try to update the open source and somewhat abandoned THX Helicopter Mod to Minecraft 1.8.8, and while I've powered through numerous obstacles(JSON nonsense, improper function signatures and the like), I find myself completely stuck updating the Server/Client Packet system, which was still using Packet250CustomPayload when I got to it. Ideally I'd like to transfer to the SimpleNetworkWrapper solution detailed elsewhere on this forum, but despite my efforts and countless hours pouring over other posts here, I find myself at somewhat of a loss.

 

Please note I'm in the middle of transitioning the code to this system, but I've hit a brick wall and need to at least know if I'm headed in the right direction.

 

Mod File:

package com.thxreloaded.thxhelimod;

import java.io.PrintStream;
import java.util.Map;

import net.minecraft.*;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
//import net.minecraft.util.WeightedRandom.Item;
import net.minecraftforge.fml.common.Mod.*;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;

import net.minecraftforge.fml.common.SidedProxy;

import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;

@Mod(modid=mod_thx.MODID, name=mod_thx.MODNAME, version=mod_thx.MODVER) //Tell forge "Oh hey, there's a new mod here to load."

public class mod_thx //Start the class Declaration
{
    //Set the ID of the mod (Should be lower case).
    public static final String MODID = "mod_thx_new";
    //Set the "Name" of the mod.
    public static final String MODNAME = "THX Helicopter Mod Reloaded";
    //Set the version of the mod.
    public static final String MODVER = "0.0.0";

    @Instance(value = mod_thx.MODID) //Tell Forge what instance to use.
    public static mod_thx instance;
    
    public static SimpleNetworkWrapper network;
    
    public static Item Helicopter;
    
    static int HELICOPTER_TYPE_ID = 99;
    static int ROCKET_TYPE_ID = 100;
    static int MISSILE_TYPE_ID = 101;
    static WorldClient theWorld = null;
        
    public mod_thx() {
        System.out.println("Constructor mod_thx()");
    }
    
    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
    	network = NetworkRegistry.INSTANCE.newSimpleChannel("MyChannel");
    	network.registerMessage(ThxPacket.Handler.class, ThxPacket.class, 0, Side.SERVER);
    	network.registerMessage(ThxPacket.Handler.class, ThxPacket.class, 1, Side.CLIENT);		
    }
        
    @EventHandler
    public void load(FMLInitializationEvent event)
    {
    	mod_thx.log("Loading...");
        //ModLoader.setInGameHook((BaseMod)this, (boolean)true, (boolean)true);
        //ModLoader.registerPacketChannel((BaseMod)this, (String)"THX_entity");
    	
        int drawDistance = 160;
        int updateFreq = 1;
        boolean trackMotion = true;
        int id = ThxConfig.getIntProperty((String)"thx_id_entity_helicopter");
        if (id > 0) {
            HELICOPTER_TYPE_ID = id;
        }
        int entityId = HELICOPTER_TYPE_ID + 10;
        mod_thx.log("Registering entity class for Helicopter with ModLoader entity id " + entityId);
        EntityRegistry.registerModEntity((Class)ThxEntityHelicopter.class, (String)"thxHelicopter", (int)entityId, this, drawDistance, updateFreq, trackMotion);
        //ModLoader.registerEntityID((Class)ThxEntityHelicopter.class, (String)"thxHelicopter", (int)entityId);
        mod_thx.log("Adding entity tracker for Helicopter with entity type id " + HELICOPTER_TYPE_ID);
        if(event.getSide() == Side.CLIENT)
        {
        	RenderingRegistry.registerEntityRenderingHandler(ThxEntityHelicopter.class, new RenderHeli(Minecraft.getMinecraft().getRenderManager()));
        }
        //ModLoader.addEntityTracker((BaseMod)this, (Class)ThxEntityHelicopter.class, (int)HELICOPTER_TYPE_ID, (int)drawDistance, (int)updateFreq, (boolean)trackMotion);
        id = ThxConfig.getIntProperty((String)"thx_id_entity_rocket");
        if (id > 0) {
            ROCKET_TYPE_ID = id;
        }
        entityId = ROCKET_TYPE_ID + 10;
        mod_thx.log("Registering entity class for Rocket with ModLoader entity id " + entityId);
        //ModLoader.registerEntityID((Class)ThxEntityRocket.class, (String)"thxRocket", (int)entityId);
        EntityRegistry.registerModEntity((Class)ThxEntityRocket.class, (String)"thxRocket", (int)entityId, this, (int)drawDistance, (int)updateFreq, (boolean)trackMotion);
        mod_thx.log("Adding entity tracker for Rocket with entity type id " + ROCKET_TYPE_ID);
        //ModLoader.addEntityTracker((BaseMod)this, (Class)ThxEntityRocket.class, (int)ROCKET_TYPE_ID, (int)drawDistance, (int)updateFreq, (boolean)trackMotion);
        id = ThxConfig.getIntProperty((String)"thx_id_entity_missile");
        if (id > 0) {
            MISSILE_TYPE_ID = id;
        }
        entityId = MISSILE_TYPE_ID + 10;
        mod_thx.log("Registering entity class for Missile with ModLoader entity id " + entityId);
        EntityRegistry.registerModEntity((Class)ThxEntityMissile.class, (String)"thxMissile", (int)entityId, this, (int)drawDistance, (int)updateFreq, (boolean)trackMotion);
        //ModLoader.registerEntityID((Class)ThxEntityMissile.class, (String)"thxMissile", (int)entityId);
        mod_thx.log("Adding entity tracker for Missile with entity type id " + MISSILE_TYPE_ID);
        //ModLoader.addEntityTracker((BaseMod)this, (Class)ThxEntityMissile.class, (int)MISSILE_TYPE_ID, (int)drawDistance, (int)updateFreq, (boolean)trackMotion);
        
        int itemId = ThxConfig.getIntProperty((String)"thx_id_item_helicopter");
        if (itemId == 0) {
            itemId = this.getNextItemId();
        }
    	
    	mod_thx.log("Setting up inventory item for helicopter with item id " + itemId);
        Helicopter = (ThxItemHelicopter) new ThxItemHelicopter(itemId);
        
        if(event.getSide() == Side.CLIENT)
        {
        	RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
        	renderItem.getItemModelMesher().register(Helicopter, 0, new ModelResourceLocation(MODID + ":" + ((ThxItemHelicopter) Helicopter).getName(), "inventory"));
        }
        
        /*mod_thx.log("Setting up inventory item for helicopter with item id " + itemId);
        ThxItemHelicopter item = (ThxItemHelicopter) new ThxItemHelicopter(itemId)
        		.setUnlocalizedName("helicopter_icon")
    			.setMaxStackSize(16);
        //GameRegistry.registerItem((Item)item, (String)"THX Helicopter Prototype");
        Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0, new ModelResourceLocation("mod_thx_new:textures/items/helicopter_icon.png", "inventory"));
        //ModLoader.addName((Object)item, (String)"THX Helicopter Prototype");*/
        mod_thx.log("Adding recipe for helicopter item: " + (Object)Helicopter);
        
        //ModLoader.addRecipe((ItemStack)itemStack, (Object[])recipe);
        GameRegistry.addRecipe(new ItemStack((Item)Helicopter), new Object[]{
            	" A ",
            	"A A",
            	"AAA",
            	'A', Items.cookie
            	});
        mod_thx.log("Done loading " + this.getVersion());
    }
        
    public void addRenderer(Map renderers)
    {
        renderers.put(ThxEntityHelicopter.class, new ThxRender(Minecraft.getMinecraft().getRenderManager()));
        renderers.put(ThxEntityRocket.class, new ThxRender(Minecraft.getMinecraft().getRenderManager()));
        renderers.put(ThxEntityMissile.class, new ThxRender(Minecraft.getMinecraft().getRenderManager()));
    }

    public String getVersion()
    {
        return "Minecraft THX Helicopter Mod - mod_thx-v025-mc_161";
    }

    int getNextItemId()
    {
        // return next available id
        /*for (int idx = 2200; idx + 256 < Item.itemList.length; idx++)
        {
            if (Item.itemList[idx + 256] == null) return idx;
        }*/
    	return 2000;
        // error:
        //throw new RuntimeException("Could not autofind next available Item ID -- please set manually in options file and restart");
    }

    public static void log(String s)
    {
        if (!ThxConfig.ENABLE_LOGGING) return;
        
        //if (theWorld == null) theWorld = FMLCommonHandler.instance().getSide().isClient().theWorld;
        
        System.out.println(String.format("[%5d] mod_thx: ", theWorld != null ? theWorld.getWorldTime() : 0)  + s);
    }
    
    public static void plog(String s) // periodic log
    {
        if (!ThxConfig.ENABLE_LOGGING) return;
        if (theWorld == null) theWorld = Minecraft.getMinecraft().theWorld;
        if (theWorld != null && theWorld.getWorldTime() % 60 == 0)
        {
            log(s); //
        }
    }
    
    public Entity spawnEntity(int type, World world, double posX, double posY, double posZ)
    {
        if (type == HELICOPTER_TYPE_ID)
        {
            return new ThxEntityHelicopter(world, posX, posY, posZ, 0f);
        }
        
        if (type == ROCKET_TYPE_ID)
        {
            return new ThxEntityRocket(world, posX, posY, posZ);
        }
        
        if (type == MISSILE_TYPE_ID)
        {
            //return new ThxEntityMissile(world, posX, posY, posZ);
        }
        
        return null;
    }
    
    /*public Packet23VehicleSpawn getSpawnPacket(Entity entity, int type)
    {
        log("Creating spawn packet for entity: " + entity);
        return new Packet23VehicleSpawn(entity, type, 1); // 1 is the id of the "thrower", it will cause velocity to get updated at spawn
    }*/
    
    // client received update packet from server
    /*public void clientCustomPayload(NetClientHandler netHandler, Packet250CustomPayload packet)
    {
        EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
        
        ThxEntityPacket250Data data = new ThxEntityPacket250Data(packet);
        
        plog("Client received packet250: " + data);
        
        ThxEntity entity = (ThxEntity) thePlayer.worldObj.getEntityByID(data.entityId);
        if (entity != null)
        {
            entity.lastUpdatePacket = data;
            
            // call apply directly instead of waiting for next onUpdate?
            //entity.applyUpdatePacketFromServer(data);
        }
        else
        {
            log("ERROR: client received update packet for unknown entity id " + data.entityId);
        }
    }*/

    // server received update packet from client
    /*public void serverCustomPayload(NetServerHandler netHandler, Packet250CustomPayload packet)
    {
        EntityPlayerMP thePlayer = netHandler.playerEntity;
        
        ThxEntityPacket250Data data = new ThxEntityPacket250Data(packet);
        
        ThxEntity entity = (ThxEntity) thePlayer.worldObj.getEntityByID(data.entityId);
        if (entity != null)
        {
            entity.lastUpdatePacket = data;
            
            // call apply directly instead of waiting for next onUpdate?
            //entity.applyUpdatePacketFromClient(data);
        }
        else
        {
            log("ERROR: server received update packet for unknown entity id " + data.entityId);
    }
    }*/
    
    public void keyboardEvent(KeyBinding kb) 
    {
        log("keyboardEvent: " + kb);
    }
}

As you can see there's some things down the bottom I commented out so the mod would compile and I could test other things.

 

ThxEntity file:

package com.thxreloaded.thxhelimod;

import net.minecraft.*;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.Packet;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;

public abstract class ThxEntity extends Entity
{
    ThxEntity targetEntity; // e.g. helicopter for ai to follow/attack, populated from above id if > 0
    
    Minecraft minecraft;
    
    final float RAD_PER_DEG = 00.01745329f;
    final float PI = 03.14159265f;

    long prevTime;
    float deltaTime;

    double prevMotionX;
    double prevMotionY;
    double prevMotionZ;

    float rotationRoll;
    float prevRotationRoll;

    float yawRad;
    float pitchRad;
    float rollRad;

    float rotationYawSpeed;
    float rotationPitchSpeed;
    float rotationRollSpeed;

    Vector3 pos = new Vector3(); // position
    Vector3 vel = new Vector3(); // velocity
    Vector3 acc = new Vector3(); // velocity
    Vector3 ypr = new Vector3(); // yaw, pitch, roll
    
    // vectors relative to entity orientation
    Vector3 fwd  = new Vector3(); // straight ahead
    Vector3 side = new Vector3(); // left side perp
    Vector3 up   = new Vector3(); // up
    
    ThxEntityHelper sidedHelper;
    
    abstract ThxEntityHelper createEntityHelper();
    
    public ThxEntityPacket250Data lastUpdatePacket;
    
    int cmd_reload;
    int cmd_create_item;
    int cmd_exit;
    int cmd_create_map;
    
    float damage;
    float throttle;
    
    Entity owner;
    
    // total update count
    float timeSinceAttacked;
    float timeSinceCollided;
    
    public ThxEntity(World world)
    {
        super(world);

        preventEntitySpawning = true; // keeps other entities from spawning on top of us

        prevTime = System.nanoTime();
        
        minecraft = Minecraft.getMinecraft();
        
        log("ThxEntity() called with world.isRemote: " + world.isRemote);
        
        sidedHelper = createEntityHelper();
    }
    
    @Override
    protected void entityInit()
    {
        //log("entityInit() called");
        dataWatcher.addObject(22, new Integer(0)); // roll
        dataWatcher.addObject(23, new Integer(0)); // throttle
        dataWatcher.addObject(24, new Integer(0)); // targetHelicopter id
        dataWatcher.addObject(25, new Integer(0)); // damage
    }
    
    void readDataWatcher()
    {
        // on client, read updated values most recently sent from server at beginning of update
        assertClientSideOnly();
        
        if (riddenByEntity != null && riddenByEntity.getEntityId() == minecraft.thePlayer.getEntityId()) return; // player is the client pilot
            
        rotationRoll   = ((float) dataWatcher.getWatchableObjectInt(22)) / 1000f;
        throttle       = ((float) dataWatcher.getWatchableObjectInt(23)) / 1000f;
        
        int targetEntityId =          dataWatcher.getWatchableObjectInt(24);
        checkForTargetEntityChange:
        {
            if (targetEntityId == 0)
            {
                targetEntity = null;
            }
            else if (targetEntity == null || targetEntity.getEntityId() != targetEntityId)
            {
            Entity target = (worldObj).getEntityByID(targetEntityId);
            if (target != null && !target.isDead && target instanceof ThxEntity)
            {
                targetEntity = (ThxEntity) target;
            }
            }
        }
        
        damage         = ((float) dataWatcher.getWatchableObjectInt(25)) / 1000f;
    }
    
    void updateDataWatcher()
    {
        // on server, record modified values in dataWatcher at end of update
        assertServerSideOnly();
        
        dataWatcher.updateObject(22, Integer.valueOf((int) (rotationRoll * 1000f)));
        dataWatcher.updateObject(23, Integer.valueOf((int) (throttle     * 1000f)));
        dataWatcher.updateObject(24, Integer.valueOf(targetEntity != null ? targetEntity.getEntityId() : 0));
        dataWatcher.updateObject(25, Integer.valueOf((int) (damage       * 1000f)));
    }
    
    @Override
    public void onUpdate()
    {
        ticksExisted++;
        
        long time = System.nanoTime();
        deltaTime = ((float) (time - prevTime)) / 1000000000f; // convert to sec
        //log(String.format("delta time: %6.4f", deltaTime));
        if (deltaTime > .05f) deltaTime = .05f; // 20 ticks per second
        prevTime = time;

        // 
        lastTickPosX = prevPosX = posX;
        lastTickPosY = prevPosY = posY;
        lastTickPosZ = prevPosZ = posZ;

        prevRotationPitch = rotationPitch;
        prevRotationYaw = rotationYaw;
        prevRotationRoll = rotationRoll;
        
        // apply custom update packet 250 if any
        if (lastUpdatePacket != null)
        {
            //if (worldObj.isRemote) applyUpdatePacketFromServer(lastUpdatePacket);
            //else applyUpdatePacketFromClient(lastUpdatePacket);
            lastUpdatePacket = null; // only apply once
        }
        
        // read updated values from server on client
        if (worldObj.isRemote) readDataWatcher();
        
        inWater = isInWater();
        
        // decrement cooldown timers
        timeSinceAttacked -= deltaTime;
        timeSinceCollided -= deltaTime;
        
        updateRotation();
        updateVectors();
    }
    
    public boolean isInWater()
    {
        // check for contact with water
        return worldObj.isAABBInMaterial(getEntityBoundingBox().expand(.0, -.4, .0), Material.water);
    }
    
    /*
     * Normalize all rotations to -180 to +180 degrees (typically only yaw is * affected)
     */
    public void updateRotation()
    {
        rotationYaw %= 360f;
        if (rotationYaw > 180f) rotationYaw -= 360f;
        else if (rotationYaw < -180f) rotationYaw += 360f;
        yawRad = rotationYaw * RAD_PER_DEG;

        rotationPitch %= 360f;
        if (rotationPitch > 180f) rotationPitch -= 360f;
        else if (rotationPitch < -180f) rotationPitch += 360f;
        pitchRad = rotationPitch * RAD_PER_DEG;

        rotationRoll %= 360f;
        if (rotationRoll > 180f) rotationRoll -= 360f;
        else if (rotationRoll < -180f) rotationRoll += 360f;
        rollRad = rotationRoll * RAD_PER_DEG;
    }

    public void updateVectors()
    {
        float cosYaw   = (float) MathHelper.cos(-yawRad - PI);
        float sinYaw   = (float) MathHelper.sin(-yawRad - PI);
        float cosPitch = (float) MathHelper.cos(-pitchRad);
        float sinPitch = (float) MathHelper.sin(-pitchRad);
        float cosRoll  = (float) MathHelper.cos(-rollRad);
        float sinRoll  = (float) MathHelper.sin(-rollRad);

        fwd.x = -sinYaw * cosPitch;
        fwd.y = sinPitch;
        fwd.z = -cosYaw * cosPitch;

        side.x = cosYaw * cosRoll;
        side.y = -sinRoll;
        side.z = -sinYaw * cosRoll;

        up.x = cosYaw * sinRoll - sinYaw * sinPitch * cosRoll;
        up.y = cosPitch * cosRoll;
        up.z = -sinYaw * sinRoll - sinPitch * cosRoll * cosYaw;
        Vector3.cross(side, fwd, up);

        pos.x = (float) posX;
        pos.y = (float) posY;
        pos.z = (float) posZ;

        vel.x = (float) motionX;
        vel.y = (float) motionY;
        vel.z = (float) motionZ;

        ypr.x = rotationYaw;
        ypr.y = rotationPitch;
        ypr.z = rotationRoll;
    }

    
    public Vector3 getForward()
    {
        float f3 = MathHelper.sin(-rotationYaw * 0.01745329F - 3.141593F);
        float f1 = MathHelper.cos(-rotationYaw * 0.01745329F - 3.141593F);
        float f5 = -MathHelper.cos(-rotationPitch * 0.01745329F);
        float f7 = MathHelper.sin(-rotationPitch * 0.01745329F);
        return new Vector3(f3 * f5, f7, f1 * f5);
    }
   

    @Override
    public void setDead()
    {
        log("setDead called");
        super.setDead();
    }
    
    /*
    @Override
    public void setPosition(double x, double y, double z)
    {
        // called on both client and server
        super.setPosition(x, y, z);
    }
    */
    
    protected void fall(float f)
    {
        // no damage from falling, unlike super.fall
        log("fall() called with arg " + f);
    }
    
    /* abstract methods from Entity base class */
    @Override
    protected void readEntityFromNBT(NBTTagCompound nbttagcompound)
    {
        //log("readEntityFromNBT called");
    }
    
    @Override
    protected void writeEntityToNBT(NBTTagCompound nbttagcompound)
    {
        //log("writeEntityToNBT called");
    }
    
    @Override
    public String toString()
    {
        return this.getClass().getSimpleName() + " " + getEntityId() + (worldObj.isRemote ? " (client)" : " (server)");
    }

    public void log(String s)
    {
        mod_thx.log(String.format("[%5d] ", ticksExisted) + this + ": " + s);
    }
    
    void plog(String s) // periodic log
    {
        if (worldObj.getWorldTime() % 60 == 0)
        {
            log(s); //
        }
    }
    
    /* subclasses can react to player pilot right click, e.g. helicopter fires missile */
    void interactByPilot()
    {
    }
    
    @Override
    public boolean interactAt/*interact*/(EntityPlayer player, Vec3 targetVec3)
    //public boolean interact(EntityPlayer player)
    {
        log("interact called with player " + player.getEntityId());
        
        if (player.equals(riddenByEntity))
        {
            interactByPilot();
            return false;
        }
        
        // feature to allow capture of a near helicopter, ejecting the current pilot
        if (riddenByEntity != null)
        {
            // already ridden by some other entity, allow takeover if close
            if (getDistanceSqToEntity(player) < 3.0)
            {
                log("current pilot [" + riddenByEntity + "] was ejected in boarding attempt by [" + player + "]");
                pilotExit();
            }
            else
            {
            return false; // boarding attempt failed
            }
        }
        
        if (player.ridingEntity != null) 
        {
            // player is already riding some other entity?
            return false;
        }
        
        
        // new pilot boarding! on server
	if (!worldObj.isRemote) 
        {
        log("interact() calling mountEntity on player " + player.getEntityId());
            player.mountEntity(this); // boarding, server
        }
        
        owner = player;
        
        player.rotationYaw = rotationYaw;
        updateRiderPosition();
        
        log("interact() added pilot: " + player);
        return true;
    }
    
    void pilotExit()
    {
        // vehicle subclasses will override
    }
    
    void takeDamage(float amount)
    {
        damage += amount;
    }
    
    @Override
    public boolean attackEntityFrom(DamageSource damageSource, float damageAmount)
    {
        if (worldObj.isRemote) return false; // server only
        
        log("attackEntityFrom called with damageSource: " + damageSource + " with amount " + damageAmount);

        if (timeSinceAttacked > 0f || isDead || damageSource == null) return false;
        //timeSinceAttacked = .5f; // sec delay before this entity can be attacked again
        timeSinceAttacked = .2f; // sec delay before this entity can be attacked again
        

        Entity attackingEntity = damageSource.getEntity();
        log("attacked by entity: " + attackingEntity);
        
        if (attackingEntity == null) return false; // when is this the case?
        if (attackingEntity.equals(this)) return false; // ignore damage from self?
        if (attackingEntity.equals(riddenByEntity))
        {
            attackedByPilot();
            return false; // ignore attack by pilot (player left click)
        }
        if (attackingEntity instanceof ThxEntity) // check for drone
        {
            attackedByThxEntity((ThxEntity) attackingEntity);
        }
        if (attackingEntity.ridingEntity instanceof ThxEntity) // check for other player pilot helicopter
        {
            attackedByThxEntity((ThxEntity) attackingEntity.ridingEntity);
        }
        return true; // hit landed
    }
    
    /* subclasses can react to player left click, e.g. helicopter fires rocket */
    void attackedByPilot()
    {
    }
    
    /* subclasses can react to attack by other thx entity */
    void attackedByThxEntity(ThxEntity entity)
    {
    }
    
    @Override
    public boolean canBeCollidedWith()
    {
        return !isDead;
    }

    @Override
    public boolean canBePushed()
    {
        return true;
    }

    @Override
    protected boolean canTriggerWalking()
    {
        return false;
    }

    public AxisAlignedBB getBoundingBox()
    {
        return getEntityBoundingBox();
    }

    @Override
    public AxisAlignedBB getCollisionBox(Entity entity)
    {
        return entity.getEntityBoundingBox();
    }

    @Override
    public boolean isInRangeToRenderDist(double d)
    {
        return d < 128.0 * 128.0;
    }

    private ThxPacket createUpdatePacket()
    {
        return new ThxEntityPacket250Data(this).createPacket250();
    }
    
    public void sendUpdatePacketFromClient()
    {
        assertClientSideOnly();
        
        //minecraft.getNetHandler().addToSendQueue(createUpdatePacket());
        mod_thx.network.sendToServer(createUpdatePacket());
    }
    
    /*public void applyUpdatePacketFromClient(ThxEntityPacket250Data packet)
    {
        assertServerSideOnly();
        
        setPositionAndRotation(packet.posX, packet.posY, packet.posZ, packet.yaw, packet.pitch);
        //setRotation(packet.yaw, packet.pitch);
        
        rotationRoll = packet.roll % 360f;

        motionX =  packet.motionX;
        motionY =  packet.motionY;
        motionZ =  packet.motionZ;
        
        damage = packet.damage;
        throttle = packet.throttle;

        // server command queue
        cmd_create_item = packet.cmd_create_item;
        cmd_reload      = packet.cmd_reload;
        cmd_exit        = packet.cmd_exit;
        cmd_create_map  = packet.cmd_create_map;
        
        //updateDataWatcher(); // this will send roll and throttle to clients // now called at the end of onUpdate instead
        
        if (packet.pilotId == 0 && riddenByEntity != null)
        {
            ////log("*** current pilot " + riddenByEntity.entityId + " is exiting (NOT calling pilotExit on server based on packet, deferring to interact");
            // must call pilotExit on serveror else pilot will exit helicopter but stay in seated position, no way to move helicoper, bugged!
            
            // called by pilotExit below
            //riddenByEntity.mountEntity(entity); // unmount
            
            // yes, it happens. should we ignore client update packets with no pilot?
            //if (true) throw new RuntimeException("does this happen?");
            
            log("*** current pilot " + riddenByEntity.getEntityId() + " is exiting");
            pilotExit(); 
        }
        
        //int riddenById = riddenByEntity != null ? riddenByEntity.entityId : 0;
        //log(String.format("end applyUpdatePacket, pilot %d [posX: %6.3f, posY: %6.3f, posZ: %6.3f, yaw: %6.3f, throttle: %6.3f, motionX: %6.3f, motionY: %6.3f, motionZ: %6.3f]", riddenById, posX, posY, posZ, rotationYaw, throttle, motionX, motionY, motionZ));
    }   */
    
    public void sendUpdatePacketFromServer()
    {
        assertServerSideOnly();
        
        ThxPacket packet = createUpdatePacket();
        
        for (int i = 0; i < worldObj.playerEntities.size(); i++) 
        {
            EntityPlayerMP player = (EntityPlayerMP) worldObj.playerEntities.get(i);
            if (riddenByEntity != null && riddenByEntity.getEntityId() == player.getEntityId()) continue; // skip pilot
            //player.playerNetServerHandler.sendPacketToPlayer(packet);
            mod_thx.network.sendTo(packet, player);
        }
    }
    
    /*public void applyUpdatePacketFromServer(ThxEntityPacket250Data packet)
    {
        log("applyUpdatePacketFromServer: " + packet);
        
        assertClientSideOnly();
        
        setPositionAndRotation(packet.posX, packet.posY, packet.posZ, packet.yaw, packet.pitch);
        
        rotationRoll = packet.roll % 360f;

        motionX =  packet.motionX;
        motionY =  packet.motionY;
        motionZ =  packet.motionZ;
        
        damage = packet.damage;
        throttle = packet.throttle;

        // not sure what owner is used for on the client...
        /*
       // if (packet.ownerId > 0)
        {
            if (owner == null || owner.entityId != packet.ownerId)
            {
                log("*** New entity owner id: " + packet.ownerId);
                    
                // first check for owner that is entity (e.g. helicopter)
                owner = ((WorldClient) worldObj).getEntityByID(packet.ownerId);
                    
                if (owner == null)
                {
                    // otherwise, check for owner that is a player
                    owner = mod_Thx.getEntityPlayerById(packet.ownerId);
                }
                    
                log("*** New entity owner: " + owner);
            }
        //}
        

        // no or wrong current pilot
        if (packet.pilotId > 0 && (riddenByEntity == null)) // || riddenByEntity.entityId != packet.pilotId))
        {
            Entity pilot = ((WorldClient) worldObj).getEntityByID(packet.pilotId);
            if (pilot != null && !pilot.isDead)
            {
                //log("*** applyUpdatePacket: pilot " + pilot + " now boarding");
                //pilot.mountEntity(this); // boarding
            }
        }
        else if (packet.pilotId == 0 && riddenByEntity != null)
        {
            log("*** applyUpdatePacket: current pilot " + riddenByEntity + " is exiting");
            //riddenByEntity.mountEntity(entity); // unmount
            pilotExit();
        }
            
        serverPosX = MathHelper.floor_float(packet.posX * 32f);
        serverPosY = MathHelper.floor_float(packet.posY * 32f);
        serverPosZ = MathHelper.floor_float(packet.posZ * 32f);
        
        //int riddenById = riddenByEntity != null ? riddenByEntity.entityId : 0;
        //plog(String.format("end applyUpdatePacket, pilot %d [posX: %6.3f, posY: %6.3f, posZ: %6.3f, yaw: %6.3f, pitch: %6.3f, roll: %6.3f, throttle: %6.3f, motionX: %6.3f, motionY: %6.3f, motionZ: %6.3f]", riddenById, posX, posY, posZ, rotationYaw, rotationPitch, rotationRoll, throttle, motionX, motionY, motionZ));
    }    */
    
    @Override
    public void updateRidden()
    {
        log("updateRidden() called, not calling super"); // super.updateRidden();
    }
    
    @Override
    protected void setBeenAttacked()
    {
        //super.setBeenAttacked(): this.velocityChanged = true; // causes EntityTrackerEntry to send Packet28 "knock-back"
    }
    
    void assertClientSideOnly()
    {
        if (worldObj.isRemote) return; // OK, we are on client as expected
        
        throw new RuntimeException("Client-side method was called on Server");
    }
    
    void assertServerSideOnly()
    {
        if (!worldObj.isRemote) return; // OK, we are on server as expected
            
        throw new RuntimeException("Server-side method was called on client");
    }

public void setPositionAndRotation(double posX, double posY, double posZ, float yaw, float pitch, int unused) {
	super.setPositionAndRotation(posX, posY, posZ, yaw, pitch);
}

}

This is where most of what I need to be happening isn't, I think. I've transferred the system to a state where it will send the packets on the new system(I think), but haven't added in the receiving end as I'm somewhat unsure of what I'm doing there.

 

ThxEntityPacket250Data file:

package com.thxreloaded.thxhelimod;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

import net.minecraft.network.Packet;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;

import com.thxreloaded.thxhelimod.ThxPacket;
import com.thxreloaded.thxhelimod.ThxPacket.Handler;

import io.netty.buffer.Unpooled;

public class ThxEntityPacket250Data
{
    public String msg          = null;
    public int entityId        = 0;
    public int ownerId         = 0;
    public int pilotId         = 0;
    public int cmd_create_item = 0;
    public int cmd_reload      = 0;
    public int cmd_exit        = 0;
    public int cmd_create_map  = 0;
    public float posX          = 0f;
    public float posY          = 0f;
    public float posZ          = 0f;
    public float yaw           = 0f;
    public float pitch         = 0f;
    public float roll          = 0f;
    public float motionX       = 0f;
    public float motionY       = 0f;
    public float motionZ       = 0f;
    public float damage        = 0f;
    public float throttle      = 0f;
            
    public ThxEntityPacket250Data()
    {
    }
    
    //public ThxEntityPacket250Data(Packet250CustomPayload packet)
    //{
      //  populate(packet);
    //}
    
    public ThxEntityPacket250Data(ThxEntity entity)
    {
        //if (entity instanceof ThxEntityProjectile) entity.log("creating ThxEntityPacket250Data for entity " + entity);
        
        populate(entity);
    }
    
    /*public void populate(Packet250CustomPayload packet)
    {
    if (!"THX_entity".equals(packet.channel)) throw new IllegalArgumentException("Incorrect packet channel: " + packet.channel);;
        
        clear();
        
        if (packet.data == null || packet.data.length == 0) return;
        
        try
        {
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(packet.data));
            
            msg = in.readUTF();
            
            entityId = in.readInt();
            ownerId  = in.readInt();
            pilotId  = in.readInt();
            
            cmd_create_item = in.readInt();
            cmd_reload      = in.readInt();
            cmd_exit        = in.readInt();
            cmd_create_map  = in.readInt();
           
            posX     = in.readFloat();
            posY     = in.readFloat();
            posZ     = in.readFloat();
            yaw      = in.readFloat();
            pitch    = in.readFloat();
            roll     = in.readFloat();
            motionX  = in.readFloat();
            motionY  = in.readFloat();
            motionZ  = in.readFloat();
            damage   = in.readFloat();
            throttle = in.readFloat();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
}*/
    
    public ThxEntityPacket250Data populate(ThxEntity entity)
    {
        entityId = entity.getEntityId();
        ownerId = entity.owner != null ? entity.owner.getEntityId() : 0;
        pilotId = entity.riddenByEntity != null ? entity.riddenByEntity.getEntityId() : 0;

        if (entity.worldObj.isRemote) 
        {
            msg = "client timestamp: " + entity.worldObj.getWorldTime();

            // don't send any server commands to client as they are not used there

            cmd_create_item = 0;
            cmd_reload      = 0;
            cmd_exit        = 0;
            cmd_create_map  = 0;
        }
        else
        {
            msg = "server timestamp: " + entity.worldObj.getWorldTime();

            // clear cmd flags after setting them in packet to avoid resending them later

            cmd_create_item = entity.cmd_create_item;
            entity.cmd_create_item = 0;

            cmd_reload      = entity.cmd_reload;
            entity.cmd_reload = 0;

            cmd_exit        = entity.cmd_exit;
            entity.cmd_exit = 0;

            cmd_create_map  = entity.cmd_create_map;
            entity.cmd_create_map = 0;
        }

        posX            = (float) entity.posX;
        posY            = (float) entity.posY;
        posZ            = (float) entity.posZ;
        yaw             = entity.rotationYaw;
        pitch           = entity.rotationPitch;
        roll            = entity.rotationRoll;
        motionX         = (float) entity.motionX;
        motionY         = (float) entity.motionY;
        motionZ         = (float) entity.motionZ;
        throttle        = entity.throttle;
        damage          = entity.damage;
        
        return this;
    }
    
    public void clear() // reset all values to allow for reuse of this instance
    {
    msg             = null;
    entityId        = 0;
    ownerId         = 0;
    pilotId         = 0;
    cmd_create_item = 0;
    cmd_reload      = 0;
    cmd_exit        = 0;
    cmd_create_map  = 0;
    posX            = 0f;
    posY            = 0f;
    posZ            = 0f;
    yaw             = 0f;
    pitch           = 0f;
    roll            = 0f;
    motionX         = 0f;
    motionY         = 0f;
    motionZ         = 0f;
    damage          = 0f;
    throttle        = 0f;
    }
    
    public ThxPacket createPacket250()
    {
    ByteArrayOutputStream baos = null;
    try
    {
        baos = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(baos);
        
        out.writeUTF(msg != null ? msg : "");
        out.writeInt(entityId);
        out.writeInt(ownerId);
        out.writeInt(pilotId); // riddenByEntity
        out.writeInt(cmd_create_item);
        out.writeInt(cmd_reload);
        out.writeInt(cmd_exit);
        out.writeInt(cmd_create_map);
        out.writeFloat(posX);
        out.writeFloat(posY);
        out.writeFloat(posZ);
        out.writeFloat(yaw);
        out.writeFloat(pitch);
        out.writeFloat(roll);
        out.writeFloat(motionX);
        out.writeFloat(motionY);
        out.writeFloat(motionZ);
        out.writeFloat(damage);
        out.writeFloat(throttle);
    }
    catch (IOException e)
    {
        throw new RuntimeException(e);
    }
    
    byte[] array = baos.toByteArray();
    
    ThxPacket packHandler = new ThxPacket(Unpooled.wrappedBuffer(array).toString());
    
    return packHandler;
    //return null;
    }

    @Override
    public String toString()
    {        
        return String.format("ThxEntityPacket250Data %s, entity %d, owner %d, pilot %d [posX: %6.2f, posY: %6.2f, posZ: %6.2f, yaw: %6.2f, pitch: %6.2f, roll: %6.2f, motionX: %6.3f, motionY: %6.3f, motionZ: %6.3f, throttle: %6.3f, damage: %d]", msg, entityId, ownerId, pilotId, posX, posY, posZ, yaw, pitch, roll, motionX, motionY, motionZ, throttle, (int) damage);
    }
}

The holy grail of outdated code. I've performed a few updates and commented out some functions to get it to compile, but it still crashes the game.

 

ThxPacketHandler file:

package com.thxreloaded.thxhelimod;

import java.io.IOException;

import io.netty.buffer.ByteBuf;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.IThreadListener;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;

class ThxPacket implements IMessage {
    
    private String text;

    public ThxPacket() { }

    public ThxPacket(String text) {
        this.text = text;
    }

    @Override
    public void fromBytes(ByteBuf buf) {
        text = ByteBufUtils.readUTF8String(buf); // this class is very useful in general for writing more complex objects
    }

    @Override
    public void toBytes(ByteBuf buf) {
        ByteBufUtils.writeUTF8String(buf, text);
    }

    public static class Handler implements IMessageHandler<ThxPacket, IMessage> {
        
        /*@Override
        public IMessage onMessage(ThxPacketHandler message, MessageContext ctx) {
            System.out.println(String.format("Received %s from %s", message.text, ctx.getServerHandler().playerEntity.getDisplayName()));
            return null; // no response in this case
        }*/

        // or in 1.8:
        @Override
        public IMessage onMessage(final ThxPacket message, final MessageContext ctx) {
            IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj; // or Minecraft.getMinecraft() on the client
            mainThread.addScheduledTask(new Runnable() {
                @Override
                public void run() {
                    System.out.println(String.format("Received %s from %s", message.text, ctx.getServerHandler().playerEntity.getDisplayName()));
                }
            });
            return null; // no response in this case
        }
    }

}

Made this file myself from code I hacked together from tutorials off this forum. I think it works? Not sure.

 

Now here's the deal. If I were to comment out all instances of packet handling in my code, the game runs. I can get in a helicopter and take off, before the out of sync server and client glitch me back to my starting point. If it's left to run however, the game freezes and eventually crashes whenever I enter a helicopter. Here's my most recent nightmare of a crash report in the Eclipse IDE...

 

[12:05:50] [Netty Server IO #1/ERROR] [FML]: There was a critical exception handling a packet on channel MyChannel
io.netty.handler.codec.DecoderException: java.lang.IllegalAccessException: Class net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec can not access a member of class com.thxreloaded.thxhelimod.ThxPacket with modifiers "public"
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) ~[MessageToMessageDecoder.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) ~[AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) ~[DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(FMLProxyPacket.java:90) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:158) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(NetworkManager.java:54) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [simpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleServerSideCustomPacket(NetworkDispatcher.java:429) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:252) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(NetworkDispatcher.java:54) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [simpleChannelInboundHandler.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) [AbstractChannelHandlerContext.class:4.0.23.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) [DefaultChannelPipeline.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:326) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:45) [LocalChannel.class:4.0.23.Final]
at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:312) [LocalChannel$5.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:380) [singleThreadEventExecutor.class:4.0.23.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357) [NioEventLoop.class:4.0.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) [singleThreadEventExecutor$2.class:4.0.23.Final]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_73]
Caused by: java.lang.IllegalAccessException: Class net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec can not access a member of class com.thxreloaded.thxhelimod.ThxPacket with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) ~[?:1.8.0_73]
at java.lang.Class.newInstance(Class.java:436) ~[?:1.8.0_73]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:79) ~[FMLIndexedMessageToMessageCodec.class:?]
at net.minecraftforge.fml.common.network.FMLIndexedMessageToMessageCodec.decode(FMLIndexedMessageToMessageCodec.java:21) ~[FMLIndexedMessageToMessageCodec.class:?]
at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) ~[MessageToMessageCodec$2.class:4.0.23.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89) ~[MessageToMessageDecoder.class:4.0.23.Final]
... 25 more
[12:05:50] [server thread/INFO]: Player292 lost connection: TextComponent{text='A fatal error has occured, this connection is terminated', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null, insertion=null}}
[12:05:50] [server thread/INFO]: Player292 left the game
[12:05:50] [server thread/INFO]: Stopping singleplayer server as player logged out
[12:05:51] [server thread/INFO]: Stopping server
[12:05:51] [server thread/INFO]: Saving players
[12:05:51] [server thread/INFO]: Saving worlds
[12:05:51] [server thread/INFO]: Saving chunks for level 'THX Test 3'/Overworld
[12:05:51] [server thread/INFO]: Saving chunks for level 'THX Test 3'/Nether
[12:05:51] [server thread/INFO]: Saving chunks for level 'THX Test 3'/The End
[12:05:51] [server thread/INFO] [FML]: Unloading dimension 0
[12:05:51] [server thread/INFO] [FML]: Unloading dimension -1
[12:05:51] [server thread/INFO] [FML]: Unloading dimension 1
[12:05:51] [server thread/INFO] [FML]: Applying holder lookups
[12:05:51] [server thread/INFO] [FML]: Holder lookups applied
[12:05:51] [pool-2-thread-1/WARN]: Couldn't look up profile properties for com.mojang.authlib.GameProfile@3f73efd3[id=e687d94c-f442-3ab7-a8a6-e1baf5dca36c,name=Player292,properties={},legacy=false]
com.mojang.authlib.exceptions.AuthenticationException: The client has sent too many requests within a certain amount of time
at com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService.makeRequest(YggdrasilAuthenticationService.java:65) ~[YggdrasilAuthenticationService.class:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService.fillGameProfile(YggdrasilMinecraftSessionService.java:175) [YggdrasilMinecraftSessionService.class:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService$1.load(YggdrasilMinecraftSessionService.java:59) [YggdrasilMinecraftSessionService$1.class:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService$1.load(YggdrasilMinecraftSessionService.java:56) [YggdrasilMinecraftSessionService$1.class:?]
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3524) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2317) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2280) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2195) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache.get(LocalCache.java:3934) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3938) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4821) [guava-17.0.jar:?]
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4827) [guava-17.0.jar:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService.fillProfileProperties(YggdrasilMinecraftSessionService.java:165) [YggdrasilMinecraftSessionService.class:?]
at net.minecraft.client.Minecraft.func_181037_M(Minecraft.java:2915) [Minecraft.class:?]
at net.minecraft.client.resources.SkinManager$3.run(SkinManager.java:130) [skinManager$3.class:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_73]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_73]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_73]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_73]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_73]

 

Please Obi-Wan, you're my only hope.

Posted

Okay, I am but a fish in a sea, but hell - just write everything from scratch. This code is not only outdated, but bad.

You are referencing client only classes in common code without proxies. You have tons of bad practices.

Whole old code will only mess up your thinking.

 

I am posting this more and more often (obviously can be written better): http://www.minecraftforge.net/forum/index.php/topic,33918.msg178740.html#msg178740

Very important: http://www.minecraftforge.net/forum/index.php/topic,22764.0.html

 

SNW:

Template: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html

Implementation: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-2-customizing-packet-handling-with

 

You REALLY should start from total scratch. System does everything for you, none of that Buffers you do is neccesary.

 

Points of interest:

Everything (almost) regarding built-in sync code (meaning "not SNW" stuff):

http://www.minecraftforge.net/forum/index.php/topic,36213.msg190583.html#msg190583

+ There is PlayerEvent.StartTracking and EntityTracker - those 2 are VERY important when designing dynamic synchronizations (top notch).

 

Note: After understanding system, I reccomend designing abstracition layer before even starting writing rest of mod. Example of what I mean is in 4th link in post (Implementation).

 

Other useful shit:

Recommend reading some of TheGreyGhost pages on how MC works.

1.7.10 is no longer supported by forge, you are on your own.

Posted

Okay, I am but a fish in a sea, but hell - just write everything from scratch. This code is not only outdated, but bad.

You are referencing client only classes in common code without proxies. You have tons of bad practices.

Whole old code will only mess up your thinking.

 

I am posting this more and more often (obviously can be written better): http://www.minecraftforge.net/forum/index.php/topic,33918.msg178740.html#msg178740

Very important: http://www.minecraftforge.net/forum/index.php/topic,22764.0.html

 

SNW:

Template: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html

Implementation: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-2-customizing-packet-handling-with

 

You REALLY should start from total scratch. System does everything for you, none of that Buffers you do is neccesary.

 

Points of interest:

Everything (almost) regarding built-in sync code (meaning "not SNW" stuff):

http://www.minecraftforge.net/forum/index.php/topic,36213.msg190583.html#msg190583

+ There is PlayerEvent.StartTracking and EntityTracker - those 2 are VERY important when designing dynamic synchronizations (top notch).

 

Note: After understanding system, I reccomend designing abstracition layer before even starting writing rest of mod. Example of what I mean is in 4th link in post (Implementation).

 

Other useful shit:

Recommend reading some of TheGreyGhost pages on how MC works.

 

Thanks very much for your quick reply.

 

When you say start from scratch, are we talking the entire mod, or just the packet handling aspect of it?

 

And either way, when I'm transferring data using a packet, is this data stored in the text field of the IMessage? In other other works, can all the information I need to seen between client and server be added onto a string with separation delimiters to be throw back and forth between the server and client? Or am I completely confused here?

Posted

When you say start from scratch, are we talking the entire mod, or just the packet handling aspect of it?

As said - the code you posted is bad in more than just sync way.

Difference between 1.6 and 1.8.9 is like having shovel and a damn bulldozer - sure they do same thing, but hell - one is thousands years more advanced and more efficiend than other.

Aside from that - the code from that old mod is simply bad (if you read 1st 2 links I gave you see for e.g that you are using "Minecraft.class" which is client only thing in Entity code). I wouldn't be surprised if it was crashing back then (tho back then there was less safety checks).

What I am saying - yeah, get the idea of mod from old one, write one as new project.

 

And either way, when I'm transferring data using a packet, is this data stored in the text field of the IMessage? In other other works, can all the information I need to seen between client and server be added onto a string with separation delimiters to be throw back and forth between the server and client? Or am I completely confused here?

I am not sure if you know how data is stored in memory. Yeah, sure you can serialize everything into a String like (example) "3424,human,8,Joe the Killer" and then decode it, but why the hell you'd do that... Any data is just bytes saved (in case of packets) in Buffer. You simply write and read values.

Read implementation link.

1.7.10 is no longer supported by forge, you are on your own.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Version 1.19 - Forge 41.0.63 I want to create a wolf entity that I can ride, so far it seems to be working, but the problem is that when I get on the wolf, I can’t control it. I then discovered that the issue is that the server doesn’t detect that I’m riding the wolf, so I’m struggling with synchronization. However, it seems to not be working properly. As I understand it, the server receives the packet but doesn’t register it correctly. I’m a bit new to Java, and I’ll try to provide all the relevant code and prints *The comments and prints are translated by chatgpt since they were originally in Spanish* Thank you very much in advance No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. No player is mounted, or the passenger is not a player. MountableWolfEntity package com.vals.valscraft.entity; import com.vals.valscraft.network.MountSyncPacket; import com.vals.valscraft.network.NetworkHandler; import net.minecraft.client.Minecraft; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.Entity; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.TickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.network.PacketDistributor; public class MountableWolfEntity extends Wolf { private boolean hasSaddle; private static final EntityDataAccessor<Byte> DATA_ID_FLAGS = SynchedEntityData.defineId(MountableWolfEntity.class, EntityDataSerializers.BYTE); public MountableWolfEntity(EntityType<? extends Wolf> type, Level level) { super(type, level); this.hasSaddle = false; } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(DATA_ID_FLAGS, (byte)0); } public static AttributeSupplier.Builder createAttributes() { return Wolf.createAttributes() .add(Attributes.MAX_HEALTH, 20.0) .add(Attributes.MOVEMENT_SPEED, 0.3); } @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemstack = player.getItemInHand(hand); if (itemstack.getItem() == Items.SADDLE && !this.hasSaddle()) { if (!player.isCreative()) { itemstack.shrink(1); } this.setSaddle(true); return InteractionResult.SUCCESS; } else if (!level.isClientSide && this.hasSaddle()) { player.startRiding(this); MountSyncPacket packet = new MountSyncPacket(true); // 'true' means the player is mounted NetworkHandler.CHANNEL.sendToServer(packet); // Ensure the server handles the packet return InteractionResult.SUCCESS; } return InteractionResult.PASS; } @Override public void travel(Vec3 travelVector) { if (this.isVehicle() && this.getControllingPassenger() instanceof Player) { System.out.println("The wolf has a passenger."); System.out.println("The passenger is a player."); Player player = (Player) this.getControllingPassenger(); // Ensure the player is the controller this.setYRot(player.getYRot()); this.yRotO = this.getYRot(); this.setXRot(player.getXRot() * 0.5F); this.setRot(this.getYRot(), this.getXRot()); this.yBodyRot = this.getYRot(); this.yHeadRot = this.yBodyRot; float forward = player.zza; float strafe = player.xxa; if (forward <= 0.0F) { forward *= 0.25F; } this.flyingSpeed = this.getSpeed() * 0.1F; this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED) * 1.5F); this.setDeltaMovement(new Vec3(strafe, travelVector.y, forward).scale(this.getSpeed())); this.calculateEntityAnimation(this, false); } else { // The wolf does not have a passenger or the passenger is not a player System.out.println("No player is mounted, or the passenger is not a player."); super.travel(travelVector); } } public boolean hasSaddle() { return this.hasSaddle; } public void setSaddle(boolean hasSaddle) { this.hasSaddle = hasSaddle; } @Override protected void dropEquipment() { super.dropEquipment(); if (this.hasSaddle()) { this.spawnAtLocation(Items.SADDLE); this.setSaddle(false); } } @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.START) { MinecraftServer server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); if (server != null) { for (ServerPlayer player : server.getPlayerList().getPlayers()) { if (player.isPassenger() && player.getVehicle() instanceof MountableWolfEntity) { MountableWolfEntity wolf = (MountableWolfEntity) player.getVehicle(); System.out.println("Tick: " + player.getName().getString() + " is correctly mounted on " + wolf); } } } } } private boolean lastMountedState = false; @Override public void tick() { super.tick(); if (!this.level.isClientSide) { // Only on the server boolean isMounted = this.isVehicle() && this.getControllingPassenger() instanceof Player; // Only print if the state changed if (isMounted != lastMountedState) { if (isMounted) { Player player = (Player) this.getControllingPassenger(); // Verify the passenger is a player System.out.println("Server: Player " + player.getName().getString() + " is now mounted."); } else { System.out.println("Server: The wolf no longer has a passenger."); } lastMountedState = isMounted; } } } @Override public void addPassenger(Entity passenger) { super.addPassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(true)); } } } @Override public void removePassenger(Entity passenger) { super.removePassenger(passenger); if (passenger instanceof Player) { Player player = (Player) passenger; if (!this.level.isClientSide && player instanceof ServerPlayer) { // Send the packet to the server to indicate the player is no longer mounted NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), new MountSyncPacket(false)); } } } @Override public boolean isControlledByLocalInstance() { Entity entity = this.getControllingPassenger(); return entity instanceof Player; } @Override public void positionRider(Entity passenger) { if (this.hasPassenger(passenger)) { double xOffset = Math.cos(Math.toRadians(this.getYRot() + 90)) * 0.4; double zOffset = Math.sin(Math.toRadians(this.getYRot() + 90)) * 0.4; passenger.setPos(this.getX() + xOffset, this.getY() + this.getPassengersRidingOffset() + passenger.getMyRidingOffset(), this.getZ() + zOffset); } } } MountSyncPacket package com.vals.valscraft.network; import com.vals.valscraft.entity.MountableWolfEntity; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class MountSyncPacket { private final boolean isMounted; public MountSyncPacket(boolean isMounted) { this.isMounted = isMounted; } public void encode(FriendlyByteBuf buffer) { buffer.writeBoolean(isMounted); } public static MountSyncPacket decode(FriendlyByteBuf buffer) { return new MountSyncPacket(buffer.readBoolean()); } public void handle(NetworkEvent.Context context) { context.enqueueWork(() -> { ServerPlayer player = context.getSender(); // Get the player from the context if (player != null) { // Verifies if the player has dismounted if (!isMounted) { Entity vehicle = player.getVehicle(); if (vehicle instanceof MountableWolfEntity wolf) { // Logic to remove the player as a passenger wolf.removePassenger(player); System.out.println("Server: Player " + player.getName().getString() + " is no longer mounted."); } } } }); context.setPacketHandled(true); // Marks the packet as handled } } networkHandler package com.vals.valscraft.network; import com.vals.valscraft.valscraft; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; import net.minecraftforge.network.NetworkEvent; import java.util.function.Supplier; public class NetworkHandler { private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel( new ResourceLocation(valscraft.MODID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); public static void init() { int packetId = 0; // Register the mount synchronization packet CHANNEL.registerMessage( packetId++, MountSyncPacket.class, MountSyncPacket::encode, MountSyncPacket::decode, (msg, context) -> msg.handle(context.get()) // Get the context with context.get() ); } }  
    • Do you use features of inventory profiles next (ipnext) or is there a change without it?
    • Remove rubidium - you are already using embeddium, which is a fork of rubidium
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.