From 38cec7a11fae7cf12bda3a8d16a50bb6136d8886 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 4 Dec 2013 00:11:08 -0500 Subject: [PATCH] The basic network handshaking for FML is done. All scenarios seem to work. --- .../cpw/mods/fml/common/ModContainer.java | 3 + .../fml/common/network/FMLNetworkHandler.java | 16 +- .../network/FMLPacketHandlerFactory.java | 27 ++ .../mods/fml/common/network/IGuiHandler.java | 42 +- .../common/network/ITinyPacketHandler.java | 20 - .../fml/common/network/NetworkDispatcher.java | 249 +++++++++++- .../fml/common/network/NetworkModHandler.java | 370 ------------------ .../fml/common/network/NetworkModHolder.java | 171 ++++++++ .../fml/common/network/NetworkRegistry.java | 73 +--- .../fml/common/network/PacketDispatcher.java | 2 +- .../packet/EntitySpawnAdjustmentPacket.java | 4 +- .../network/packet/EntitySpawnPacket.java | 10 +- .../fml/common/network/packet/FMLPacket.java | 48 +-- .../common/network/packet/ModIdMapPacket.java | 4 +- .../network/packet/ModIdentifiersPacket.java | 10 +- .../network/packet/ModListRequestPacket.java | 8 +- .../network/packet/ModListResponsePacket.java | 10 +- .../network/packet/ModMissingPacket.java | 4 +- .../common/network/packet/OpenGuiHandler.java | 18 + .../common/network/packet/OpenGuiPacket.java | 36 +- .../common/network/packet/PacketManager.java | 72 ++++ .../fml/common/registry/LanguageRegistry.java | 2 +- .../fml/common/registry/VillagerRegistry.java | 2 +- .../cpw/mods/fml/server/FMLServerHandler.java | 32 -- src/main/resources/fml_at.cfg | 4 +- 25 files changed, 625 insertions(+), 612 deletions(-) create mode 100644 src/main/java/cpw/mods/fml/common/network/FMLPacketHandlerFactory.java delete mode 100644 src/main/java/cpw/mods/fml/common/network/ITinyPacketHandler.java delete mode 100644 src/main/java/cpw/mods/fml/common/network/NetworkModHandler.java create mode 100644 src/main/java/cpw/mods/fml/common/network/NetworkModHolder.java create mode 100644 src/main/java/cpw/mods/fml/common/network/packet/OpenGuiHandler.java create mode 100644 src/main/java/cpw/mods/fml/common/network/packet/PacketManager.java diff --git a/src/main/java/cpw/mods/fml/common/ModContainer.java b/src/main/java/cpw/mods/fml/common/ModContainer.java index eaeb9c5834..c92de9f75a 100644 --- a/src/main/java/cpw/mods/fml/common/ModContainer.java +++ b/src/main/java/cpw/mods/fml/common/ModContainer.java @@ -21,6 +21,7 @@ import java.util.Set; import com.google.common.collect.ImmutableMap; import com.google.common.eventbus.EventBus; +import cpw.mods.fml.common.network.NetworkModHolder; import cpw.mods.fml.common.versioning.ArtifactVersion; import cpw.mods.fml.common.versioning.VersionRange; @@ -140,4 +141,6 @@ public interface ModContainer public Class getCustomResourcePackClass(); Map getSharedModDescriptor(); + + NetworkModHolder getNetworkModHolder(); } diff --git a/src/main/java/cpw/mods/fml/common/network/FMLNetworkHandler.java b/src/main/java/cpw/mods/fml/common/network/FMLNetworkHandler.java index ae177737d2..c7127b7b32 100644 --- a/src/main/java/cpw/mods/fml/common/network/FMLNetworkHandler.java +++ b/src/main/java/cpw/mods/fml/common/network/FMLNetworkHandler.java @@ -15,6 +15,7 @@ package cpw.mods.fml.common.network; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.EnumConnectionState; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; @@ -406,16 +407,20 @@ public class FMLNetworkHandler } } */ - public static void fmlHandshake(ServerConfigurationManager scm, NetworkManager manager, EntityPlayerMP player) + public static void fmlServerHandshake(ServerConfigurationManager scm, NetworkManager manager, EntityPlayerMP player) { - NetHandlerPlayServer nethandler = new NetHandlerPlayServer(scm.func_72365_p(), manager, player); - player.field_71135_a = null; - scm.func_72355_a(manager, player, nethandler); + NetworkDispatcher dispatcher = NetworkDispatcher.allocAndSet(manager, scm); + dispatcher.serverToClientHandshake(player); + } + + public static void fmlClientHandshake(NetworkManager field_147393_d) + { + NetworkDispatcher dispatcher = NetworkDispatcher.allocAndSet(field_147393_d); + dispatcher.clientToServerHandshake(); } public static void openGui(EntityPlayer entityPlayer, Object mod, int modGuiId, World world, int x, int y, int z) { - // TODO Auto-generated method stub } @@ -430,4 +435,5 @@ public class FMLNetworkHandler // TODO Auto-generated method stub return null; } + } diff --git a/src/main/java/cpw/mods/fml/common/network/FMLPacketHandlerFactory.java b/src/main/java/cpw/mods/fml/common/network/FMLPacketHandlerFactory.java new file mode 100644 index 0000000000..09c4433cb6 --- /dev/null +++ b/src/main/java/cpw/mods/fml/common/network/FMLPacketHandlerFactory.java @@ -0,0 +1,27 @@ +package cpw.mods.fml.common.network; + +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetworkManager; + +public class FMLPacketHandlerFactory implements IPacketHandlerFactory { + private static final String[] CHANNEL = new String[] { "FML" }; + @Override + public String[] channels() + { + return CHANNEL; + } + + @Override + public IClientSidePacketHandler makeClientPacketHandler(NetworkMod mod, NetworkManager manager, INetHandler clientPlayHandler, String channel) + { + return null; + } + + @Override + public IServerSidePacketHandler makeServerPacketHandler(NetworkMod mod, NetworkManager manager, INetHandler serverPlayHandler) + { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/main/java/cpw/mods/fml/common/network/IGuiHandler.java b/src/main/java/cpw/mods/fml/common/network/IGuiHandler.java index 444f163792..7214563cca 100644 --- a/src/main/java/cpw/mods/fml/common/network/IGuiHandler.java +++ b/src/main/java/cpw/mods/fml/common/network/IGuiHandler.java @@ -5,7 +5,7 @@ * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * + * * Contributors: * cpw - implementation */ @@ -19,19 +19,13 @@ public interface IGuiHandler { /** * Returns a Server side Container to be displayed to the user. - * - * @param ID - * The Gui ID Number - * @param player - * The player viewing the Gui - * @param world - * The current world - * @param x - * X Position - * @param y - * Y Position - * @param z - * Z Position + * + * @param ID The Gui ID Number + * @param player The player viewing the Gui + * @param world The current world + * @param x X Position + * @param y Y Position + * @param z Z Position * @return A GuiScreen/Container to be displayed to the user, null if none. */ public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z); @@ -39,19 +33,13 @@ public interface IGuiHandler * Returns a Container to be displayed to the user. On the client side, this * needs to return a instance of GuiScreen On the server side, this needs to * return a instance of Container - * - * @param ID - * The Gui ID Number - * @param player - * The player viewing the Gui - * @param world - * The current world - * @param x - * X Position - * @param y - * Y Position - * @param z - * Z Position + * + * @param ID The Gui ID Number + * @param player The player viewing the Gui + * @param world The current world + * @param x X Position + * @param y Y Position + * @param z Z Position * @return A GuiScreen/Container to be displayed to the user, null if none. */ public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z); diff --git a/src/main/java/cpw/mods/fml/common/network/ITinyPacketHandler.java b/src/main/java/cpw/mods/fml/common/network/ITinyPacketHandler.java deleted file mode 100644 index 163c0dbe22..0000000000 --- a/src/main/java/cpw/mods/fml/common/network/ITinyPacketHandler.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Forge Mod Loader - * Copyright (c) 2012-2013 cpw. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v2.1 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * Contributors: - * cpw - implementation - */ - -package cpw.mods.fml.common.network; - -import net.minecraft.network.packet.*; - -public interface ITinyPacketHandler -{ - void handle(NetHandler handler, Packet131MapData mapData); -} diff --git a/src/main/java/cpw/mods/fml/common/network/NetworkDispatcher.java b/src/main/java/cpw/mods/fml/common/network/NetworkDispatcher.java index 9378e86e58..91d5d6f313 100644 --- a/src/main/java/cpw/mods/fml/common/network/NetworkDispatcher.java +++ b/src/main/java/cpw/mods/fml/common/network/NetworkDispatcher.java @@ -1,16 +1,259 @@ package cpw.mods.fml.common.network; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import sun.net.ProgressSource.State; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.AttributeKey; +import io.netty.util.ReferenceCountUtil; +import io.netty.util.concurrent.ScheduledFuture; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.EnumConnectionState; +import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.client.C17PacketCustomPayload; +import net.minecraft.network.play.server.S3FPacketCustomPayload; +import net.minecraft.server.management.ServerConfigurationManager; import com.google.common.collect.ListMultimap; -public class NetworkDispatcher { - private static final AttributeKey FML_DISPATCHER = new AttributeKey("fml:dispatcher"); - private static final AttributeKey> FML_PACKET_HANDLERS = new AttributeKey>("fml:packet_handlers"); +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.network.packet.PacketManager; +import cpw.mods.fml.relauncher.Side; + +public class NetworkDispatcher extends SimpleChannelInboundHandler { + private static enum ConnectionState { + OPENING, AWAITING_HANDSHAKE, HANDSHAKING, CONNECTED; + } + + private static enum ConnectionType { + MODDED, BUKKIT, VANILLA; + } public static NetworkDispatcher get(NetworkManager manager) { return manager.channel().attr(FML_DISPATCHER).get(); } + + public static NetworkDispatcher allocAndSet(NetworkManager manager) + { + NetworkDispatcher net = new NetworkDispatcher(manager); + manager.channel().attr(FML_DISPATCHER).getAndSet(net); + return net; + } + + public static NetworkDispatcher allocAndSet(NetworkManager manager, ServerConfigurationManager scm) + { + NetworkDispatcher net = new NetworkDispatcher(manager, scm); + manager.channel().attr(FML_DISPATCHER).getAndSet(net); + return net; + } + + private static final AttributeKey FML_DISPATCHER = new AttributeKey("fml:dispatcher"); + private static final AttributeKey> FML_PACKET_HANDLERS = new AttributeKey>("fml:packet_handlers"); + private final NetworkManager manager; + private final ServerConfigurationManager scm; + private EntityPlayerMP player; + private ConnectionState state; + private ConnectionType connectionType; + private Side side; + + public NetworkDispatcher(NetworkManager manager) + { + super(Packet.class, false); + this.manager = manager; + this.scm = null; + this.side = Side.CLIENT; + } + + public NetworkDispatcher(NetworkManager manager, ServerConfigurationManager scm) + { + super(Packet.class, false); + this.manager = manager; + this.scm = scm; + this.side = Side.SERVER; + } + + public void serverToClientHandshake(EntityPlayerMP player) + { + this.player = player; + insertIntoChannel(); + } + + private void insertIntoChannel() + { + this.manager.channel().config().setAutoRead(false); + // Insert ourselves into the pipeline + this.manager.channel().pipeline().addBefore("packet_handler", "fml:packet_handler", this); + } + + public void clientToServerHandshake() + { + insertIntoChannel(); + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception + { + this.state = ConnectionState.OPENING; + if (side == Side.CLIENT) + { + clientListenForServerHandshake(); + } + else + { + serverInitiateHandshake(); + } + this.manager.channel().config().setAutoRead(true); + } + + private void serverInitiateHandshake() + { + // Send mod salutation to the client + // This will be ignored by vanilla clients + this.state = ConnectionState.AWAITING_HANDSHAKE; + this.manager.channel().pipeline().addFirst("fml:vanilla_detector", new VanillaTimeoutWaiter()); + this.manager.func_150725_a(new S3FPacketCustomPayload("FML", new byte[0])); + } + + private void clientListenForServerHandshake() + { + manager.func_150723_a(EnumConnectionState.PLAY); + this.state = ConnectionState.AWAITING_HANDSHAKE; + } + + private void continueToClientPlayState() + { + this.state = ConnectionState.CONNECTED; + this.connectionType = ConnectionType.MODDED; + completeClientSideConnection(); + // Send modded ack to server + this.manager.func_150725_a(new C17PacketCustomPayload("FML", new byte[0])); + } + + private void completeClientSideConnection() + { + } + + private void continueToServerPlayState() + { + this.state = ConnectionState.CONNECTED; + this.connectionType = ConnectionType.MODDED; + completeServerSideConnection(); + } + + private void completeServerSideConnection() + { + NetHandlerPlayServer nethandler = new NetHandlerPlayServer(scm.func_72365_p(), manager, player); + // NULL the play server here - we restore it further on. If not, there are packets sent before the login + player.field_71135_a = null; + scm.func_72355_a(manager, player, nethandler); + } + @Override + protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception + { + boolean handled = false; + if (msg instanceof C17PacketCustomPayload) + { + handled = handleServerSideCustomPacket((C17PacketCustomPayload) msg); + } + else if (msg instanceof S3FPacketCustomPayload) + { + handled = handleClientSideCustomPacket((S3FPacketCustomPayload)msg); + } + else if (state != ConnectionState.CONNECTED) + { + FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla"); + handleVanillaConnection(); + } + if (!handled) + { + ctx.fireChannelRead(msg); + } + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception + { + if (evt instanceof ConnectionType && side == Side.SERVER) + { + FMLLog.info("Timeout occurred, assuming a vanilla client"); + handleVanillaConnection(); + } + } + + private void handleVanillaConnection() + { + state = ConnectionState.CONNECTED; + connectionType = ConnectionType.VANILLA; + if (side == Side.CLIENT) + { + completeClientSideConnection(); + } + else + { + completeServerSideConnection(); + } + } + + private boolean handleClientSideCustomPacket(S3FPacketCustomPayload msg) + { + if ("FML".equals(msg.func_149169_c())) + { + continueToClientPlayState(); + FMLLog.info("Client side modded connection established"); + return true; + } + return false; + } + + private boolean handleServerSideCustomPacket(C17PacketCustomPayload msg) + { + if (state == ConnectionState.AWAITING_HANDSHAKE) + { + this.manager.channel().pipeline().remove("fml:vanilla_detector"); + state = ConnectionState.HANDSHAKING; + } + if ("FML".equals(msg.func_149559_c())) + { + FMLLog.info("Server side modded connection established"); + continueToServerPlayState(); + return true; + } + return false; + } + + private class VanillaTimeoutWaiter extends ChannelInboundHandlerAdapter + { + private ScheduledFuture future; + + @Override + public void handlerAdded(final ChannelHandlerContext ctx) throws Exception + { + future = ctx.executor().schedule(new Callable() { + @Override + public Void call() throws Exception + { + if (state != ConnectionState.CONNECTED) + { + FMLLog.info("Timeout occurred waiting for response, assuming vanilla connection"); + ctx.fireUserEventTriggered(ConnectionType.VANILLA); + } + return null; + } + }, 10, TimeUnit.SECONDS); + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception + { + future.cancel(true); + } + } } diff --git a/src/main/java/cpw/mods/fml/common/network/NetworkModHandler.java b/src/main/java/cpw/mods/fml/common/network/NetworkModHandler.java deleted file mode 100644 index c184a9efc1..0000000000 --- a/src/main/java/cpw/mods/fml/common/network/NetworkModHandler.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Forge Mod Loader - * Copyright (c) 2012-2013 cpw. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v2.1 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * Contributors: - * cpw - implementation - */ - -package cpw.mods.fml.common.network; - -import java.lang.reflect.Method; -import java.util.Set; -import java.util.logging.Level; - -import net.minecraft.item.Item; - -import com.google.common.base.Strings; - -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.FMLLog; -import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.discovery.ASMDataTable; -import cpw.mods.fml.common.discovery.ASMDataTable.ASMData; -import cpw.mods.fml.common.versioning.DefaultArtifactVersion; -import cpw.mods.fml.common.versioning.InvalidVersionSpecificationException; -import cpw.mods.fml.common.versioning.VersionRange; -import cpw.mods.fml.relauncher.Side; - -public class NetworkModHandler -{ - private static Object connectionHandlerDefaultValue; - private static Object packetHandlerDefaultValue; - private static Object clientHandlerDefaultValue; - private static Object serverHandlerDefaultValue; - private static Object tinyPacketHandlerDefaultValue; - - private static int assignedIds = 1; - - private int localId; - private int networkId; - - private ModContainer container; - private NetworkMod mod; - private Method checkHandler; - - private VersionRange acceptableRange; - private ITinyPacketHandler tinyPacketHandler; - - public NetworkModHandler(ModContainer container, NetworkMod modAnnotation) - { - this.container = container; - this.mod = modAnnotation; - this.localId = assignedIds++; - this.networkId = this.localId; - // Skip over the map object because it has special network id meaning - if (Item.field_77744_bd.field_77779_bT == assignedIds) - { - assignedIds++; - } - } - public NetworkModHandler(ModContainer container, Class networkModClass, ASMDataTable table) - { - this(container, networkModClass.getAnnotation(NetworkMod.class)); - if (this.mod == null) - { - return; - } - - Set versionCheckHandlers = table.getAnnotationsFor(container).get(NetworkMod.VersionCheckHandler.class.getName()); - String versionCheckHandlerMethod = null; - for (ASMData vch : versionCheckHandlers) - { - if (vch.getClassName().equals(networkModClass.getName())) - { - versionCheckHandlerMethod = vch.getObjectName(); - versionCheckHandlerMethod = versionCheckHandlerMethod.substring(0,versionCheckHandlerMethod.indexOf('(')); - break; - } - } - if (versionCheckHandlerMethod != null) - { - try - { - Method checkHandlerMethod = networkModClass.getDeclaredMethod(versionCheckHandlerMethod, String.class); - if (checkHandlerMethod.isAnnotationPresent(NetworkMod.VersionCheckHandler.class)) - { - this.checkHandler = checkHandlerMethod; - } - } - catch (Exception e) - { - FMLLog.log(Level.WARNING, e, "The declared version check handler method %s on network mod id %s is not accessible", versionCheckHandlerMethod, container.getModId()); - } - } - - configureNetworkMod(container); - } - protected void configureNetworkMod(ModContainer container) - { - if (this.checkHandler == null) - { - String versionBounds = mod.versionBounds(); - if (!Strings.isNullOrEmpty(versionBounds)) - { - try - { - this.acceptableRange = VersionRange.createFromVersionSpec(versionBounds); - } - catch (InvalidVersionSpecificationException e) - { - FMLLog.log(Level.WARNING, e, "Invalid bounded range %s specified for network mod id %s", versionBounds, container.getModId()); - } - } - } - - FMLLog.finest("Testing mod %s to verify it accepts its own version in a remote connection", container.getModId()); - boolean acceptsSelf = acceptVersion(container.getVersion()); - if (!acceptsSelf) - { - FMLLog.severe("The mod %s appears to reject its own version number (%s) in its version handling. This is likely a severe bug in the mod!", container.getModId(), container.getVersion()); - } - else - { - FMLLog.finest("The mod %s accepts its own version (%s)", container.getModId(), container.getVersion()); - } - - tryCreatingPacketHandler(container, mod.packetHandler(), mod.channels(), null); - if (FMLCommonHandler.instance().getSide().isClient()) - { - if (mod.clientPacketHandlerSpec() != getClientHandlerSpecDefaultValue()) - { - tryCreatingPacketHandler(container, mod.clientPacketHandlerSpec().packetHandler(), mod.clientPacketHandlerSpec().channels(), Side.CLIENT); - } - } - if (mod.serverPacketHandlerSpec() != getServerHandlerSpecDefaultValue()) - { - tryCreatingPacketHandler(container, mod.serverPacketHandlerSpec().packetHandler(), mod.serverPacketHandlerSpec().channels(), Side.SERVER); - } - - if (mod.connectionHandler() != getConnectionHandlerDefaultValue()) - { - IConnectionHandler instance; - try - { - instance = mod.connectionHandler().newInstance(); - } - catch (Exception e) - { - FMLLog.log(Level.SEVERE, e, "Unable to create connection handler instance %s", mod.connectionHandler().getName()); - throw new FMLNetworkException(e); - } - - NetworkRegistry.instance().registerConnectionHandler(instance); - } - - if (mod.tinyPacketHandler()!=getTinyPacketHandlerDefaultValue()) - { - try - { - tinyPacketHandler = mod.tinyPacketHandler().newInstance(); - } - catch (Exception e) - { - FMLLog.log(Level.SEVERE, e, "Unable to create tiny packet handler instance %s", mod.tinyPacketHandler().getName()); - throw new FMLNetworkException(e); - } - } - } - /** - * @param container - */ - private void tryCreatingPacketHandler(ModContainer container, Class clazz, String[] channels, Side side) - { - if (side!=null && side.isClient() && ! FMLCommonHandler.instance().getSide().isClient()) - { - return; - } - if (clazz!=getPacketHandlerDefaultValue()) - { - if (channels.length==0) - { - FMLLog.log(Level.WARNING, "The mod id %s attempted to register a packet handler without specifying channels for it", container.getModId()); - } - else - { - IPacketHandler instance; - try - { - instance = clazz.newInstance(); - } - catch (Exception e) - { - FMLLog.log(Level.SEVERE, e, "Unable to create a packet handler instance %s for mod %s", clazz.getName(), container.getModId()); - throw new FMLNetworkException(e); - } - - for (String channel : channels) - { - NetworkRegistry.instance().registerChannel(instance, channel, side); - } - } - } - else if (channels.length > 0) - { - FMLLog.warning("The mod id %s attempted to register channels without specifying a packet handler", container.getModId()); - } - } - /** - * @return the default {@link NetworkMod#connectionHandler()} annotation value - */ - private Object getConnectionHandlerDefaultValue() - { - try { - if (connectionHandlerDefaultValue == null) - { - connectionHandlerDefaultValue = NetworkMod.class.getMethod("connectionHandler").getDefaultValue(); - } - return connectionHandlerDefaultValue; - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("Derp?", e); - } - } - - /** - * @return the default {@link NetworkMod#packetHandler()} annotation value - */ - private Object getPacketHandlerDefaultValue() - { - try { - if (packetHandlerDefaultValue == null) - { - packetHandlerDefaultValue = NetworkMod.class.getMethod("packetHandler").getDefaultValue(); - } - return packetHandlerDefaultValue; - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("Derp?", e); - } - } - - /** - * @return the default {@link NetworkMod#tinyPacketHandler()} annotation value - */ - private Object getTinyPacketHandlerDefaultValue() - { - try { - if (tinyPacketHandlerDefaultValue == null) - { - tinyPacketHandlerDefaultValue = NetworkMod.class.getMethod("tinyPacketHandler").getDefaultValue(); - } - return tinyPacketHandlerDefaultValue; - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("Derp?", e); - } - } - /** - * @return the {@link NetworkMod#clientPacketHandlerSpec()} default annotation value - */ - private Object getClientHandlerSpecDefaultValue() - { - try { - if (clientHandlerDefaultValue == null) - { - clientHandlerDefaultValue = NetworkMod.class.getMethod("clientPacketHandlerSpec").getDefaultValue(); - } - return clientHandlerDefaultValue; - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("Derp?", e); - } - } - /** - * @return the default {@link NetworkMod#serverPacketHandlerSpec()} annotation value - */ - private Object getServerHandlerSpecDefaultValue() - { - try { - if (serverHandlerDefaultValue == null) - { - serverHandlerDefaultValue = NetworkMod.class.getMethod("serverPacketHandlerSpec").getDefaultValue(); - } - return serverHandlerDefaultValue; - } - catch (NoSuchMethodException e) - { - throw new RuntimeException("Derp?", e); - } - } - public boolean requiresClientSide() - { - return mod.clientSideRequired(); - } - - public boolean requiresServerSide() - { - return mod.serverSideRequired(); - } - - public boolean acceptVersion(String version) - { - if (checkHandler != null) - { - try - { - return (Boolean)checkHandler.invoke(container.getMod(), version); - } - catch (Exception e) - { - FMLLog.log(Level.WARNING, e, "There was a problem invoking the checkhandler method %s for network mod id %s", checkHandler.getName(), container.getModId()); - return false; - } - } - - if (acceptableRange!=null) - { - return acceptableRange.containsVersion(new DefaultArtifactVersion(version)); - } - - return container.getVersion().equals(version); - } - - public int getLocalId() - { - return localId; - } - - public int getNetworkId() - { - return networkId; - } - - public ModContainer getContainer() - { - return container; - } - - public NetworkMod getMod() - { - return mod; - } - - public boolean isNetworkMod() - { - return mod != null; - } - - public void setNetworkId(int value) - { - this.networkId = value; - } - - public boolean hasTinyPacketHandler() - { - return tinyPacketHandler != null; - } - public ITinyPacketHandler getTinyPacketHandler() - { - return tinyPacketHandler; - } -} diff --git a/src/main/java/cpw/mods/fml/common/network/NetworkModHolder.java b/src/main/java/cpw/mods/fml/common/network/NetworkModHolder.java new file mode 100644 index 0000000000..b032dca1d2 --- /dev/null +++ b/src/main/java/cpw/mods/fml/common/network/NetworkModHolder.java @@ -0,0 +1,171 @@ +/* + * Forge Mod Loader + * Copyright (c) 2012-2013 cpw. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v2.1 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * + * Contributors: + * cpw - implementation + */ + +package cpw.mods.fml.common.network; + +import java.lang.reflect.Method; +import java.util.Set; +import java.util.logging.Level; + +import com.google.common.base.Strings; + +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.discovery.ASMDataTable; +import cpw.mods.fml.common.discovery.ASMDataTable.ASMData; +import cpw.mods.fml.common.versioning.DefaultArtifactVersion; +import cpw.mods.fml.common.versioning.InvalidVersionSpecificationException; +import cpw.mods.fml.common.versioning.VersionRange; + +public class NetworkModHolder +{ + private static int assignedIds = 1; + + private int localId; + private int networkId; + + private ModContainer container; + private NetworkMod mod; + private Method checkHandler; + + private VersionRange acceptableRange; + + private IPacketHandlerFactory packetHandlerFactory; + + public NetworkModHolder(ModContainer container, NetworkMod modAnnotation) + { + this.container = container; + this.mod = modAnnotation; + this.localId = assignedIds++; + this.networkId = this.localId; + } + public NetworkModHolder(ModContainer container, Class networkModClass, ASMDataTable table) + { + this(container, networkModClass.getAnnotation(NetworkMod.class)); + if (this.mod == null) + { + return; + } + + Set versionCheckHandlers = table.getAnnotationsFor(container).get(NetworkMod.VersionCheckHandler.class.getName()); + String versionCheckHandlerMethod = null; + for (ASMData vch : versionCheckHandlers) + { + if (vch.getClassName().equals(networkModClass.getName())) + { + versionCheckHandlerMethod = vch.getObjectName(); + versionCheckHandlerMethod = versionCheckHandlerMethod.substring(0,versionCheckHandlerMethod.indexOf('(')); + break; + } + } + if (versionCheckHandlerMethod != null) + { + try + { + Method checkHandlerMethod = networkModClass.getDeclaredMethod(versionCheckHandlerMethod, String.class); + if (checkHandlerMethod.isAnnotationPresent(NetworkMod.VersionCheckHandler.class)) + { + this.checkHandler = checkHandlerMethod; + } + } + catch (Exception e) + { + FMLLog.log(Level.WARNING, e, "The declared version check handler method %s on network mod id %s is not accessible", versionCheckHandlerMethod, container.getModId()); + } + } + + configureNetworkMod(container); + } + protected void configureNetworkMod(ModContainer container) + { + if (this.checkHandler == null) + { + String versionBounds = mod.versionBounds(); + if (!Strings.isNullOrEmpty(versionBounds)) + { + try + { + this.acceptableRange = VersionRange.createFromVersionSpec(versionBounds); + } + catch (InvalidVersionSpecificationException e) + { + FMLLog.log(Level.WARNING, e, "Invalid bounded range %s specified for network mod id %s", versionBounds, container.getModId()); + } + } + } + + FMLLog.finest("Testing mod %s to verify it accepts its own version in a remote connection", container.getModId()); + boolean acceptsSelf = acceptVersion(container.getVersion()); + if (!acceptsSelf) + { + FMLLog.severe("The mod %s appears to reject its own version number (%s) in its version handling. This is likely a severe bug in the mod!", container.getModId(), container.getVersion()); + } + else + { + FMLLog.finest("The mod %s accepts its own version (%s)", container.getModId(), container.getVersion()); + } + } + + public boolean acceptVersion(String version) + { + if (checkHandler != null) + { + try + { + return (Boolean)checkHandler.invoke(container.getMod(), version); + } + catch (Exception e) + { + FMLLog.log(Level.WARNING, e, "There was a problem invoking the checkhandler method %s for network mod id %s", checkHandler.getName(), container.getModId()); + return false; + } + } + + if (acceptableRange!=null) + { + return acceptableRange.containsVersion(new DefaultArtifactVersion(version)); + } + + return container.getVersion().equals(version); + } + + public int getLocalId() + { + return localId; + } + + public int getNetworkId() + { + return networkId; + } + + public ModContainer getContainer() + { + return container; + } + + public NetworkMod getMod() + { + return mod; + } + + public boolean isNetworkMod() + { + return mod != null; + } + + public void setNetworkId(int value) + { + this.networkId = value; + } + +} 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 2f82eef020..96a531a3a9 100644 --- a/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java +++ b/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java @@ -5,7 +5,7 @@ * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * + * * Contributors: * cpw - implementation */ @@ -40,41 +40,22 @@ import com.google.common.collect.Sets; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.LoaderException; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.network.packet.FMLPacket; import cpw.mods.fml.common.network.packet.FMLPacket.Type; +import cpw.mods.fml.common.network.packet.PacketManager; import cpw.mods.fml.relauncher.Side; /** * @author cpw * */ -public class NetworkRegistry +public enum NetworkRegistry { - - private static final NetworkRegistry INSTANCE = new NetworkRegistry(); - /** - * A map of active channels per player - */ - private Multimap activeChannels = ArrayListMultimap.create(); - /** - * A map of the packet handlers for packets - */ - private Multimap universalPacketHandlers = ArrayListMultimap.create(); - private Multimap clientPacketHandlers = ArrayListMultimap.create(); - private Multimap serverPacketHandlers = ArrayListMultimap.create(); - /** - * A linked set of registered connection handlers - */ - private Set connectionHandlers = Sets.newLinkedHashSet(); + INSTANCE; private Map serverGuiHandlers = Maps.newHashMap(); private Map clientGuiHandlers = Maps.newHashMap(); - private List chatListeners = Lists.newArrayList(); - - public static NetworkRegistry instance() - { - return INSTANCE; - } /** * Get the packet 250 channel registration string * @return the {@link Packet250CustomPayload} channel registration string @@ -286,10 +267,10 @@ public class NetworkRegistry ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod); if (mc == null) { - mc = Loader.instance().activeModContainer(); - FMLLog.log(Level.WARNING, "Mod %s attempted to register a gui network handler during a construction phase", mc.getModId()); + FMLLog.log(Level.SEVERE, "Mod %s attempted to register a gui network handler during a construction phase", mc.getModId()); + throw new RuntimeException("Invalid attempt to create a GUI during mod construction. Use an EventHandler instead"); } - NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler(mc); + NetworkModHolder nmh = mc.getNetworkModHolder(); if (nmh == null) { FMLLog.log(Level.FINE, "The mod %s needs to be a @NetworkMod to register a Networked Gui Handler", mc.getModId()); @@ -303,7 +284,7 @@ public class NetworkRegistry void openRemoteGui(ModContainer mc, EntityPlayerMP player, int modGuiId, World world, int x, int y, int z) { IGuiHandler handler = serverGuiHandlers.get(mc); - NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler(mc); + NetworkModHolder nmh = mc.getNetworkModHolder(); if (handler != null && nmh != null) { Container container = (Container)handler.getServerGuiElement(modGuiId, player, world, x, y, z); @@ -312,10 +293,7 @@ public class NetworkRegistry player.func_71117_bO(); player.func_71128_l(); int windowId = player.field_71139_cq; - Packet250CustomPayload pkt = new Packet250CustomPayload(); - pkt.field_73630_a = "FML"; - pkt.field_73629_c = FMLPacket.makePacket(Type.GUIOPEN, windowId, nmh.getNetworkId(), modGuiId, x, y, z); - pkt.field_73628_b = pkt.field_73629_c.length; + Packet pkt = PacketManager.INSTANCE.makeGuiPacket(windowId, nmh.getNetworkId(), modGuiId, x, y, z); player.field_71135_a.func_72567_b(pkt); player.field_71070_bA = container; player.field_71070_bA.field_75152_c = windowId; @@ -328,35 +306,4 @@ public class NetworkRegistry IGuiHandler handler = clientGuiHandlers.get(mc); FMLCommonHandler.instance().showGuiScreen(handler.getClientGuiElement(modGuiId, player, world, x, y, z)); } - public Packet3Chat handleChat(NetHandler handler, Packet3Chat chat) - { - Side s = Side.CLIENT; - if (handler instanceof NetServerHandler) - { - s = Side.SERVER; - } - for (IChatListener listener : chatListeners) - { - chat = s.isClient() ? listener.clientChat(handler, chat) : listener.serverChat(handler, chat); - } - - return chat; - } - public void handleTinyPacket(NetHandler handler, Packet131MapData mapData) - { - NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler((int)mapData.field_73438_a); - if (nmh == null) - { - FMLLog.info("Received a tiny packet for network id %d that is not recognised here", mapData.field_73438_a); - return; - } - if (nmh.hasTinyPacketHandler()) - { - nmh.getTinyPacketHandler().handle(handler, mapData); - } - else - { - FMLLog.info("Received a tiny packet for a network mod that does not accept tiny packets %s", nmh.getContainer().getModId()); - } - } } diff --git a/src/main/java/cpw/mods/fml/common/network/PacketDispatcher.java b/src/main/java/cpw/mods/fml/common/network/PacketDispatcher.java index e876a8cea5..f4279fc726 100644 --- a/src/main/java/cpw/mods/fml/common/network/PacketDispatcher.java +++ b/src/main/java/cpw/mods/fml/common/network/PacketDispatcher.java @@ -87,7 +87,7 @@ public class PacketDispatcher public static Packet131MapData getTinyPacket(Object mod, short tag, byte[] data) { - NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler(mod); + NetworkModHolder nmh = FMLNetworkHandler.instance().findNetworkModHandler(mod); return new Packet131MapData((short) nmh.getNetworkId(), tag, data); } } diff --git a/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnAdjustmentPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnAdjustmentPacket.java index a493e1822d..69584c1434 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnAdjustmentPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnAdjustmentPacket.java @@ -36,7 +36,7 @@ public class EntitySpawnAdjustmentPacket extends FMLPacket public int serverZ; @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { ByteArrayDataOutput dat = ByteStreams.newDataOutput(); dat.writeInt((Integer) data[0]); @@ -47,7 +47,7 @@ public class EntitySpawnAdjustmentPacket extends FMLPacket } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput dat = ByteStreams.newDataInput(data); entityId = dat.readInt(); diff --git a/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnPacket.java index 10f11c2a13..70147e16a6 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/EntitySpawnPacket.java @@ -33,7 +33,7 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.network.FMLNetworkHandler; -import cpw.mods.fml.common.network.NetworkModHandler; +import cpw.mods.fml.common.network.NetworkModHolder; import cpw.mods.fml.common.registry.EntityRegistry; import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; @@ -68,11 +68,11 @@ public class EntitySpawnPacket extends FMLPacket } @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { EntityRegistration er = (EntityRegistration) data[0]; Entity ent = (Entity) data[1]; - NetworkModHandler handler = (NetworkModHandler) data[2]; + NetworkModHolder handler = (NetworkModHolder) data[2]; ByteArrayDataOutput dat = ByteStreams.newDataOutput(); dat.writeInt(handler.getNetworkId()); @@ -142,7 +142,7 @@ public class EntitySpawnPacket extends FMLPacket } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput dat = ByteStreams.newDataInput(data); networkId = dat.readInt(); @@ -183,7 +183,7 @@ public class EntitySpawnPacket extends FMLPacket @Override public void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName) { - NetworkModHandler nmh = handler.findNetworkModHandler(networkId); + NetworkModHolder nmh = handler.findNetworkModHandler(networkId); ModContainer mc = nmh.getContainer(); EntityRegistration registration = EntityRegistry.instance().lookupModSpawn(mc, modEntityId); diff --git a/src/main/java/cpw/mods/fml/common/network/packet/FMLPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/FMLPacket.java index d09c378f71..6a5b25f2cb 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/FMLPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/FMLPacket.java @@ -13,6 +13,7 @@ package cpw.mods.fml.common.network.packet; import java.util.Arrays; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; @@ -52,7 +53,7 @@ public abstract class FMLPacket /** * Open a GUI on the client from the server */ - GUIOPEN(OpenGuiPacket.class, false), + GUIOPEN(OpenGuiPacket.class, false, "OpenGuiHandler"), /** * Spawn an entity on the client from the server */ @@ -69,12 +70,15 @@ public abstract class FMLPacket private Class packetType; private boolean isMultipart; + private String executorClass; + private ConcurrentMap partTracker; - private Type(Class clazz, boolean isMultipart) + private Type(Class clazz, boolean isMultipart, String executorClass) { this.packetType = clazz; this.isMultipart = isMultipart; + this.executorClass = executorClass; } FMLPacket make() @@ -91,12 +95,12 @@ public abstract class FMLPacket } } - public boolean isMultipart() + boolean isMultipart() { return isMultipart; } - private FMLPacket findCurrentPart(INetworkManager network) + private FMLPacket findCurrentPart(NetworkManager network) { if (partTracker == null) { @@ -110,16 +114,13 @@ public abstract class FMLPacket } } - @SuppressWarnings("unused") - private Type type; - public static byte[][] makePacketSet(Type type, Object... data) { if (!type.isMultipart()) { return new byte[0][]; } - byte[] packetData = type.make().generatePacket(data); + byte[] packetData = type.make().generatePacketData(data); byte[][] chunks = new byte[packetData.length / 32000 + 1][]; for (int i = 0; i < packetData.length / 32000 + 1; i++) @@ -129,36 +130,13 @@ public abstract class FMLPacket } return chunks; } - public static byte[] makePacket(Type type, Object... data) + static byte[] makePacket(Type type, Object... data) { - byte[] packetData = type.make().generatePacket(data); + byte[] packetData = type.make().generatePacketData(data); return Bytes.concat(new byte[] { UnsignedBytes.checkedCast(type.ordinal()) }, packetData ); } - public static FMLPacket readPacket(INetworkManager network, byte[] payload) - { - int type = UnsignedBytes.toInt(payload[0]); - Type eType = Type.values()[type]; - FMLPacket pkt; - if (eType.isMultipart()) - { - pkt = eType.findCurrentPart(network); - } - else - { - pkt = eType.make(); - } - return pkt.consumePacket(Arrays.copyOfRange(payload, 1, payload.length)); - } + abstract byte[] generatePacketData(Object... data); - public FMLPacket(Type type) - { - this.type = type; - } - - public abstract byte[] generatePacket(Object... data); - - public abstract FMLPacket consumePacket(byte[] data); - - public abstract void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName); + abstract FMLPacket consumePacketData(byte[] data); } diff --git a/src/main/java/cpw/mods/fml/common/network/packet/ModIdMapPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/ModIdMapPacket.java index 9ccfdd428d..323b3833e4 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/ModIdMapPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/ModIdMapPacket.java @@ -46,7 +46,7 @@ public class ModIdMapPacket extends FMLPacket { } @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { NBTTagList completeList = (NBTTagList) data[0]; NBTTagCompound wrap = new NBTTagCompound(); @@ -63,7 +63,7 @@ public class ModIdMapPacket extends FMLPacket { } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput bdi = ByteStreams.newDataInput(data); int chunkIdx = UnsignedBytes.toInt(bdi.readByte()); diff --git a/src/main/java/cpw/mods/fml/common/network/packet/ModIdentifiersPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/ModIdentifiersPacket.java index 5d5d549af6..b9f16f2409 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/ModIdentifiersPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/ModIdentifiersPacket.java @@ -27,7 +27,7 @@ import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import cpw.mods.fml.common.network.FMLNetworkHandler; -import cpw.mods.fml.common.network.NetworkModHandler; +import cpw.mods.fml.common.network.NetworkModHolder; public class ModIdentifiersPacket extends FMLPacket { @@ -40,13 +40,13 @@ public class ModIdentifiersPacket extends FMLPacket } @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { ByteArrayDataOutput dat = ByteStreams.newDataOutput(); - CollectionnetworkMods = FMLNetworkHandler.instance().getNetworkIdMap().values(); + CollectionnetworkMods = FMLNetworkHandler.instance().getNetworkIdMap().values(); dat.writeInt(networkMods.size()); - for (NetworkModHandler handler : networkMods) + for (NetworkModHolder handler : networkMods) { dat.writeUTF(handler.getContainer().getModId()); dat.writeInt(handler.getNetworkId()); @@ -57,7 +57,7 @@ public class ModIdentifiersPacket extends FMLPacket } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput dat = ByteStreams.newDataInput(data); int listSize = dat.readInt(); diff --git a/src/main/java/cpw/mods/fml/common/network/packet/ModListRequestPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/ModListRequestPacket.java index 06aef7bf3e..d86bb69412 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/ModListRequestPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/ModListRequestPacket.java @@ -34,7 +34,7 @@ import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.network.FMLNetworkHandler; -import cpw.mods.fml.common.network.NetworkModHandler; +import cpw.mods.fml.common.network.NetworkModHolder; import cpw.mods.fml.common.network.PacketDispatcher; public class ModListRequestPacket extends FMLPacket @@ -48,7 +48,7 @@ public class ModListRequestPacket extends FMLPacket } @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { ByteArrayDataOutput dat = ByteStreams.newDataOutput(); Set activeMods = FMLNetworkHandler.instance().getNetworkModList(); @@ -62,7 +62,7 @@ public class ModListRequestPacket extends FMLPacket } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { sentModList = Lists.newArrayList(); ByteArrayDataInput in = ByteStreams.newDataInput(data); @@ -114,7 +114,7 @@ public class ModListRequestPacket extends FMLPacket { if (e.getValue().isNetworkMod()) { - NetworkModHandler missingHandler = FMLNetworkHandler.instance().findNetworkModHandler(e.getValue()); + NetworkModHolder missingHandler = FMLNetworkHandler.instance().findNetworkModHandler(e.getValue()); if (missingHandler.requiresServerSide()) { // TODO : what should we do if a mod is marked "serverSideRequired"? Stop the connection? diff --git a/src/main/java/cpw/mods/fml/common/network/packet/ModListResponsePacket.java b/src/main/java/cpw/mods/fml/common/network/packet/ModListResponsePacket.java index ca23a9c395..b2eb87ff3d 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/ModListResponsePacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/ModListResponsePacket.java @@ -38,7 +38,7 @@ import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.network.FMLNetworkHandler; -import cpw.mods.fml.common.network.NetworkModHandler; +import cpw.mods.fml.common.network.NetworkModHolder; import cpw.mods.fml.common.network.PacketDispatcher; import cpw.mods.fml.common.registry.GameData; @@ -53,7 +53,7 @@ public class ModListResponsePacket extends FMLPacket } @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { @SuppressWarnings("unchecked") Map modVersions = (Map) data[0]; @@ -75,7 +75,7 @@ public class ModListResponsePacket extends FMLPacket } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput dat = ByteStreams.newDataInput(data); int versionListSize = dat.readInt(); @@ -107,7 +107,7 @@ public class ModListResponsePacket extends FMLPacket for (String m : missingMods) { ModContainer mc = indexedModList.get(m); - NetworkModHandler networkMod = handler.findNetworkModHandler(mc); + NetworkModHolder networkMod = handler.findNetworkModHandler(mc); if (networkMod.requiresClientSide()) { missingClientMods.add(m); @@ -117,7 +117,7 @@ public class ModListResponsePacket extends FMLPacket for (Entry modVersion : modVersions.entrySet()) { ModContainer mc = indexedModList.get(modVersion.getKey()); - NetworkModHandler networkMod = handler.findNetworkModHandler(mc); + NetworkModHolder networkMod = handler.findNetworkModHandler(mc); if (!networkMod.acceptVersion(modVersion.getValue())) { versionIncorrectMods.add(modVersion.getKey()); diff --git a/src/main/java/cpw/mods/fml/common/network/packet/ModMissingPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/ModMissingPacket.java index 630f5beb9d..dbe7735d79 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/ModMissingPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/ModMissingPacket.java @@ -44,7 +44,7 @@ public class ModMissingPacket extends FMLPacket } @Override - public byte[] generatePacket(Object... data) + public byte[] generatePacketData(Object... data) { ByteArrayDataOutput dat = ByteStreams.newDataOutput(); @@ -76,7 +76,7 @@ public class ModMissingPacket extends FMLPacket String modVersion; } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput dat = ByteStreams.newDataInput(data); int missingLen = dat.readInt(); diff --git a/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiHandler.java b/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiHandler.java new file mode 100644 index 0000000000..87252bb999 --- /dev/null +++ b/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiHandler.java @@ -0,0 +1,18 @@ +package cpw.mods.fml.common.network.packet; + +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.entity.player.EntityPlayer; +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.common.network.packet.PacketManager.PacketExecutor; + +public class OpenGuiHandler extends PacketExecutor { + @Override + public Void call() throws Exception + { + EntityPlayer player = FMLClientHandler.instance().getClient().field_71439_g; + player.openGui(packet.networkId, packet.modGuiId, player.field_70170_p, packet.x, packet.y, packet.z); + player.field_71070_bA.field_75152_c = packet.windowId; + return null; + } + +} diff --git a/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiPacket.java b/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiPacket.java index c63dd199d2..207297cfac 100644 --- a/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/packet/OpenGuiPacket.java @@ -5,39 +5,28 @@ * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * + * * Contributors: * cpw - implementation */ package cpw.mods.fml.common.network.packet; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.network.INetworkManager; -import net.minecraft.network.packet.NetHandler; - import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; -import cpw.mods.fml.common.network.FMLNetworkHandler; - public class OpenGuiPacket extends FMLPacket { - private int windowId; - private int networkId; - private int modGuiId; - private int x; - private int y; - private int z; - - public OpenGuiPacket() - { - super(Type.GUIOPEN); - } + int windowId; + int networkId; + int modGuiId; + int x; + int y; + int z; @Override - public byte[] generatePacket(Object... data) + byte[] generatePacketData(Object... data) { ByteArrayDataOutput dat = ByteStreams.newDataOutput(); dat.writeInt((Integer) data[0]); // windowId @@ -50,7 +39,7 @@ public class OpenGuiPacket extends FMLPacket } @Override - public FMLPacket consumePacket(byte[] data) + public FMLPacket consumePacketData(byte[] data) { ByteArrayDataInput dat = ByteStreams.newDataInput(data); windowId = dat.readInt(); @@ -62,12 +51,5 @@ public class OpenGuiPacket extends FMLPacket return this; } - @Override - public void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName) - { - EntityPlayer player = netHandler.getPlayer(); - player.openGui(networkId, modGuiId, player.field_70170_p, x, y, z); - player.field_71070_bA.field_75152_c = windowId; - } } diff --git a/src/main/java/cpw/mods/fml/common/network/packet/PacketManager.java b/src/main/java/cpw/mods/fml/common/network/packet/PacketManager.java new file mode 100644 index 0000000000..a0f0ad5c5e --- /dev/null +++ b/src/main/java/cpw/mods/fml/common/network/packet/PacketManager.java @@ -0,0 +1,72 @@ +package cpw.mods.fml.common.network.packet; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Callable; + +import net.minecraft.network.INetHandler; +import net.minecraft.network.play.client.C17PacketCustomPayload; +import net.minecraft.network.play.server.S3FPacketCustomPayload; + +import com.google.common.collect.Maps; +import com.google.common.primitives.UnsignedBytes; + +import cpw.mods.fml.common.network.NetworkDispatcher; +import cpw.mods.fml.common.network.packet.FMLPacket.Type; + +public enum PacketManager { + INSTANCE; + + private Map, PacketExecutor> packetExecutors = Maps.newHashMap(); + + + public C17PacketCustomPayload makeGuiPacket(int windowId, int i, int modGuiId, int x, int y, int z) + { + byte[] data = FMLPacket.makePacket(Type.GUIOPEN, windowId, i, modGuiId, x, y, z); + C17PacketCustomPayload packet = new C17PacketCustomPayload("FML", data); + return packet; + } + + + + public FMLPacket readPacket(NetworkDispatcher dispatcher, C17PacketCustomPayload clientSentPacket) + { + byte[] payload = clientSentPacket.func_149558_e(); + return buildPacket(dispatcher, payload); + } + public FMLPacket readPacket(NetworkDispatcher dispatcher, S3FPacketCustomPayload serverSentPacket) + { + byte[] payload = serverSentPacket.func_149168_d(); + return buildPacket(dispatcher, payload); + } + + private FMLPacket buildPacket(NetworkDispatcher dispatcher, byte[] payload) + { + int type = UnsignedBytes.toInt(payload[0]); + Type eType = Type.values()[type]; + FMLPacket pkt; + if (eType.isMultipart()) + { + pkt = eType.findCurrentPart(network); + } + else + { + pkt = eType.make(); + } + return pkt.consumePacketData(Arrays.copyOfRange(payload, 1, payload.length)); + } + + + static abstract class PacketExecutor implements Callable + { + P packet; + T netHandler; + } + + + public Packet makeFMLHandshake() + { + // TODO Auto-generated method stub + return null; + } +} diff --git a/src/main/java/cpw/mods/fml/common/registry/LanguageRegistry.java b/src/main/java/cpw/mods/fml/common/registry/LanguageRegistry.java index df90bf6c88..0acab241a3 100644 --- a/src/main/java/cpw/mods/fml/common/registry/LanguageRegistry.java +++ b/src/main/java/cpw/mods/fml/common/registry/LanguageRegistry.java @@ -105,7 +105,7 @@ public class LanguageRegistry if (objectToName instanceof Item) { objectName=((Item)objectToName).func_77658_a(); } else if (objectToName instanceof Block) { - objectName=((Block)objectToName).func_71917_a(); + objectName=((Block)objectToName).func_149739_a(); } else if (objectToName instanceof ItemStack) { objectName=((ItemStack)objectToName).func_77973_b().func_77667_c((ItemStack)objectToName); } else { diff --git a/src/main/java/cpw/mods/fml/common/registry/VillagerRegistry.java b/src/main/java/cpw/mods/fml/common/registry/VillagerRegistry.java index 1e265f9163..f6f0b58f32 100644 --- a/src/main/java/cpw/mods/fml/common/registry/VillagerRegistry.java +++ b/src/main/java/cpw/mods/fml/common/registry/VillagerRegistry.java @@ -238,7 +238,7 @@ public class VillagerRegistry { EntityVillager.field_70960_bC.put(item, new Tuple(min, max)); } - EntityVillager.func_146089_b(list, item.func_77612_l(), random, chance); + EntityVillager.func_146089_b(list, item, random, chance); } public static void applyRandomTrade(EntityVillager villager, Random rand) diff --git a/src/main/java/cpw/mods/fml/server/FMLServerHandler.java b/src/main/java/cpw/mods/fml/server/FMLServerHandler.java index 777a9eaf16..96e267436b 100644 --- a/src/main/java/cpw/mods/fml/server/FMLServerHandler.java +++ b/src/main/java/cpw/mods/fml/server/FMLServerHandler.java @@ -23,15 +23,10 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import net.minecraft.entity.Entity; -import net.minecraft.network.INetworkManager; -import net.minecraft.network.packet.NetHandler; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.Packet131MapData; import net.minecraft.server.MinecraftServer; import net.minecraft.util.StringTranslate; import com.google.common.collect.ImmutableList; -import com.google.common.collect.MapDifference; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; @@ -43,7 +38,6 @@ import cpw.mods.fml.common.network.packet.EntitySpawnPacket; import cpw.mods.fml.common.network.packet.ModMissingPacket; import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.GameData; -import cpw.mods.fml.common.registry.ItemData; import cpw.mods.fml.common.registry.LanguageRegistry; import cpw.mods.fml.relauncher.Side; @@ -163,40 +157,14 @@ public class FMLServerHandler implements IFMLSidedHandler // NOOP } @Override - public void sendPacket(Packet packet) - { - throw new RuntimeException("You cannot send a bare packet without a target on the server!"); - } - @Override public void displayMissingMods(ModMissingPacket modMissingPacket) { // NOOP on server } - @Override - public void handleTinyPacket(NetHandler handler, Packet131MapData mapData) - { - // NOOP on server - } - @Override - public void setClientCompatibilityLevel(byte compatibilityLevel) - { - // NOOP on server - } - @Override - public byte getClientCompatibilityLevel() - { - return 0; - } - @Override public boolean shouldServerShouldBeKilledQuietly() { return false; - } - @Override - public void disconnectIDMismatch(MapDifference s, NetHandler handler, INetworkManager mgr) - { - } @Override public void addModAsResource(ModContainer container) diff --git a/src/main/resources/fml_at.cfg b/src/main/resources/fml_at.cfg index d76e7e53d1..422f59b45e 100644 --- a/src/main/resources/fml_at.cfg +++ b/src/main/resources/fml_at.cfg @@ -37,8 +37,8 @@ public net.minecraft.util.WeightedRandom$Item.field_76292_a #probability #public jy.a(Ljy;Z)Z #MD:NetLoginHandler/func_72531_a #'complete connection' #public jy.g #FD:NetLoginHandler/field_72543_h #userName ## EntityPlayerMP getNextWindowId -#public jv.bN()V #MD:EntityPlayerMP/func_71117_bO -#public jv.bY #FD:EntityPlayerMP/field_71139_cq +public net.minecraft.entity.player.EntityPlayerMP.func_71117_bO()V +public net.minecraft.entity.player.EntityPlayerMP.field_71139_cq ## EntityAITaskEntry #public pu #CL:EntityAITaskEntry ## EntityAITasks