jabelar Posted May 10, 2014 Posted May 10, 2014 In the course of trying to send a packet in multiplayer mode, while running in dev environment, I get the following error related to a vanilla class. Minecraft otherwise seems to be working, so it's not like the class paths are totally hosed. Any ideas? I can't imagine that I created the problem as I don't touch this class, it is still present in the code, and I reinstalled Forge just to make sure. [13:59:45] [server thread/ERROR] [net.minecraft.server.MinecraftServer]: Encountered an unexpected exception java.lang.NoClassDefFoundError: net/minecraft/client/multiplayer/WorldClient at wildanimals.entities.herdanimals.EntityHerdAnimal.sendSyncPacket(EntityHerdAnimal.java:474) ~[EntityHerdAnimal.class:?] at wildanimals.entities.herdanimals.EntityHerdAnimal.setRearing(EntityHerdAnimal.java:417) ~[EntityHerdAnimal.class:?] at wildanimals.entities.herdanimals.EntityHerdAnimal.attackEntityFrom(EntityHerdAnimal.java:292) ~[EntityHerdAnimal.class:?] at net.minecraft.entity.player.EntityPlayer.attackTargetEntityWithCurrentItem(EntityPlayer.java:1401) ~[EntityPlayer.class:?] at net.minecraft.network.NetHandlerPlayServer.processUseEntity(NetHandlerPlayServer.java:873) ~[NetHandlerPlayServer.class:?] at net.minecraft.network.play.client.C02PacketUseEntity.processPacket(C02PacketUseEntity.java:51) ~[C02PacketUseEntity.class:?] at net.minecraft.network.play.client.C02PacketUseEntity.processPacket(C02PacketUseEntity.java:69) ~[C02PacketUseEntity.class:?] at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:232) ~[NetworkManager.class:?] at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182) ~[NetworkSystem.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:720) ~[MinecraftServer.class:?] at net.minecraft.server.dedicated.DedicatedServer.updateTimeLightAndEntities(DedicatedServer.java:341) ~[DedicatedServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:608) ~[MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:482) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:746) [MinecraftServer$2.class:?] Caused by: java.lang.ClassNotFoundException: net.minecraft.client.multiplayer.WorldClient at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:188) ~[launchwrapper-1.9.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[?:1.7.0_51] at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[?:1.7.0_51] ... 14 more Caused by: java.lang.RuntimeException: Attempted to load class net/minecraft/client/multiplayer/WorldClient for invalid side SERVER at cpw.mods.fml.common.asm.transformers.SideTransformer.transform(SideTransformer.java:50) ~[forgeSrc-1.7.2-10.12.1.1071.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:276) ~[launchwrapper-1.9.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:174) ~[launchwrapper-1.9.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:425) ~[?:1.7.0_51] at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ~[?:1.7.0_51] Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
GotoLink Posted May 11, 2014 Posted May 11, 2014 Attempted to load class net/minecraft/client/multiplayer/WorldClient for invalid side SERVER It is the client. Server can't access it. Quote
jabelar Posted May 11, 2014 Author Posted May 11, 2014 Attempted to load class net/minecraft/client/multiplayer/WorldClient for invalid side SERVER It is the client. Server can't access it. Okay, but that line (474 in HerdAnimals class) is after checking that you're on server side (the problem line is the sendToAll() inside the try): public void sendSyncPacket() { if (!this.worldObj.isRemote) { try { WildAnimals.channel.sendToAll(PacketWildAnimals.createEntityPacket(this)); } catch (IOException e) { e.printStackTrace(); } } } And the sendToAll() method is a vanilla server side method: /** * Send a packet to all on the server * * @param pkt */ public void sendToAll(FMLProxyPacket pkt) { channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL); channels.get(Side.SERVER).writeAndFlush(pkt).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } So I'm using the vanilla Entity worldObj field (which should exist on both sides right? I also tried the isClientWorld() method still failed), checking to ensure I'm on server side and calling a server side method. So why do I get a "no class def error" on server side? One other thing to mention -- the same code seems to work fine in single player. I still call sendAll() but of course there is only one client. So it that kinda seems like a @Side kind of thing, but I'm not using that annotation and the neither does the FMLEventChannel class. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
GotoLink Posted May 11, 2014 Posted May 11, 2014 Either "WildAnimals" or "PacketWildAnimals" use a client side only stuff without having the necessary @SideOnly annotation. Check the respective imports. Quote
jabelar Posted May 11, 2014 Author Posted May 11, 2014 Either "WildAnimals" or "PacketWildAnimals" use a client side only stuff without having the necessary @SideOnly annotation. Check the respective imports. Okay, I admit it seems like some sort of side annotation issue. However, I'm still a little perplexed for two reasons: 1) the error report doesn't call out any of my classes as the missing problematic class. 2) I don't use the SideOnly annotation much except for the traditional proxy stuff and all my packet handling is in common proxy. Here is my PacketWildAnimals class, which doesn't have any side annotations so should be available on both sides: package wildanimals.network.entities; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import java.io.IOException; import wildanimals.WildAnimals; import wildanimals.entities.bigcats.EntityBigCat; import wildanimals.entities.herdanimals.EntityHerdAnimal; import wildanimals.entities.serpents.EntitySerpent; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; // this class is intended to be sent from server to client to keep custom entities synced public class PacketWildAnimals { // define IDs for custom packet types public final static int packetTypeIDEntity = 1; public final static int packetTypeIDC2STest = 2; public PacketWildAnimals() { // don't need anything here } // ***************************************** // Server To Client Packet Creation // ***************************************** public static FMLProxyPacket createEntityPacket(Entity parEntity) throws IOException { // DEBUG System.out.println("Sending PacketWildAnimals on Server Side"); ByteBufOutputStream bbos = new ByteBufOutputStream(Unpooled.buffer()); // create payload by writing to data stream // first identity packet type bbos.writeInt(packetTypeIDEntity); // write entity instance id (not the class registry id!) bbos.writeInt(parEntity.getEntityId()); // now write entity-specific custom fields // process herd animals if (parEntity instanceof EntityHerdAnimal) { EntityHerdAnimal entityHerdAnimal = (EntityHerdAnimal)parEntity; bbos.writeFloat(entityHerdAnimal.getScaleFactor()); bbos.writeBoolean(entityHerdAnimal.isRearing()); } // process serpents else if (parEntity instanceof EntitySerpent) { EntitySerpent entitySerpent = (EntitySerpent)parEntity; bbos.writeFloat(entitySerpent.getScaleFactor()); } // process big cats else if (parEntity instanceof EntityBigCat) { EntityBigCat entityBigCat = (EntityBigCat)parEntity; bbos.writeFloat(entityBigCat.getScaleFactor()); } // put payload into a packet FMLProxyPacket thePacket = new FMLProxyPacket(bbos.buffer(), WildAnimals.networkChannelName); // don't forget to close stream to avoid memory leak bbos.close(); return thePacket; } // ***************************************** // Client to Server Packet Creation // ***************************************** public static FMLProxyPacket createClientToServerTestPacket(EntityPlayer parPlayer, int parTestValue) throws IOException { if (parPlayer.getEntityWorld().isRemote) { // DEBUG System.out.println("Sending PacketWildAnimals on Client Side"); ByteBufOutputStream bbos = new ByteBufOutputStream(Unpooled.buffer()); // create payload by writing to data stream // first identity packet type bbos.writeInt(packetTypeIDC2STest); // write entity instance id (not the class registry id!) bbos.writeInt(parTestValue); // put payload into a packet FMLProxyPacket thePacket = new FMLProxyPacket(bbos.buffer(), WildAnimals.networkChannelName); // don't forget to close stream to avoid memory leak bbos.close(); return thePacket; } else { return null; } } // ***************************************** // Received By Client Packet Processing // ***************************************** public static void processPacketOnClient(ByteBuf parBB, Side parSide) throws IOException { if (parSide == Side.CLIENT) // packet received on client side { // DEBUG System.out.println("Received PacketWildAnimals on Client Side"); World theWorld = Minecraft.getMinecraft().theWorld; ByteBufInputStream bbis = new ByteBufInputStream(parBB); // process data stream // first read packet type int packetTypeID = bbis.readInt(); switch (packetTypeID) { case packetTypeIDEntity: // a packet sent from server to sync entity custom fields { // find entity instance int entityID = bbis.readInt(); // DEBUG System.out.println("Entity ID = "+entityID); Entity foundEntity = getEntityByID(entityID, theWorld); // DEBUG if (foundEntity != null) { System.out.println("Entity Class Name = "+foundEntity.getClass().getSimpleName()); } else { System.out.println("Entity Class Name = null"); } // process based on type of entity class // process herd animals if (foundEntity instanceof EntityHerdAnimal) { EntityHerdAnimal foundEntityHerdAnimal = (EntityHerdAnimal)foundEntity; // apply custom fields to entity instance foundEntityHerdAnimal.setScaleFactor(bbis.readFloat()); foundEntityHerdAnimal.setRearing(bbis.readBoolean()); // DEBUG System.out.println("Is rearing = "+foundEntityHerdAnimal.isRearing()); } // process serpents else if (foundEntity instanceof EntitySerpent) { EntitySerpent foundEntitySerpent = (EntitySerpent)foundEntity; // apply custom fields to entity instance foundEntitySerpent.setScaleFactor(bbis.readFloat()); } // process big cats else if (foundEntity instanceof EntityBigCat) { EntityBigCat foundEntityBigCat = (EntityBigCat)foundEntity; // apply custom fields to entity instance foundEntityBigCat.setScaleFactor(bbis.readFloat()); } break; } } // don't forget to close stream to avoid memory leak bbis.close(); } } // ***************************************** // Received By Server Packet Processing // ***************************************** public static void processPacketOnServer(ByteBuf parBB, Side parSide, EntityPlayer parPlayer) throws IOException { if (parSide == Side.SERVER) // packet received on server side { // DEBUG System.out.println("Received PacketWildAnimals on Server Side from Player = "+parPlayer.getEntityId()); ByteBufInputStream bbis = new ByteBufInputStream(parBB); // process data stream // first read packet type int packetTypeID = bbis.readInt(); // DEBUG System.out.println("Packet type ID = "+packetTypeID); switch (packetTypeID) { case packetTypeIDC2STest: { // DEBUG System.out.println("Test packet received"); int testVal = bbis.readInt(); // DEBUG System.out.println("Test payload value = "+testVal); break ; } } // don't forget to close stream to avoid memory leak bbis.close(); } } // some helper functions public static Entity getEntityByID(int entityID, World world) { for(Object o: world.getLoadedEntityList()) { if(((Entity)o).getEntityId() == entityID) { System.out.println("Found the entity"); return ((Entity)o); } } return null; } } And here is my CommonProxy, where all the networking stuff is: package wildanimals.proxy; import java.io.File; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.util.ChatComponentText; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; import wildanimals.WildAnimals; import wildanimals.WildAnimalsEventHandler; import wildanimals.WildAnimalsFMLEventHandler; import wildanimals.WildAnimalsOreGenEventHandler; import wildanimals.WildAnimalsTerrainGenEventHandler; import wildanimals.entities.bigcats.EntityJaguar; import wildanimals.entities.bigcats.EntityLion; import wildanimals.entities.bigcats.EntityLynx; import wildanimals.entities.bigcats.EntityManEatingJaguar; import wildanimals.entities.bigcats.EntityManEatingLion; import wildanimals.entities.bigcats.EntityManEatingLynx; import wildanimals.entities.bigcats.EntityManEatingTiger; import wildanimals.entities.bigcats.EntityTiger; import wildanimals.entities.herdanimals.EntityElephant; import wildanimals.entities.serpents.EntitySerpent; import wildanimals.items.ItemWildAnimalSpawnEgg; import wildanimals.networking.ServerPacketHandler; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.network.IGuiHandler; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.registry.EntityRegistry; import cpw.mods.fml.common.registry.GameRegistry; public class CommonProxy { protected int modEntityID = 0; protected Configuration config; public void preInit(FMLPreInitializationEvent event) { // load configuration before doing anything else // got config tutorial from http://www.minecraftforge.net/wiki/How_to_make_an_advanced_configuration_file processConfig(); // register stuff registerBlocks(); registerItems(); registerTileEntities(); registerModEntities(); registerEntitySpawns(); registerFuelHandlers(); } public void init(FMLInitializationEvent event) { // register custom event listeners registerEventListeners(); // register networking channel registerNetworkingChannel(); // register server packet handler registerServerPacketHandler(); // register recipes here to allow use of items from other mods registerRecipes(); } public void postInit(FMLPostInitializationEvent event) { // can do some inter-mod stuff here } protected void processConfig() { // might need to use suggestedConfigFile (event.getSuggestedConfigFile) location to publish System.out.println(WildAnimals.MODNAME+" config path = "+WildAnimals.configPath); WildAnimals.configFile = new File(WildAnimals.configPath); System.out.println("Config file exists = "+WildAnimals.configFile.canRead()); config = new Configuration(WildAnimals.configFile); WildAnimals.config = config; WildAnimals.configBigCatsAreManEaters = config.get(Configuration.CATEGORY_GENERAL, "BigCatsAreManEaters", true).getBoolean(true); System.out.println("Big cats are man eaters = "+WildAnimals.configBigCatsAreManEaters); WildAnimals.configIncludeSnakes = config.get(Configuration.CATEGORY_GENERAL, "IncludeSnakes", false).getBoolean(false); System.out.println("Include snakes = "+WildAnimals.configIncludeSnakes); WildAnimals.configIncludeBigCats = config.get(Configuration.CATEGORY_GENERAL, "IncludeBigCats", true).getBoolean(true); System.out.println("Include big cats = "+WildAnimals.configIncludeBigCats); WildAnimals.configIncludeHerdAnimals = config.get(Configuration.CATEGORY_GENERAL, "IncludeHerdAnimals", true).getBoolean(true); System.out.println("Include herd animals = "+WildAnimals.configIncludeHerdAnimals); } // register blocks public void registerBlocks() { //example: GameRegistry.registerBlock(blockTomato, "tomatoes"); } // register items private void registerItems() { // DEBUG System.out.println("Registering items"); // spawn eggs are registered during entity registration // example: GameRegistry.registerCustomItemStack(name, itemStack); } // register tileentities public void registerTileEntities() { // DEBUG System.out.println("Registering tile entities"); // example: GameRegistry.registerTileEntity(TileEntityStove.class, "stove_tile_entity"); } // register recipes public void registerRecipes() { // DEBUG System.out.println("Registering recipes"); // examples: // GameRegistry.addRecipe(recipe); // GameRegistry.addShapedRecipe(output, params); // GameRegistry.addShapelessRecipe(output, params); // GameRegistry.addSmelting(input, output, xp); } // register entities // lots of conflicting tutorials on this, currently following: nly register mod id http://www.minecraftforum.net/topic/1417041-mod-entity-problem/page__st__140#entry18822284 // another tut says to only register global id like http://www.minecraftforge.net/wiki/How_to_register_a_mob_entity#Registering_an_Entity // another tut says to use both: http://www.minecraftforum.net/topic/2389683-172-forge-add-new-block-item-entity-ai-creative-tab-language-localization-block-textures-side-textures/ public void registerModEntities() { // DEBUG System.out.println("Registering entities"); // uses configuration file to control whether each entity type is registered, to allow user customization // Big cats if (WildAnimals.configIncludeBigCats) { if (WildAnimals.configBigCatsAreManEaters) { registerModEntityWithEgg(EntityManEatingTiger.class, "Tiger", 0xE18519, 0x000000); registerModEntityWithEgg(EntityManEatingLion.class, "Lion", 0xD9C292, 0xFFFFFF); registerModEntityWithEgg(EntityManEatingLynx.class, "Lynx", 0xD9C292, 0xFFFFFF); registerModEntityWithEgg(EntityManEatingJaguar.class, "Jaguar", 0xF4E003, 0x000000); } else { registerModEntityWithEgg(EntityTiger.class, "Tiger", 0xE18519, 0x000000); registerModEntityWithEgg(EntityLion.class, "Lion", 0xD9C292, 0xFFFFFF); registerModEntityWithEgg(EntityLynx.class, "Lynx", 0xD9C292, 0xFFFFFF); registerModEntityWithEgg(EntityJaguar.class, "Jaguar", 0xF4E003, 0x000000); } } // Herd animals if (WildAnimals.configIncludeHerdAnimals) { registerModEntityWithEgg(EntityElephant.class, "Elephant", 0x888888, 0xAAAAAA); } // Serpents if (WildAnimals.configIncludeSnakes) { registerModEntityWithEgg(EntitySerpent.class, "Python", 0x3F5505, 0x4E6414); } } public void registerModEntity(Class parEntityClass, String parEntityName) { EntityRegistry.registerModEntity(parEntityClass, parEntityName, ++modEntityID, WildAnimals.instance, 80, 3, false); } public void registerModEntityWithEgg(Class parEntityClass, String parEntityName, int parEggColor, int parEggSpotsColor) { EntityRegistry.registerModEntity(parEntityClass, parEntityName, ++modEntityID, WildAnimals.instance, 80, 3, false); registerSpawnEgg(parEntityName, parEggColor, parEggSpotsColor); } // can't use vanilla spawn eggs with entities registered with modEntityID, so use custom eggs. // name passed must match entity name string public void registerSpawnEgg(String parSpawnName, int parEggColor, int parEggSpotsColor) { Item itemSpawnEgg = new ItemWildAnimalSpawnEgg(parSpawnName, parEggColor, parEggSpotsColor).setUnlocalizedName("spawn_egg_"+parSpawnName.toLowerCase()).setTextureName("wildanimals:spawn_egg"); GameRegistry.registerItem(itemSpawnEgg, "spawnEgg"+parSpawnName); } public void registerEntitySpawns() { // register natural spawns for entities // EntityRegistry.addSpawn(MyEntity.class, spawnProbability, minSpawn, maxSpawn, enumCreatureType, [spawnBiome]); // See the constructor in BiomeGenBase.java to see the rarity of vanilla mobs; Sheep are probability 10 while Endermen are probability 1 // minSpawn and maxSpawn are about how groups of the entity spawn // enumCreatureType represents the "rules" Minecraft uses to determine spawning, based on creature type. By default, you have three choices: // EnumCreatureType.creature uses rules for animals: spawn everywhere it is light out. // EnumCreatureType.monster uses rules for monsters: spawn everywhere it is dark out. // EnumCreatureType.waterCreature uses rules for water creatures: spawn only in water. // [spawnBiome] is an optional parameter of type BiomeGenBase that limits the creature spawn to a single biome type. Without this parameter, it will spawn everywhere. // DEBUG System.out.println("Registering natural spawns"); // Big cats // savanna cats // EntityRegistry.addSpawn(EntityLion.class, 6, 0, 5, EnumCreatureType.creature, BiomeGenBase.savanna); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLion.class, 6, 0, 5, EnumCreatureType.creature, BiomeGenBase.savannaPlateau); //change the values to vary the spawn rarity, biome, etc. // // hill cats // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.birchForestHills); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.coldTaigaHills); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.desertHills); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.extremeHills); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.extremeHillsEdge); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.extremeHillsPlus); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.forestHills); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.iceMountains); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.megaTaigaHills); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.mesaPlateau); //change the values to vary the spawn rarity, biome, etc. // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.mesaPlateau_F); //change the values to vary the spawn rarity, biome, etc. // // swamp cats // EntityRegistry.addSpawn(EntityLynx.class, 5, 0, 1, EnumCreatureType.creature, BiomeGenBase.swampland); //change the values to vary the spawn rarity, biome, etc. // jungle cats EntityRegistry.addSpawn(EntityJaguar.class, 6, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungle); //change the values to vary the spawn rarity, biome, etc. EntityRegistry.addSpawn(EntityJaguar.class, 3, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungleHills); //change the values to vary the spawn rarity, biome, etc. EntityRegistry.addSpawn(EntityJaguar.class, 1, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungleEdge); //change the values to vary the spawn rarity, biome, etc. // Jaden didn't want tigers! EntityRegistry.addSpawn(EntityTiger.class, 1, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungle); //change the values to vary the spawn rarity, biome, etc. if (WildAnimals.configBigCatsAreManEaters) { EntityRegistry.addSpawn(EntityManEatingTiger.class, 1, 0, 1, EnumCreatureType.creature, BiomeGenBase.jungle); //change the values to vary the spawn rarity, biome, etc. } // Herd animals // savanna herds EntityRegistry.addSpawn(EntityElephant.class, 10, 0, 1, EnumCreatureType.creature, BiomeGenBase.savanna); //change the values to vary the spawn rarity, biome, etc. EntityRegistry.addSpawn(EntityElephant.class, 10, 0, 1, EnumCreatureType.creature, BiomeGenBase.savannaPlateau); //change the values to vary the spawn rarity, biome, etc. } public void registerFuelHandlers() { // DEBUG System.out.println("Registering fuel handlers"); // example: GameRegistry.registerFuelHandler(handler); } public void registerEventListeners() { // DEBUG System.out.println("Registering event listeners"); MinecraftForge.EVENT_BUS.register(new WildAnimalsEventHandler()); MinecraftForge.TERRAIN_GEN_BUS.register(new WildAnimalsTerrainGenEventHandler());; MinecraftForge.ORE_GEN_BUS.register(new WildAnimalsOreGenEventHandler()); // some events, especially tick, is handled on FML bus FMLCommonHandler.instance().bus().register(new WildAnimalsFMLEventHandler()); } public void sendMessageToPlayer(ChatComponentText msg) { } public void serverLoad(FMLServerStartingEvent event) { } // Got this idea to use IGuiHandler interface from message from Noppes at http://www.minecraftforge.net/forum/index.php/topic,15403.0.html // With code example at https://dl.dropboxusercontent.com/u/3096920/NetworkExampleMod.zip public void registerNetworkingChannel() { WildAnimals.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel(WildAnimals.networkChannelName); // when you want to send a packet elsewhere, use one of these methods (server or client): // wildanimals.channel.sendToServer(FMLProxyPacket); // wildanimals.channel.sendTo(FMLProxyPacket, EntityPlayerMP); for player-specific GUI interaction // wildanimals.channel.sendToAll(FMLProxyPacket); for all player sync like entities // and there are other sendToxxx methods to check out. } public void registerServerPacketHandler() { WildAnimals.channel.register(new ServerPacketHandler()); } } And here is my main class which does fairly traditional use of proxy: package wildanimals; import java.io.File; import net.minecraft.entity.EntityList; import net.minecraftforge.common.config.Configuration; import wildanimals.proxy.CommonProxy; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.network.FMLEventChannel; @Mod(modid = WildAnimals.MODID, name = WildAnimals.MODNAME, version = WildAnimals.VERSION) public class WildAnimals { public static final String MODID = "wildanimals"; public static final String MODNAME = "wildanimals+"; public static final String VERSION = "0.0.1"; public static final String networkChannelName = "wildanimals"; public static FMLEventChannel channel; // set up configuration properties (will be read from config file in preInit) public static String configPath = "wildanimals/src/main/resources/assets/"+WildAnimals.MODID+"/config/config.cfg"; public static File configFile; public static Configuration config; public static Boolean configBigCatsAreManEaters = true; public static Boolean configIncludeSnakes = true; public static Boolean configIncludeBigCats = true; public static Boolean configIncludeHerdAnimals = true; // instantiate the mod @Instance(MODID) public static WildAnimals instance; // create custom creativetab for mod items //public static CreativeTabs tabWildAnimalsPlus = new WildAnimalsCreativeTab("wildanimals+"); // instantiate blocks //public final static Block blockTomato = new BlockTomato(); // instantiate items //public final static Item tomato = new ItemTomato(); // Says where the client and server 'proxy' code is loaded. @SidedProxy(clientSide="wildanimals.proxy.client.ClientProxy", serverSide="wildanimals.proxy.CommonProxy") public static CommonProxy proxy; @EventHandler // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the GameRegistry." public void preInit(FMLPreInitializationEvent event) { // DEBUG System.out.println("preInit()"+event.getModMetadata().name); event.getModMetadata().autogenerated = false ; // stops it from complaining about missing mcmod.info proxy.preInit(event); } @EventHandler // load "Do your mod setup. Build whatever data structures you care about. Register recipes." public void init(FMLInitializationEvent event) { // DEBUG System.out.println("init()"); proxy.init(event); } @EventHandler // postInit "Handle interaction with other mods, complete your setup based on this." public void postInit(FMLPostInitializationEvent event) { // DEBUG System.out.println("postInit()"); proxy.postInit(event); } @EventHandler // register server commands // refer to tutorial at http://www.minecraftforge.net/wiki/Server_Command#Mod_Implementation public void serverLoad(FMLServerStartingEvent event) { // DEBUG System.out.println("serverLoad()"); proxy.serverLoad(event); } } But I'll keep crawling through it. I guess I'll add some side only annotations and see if it complains unexpectedly so I can figure out where the failure in my logic is. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
jabelar Posted May 11, 2014 Author Posted May 11, 2014 Well, I added some SideOnly annotation in the PacketWildAnimals and it fixed the problem. I have to say I don't quite understand it -- if it was calling a method before on wrong side, wouldn't the SideOnly also cause failure because then there wouldn't be any method present at all? In any case, I'll consider this solved. Here is the revised PacketWildAnimals class: package wildanimals.network.entities; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; import java.io.IOException; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import wildanimals.WildAnimals; import wildanimals.entities.bigcats.EntityBigCat; import wildanimals.entities.herdanimals.EntityHerdAnimal; import wildanimals.entities.serpents.EntitySerpent; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; // this class is intended to be sent from server to client to keep custom entities synced public class PacketWildAnimals { // define IDs for custom packet types public final static int packetTypeIDEntity = 1; public final static int packetTypeIDC2STest = 2; public PacketWildAnimals() { // don't need anything here } // ***************************************** // Server To Client Packet Creation // ***************************************** @SideOnly(Side.SERVER) public static FMLProxyPacket createEntityPacket(Entity parEntity) throws IOException { // DEBUG System.out.println("Sending PacketWildAnimals on Server Side"); ByteBufOutputStream bbos = new ByteBufOutputStream(Unpooled.buffer()); // create payload by writing to data stream // first identity packet type bbos.writeInt(packetTypeIDEntity); // write entity instance id (not the class registry id!) bbos.writeInt(parEntity.getEntityId()); // now write entity-specific custom fields // process herd animals if (parEntity instanceof EntityHerdAnimal) { EntityHerdAnimal entityHerdAnimal = (EntityHerdAnimal)parEntity; bbos.writeFloat(entityHerdAnimal.getScaleFactor()); bbos.writeBoolean(entityHerdAnimal.isRearing()); } // process serpents else if (parEntity instanceof EntitySerpent) { EntitySerpent entitySerpent = (EntitySerpent)parEntity; bbos.writeFloat(entitySerpent.getScaleFactor()); } // process big cats else if (parEntity instanceof EntityBigCat) { EntityBigCat entityBigCat = (EntityBigCat)parEntity; bbos.writeFloat(entityBigCat.getScaleFactor()); } // put payload into a packet FMLProxyPacket thePacket = new FMLProxyPacket(bbos.buffer(), WildAnimals.networkChannelName); // don't forget to close stream to avoid memory leak bbos.close(); return thePacket; } // ***************************************** // Client to Server Packet Creation // ***************************************** @SideOnly(Side.CLIENT) public static FMLProxyPacket createClientToServerTestPacket(EntityPlayer parPlayer, int parTestValue) throws IOException { if (parPlayer.getEntityWorld().isRemote) { // DEBUG System.out.println("Sending PacketWildAnimals on Client Side"); ByteBufOutputStream bbos = new ByteBufOutputStream(Unpooled.buffer()); // create payload by writing to data stream // first identity packet type bbos.writeInt(packetTypeIDC2STest); // write entity instance id (not the class registry id!) bbos.writeInt(parTestValue); // put payload into a packet FMLProxyPacket thePacket = new FMLProxyPacket(bbos.buffer(), WildAnimals.networkChannelName); // don't forget to close stream to avoid memory leak bbos.close(); return thePacket; } else { return null; } } // ***************************************** // Received By Client Packet Processing // ***************************************** @SideOnly(Side.CLIENT) public static void processPacketOnClient(ByteBuf parBB, Side parSide) throws IOException { if (parSide == Side.CLIENT) // packet received on client side { // DEBUG System.out.println("Received PacketWildAnimals on Client Side"); World theWorld = Minecraft.getMinecraft().theWorld; ByteBufInputStream bbis = new ByteBufInputStream(parBB); // process data stream // first read packet type int packetTypeID = bbis.readInt(); switch (packetTypeID) { case packetTypeIDEntity: // a packet sent from server to sync entity custom fields { // find entity instance int entityID = bbis.readInt(); // DEBUG System.out.println("Entity ID = "+entityID); Entity foundEntity = getEntityByID(entityID, theWorld); // DEBUG if (foundEntity != null) { System.out.println("Entity Class Name = "+foundEntity.getClass().getSimpleName()); } else { System.out.println("Entity Class Name = null"); } // process based on type of entity class // process herd animals if (foundEntity instanceof EntityHerdAnimal) { EntityHerdAnimal foundEntityHerdAnimal = (EntityHerdAnimal)foundEntity; // apply custom fields to entity instance foundEntityHerdAnimal.setScaleFactor(bbis.readFloat()); foundEntityHerdAnimal.setRearing(bbis.readBoolean()); // DEBUG System.out.println("Is rearing = "+foundEntityHerdAnimal.isRearing()); } // process serpents else if (foundEntity instanceof EntitySerpent) { EntitySerpent foundEntitySerpent = (EntitySerpent)foundEntity; // apply custom fields to entity instance foundEntitySerpent.setScaleFactor(bbis.readFloat()); } // process big cats else if (foundEntity instanceof EntityBigCat) { EntityBigCat foundEntityBigCat = (EntityBigCat)foundEntity; // apply custom fields to entity instance foundEntityBigCat.setScaleFactor(bbis.readFloat()); } break; } } // don't forget to close stream to avoid memory leak bbis.close(); } } // ***************************************** // Received By Server Packet Processing // ***************************************** @SideOnly(Side.SERVER) public static void processPacketOnServer(ByteBuf parBB, Side parSide, EntityPlayer parPlayer) throws IOException { if (parSide == Side.SERVER) // packet received on server side { // DEBUG System.out.println("Received PacketWildAnimals on Server Side from Player = "+parPlayer.getEntityId()); ByteBufInputStream bbis = new ByteBufInputStream(parBB); // process data stream // first read packet type int packetTypeID = bbis.readInt(); // DEBUG System.out.println("Packet type ID = "+packetTypeID); switch (packetTypeID) { case packetTypeIDC2STest: { // DEBUG System.out.println("Test packet received"); int testVal = bbis.readInt(); // DEBUG System.out.println("Test payload value = "+testVal); break ; } } // don't forget to close stream to avoid memory leak bbis.close(); } } // some helper functions public static Entity getEntityByID(int entityID, World world) { for(Object o: world.getLoadedEntityList()) { if(((Entity)o).getEntityId() == entityID) { System.out.println("Found the entity"); return ((Entity)o); } } return null; } } Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
jabelar Posted May 12, 2014 Author Posted May 12, 2014 Actually I understand it now. I guess that Java is going to process any imports needed for any methods in the class, whether or not they might actually be called during execution. So the import of the World class was causing trouble. I thought Java would only look at the import if it needed it (i.e. when method was called) during execution, but it actually makes more sense that it would look at it in advance so it would be able to execute the method if called. I still think the error report should indicate the actual error (i.e. the import line in the PacketWildAnimals class) rather than the line that calls the class. Definitely solved. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
Recommended Posts
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.