diff --git a/src/main/java/cpw/mods/fml/common/network/ByteBufUtils.java b/src/main/java/cpw/mods/fml/common/network/ByteBufUtils.java index 3e32bc9999..0716cc56db 100644 --- a/src/main/java/cpw/mods/fml/common/network/ByteBufUtils.java +++ b/src/main/java/cpw/mods/fml/common/network/ByteBufUtils.java @@ -1,16 +1,39 @@ package cpw.mods.fml.common.network; +import java.io.IOException; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import org.apache.commons.lang3.Validate; import com.google.common.base.Charsets; +import com.google.common.base.Throwables; import io.netty.buffer.ByteBuf; +/** + * Utilities for interacting with {@link ByteBuf}. + * @author cpw + * + */ public class ByteBufUtils { + /** + * The number of bytes to write the supplied int using the 7 bit varint encoding. + * + * @param toCount The number to analyse + * @return The number of bytes it will take to write it (maximum of 5) + */ public static int varIntByteCount(int toCount) { - return (toCount & -128) == 0 ? 1 : ((toCount & -16384) == 0 ? 2 : ((toCount & -2097152) == 0 ? 3 : ((toCount & -268435456) == 0 ? 4 : 5))); + return (toCount & 0xFFFFFF80) == 0 ? 1 : ((toCount & 0xFFFFC000) == 0 ? 2 : ((toCount & 0xFFE00000) == 0 ? 3 : ((toCount & 0xF0000000) == 0 ? 4 : 5))); } + /** + * Read a varint from the supplied buffer. + * + * @param buf The buffer to read from + * @param maxSize The maximum length of bytes to read + * @return The integer + */ public static int readVarInt(ByteBuf buf, int maxSize) { Validate.isTrue(maxSize < 6 && maxSize > 0, "Varint length is between 1 and 5, not %d", maxSize); @@ -33,9 +56,17 @@ public class ByteBufUtils { return i; } + /** + * Write an integer to the buffer using variable length encoding. The maxSize constrains + * how many bytes (and therefore the maximum number) that will be written. + * + * @param to The buffer to write to + * @param toWrite The integer to write + * @param maxSize The maximum number of bytes to use + */ public static void writeVarInt(ByteBuf to, int toWrite, int maxSize) { - Validate.isTrue(varIntByteCount(toWrite) < maxSize, "Integer is too big for %d bytes", maxSize); + Validate.isTrue(varIntByteCount(toWrite) <= maxSize, "Integer is too big for %d bytes", maxSize); while ((toWrite & -128) != 0) { to.writeByte(toWrite & 127 | 128); @@ -44,6 +75,13 @@ public class ByteBufUtils { to.writeByte(toWrite); } + /** + * Read a UTF8 string from the byte buffer. + * It is encoded as [] + * + * @param from The buffer to read from + * @return The string + */ public static String readUTF8String(ByteBuf from) { int len = readVarInt(from,2); @@ -52,6 +90,12 @@ public class ByteBufUtils { return str; } + /** + * Write a String with UTF8 byte encoding to the buffer. + * It is encoded as [] + * @param to the buffer to write to + * @param string The string to write + */ public static void writeUTF8String(ByteBuf to, String string) { byte[] utf8Bytes = string.getBytes(Charsets.UTF_8); @@ -59,4 +103,80 @@ public class ByteBufUtils { writeVarInt(to, utf8Bytes.length, 2); to.writeBytes(utf8Bytes); } + + /** + * Write an {@link ItemStack} using minecraft compatible encoding. + * + * @param to The buffer to write to + * @param stack The itemstack to write + */ + public static void writeItemStack(ByteBuf to, ItemStack stack) + { + PacketBuffer pb = new PacketBuffer(to); + try + { + pb.func_150788_a(stack); + } catch (IOException e) + { + // Unpossible? + throw Throwables.propagate(e); + } + } + + /** + * Read an {@link ItemStack} from the byte buffer provided. It uses the minecraft encoding. + * + * @param from The buffer to read from + * @return The itemstack read + */ + public static ItemStack readItemStack(ByteBuf from) + { + PacketBuffer pb = new PacketBuffer(from); + try + { + return pb.func_150791_c(); + } catch (IOException e) + { + // Unpossible? + throw Throwables.propagate(e); + } + } + + /** + * Write an {@link NBTTagCompound} to the byte buffer. It uses the minecraft encoding. + * + * @param to The buffer to write to + * @param tag The tag to write + */ + public static void writeTag(ByteBuf to, NBTTagCompound tag) + { + PacketBuffer pb = new PacketBuffer(to); + try + { + pb.func_150786_a(tag); + } catch (IOException e) + { + // Unpossible? + throw Throwables.propagate(e); + } + } + + /** + * Read an {@link NBTTagCompound} from the byte buffer. It uses the minecraft encoding. + * + * @param from The buffer to read from + * @return The read tag + */ + public static NBTTagCompound readTag(ByteBuf from) + { + PacketBuffer pb = new PacketBuffer(from); + try + { + return pb.func_150793_b(); + } catch (IOException e) + { + // Unpossible? + throw Throwables.propagate(e); + } + } } diff --git a/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java b/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java index 8facac2e12..7d8b6c64ff 100644 --- a/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java +++ b/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java @@ -39,6 +39,7 @@ import cpw.mods.fml.common.discovery.ASMDataTable; import cpw.mods.fml.common.network.handshake.NetworkDispatcher; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.common.network.internal.NetworkModHolder; +import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; /** @@ -69,7 +70,21 @@ public enum NetworkRegistry channels.put(Side.SERVER, Maps.newConcurrentMap()); } + /** + * Represents a target point for the ALLROUNDPOINT target. + * + * @author cpw + * + */ public static class TargetPoint { + /** + * A target point + * @param dimension The dimension to target + * @param x The X coordinate + * @param y The Y coordinate + * @param z The Z coordinate + * @param range The range + */ public TargetPoint(int dimension, double x, double y, double z, double range) { this.x = x; @@ -86,6 +101,16 @@ public enum NetworkRegistry } /** * Create a new synchronous message channel pair based on netty. + * + * There are two preconstructed models available: + *
    + *
  • {@link #newSimpleChannel(String)} provides {@link SimpleNetworkWrapper}, a simple implementation of a netty handler, suitable for those who don't + * wish to dive too deeply into netty. + *
  • {@link #newEventChannel(String)} provides {@link FMLEventChannel} an event driven implementation, with lower level + * access to the network data stream, for those with advanced bitbanging needs that don't wish to poke netty too hard. + *
  • Alternatively, simply use the netty features provided here and implement the full power of the netty stack. + *
+ * * There are two channels created : one for each logical side (considered as the source of an outbound message) * The returned map will contain a value for each logical side, though both will only be working in the * integrated server case. @@ -127,6 +152,22 @@ public enum NetworkRegistry return result; } + /** + * Construct a new {@link SimpleNetworkWrapper} for the channel. + * + * @param name The name of the channel + * @return A {@link SimpleNetworkWrapper} for handling this channel + */ + public SimpleNetworkWrapper newSimpleChannel(String name) + { + return new SimpleNetworkWrapper(name); + } + /** + * Construct a new {@link FMLEventChannel} for the channel. + * + * @param name The name of the channel + * @return An {@link FMLEventChannel} for handling this channel + */ public FMLEventChannel newEventDrivenChannel(String name) { return new FMLEventChannel(name); diff --git a/src/test/java/cpw/mods/fml/test/TestModSorting.java b/src/test/java/cpw/mods/fml/test/TestModSorting.java deleted file mode 100644 index 038f0899c4..0000000000 --- a/src/test/java/cpw/mods/fml/test/TestModSorting.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * The FML Forge Mod Loader suite. - * Copyright (C) 2012 cpw - * - * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -package cpw.mods.fml.test; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import static org.junit.Assert.*; -import static org.hamcrest.CoreMatchers.*; - -import cpw.mods.fml.common.FMLModContainer; -import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.toposort.ModSorter; - -/* -2012-06-09 00:21:06 [FINE] mod_CodeChickenCore: CodeChickenCore-Server 0.5.2.zip (before:*) -2012-06-09 00:21:06 [FINE] mod_IC2: industrialcraft-2-server_1.95b.jar () -2012-06-09 00:21:06 [FINE] mod_IC2AdvancedMachines: AdvancedMachines_4.1_server.zip (after:mod_IC2) -2012-06-09 00:21:06 [FINE] mod_EE: EE2ServerV1.4.6.0.jar () -2012-06-09 00:21:06 [FINE] mod_EnderStorage: EnderStorage-Server 1.1.1.zip () -2012-06-09 00:21:06 [FINE] mod_IC2NuclearControl: IC2NuclearControl_server_v1.1.8.zip () -2012-06-09 00:21:06 [FINE] mod_InventoryStocker: InventoryStocker-1.2.5.b43-server.zip () -2012-06-09 00:21:06 [FINE] mod_NotEnoughItems: NotEnoughItems-Server 1.2.2.3.zip () -2012-06-09 00:21:06 [FINE] mod_Railcraft: Railcraft_Server_5.3.2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerControl: RedPowerControl-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerCore: RedPowerCore-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerLighting: RedPowerLighting-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerLogic: RedPowerLogic-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerMachine: RedPowerMachine-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerWiring: RedPowerWiring-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_RedPowerWorld: RedPowerWorld-Server-2.0pr5b2.zip () -2012-06-09 00:21:06 [FINE] mod_Transformers: TransformersServer v1.2.zip (required-after:mod_IC2;required-after:mod_BuildCraftBuilders;required-after:mod_BuildCraftCore;required-after:mod_BuildCraftEnergy;required-after:mod_BuildCraftFactory;required-after:mod_BuildCraftTransport) -2012-06-09 00:21:06 [FINE] mod_WirelessRedstoneCore: WR-CBE Core-Server 1.2.2.zip () -2012-06-09 00:21:06 [FINE] mod_WirelessRedstoneRedPower: WR-CBE RedPower-Server 1.2.2.zip (after:mod_WirelessRedstoneCore) -2012-06-09 00:21:06 [FINE] mod_BuildCraftCore: buildcraft-server-A-core-2.2.14.zip () -2012-06-09 00:21:06 [FINE] mod_BuildCraftBuilders: buildcraft-server-B-builders-2.2.14.zip () -2012-06-09 00:21:06 [FINE] mod_BuildCraftEnergy: buildcraft-server-B-energy-2.2.14.zip () -2012-06-09 00:21:06 [FINE] mod_BuildCraftFactory: buildcraft-server-B-factory-2.2.14.zip () -2012-06-09 00:21:06 [FINE] mod_BuildCraftTransport: buildcraft-server-B-transport-2.2.14.zip () -2012-06-09 00:21:06 [FINE] mod_AdditionalPipes: buildcraft-server-DA-additionalpipes-2.1.3.zip (after:mod_BuildCraftTransport) -2012-06-09 00:21:06 [FINE] mod_Forestry: forestry-server-A-1.4.6.2_bc2.2.jar (after:mod_IC2;after:mod_BuildCraftCore;after:mod_BuildCraftEnergy;after:mod_BuildCraftFactory;after:mod_BuildCraftSilicon;after:mod_BuildCraftTransport) -2012-06-09 00:21:06 [FINE] mod_LoginMessage: mod_LoginMessage-125-FML.zip () -2012-06-09 00:21:06 [FINE] mod_CompactSolars: mod_compactsolars-server-2.3.2.10.zip (after:mod_IC2) -2012-06-09 00:21:06 [FINE] mod_SeedManager: SeedManager-2.0-server.zip (required-after:mod_IC2;after:*) - */ - -public class TestModSorting { - private List mods = new ArrayList(); - - @Before - public void setUp() throws Exception { - TestModContainer mc = null; - mc = new TestModContainer("mod_IC2AdvancedMachines"); - mc.setPreDepends("mod_IC2"); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_CodeChickenCore"); - mc.setPreDepends(); - mc.setPostDepends("*"); - mods.add(mc); - - mc = new TestModContainer("mod_EE"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_EnderStorage"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_IC2NuclearControl"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_InventoryStocker"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_NotEnoughItems"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_Railcraft"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerControl"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerCore"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerLighting"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerLogic"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerMachine"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerWiring"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_RedPowerWorld"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_SeedManager"); - mc.setPreDepends("mod_IC2","*"); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_Transformers"); - mc.setPreDepends("mod_IC2","mod_BuildCraftBuilders","mod_BuildCraftCore","mod_BuildCraftEnergy","mod_BuildCraftFactory","mod_BuildCraftTransport"); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_WirelessRedstoneCore"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_WirelessRedstoneRedPower"); - mc.setPreDepends("mod_WirelessRedstoneCore"); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_BuildCraftCore"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_BuildCraftBuilders"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_BuildCraftEnergy"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_BuildCraftFactory"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_BuildCraftTransport"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_AdditionalPipes"); - mc.setPreDepends("mod_BuildCraftTransport"); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_Forestry"); - mc.setPreDepends("mod_IC2","mod_BuildCraftCore","mod_BuildCraftEnergy","mod_BuildCraftFactory","mod_BuildCraftSilicon","mod_BuildCraftTransport"); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_IC2"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_LoginMessage"); - mc.setPreDepends(); - mc.setPostDepends(); - mods.add(mc); - - mc = new TestModContainer("mod_CompactSolars"); - mc.setPreDepends("mod_IC2"); - mc.setPostDepends(); - mods.add(mc); - -// mc = new TestModContainer(""); -// mc.setPreDepends(); -// mc.setPostDepends(); -// mods.add(mc); -// - - Collections.shuffle(mods); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testModSorting() { - HashMap modList=new HashMap(); - List mods = new ArrayList(this.mods); - - for (ModContainer m : mods) { - modList.put(m.getName(), m); - } - - ModSorter ms=new ModSorter(mods,modList); - List sortedMods=ms.sort(); - assertEquals("29 mods",29,sortedMods.size()); - - assertEquals("Chicken Core is at index zero", sortedMods.indexOf(modList.get("mod_CodeChickenCore")),0); - ModContainer forestry=modList.get("mod_Forestry"); - ModContainer ic2=modList.get("mod_IC2"); - ModContainer bccore=modList.get("mod_BuildCraftCore"); - ModContainer bcener=modList.get("mod_BuildCraftEnergy"); - ModContainer bcfact=modList.get("mod_BuildCraftFactory"); - ModContainer bcbuild=modList.get("mod_BuildCraftBuilders"); - ModContainer bctrans=modList.get("mod_BuildCraftTransport"); - ModContainer tfrmrs=modList.get("mod_Transformers"); - assertTrue("Forestry is after IC2", sortedMods.indexOf(forestry)>sortedMods.indexOf(ic2)); - assertTrue("Forestry is after BC core", sortedMods.indexOf(forestry)>sortedMods.indexOf(bccore)); - assertTrue("Forestry is after BC energy", sortedMods.indexOf(forestry)>sortedMods.indexOf(bcener)); - assertTrue("Forestry is after BC factory", sortedMods.indexOf(forestry)>sortedMods.indexOf(bcfact)); - assertTrue("Forestry is after BC trans", sortedMods.indexOf(forestry)>sortedMods.indexOf(bctrans)); - assertTrue("Transformers is after IC2", sortedMods.indexOf(tfrmrs)>sortedMods.indexOf(ic2)); - assertTrue("Transformers is after BC core", sortedMods.indexOf(tfrmrs)>sortedMods.indexOf(bccore)); - assertTrue("Transformers is after BC ener", sortedMods.indexOf(tfrmrs)>sortedMods.indexOf(bcener)); - assertTrue("Transformers is after BC fact", sortedMods.indexOf(tfrmrs)>sortedMods.indexOf(bcfact)); - assertTrue("Transformers is after BC build", sortedMods.indexOf(tfrmrs)>sortedMods.indexOf(bcbuild)); - assertTrue("Transformers is after BC trans", sortedMods.indexOf(tfrmrs)>sortedMods.indexOf(bctrans)); - assertTrue("AdvMach is after IC2", sortedMods.indexOf(modList.get("mod_IC2AdvancedMachines"))>sortedMods.indexOf(ic2)); - assertTrue("CompactSolars is after IC2", sortedMods.indexOf(modList.get("mod_CompactSolars"))>sortedMods.indexOf(ic2)); - assertTrue("WR RP is after WR core", sortedMods.indexOf(modList.get("mod_WirelessRedstoneRedPower"))>sortedMods.indexOf(modList.get("mod_WirelessRedstoneCore"))); - assertTrue("AdditionalPipes is after BC trans", sortedMods.indexOf(modList.get("mod_AdditionalPipes"))>sortedMods.indexOf(bctrans)); - assertTrue("SeedManager is after IC2", sortedMods.indexOf(modList.get("mod_SeedManager"))>sortedMods.indexOf(ic2)); - assertEquals("SeedManager is at the end", 28, sortedMods.indexOf(modList.get("mod_SeedManager"))); - - sortedMods.remove(modList.get("mod_CodeChickenCore")); - mods.remove(modList.get("mod_CodeChickenCore")); - sortedMods.remove(ic2); - mods.remove(ic2); - sortedMods.remove(forestry); - mods.remove(forestry); - sortedMods.remove(bccore); - mods.remove(bccore); - sortedMods.remove(bcbuild); - mods.remove(bcbuild); - sortedMods.remove(bcener); - mods.remove(bcener); - sortedMods.remove(bcfact); - mods.remove(bcfact); - sortedMods.remove(bctrans); - mods.remove(bctrans); - sortedMods.remove(tfrmrs); - mods.remove(tfrmrs); - sortedMods.remove(modList.get("mod_IC2AdvancedMachines")); - mods.remove(modList.get("mod_IC2AdvancedMachines")); - sortedMods.remove(modList.get("mod_SeedManager")); - mods.remove(modList.get("mod_SeedManager")); - sortedMods.remove(modList.get("mod_AdditionalPipes")); - mods.remove(modList.get("mod_AdditionalPipes")); - sortedMods.remove(modList.get("mod_WirelessRedstoneCore")); - mods.remove(modList.get("mod_WirelessRedstoneCore")); - sortedMods.remove(modList.get("mod_WirelessRedstoneRedPower")); - mods.remove(modList.get("mod_WirelessRedstoneRedPower")); - sortedMods.remove(modList.get("mod_CompactSolars")); - mods.remove(modList.get("mod_CompactSolars")); - assertArrayEquals("Sort is stable", mods.toArray(),sortedMods.toArray()); - } - - public class TestModContainer extends FMLModContainer { - private List preDeps; - private List postDeps; - private String name; - - public TestModContainer(String name) { - super((File)null); - this.name = name; - } - - public void setPreDepends(String ... pre) { - preDeps = Arrays.asList(pre); - } - - public void setPostDepends(String ... post) { - postDeps = Arrays.asList(post); - } - - @Override - public List getPreDepends() { - return preDeps; - } - - @Override - public List getPostDepends() { - return postDeps; - } - - @Override - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - } -}