diff --git a/fml/common/cpw/mods/fml/common/FMLLog.java b/fml/common/cpw/mods/fml/common/FMLLog.java index 53326568d7..2ece0d8970 100644 --- a/fml/common/cpw/mods/fml/common/FMLLog.java +++ b/fml/common/cpw/mods/fml/common/FMLLog.java @@ -5,7 +5,7 @@ import java.util.logging.Logger; public class FMLLog { - private static cpw.mods.fml.relauncher.FMLLog coreLog = cpw.mods.fml.relauncher.FMLLog.log; + private static cpw.mods.fml.relauncher.FMLRelaunchLog coreLog = cpw.mods.fml.relauncher.FMLRelaunchLog.log; public static void log(Level level, String format, Object... data) { diff --git a/fml/common/cpw/mods/fml/common/FMLModContainer.java b/fml/common/cpw/mods/fml/common/FMLModContainer.java index 0b0276d350..08cdad9502 100644 --- a/fml/common/cpw/mods/fml/common/FMLModContainer.java +++ b/fml/common/cpw/mods/fml/common/FMLModContainer.java @@ -50,6 +50,7 @@ import cpw.mods.fml.common.event.FMLServerStartedEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppingEvent; import cpw.mods.fml.common.event.FMLStateEvent; +import cpw.mods.fml.common.network.FMLNetworkHandler; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.versioning.ArtifactVersion; import cpw.mods.fml.common.versioning.DefaultArtifactVersion; @@ -275,6 +276,7 @@ public class FMLModContainer implements ModContainer ASMDataTable asmHarvestedAnnotations = event.getASMHarvestedData(); asmHarvestedAnnotations.getAnnotationsFor(this); annotations = gatherAnnotations(clazz); + isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData()); modInstance = clazz.newInstance(); processFieldAnnotations(); } diff --git a/fml/common/cpw/mods/fml/common/LoadController.java b/fml/common/cpw/mods/fml/common/LoadController.java index 9541626225..4ff7f2c03b 100644 --- a/fml/common/cpw/mods/fml/common/LoadController.java +++ b/fml/common/cpw/mods/fml/common/LoadController.java @@ -68,7 +68,6 @@ public class LoadController } eventChannels = eventBus.build(); - FMLNetworkHandler.instance().freezeModList(activeModList); } public void distributeStateMessage(LoaderState state, Object... eventData) diff --git a/fml/common/cpw/mods/fml/relauncher/FMLSanityChecker.java b/fml/common/cpw/mods/fml/common/asm/FMLSanityChecker.java similarity index 87% rename from fml/common/cpw/mods/fml/relauncher/FMLSanityChecker.java rename to fml/common/cpw/mods/fml/common/asm/FMLSanityChecker.java index d2047f5b28..c8d3c4a83b 100644 --- a/fml/common/cpw/mods/fml/relauncher/FMLSanityChecker.java +++ b/fml/common/cpw/mods/fml/common/asm/FMLSanityChecker.java @@ -1,4 +1,4 @@ -package cpw.mods.fml.relauncher; +package cpw.mods.fml.common.asm; import java.util.Map; @@ -9,6 +9,10 @@ import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Opcodes; +import cpw.mods.fml.relauncher.FMLRelauncher; +import cpw.mods.fml.relauncher.IFMLCallHook; +import cpw.mods.fml.relauncher.RelaunchClassLoader; + public class FMLSanityChecker implements IFMLCallHook { static class MLDetectorClassVisitor extends ClassVisitor @@ -22,7 +26,7 @@ public class FMLSanityChecker implements IFMLCallHook @Override public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4) { - if (arg1 == "fmlMarker") + if ("fmlMarker".equals(arg1)) { foundMarker = true; } @@ -46,7 +50,7 @@ public class FMLSanityChecker implements IFMLCallHook cr.accept(mlTester, ClassReader.SKIP_CODE); if (!mlTester.foundMarker) { - JOptionPane.showMessageDialog(FMLRelauncher.instance().popupWindow, "CRITICAL ERROR
" + + JOptionPane.showMessageDialog(null, "CRITICAL ERROR
" + "ModLoader was detected in this environment
" + "ForgeModLoader cannot be installed alongside ModLoader
" + "All mods should work without ModLoader being installed
" + diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java b/fml/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java new file mode 100644 index 0000000000..4fd282f006 --- /dev/null +++ b/fml/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java @@ -0,0 +1,295 @@ +package cpw.mods.fml.common.asm.transformers; + +import static org.objectweb.asm.Opcodes.ACC_PRIVATE; +import static org.objectweb.asm.Opcodes.ACC_PROTECTED; +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ACC_FINAL; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; + +import com.google.common.base.CharMatcher; +import com.google.common.base.Charsets; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Iterables; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.io.LineProcessor; +import com.google.common.io.Resources; + +import cpw.mods.fml.relauncher.IClassTransformer; + +public class MarkerTransformer implements IClassTransformer +{ + private ListMultimap markers = ArrayListMultimap.create(); + + public MarkerTransformer() throws IOException + { + this("fml_marker.cfg"); + } + protected MarkerTransformer(String rulesFile) throws IOException + { + readMapFile(rulesFile); + } + + private void readMapFile(String rulesFile) throws IOException + { + File file = new File(rulesFile); + URL rulesResource; + if (file.exists()) + { + rulesResource = file.toURI().toURL(); + } + else + { + rulesResource = Resources.getResource(rulesFile); + } + Resources.readLines(rulesResource, Charsets.UTF_8, new LineProcessor() + { + @Override + public Void getResult() + { + return null; + } + + @Override + public boolean processLine(String input) throws IOException + { + String line = Iterables.getFirst(Splitter.on('#').limit(2).split(input), "").trim(); + if (line.length()==0) + { + return true; + } + List parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line)); + if (parts.size()!=2) + { + throw new RuntimeException("Invalid config file line "+ input); + } + List markerInterfaces = Lists.newArrayList(Splitter.on(",").trimResults().split(parts.get(1))); + for (String marker : markerInterfaces) + { + markers.put(parts.get(0), marker); + } + return true; + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public byte[] transform(String name, byte[] bytes) + { + if (!markers.containsKey(name)) { return bytes; } + + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, 0); + + for (String marker : markers.get(name)) + { + classNode.interfaces.add(marker); + } + + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + classNode.accept(writer); + return writer.toByteArray(); + } + + public static void main(String[] args) + { + if (args.length < 2) + { + System.out.println("Usage: MarkerTransformer [MapFile2]... "); + return; + } + + boolean hasTransformer = false; + MarkerTransformer[] trans = new MarkerTransformer[args.length - 1]; + for (int x = 1; x < args.length; x++) + { + try + { + trans[x - 1] = new MarkerTransformer(args[x]); + hasTransformer = true; + } + catch (IOException e) + { + System.out.println("Could not read Transformer Map: " + args[x]); + e.printStackTrace(); + } + } + + if (!hasTransformer) + { + System.out.println("Culd not find a valid transformer to perform"); + return; + } + + File orig = new File(args[0]); + File temp = new File(args[0] + ".ATBack"); + if (!orig.exists() && !temp.exists()) + { + System.out.println("Could not find target jar: " + orig); + return; + } +/* + if (temp.exists()) + { + if (orig.exists() && !orig.renameTo(new File(args[0] + (new SimpleDateFormat(".yyyy.MM.dd.HHmmss")).format(new Date())))) + { + System.out.println("Could not backup existing file: " + orig); + return; + } + if (!temp.renameTo(orig)) + { + System.out.println("Could not restore backup from previous run: " + temp); + return; + } + } +*/ + if (!orig.renameTo(temp)) + { + System.out.println("Could not rename file: " + orig + " -> " + temp); + return; + } + + try + { + processJar(temp, orig, trans); + } + catch (IOException e) + { + e.printStackTrace(); + } + + if (!temp.delete()) + { + System.out.println("Could not delete temp file: " + temp); + } + } + + private static void processJar(File inFile, File outFile, MarkerTransformer[] transformers) throws IOException + { + ZipInputStream inJar = null; + ZipOutputStream outJar = null; + + try + { + try + { + inJar = new ZipInputStream(new BufferedInputStream(new FileInputStream(inFile))); + } + catch (FileNotFoundException e) + { + throw new FileNotFoundException("Could not open input file: " + e.getMessage()); + } + + try + { + outJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile))); + } + catch (FileNotFoundException e) + { + throw new FileNotFoundException("Could not open output file: " + e.getMessage()); + } + + ZipEntry entry; + while ((entry = inJar.getNextEntry()) != null) + { + if (entry.isDirectory()) + { + outJar.putNextEntry(entry); + continue; + } + + byte[] data = new byte[4096]; + ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream(); + + int len; + do + { + len = inJar.read(data); + if (len > 0) + { + entryBuffer.write(data, 0, len); + } + } + while (len != -1); + + byte[] entryData = entryBuffer.toByteArray(); + + String entryName = entry.getName(); + + if (entryName.endsWith(".class") && !entryName.startsWith(".")) + { + ClassNode cls = new ClassNode(); + ClassReader rdr = new ClassReader(entryData); + rdr.accept(cls, 0); + String name = cls.name.replace('/', '.').replace('\\', '.'); + + for (MarkerTransformer trans : transformers) + { + entryData = trans.transform(name, entryData); + } + } + + ZipEntry newEntry = new ZipEntry(entryName); + outJar.putNextEntry(newEntry); + outJar.write(entryData); + } + } + finally + { + if (outJar != null) + { + try + { + outJar.close(); + } + catch (IOException e) + { + } + } + + if (inJar != null) + { + try + { + inJar.close(); + } + catch (IOException e) + { + } + } + } + } +} \ No newline at end of file diff --git a/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java b/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java index c769d3d83a..27b90475ed 100644 --- a/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java +++ b/fml/common/cpw/mods/fml/common/discovery/ASMDataTable.java @@ -1,6 +1,7 @@ package cpw.mods.fml.common.discovery; import java.io.File; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -69,7 +70,7 @@ public class ASMDataTable return container.getSource().equals(data.candidate.getModContainer()); } } - private SetMultimap globalAnnotationData; + private SetMultimap globalAnnotationData = HashMultimap.create(); private Map> containerAnnotationData; private List containers = Lists.newArrayList(); diff --git a/fml/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java b/fml/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java index b9bfc5c231..8e2cf3154b 100644 --- a/fml/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java +++ b/fml/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java @@ -18,8 +18,12 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.Map; +import net.minecraft.src.BaseMod; + import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.TickType; +import cpw.mods.fml.common.network.IPacketHandler; /** * @author cpw @@ -104,4 +108,9 @@ public class ModLoaderHelper ModLoaderModContainer mlmc=findOrBuildModContainer(mod); return mlmc; } + + public static IPacketHandler buildPacketHandlerFor(BaseMod mod) + { + return null; + } } diff --git a/fml/common/cpw/mods/fml/common/network/FMLNetworkException.java b/fml/common/cpw/mods/fml/common/network/FMLNetworkException.java index 34497f7435..8574944dfe 100644 --- a/fml/common/cpw/mods/fml/common/network/FMLNetworkException.java +++ b/fml/common/cpw/mods/fml/common/network/FMLNetworkException.java @@ -7,4 +7,8 @@ public class FMLNetworkException extends RuntimeException { super(e); } + + public FMLNetworkException() + { + } } diff --git a/fml/common/cpw/mods/fml/common/network/FMLNetworkHandler.java b/fml/common/cpw/mods/fml/common/network/FMLNetworkHandler.java index 31b55afea5..fe0d8172b3 100644 --- a/fml/common/cpw/mods/fml/common/network/FMLNetworkHandler.java +++ b/fml/common/cpw/mods/fml/common/network/FMLNetworkHandler.java @@ -22,16 +22,21 @@ import cpw.mods.fml.common.Loader; 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.relauncher.FMLRelaunchLog; import net.minecraft.server.MinecraftServer; +import net.minecraft.src.EntityPlayerMP; +import net.minecraft.src.EnumGameType; import net.minecraft.src.NetHandler; import net.minecraft.src.NetLoginHandler; +import net.minecraft.src.NetServerHandler; import net.minecraft.src.NetworkManager; import net.minecraft.src.Packet; import net.minecraft.src.Packet1Login; import net.minecraft.src.Packet250CustomPayload; import net.minecraft.src.ServerConfigurationManager; import net.minecraft.src.TcpConnection; +import net.minecraft.src.WorldType; public class FMLNetworkHandler { @@ -55,14 +60,18 @@ public class FMLNetworkHandler } if (target.equals("FML")) { - instance().handleFMLPacket(packet, network); + instance().handleFMLPacket(packet, network, handler); + } + else + { + NetworkRegistry.instance().handleCustomPacket(packet, network, handler); } } - private void handleFMLPacket(Packet250CustomPayload packet, NetworkManager network) + private void handleFMLPacket(Packet250CustomPayload packet, NetworkManager network, NetHandler netHandler) { FMLPacket pkt = FMLPacket.readPacket(packet.field_73629_c); - pkt.execute(network, this); + pkt.execute(network, this, netHandler); } public static void onClientConnectToServer(NetLoginHandler netLoginHandler, MinecraftServer server, SocketAddress address, String userName) @@ -74,21 +83,24 @@ public class FMLNetworkHandler { if (!loginStates.containsKey(netLoginHandler)) { - // Vanilla reasons first - ServerConfigurationManager playerList = server.func_71203_ab(); - String kickReason = playerList.func_72399_a(address, userName); - - if (kickReason!=null) + if (handleVanillaLoginKick(netLoginHandler, server, address, userName)) { - netLoginHandler.completeConnection(kickReason); + // No FML on the client + FMLRelaunchLog.fine("Connection from %s rejected - no FML packet received from client", userName); + netLoginHandler.completeConnection("You don't have FML installed, or your installation is too old"); + return; } - // No FML on the client - netLoginHandler.completeConnection("You don't have FML installed, or your installation is too old"); - return; } // Are we ready to negotiate with the client? if (loginStates.get(netLoginHandler) == 1) { + // The vanilla side wanted to kick + if (!handleVanillaLoginKick(netLoginHandler, server, address, userName)) + { + loginStates.remove(netLoginHandler); + return; + } + // Reset the "connection completed" flag so processing can continue NetLoginHandler.func_72531_a(netLoginHandler, false); // Send the mod list request packet to the client from the server @@ -109,12 +121,37 @@ public class FMLNetworkHandler } } + /** + * @param netLoginHandler + * @param server + * @param address + * @param userName + * @return if the user can carry on + */ + private boolean handleVanillaLoginKick(NetLoginHandler netLoginHandler, MinecraftServer server, SocketAddress address, String userName) + { + // Vanilla reasons first + ServerConfigurationManager playerList = server.func_71203_ab(); + String kickReason = playerList.func_72399_a(address, userName); + + if (kickReason!=null) + { + netLoginHandler.completeConnection(kickReason); + } + return kickReason == null; + } + public static void handleLoginPacketOnServer(NetLoginHandler handler, Packet1Login login) { if (login.field_73561_a == FML_HASH && login.field_73558_e == PROTOCOL_VERSION) { + FMLRelaunchLog.finest("Received valid FML login packet from %s", handler.field_72538_b.func_74430_c()); instance().loginStates.put(handler,1); } + else + { + FMLRelaunchLog.fine("Received invalid FML login packet %d, %d from %s", login.field_73561_a, login.field_73558_e, handler.field_72538_b.func_74430_c()); + } } public static FMLNetworkHandler instance() { @@ -128,9 +165,11 @@ public class FMLNetworkHandler fake.field_73561_a = FML_HASH; // The FML protocol version fake.field_73558_e = PROTOCOL_VERSION; + fake.field_73557_d = EnumGameType.NOT_SET; + fake.field_73559_b = WorldType.field_77139_a[0]; return fake; } - public static Packet250CustomPayload getModListRequestPacket() + public Packet250CustomPayload getModListRequestPacket() { Packet250CustomPayload pkt = new Packet250CustomPayload(); pkt.field_73630_a = "FML"; @@ -157,8 +196,31 @@ public class FMLNetworkHandler return networkModHandlers.get(mc); } - public List getNetworkModList() + public Set getNetworkModList() { - return null; + return networkModHandlers.keySet(); + } + + public static void handlePlayerLogin(EntityPlayerMP player, NetServerHandler netHandler, NetworkManager manager) + { + instance().playerLoggedIn(player, netHandler, manager); + } + + private void playerLoggedIn(EntityPlayerMP player, NetServerHandler netHandler, NetworkManager manager) + { + NetworkRegistry.instance().playerLoggedIn(player, netHandler, manager); + } + + public Map getNetworkIdMap() + { + return networkIdLookup; + } + + public void bindNetworkId(String key, Integer value) + { + Map mods = Loader.instance().getIndexedModList(); + NetworkModHandler handler = findNetworkModHandler(mods.get(key)); + handler.setNetworkId(value); + networkIdLookup.put(value,handler); } } \ No newline at end of file diff --git a/fml/common/cpw/mods/fml/common/network/IConnectionHandler.java b/fml/common/cpw/mods/fml/common/network/IConnectionHandler.java new file mode 100644 index 0000000000..16f17c2678 --- /dev/null +++ b/fml/common/cpw/mods/fml/common/network/IConnectionHandler.java @@ -0,0 +1,13 @@ +package cpw.mods.fml.common.network; + +import net.minecraft.src.EntityPlayer; +import net.minecraft.src.EntityPlayerMP; +import net.minecraft.src.NetHandler; +import net.minecraft.src.NetServerHandler; +import net.minecraft.src.NetworkManager; + +public interface IConnectionHandler +{ + void playerLoggedIn(Player player, NetHandler netHandler, NetworkManager manager); + +} diff --git a/fml/common/cpw/mods/fml/common/network/IPacketHandler.java b/fml/common/cpw/mods/fml/common/network/IPacketHandler.java new file mode 100644 index 0000000000..fc05caadfa --- /dev/null +++ b/fml/common/cpw/mods/fml/common/network/IPacketHandler.java @@ -0,0 +1,9 @@ +package cpw.mods.fml.common.network; + +import net.minecraft.src.NetworkManager; +import net.minecraft.src.Packet250CustomPayload; + +public interface IPacketHandler +{ + public void onPacketData(NetworkManager manager, Packet250CustomPayload packet); +} diff --git a/fml/common/cpw/mods/fml/common/network/ModIdentifiersPacket.java b/fml/common/cpw/mods/fml/common/network/ModIdentifiersPacket.java index 5734ecc49c..c73f7c975f 100644 --- a/fml/common/cpw/mods/fml/common/network/ModIdentifiersPacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModIdentifiersPacket.java @@ -1,12 +1,25 @@ package cpw.mods.fml.common.network; import static cpw.mods.fml.common.network.FMLPacket.Type.*; + +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.google.common.collect.Maps; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; + import net.minecraft.src.NetHandler; import net.minecraft.src.NetworkManager; public class ModIdentifiersPacket extends FMLPacket { + private Map modIds = Maps.newHashMap(); + public ModIdentifiersPacket() { super(MOD_IDENTIFIERS); @@ -15,21 +28,41 @@ public class ModIdentifiersPacket extends FMLPacket @Override public byte[] generatePacket(Object... data) { - // TODO Auto-generated method stub - return null; + ByteArrayDataOutput dat = ByteStreams.newDataOutput(); + CollectionnetworkMods = FMLNetworkHandler.instance().getNetworkIdMap().values(); + + dat.writeInt(networkMods.size()); + for (NetworkModHandler handler : networkMods) + { + dat.writeUTF(handler.getContainer().getModId()); + dat.writeInt(handler.getNetworkId()); + } + + // TODO send the other id maps as well + return dat.toByteArray(); } @Override public FMLPacket consumePacket(byte[] data) { - // TODO Auto-generated method stub - return null; + ByteArrayDataInput dat = ByteStreams.newDataInput(data); + int listSize = dat.readInt(); + for (int i = 0; i < listSize; i++) + { + String modId = dat.readUTF(); + int networkId = dat.readInt(); + modIds.put(modId, networkId); + } + return this; } @Override public void execute(NetworkManager network, FMLNetworkHandler handler, NetHandler netHandler) { - // TODO Auto-generated method stub - + for (Entry idEntry : modIds.entrySet()) + { + handler.bindNetworkId(idEntry.getKey(), idEntry.getValue()); + } + // TODO other id maps } } diff --git a/fml/common/cpw/mods/fml/common/network/ModListRequestPacket.java b/fml/common/cpw/mods/fml/common/network/ModListRequestPacket.java index 270f9614d2..57ccf23be8 100644 --- a/fml/common/cpw/mods/fml/common/network/ModListRequestPacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModListRequestPacket.java @@ -4,6 +4,7 @@ import static cpw.mods.fml.common.network.FMLPacket.Type.*; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import net.minecraft.src.NetHandler; @@ -33,7 +34,7 @@ public class ModListRequestPacket extends FMLPacket public byte[] generatePacket(Object... data) { ByteArrayDataOutput dat = ByteStreams.newDataOutput(); - List activeMods = FMLNetworkHandler.instance().getNetworkModList(); + Set activeMods = FMLNetworkHandler.instance().getNetworkModList(); dat.writeInt(activeMods.size()); for (ModContainer mc : activeMods) { diff --git a/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java b/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java index 4f764098a4..58e8b2770b 100644 --- a/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java @@ -100,18 +100,21 @@ public class ModListResponsePacket extends FMLPacket } } + Packet250CustomPayload pkt = new Packet250CustomPayload(); + pkt.field_73630_a = "FML"; if (missingClientMods.size()>0 || versionIncorrectMods.size() > 0) { - Packet250CustomPayload pkt = new Packet250CustomPayload(); - pkt.field_73630_a = "FML"; pkt.field_73629_c = FMLPacket.makePacket(MOD_MISSING, missingClientMods, versionIncorrectMods); - pkt.field_73628_b = pkt.field_73629_c.length; - network.func_74429_a(pkt); - NetLoginHandler.func_72531_a((NetLoginHandler) netHandler, false); - return; + } + else + { + pkt.field_73629_c = FMLPacket.makePacket(MOD_IDENTIFIERS); } - handler.generateModIdentifierData(); + pkt.field_73628_b = pkt.field_73629_c.length; + network.func_74429_a(pkt); + // reset the continuation flag - we have completed extra negotiation and the login should complete now + NetLoginHandler.func_72531_a((NetLoginHandler) netHandler, true); } } diff --git a/fml/common/cpw/mods/fml/common/network/ModMissingPacket.java b/fml/common/cpw/mods/fml/common/network/ModMissingPacket.java index 165ddf2f7c..22696ecee4 100644 --- a/fml/common/cpw/mods/fml/common/network/ModMissingPacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModMissingPacket.java @@ -1,5 +1,6 @@ package cpw.mods.fml.common.network; +import net.minecraft.src.NetHandler; import net.minecraft.src.NetworkManager; public class ModMissingPacket extends FMLPacket @@ -25,7 +26,7 @@ public class ModMissingPacket extends FMLPacket } @Override - public void execute(NetworkManager network, FMLNetworkHandler handler) + public void execute(NetworkManager network, FMLNetworkHandler handler, NetHandler netHandler) { // TODO Auto-generated method stub diff --git a/fml/common/cpw/mods/fml/common/network/NetworkMod.java b/fml/common/cpw/mods/fml/common/network/NetworkMod.java index 68afa97cf4..3d8095fa1c 100644 --- a/fml/common/cpw/mods/fml/common/network/NetworkMod.java +++ b/fml/common/cpw/mods/fml/common/network/NetworkMod.java @@ -33,6 +33,26 @@ public @interface NetworkMod * @return */ String versionBounds() default ""; + + /** + * A packet handler implementation for channels registered through this annotation + * + * @return + */ + Class packetHandler() default NULL.class; + + /** + * A connection handler implementation for this network mod + * + * @return + */ + Class connectionHandler() default NULL.class; + /** + * Special dummy class for handling stupid annotation default values + * @author cpw + * + */ + static interface NULL extends IPacketHandler, IConnectionHandler {}; /** * A marker for a method that will be offered the client's version string * if more sophisticated version rejection handling is required: diff --git a/fml/common/cpw/mods/fml/common/network/NetworkModHandler.java b/fml/common/cpw/mods/fml/common/network/NetworkModHandler.java index b83fab85bb..af4b9671ce 100644 --- a/fml/common/cpw/mods/fml/common/network/NetworkModHandler.java +++ b/fml/common/cpw/mods/fml/common/network/NetworkModHandler.java @@ -6,6 +6,10 @@ import java.util.Collection; import java.util.Set; import java.util.logging.Level; +import net.minecraft.src.EntityPlayerMP; +import net.minecraft.src.NetServerHandler; +import net.minecraft.src.NetworkManager; + import org.objectweb.asm.Type; import com.google.common.base.Strings; @@ -43,7 +47,7 @@ public class NetworkModHandler this.localId = assignedIds++; this.networkId = this.localId; - Set versionCheckHandlers = table.getAnnotationsFor(container).get(Type.getDescriptor(NetworkMod.VersionCheckHandler.class)); + Set versionCheckHandlers = table.getAnnotationsFor(container).get(NetworkMod.VersionCheckHandler.class.getName()); String versionCheckHandlerMethod = null; for (ASMData vch : versionCheckHandlers) { @@ -84,6 +88,45 @@ public class NetworkModHandler } } } + + if (!mod.packetHandler().getName().equals(NetworkMod.NULL.class.getName())) + { + IPacketHandler instance; + try + { + instance = mod.packetHandler().newInstance(); + } + catch (Exception e) + { + FMLLog.log(Level.SEVERE, e, "Unable to create packet handler instance %s", mod.packetHandler().getName()); + throw new FMLNetworkException(e); + } + + for (String channel : mod.channels()) + { + NetworkRegistry.instance().registerChannel(instance, channel); + } + } + else if (mod.channels().length > 0) + { + FMLLog.warning("The mod id %s attempted to register channels without specifying a valid packet handler", container.getModId()); + } + + if (!mod.connectionHandler().getName().equals(NetworkMod.NULL.class.getName())) + { + 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); + } } public boolean requiresClientSide() @@ -143,4 +186,9 @@ public class NetworkModHandler { return mod != null; } + + public void setNetworkId(int value) + { + this.networkId = value; + } } diff --git a/fml/common/cpw/mods/fml/common/network/NetworkRegistry.java b/fml/common/cpw/mods/fml/common/network/NetworkRegistry.java index e522405f4c..bb25dd3600 100644 --- a/fml/common/cpw/mods/fml/common/network/NetworkRegistry.java +++ b/fml/common/cpw/mods/fml/common/network/NetworkRegistry.java @@ -3,20 +3,29 @@ package cpw.mods.fml.common.network; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import net.minecraft.src.EntityPlayer; +import net.minecraft.src.EntityPlayerMP; +import net.minecraft.src.NetHandler; +import net.minecraft.src.NetServerHandler; +import net.minecraft.src.NetworkManager; +import net.minecraft.src.Packet250CustomPayload; import com.google.common.base.Charsets; import com.google.common.base.Joiner; +import com.google.common.base.Splitter; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.ModContainer; @@ -30,30 +39,25 @@ public class NetworkRegistry */ private Multimap activeChannels = ArrayListMultimap.create(); /** - * A map of mods to their network channels - the list is a set + * A map of the packet handlers for packets */ - private SetMultimap channelList = LinkedHashMultimap.create(); + private Map packetHandlers = Maps.newHashMap(); + /** + * A linked set of registered connection handlers + */ + private Set connectionHandlers = Sets.newLinkedHashSet(); public static NetworkRegistry instance() { return INSTANCE; } - /** - * Get the channel list for a mod - * @param modLoaderModContainer - * @return - */ - public Set getChannelListFor(ModContainer container) - { - return channelList.get(container); - } /** * Get the packet 250 channel registration string * @return */ - public byte[] getPacketRegistry() + byte[] getPacketRegistry() { - return Joiner.on('\0').join(channelList.values()).getBytes(Charsets.UTF_8); + return Joiner.on('\0').join(packetHandlers.keySet()).getBytes(Charsets.UTF_8); } /** * Is the specified channel active for the player? @@ -70,16 +74,22 @@ public class NetworkRegistry * @param container * @param channelName */ - public void registerChannel(ModContainer container, String channelName) + public void registerChannel(IPacketHandler handler, String channelName) { - channelList.put(container, channelName); + if ("FML".equals(channelName) || (channelName != null && channelName.startsWith("MC|"))) + { + FMLLog.severe("Illegal attempt to register a special channel %s", channelName); + throw new FMLNetworkException(); + } + + packetHandlers.put(channelName, handler); // invertedChannelList = Multimaps.invertFrom(channelList, ArrayListMultimap.create()); } /** * Activate the channel for the player * @param player */ - public void activateChannel(Player player, String channel) + void activateChannel(Player player, String channel) { activeChannels.put(player, channel); } @@ -88,8 +98,88 @@ public class NetworkRegistry * @param player * @param channel */ - public void deactivateChannel(Player player, String channel) + void deactivateChannel(Player player, String channel) { activeChannels.remove(player, channel); } + /** + * Register a connection handler + * + * @param handler + */ + public void registerConnectionHandler(IConnectionHandler handler) + { + connectionHandlers.add(handler); + } + + void playerLoggedIn(EntityPlayerMP player, NetServerHandler netHandler, NetworkManager manager) + { + for (IConnectionHandler handler : connectionHandlers) + { + handler.playerLoggedIn((Player)player, netHandler, manager); + } + generateChannelRegistration(player, netHandler, manager); + } + + void generateChannelRegistration(EntityPlayer player, NetHandler netHandler, NetworkManager manager) + { + Packet250CustomPayload pkt = new Packet250CustomPayload(); + pkt.field_73630_a = "REGISTER"; + pkt.field_73629_c = getPacketRegistry(); + pkt.field_73628_b = pkt.field_73629_c.length; + manager.func_74429_a(pkt); + } + + void handleCustomPacket(Packet250CustomPayload packet, NetworkManager network, NetHandler handler) + { + if ("REGISTER".equals(packet.field_73630_a)) + { + handleRegistrationPacket(packet, (Player)handler.getPlayer()); + } + else if ("UNREGISTER".equals(packet.field_73630_a)) + { + handleUnregistrationPacket(packet, (Player)handler.getPlayer()); + } + else + { + handlePacket(packet, network, (Player)handler.getPlayer()); + } + } + + + private void handlePacket(Packet250CustomPayload packet, NetworkManager network, Player player) + { + if (activeChannels.containsEntry(player, packet.field_73630_a)) + { + IPacketHandler handler = packetHandlers.get(packet.field_73630_a); + handler.onPacketData(network, packet); + } + } + + private void handleRegistrationPacket(Packet250CustomPayload packet, Player player) + { + List channels = extractChannelList(packet); + for (String channel : channels) + { + activateChannel(player, channel); + } + } + private void handleUnregistrationPacket(Packet250CustomPayload packet, Player player) + { + List channels = extractChannelList(packet); + for (String channel : channels) + { + deactivateChannel(player, channel); + } + } + /** + * @param packet + * @return + */ + private List extractChannelList(Packet250CustomPayload packet) + { + String request = new String(packet.field_73629_c, Charsets.UTF_8); + List channels = Lists.newArrayList(Splitter.on('\0').split(request)); + return channels; + } } diff --git a/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java b/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java index c6df53e3fc..e64a2a85c9 100644 --- a/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java +++ b/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java @@ -13,7 +13,7 @@ public class FMLCorePlugin implements IFMLLoadingPlugin @Override public String[] getASMTransformerClass() { - return new String[] {"cpw.mods.fml.common.asm.ASMTransformer"}; + return new String[] {"cpw.mods.fml.common.asm.ASMTransformer", "cpw.mods.fml.common.asm.MarkerTransformer"}; } @Override @@ -25,7 +25,7 @@ public class FMLCorePlugin implements IFMLLoadingPlugin @Override public String getSetupClass() { - return "cpw.mods.fml.relauncher.FMLSanityChecker"; + return "cpw.mods.fml.common.asm.FMLSanityChecker"; } @Override diff --git a/fml/common/cpw/mods/fml/relauncher/FMLInjectionData.java b/fml/common/cpw/mods/fml/relauncher/FMLInjectionData.java index a1a5478010..cf1d164cf1 100644 --- a/fml/common/cpw/mods/fml/relauncher/FMLInjectionData.java +++ b/fml/common/cpw/mods/fml/relauncher/FMLInjectionData.java @@ -33,7 +33,7 @@ public class FMLInjectionData } catch (IOException ex) { - FMLLog.log(Level.SEVERE, ex, "Could not get FML version information - corrupted installation detected!"); + FMLRelaunchLog.log(Level.SEVERE, ex, "Could not get FML version information - corrupted installation detected!"); } } diff --git a/fml/common/cpw/mods/fml/relauncher/FMLLog.java b/fml/common/cpw/mods/fml/relauncher/FMLRelaunchLog.java similarity index 95% rename from fml/common/cpw/mods/fml/relauncher/FMLLog.java rename to fml/common/cpw/mods/fml/relauncher/FMLRelaunchLog.java index d2e560031e..a9f0711b46 100644 --- a/fml/common/cpw/mods/fml/relauncher/FMLLog.java +++ b/fml/common/cpw/mods/fml/relauncher/FMLRelaunchLog.java @@ -12,7 +12,7 @@ import java.util.logging.Logger; import cpw.mods.fml.relauncher.FMLLogFormatter; -public class FMLLog +public class FMLRelaunchLog { private static class LoggingOutStream extends ByteArrayOutputStream @@ -55,13 +55,13 @@ public class FMLLog * Our special logger for logging issues to. We copy various assets from the * Minecraft logger to acheive a similar appearance. */ - public static FMLLog log = new FMLLog(); + public static FMLRelaunchLog log = new FMLRelaunchLog(); static File minecraftHome; private static boolean configured; private Logger myLog; - private FMLLog() + private FMLRelaunchLog() { } /** @@ -90,7 +90,7 @@ public class FMLLog log.myLog.setLevel(Level.ALL); try { - File logPath = new File(minecraftHome, "ForgeModLoader-%g.log"); + File logPath = new File(minecraftHome, FMLRelauncher.logFileNamePattern); FileHandler fileHandler = new FileHandler(logPath.getPath(), 0, 3); fileHandler.setFormatter(formatter); fileHandler.setLevel(Level.ALL); diff --git a/fml/common/cpw/mods/fml/relauncher/FMLRelauncher.java b/fml/common/cpw/mods/fml/relauncher/FMLRelauncher.java index 86612c45b0..89c6ccc796 100644 --- a/fml/common/cpw/mods/fml/relauncher/FMLRelauncher.java +++ b/fml/common/cpw/mods/fml/relauncher/FMLRelauncher.java @@ -24,6 +24,7 @@ import javax.swing.ProgressMonitorInputStream; public class FMLRelauncher { private static FMLRelauncher INSTANCE; + public static String logFileNamePattern; private RelaunchClassLoader classLoader; private Object newApplet; private Class appletClass; @@ -32,11 +33,13 @@ public class FMLRelauncher public static void handleClientRelaunch(ArgsWrapper wrap) { + logFileNamePattern = "ForgeModLoader-client-%g.log"; instance().relaunchClient(wrap); } public static void handleServerRelaunch(ArgsWrapper wrap) { + logFileNamePattern = "ForgeModLoader-server-%g.log"; instance().relaunchServer(wrap); } @@ -129,7 +132,7 @@ public class FMLRelauncher private void setupHome(File minecraftHome) { FMLInjectionData.build(minecraftHome, classLoader); - FMLLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft client:%s, server:%s loading", FMLInjectionData.major, FMLInjectionData.minor, FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion, FMLInjectionData.mcsversion); + FMLRelaunchLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft client:%s, server:%s loading", FMLInjectionData.major, FMLInjectionData.minor, FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion, FMLInjectionData.mcsversion); try { @@ -216,7 +219,7 @@ public class FMLRelauncher } else { - FMLLog.severe("Found unknown applet parent %s, unable to inject!\n", launcherClass); + FMLRelaunchLog.severe("Found unknown applet parent %s, unable to inject!\n", launcherClass); throw new RuntimeException(); } } diff --git a/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java b/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java index 114c9eec7b..7c08511c5b 100644 --- a/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java +++ b/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java @@ -37,7 +37,7 @@ public class RelaunchClassLoader extends URLClassLoader this.parent = getClass().getClassLoader(); this.cachedClasses = new HashMap(1000); this.transformers = new ArrayList(2); - ReflectionHelper.setPrivateValue(ClassLoader.class, null, this, "scl"); +// ReflectionHelper.setPrivateValue(ClassLoader.class, null, this, "scl"); Thread.currentThread().setContextClassLoader(this); } diff --git a/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java b/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java index 4fe9ccda4c..bfbebe0aba 100644 --- a/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java +++ b/fml/common/cpw/mods/fml/relauncher/RelaunchLibraryManager.java @@ -158,7 +158,7 @@ public class RelaunchLibraryManager { if (!caughtErrors.isEmpty()) { - FMLLog.severe("There were errors during initial FML setup. " + + FMLRelaunchLog.severe("There were errors during initial FML setup. " + "Some files failed to download or were otherwise corrupted. " + "You will need to manually obtain the following files from " + "these download links and ensure your lib directory is clean. "); @@ -166,21 +166,21 @@ public class RelaunchLibraryManager { for (String file : set.getLibraries()) { - FMLLog.severe("*** Download "+set.getRootURL(), file); + FMLRelaunchLog.severe("*** Download "+set.getRootURL(), file); } } - FMLLog.severe("<===========>"); - FMLLog.severe("The following is the errors that caused the setup to fail. " + + FMLRelaunchLog.severe("<===========>"); + FMLRelaunchLog.severe("The following is the errors that caused the setup to fail. " + "They may help you diagnose and resolve the issue"); for (Throwable t : caughtErrors) { - FMLLog.severe(t.getMessage()); + FMLRelaunchLog.severe(t.getMessage()); } - FMLLog.severe("<<< ==== >>>"); - FMLLog.severe("The following is diagnostic information for developers to review."); + FMLRelaunchLog.severe("<<< ==== >>>"); + FMLRelaunchLog.severe("The following is diagnostic information for developers to review."); for (Throwable t : caughtErrors) { - FMLLog.log(Level.SEVERE, t, "Error details"); + FMLRelaunchLog.log(Level.SEVERE, t, "Error details"); } throw new RuntimeException("A fatal error occured and FML cannot continue"); } @@ -256,7 +256,7 @@ public class RelaunchLibraryManager for (File coreMod : coreModList) { - FMLLog.fine("Found a candidate coremod %s", coreMod.getName()); + FMLRelaunchLog.fine("Found a candidate coremod %s", coreMod.getName()); JarFile jar; Attributes mfAttributes; try @@ -266,14 +266,14 @@ public class RelaunchLibraryManager } catch (IOException ioe) { - FMLLog.log(Level.SEVERE, ioe, "Unable to read the coremod jar file %s - ignoring", coreMod.getName()); + FMLRelaunchLog.log(Level.SEVERE, ioe, "Unable to read the coremod jar file %s - ignoring", coreMod.getName()); continue; } String fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin"); if (fmlCorePlugin == null) { - FMLLog.severe("The coremod %s does not contain a valid jar manifest- it will be ignored", coreMod.getName()); + FMLRelaunchLog.severe("The coremod %s does not contain a valid jar manifest- it will be ignored", coreMod.getName()); continue; } @@ -300,7 +300,7 @@ public class RelaunchLibraryManager } catch (MalformedURLException e) { - FMLLog.log(Level.SEVERE, e, "Unable to convert file into a URL. weird"); + FMLRelaunchLog.log(Level.SEVERE, e, "Unable to convert file into a URL. weird"); continue; } try @@ -316,23 +316,23 @@ public class RelaunchLibraryManager libraries.add((ILibrarySet) Class.forName(libName, true, classLoader).newInstance()); } } - FMLLog.fine("Loaded coremod %s", coreMod.getName()); + FMLRelaunchLog.fine("Loaded coremod %s", coreMod.getName()); } catch (ClassNotFoundException cnfe) { - FMLLog.log(Level.SEVERE, cnfe, "Coremod %s: Unable to class load the plugin %s", coreMod.getName(), fmlCorePlugin); + FMLRelaunchLog.log(Level.SEVERE, cnfe, "Coremod %s: Unable to class load the plugin %s", coreMod.getName(), fmlCorePlugin); } catch (ClassCastException cce) { - FMLLog.log(Level.SEVERE, cce, "Coremod %s: The plugin %s is not an implementor of IFMLLoadingPlugin", coreMod.getName(), fmlCorePlugin); + FMLRelaunchLog.log(Level.SEVERE, cce, "Coremod %s: The plugin %s is not an implementor of IFMLLoadingPlugin", coreMod.getName(), fmlCorePlugin); } catch (InstantiationException ie) { - FMLLog.log(Level.SEVERE, ie, "Coremod %s: The plugin class %s was not instantiable", coreMod.getName(), fmlCorePlugin); + FMLRelaunchLog.log(Level.SEVERE, ie, "Coremod %s: The plugin class %s was not instantiable", coreMod.getName(), fmlCorePlugin); } catch (IllegalAccessException iae) { - FMLLog.log(Level.SEVERE, iae, "Coremod %s: The plugin class %s was not accessible", coreMod.getName(), fmlCorePlugin); + FMLRelaunchLog.log(Level.SEVERE, iae, "Coremod %s: The plugin class %s was not accessible", coreMod.getName(), fmlCorePlugin); } } } @@ -419,7 +419,7 @@ public class RelaunchLibraryManager { URL libDownload = new URL(String.format(rootUrl,libFile.getName())); String infoString = String.format("Downloading file %s", libDownload.toString()); - FMLLog.info(infoString); + FMLRelaunchLog.info(infoString); InputStream urlStream = libDownload.openStream(); urlStream = FMLRelauncher.instance().wrapStream(urlStream, infoString); ReadableByteChannel urlChannel = Channels.newChannel(urlStream); @@ -430,11 +430,11 @@ public class RelaunchLibraryManager libFileStream.close(); urlChannel.close(); urlStream.close(); - FMLLog.info("Download complete"); + FMLRelaunchLog.info("Download complete"); } catch (Exception e) { - FMLLog.severe("There was a problem downloading the file %s automatically. Perhaps you" + + FMLRelaunchLog.severe("There was a problem downloading the file %s automatically. Perhaps you" + "have an environment without internet access. You will need to download " + "the file manually\n", libFile.getName()); libFile.delete(); diff --git a/fml/common/fml_marker.cfg b/fml/common/fml_marker.cfg new file mode 100644 index 0000000000..56c6df5dd2 --- /dev/null +++ b/fml/common/fml_marker.cfg @@ -0,0 +1,4 @@ +# Marker interfaces to add to minecraft - helps in bukkit and client/server unification +# Only runs at runtime because it's not necessary at compile time +# entityplayer -> network/player +of cpw/mods/fml/common/network/Player \ No newline at end of file diff --git a/fml/patches/common/net/minecraft/src/NetHandler.java.patch b/fml/patches/common/net/minecraft/src/NetHandler.java.patch index 7d88ac6b6c..94b52f460d 100644 --- a/fml/patches/common/net/minecraft/src/NetHandler.java.patch +++ b/fml/patches/common/net/minecraft/src/NetHandler.java.patch @@ -1,9 +1,11 @@ --- ../src-base/common/net/minecraft/src/NetHandler.java +++ ../src-work/common/net/minecraft/src/NetHandler.java -@@ -345,4 +345,6 @@ +@@ -345,4 +345,8 @@ { return false; } + + public abstract void handleVanilla250Packet(Packet250CustomPayload payload); ++ ++ public abstract EntityPlayer getPlayer(); } diff --git a/fml/patches/common/net/minecraft/src/NetLoginHandler.java.patch b/fml/patches/common/net/minecraft/src/NetLoginHandler.java.patch index 41fed01829..62ab95b8ad 100644 --- a/fml/patches/common/net/minecraft/src/NetLoginHandler.java.patch +++ b/fml/patches/common/net/minecraft/src/NetLoginHandler.java.patch @@ -9,7 +9,23 @@ import net.minecraft.server.MinecraftServer; public class NetLoginHandler extends NetHandler -@@ -129,8 +131,11 @@ +@@ -39,7 +41,7 @@ + this.func_72529_d(); + } + +- if (this.field_72535_g++ == 600) ++ if (this.field_72535_g++ == 6000) + { + this.func_72527_a("Took too long to log in"); + } +@@ -125,12 +127,17 @@ + } + } + +- public void func_72455_a(Packet1Login p_72455_1_) {} ++ public void func_72455_a(Packet1Login p_72455_1_) { ++ FMLNetworkHandler.handleLoginPacketOnServer(this, p_72455_1_); ++ } public void func_72529_d() { @@ -23,7 +39,7 @@ if (var1 != null) { this.func_72527_a(var1); -@@ -221,4 +226,15 @@ +@@ -221,4 +228,20 @@ { return p_72531_0_.field_72544_i = p_72531_1_; } @@ -38,4 +54,9 @@ + { + // NOOP for login + } ++ ++ public EntityPlayer getPlayer() ++ { ++ return null; ++ }; } diff --git a/fml/patches/common/net/minecraft/src/NetServerHandler.java.patch b/fml/patches/common/net/minecraft/src/NetServerHandler.java.patch index 6a66004d53..b244e39ff7 100644 --- a/fml/patches/common/net/minecraft/src/NetServerHandler.java.patch +++ b/fml/patches/common/net/minecraft/src/NetServerHandler.java.patch @@ -21,3 +21,14 @@ DataInputStream var2; ItemStack var3; ItemStack var4; +@@ -1028,4 +1035,10 @@ + } + } + } ++ ++ @Override ++ public EntityPlayer getPlayer() ++ { ++ return field_72574_e; ++ } + } diff --git a/fml/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch b/fml/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch index fc7deade2d..54fade9ca6 100644 --- a/fml/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch +++ b/fml/patches/minecraft/net/minecraft/src/NetClientHandler.java.patch @@ -22,7 +22,7 @@ public void func_72501_a(Packet250CustomPayload p_72501_1_) { -+ ++ FMLNetworkHandler.handlePacket250Packet(p_72501_1_, field_72555_g, this); + } + + public void handleVanilla250Packet(Packet250CustomPayload p_72501_1_) @@ -30,3 +30,14 @@ if ("MC|TPack".equals(p_72501_1_.field_73630_a)) { String[] var2 = (new String(p_72501_1_.field_73629_c)).split("\u0000"); +@@ -1208,4 +1217,10 @@ + { + return this.field_72555_g; + } ++ ++ @Override ++ public EntityPlayer getPlayer() ++ { ++ return field_72563_h.field_71439_g; ++ } + } diff --git a/fml/patches/minecraft/net/minecraft/src/ServerConfigurationManager.java.patch b/fml/patches/minecraft/net/minecraft/src/ServerConfigurationManager.java.patch new file mode 100644 index 0000000000..45325d9a8a --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/src/ServerConfigurationManager.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/net/minecraft/src/ServerConfigurationManager.java ++++ ../src-work/minecraft/net/minecraft/src/ServerConfigurationManager.java +@@ -9,6 +9,8 @@ + import java.util.List; + import java.util.Set; + import java.util.logging.Logger; ++ ++import cpw.mods.fml.common.network.FMLNetworkHandler; + import net.minecraft.server.MinecraftServer; + + public abstract class ServerConfigurationManager +@@ -54,6 +56,7 @@ + ChunkCoordinates var5 = var4.func_72861_E(); + this.func_72381_a(p_72355_2_, (EntityPlayerMP)null, var4); + NetServerHandler var6 = new NetServerHandler(this.field_72400_f, p_72355_1_, p_72355_2_); ++ FMLNetworkHandler.handlePlayerLogin(p_72355_2_, var6, p_72355_1_); + var6.func_72567_b(new Packet1Login(p_72355_2_.field_70157_k, var4.func_72912_H().func_76067_t(), p_72355_2_.field_71134_c.func_73081_b(), var4.func_72912_H().func_76093_s(), var4.field_73011_w.field_76574_g, var4.field_73013_u, var4.func_72800_K(), this.func_72352_l())); + var6.func_72567_b(new Packet6SpawnPosition(var5.field_71574_a, var5.field_71572_b, var5.field_71573_c)); + var6.func_72567_b(new Packet202PlayerAbilities(p_72355_2_.field_71075_bZ));