From c6a0bc2487daa5053b6932e47d523b4a2bc8d613 Mon Sep 17 00:00:00 2001 From: Christian Weeks Date: Tue, 3 Apr 2012 17:04:26 -0400 Subject: [PATCH] Modloader complete --- common/cpw/mods/fml/common/FMLHooks.java | 32 +++++++++++++ .../cpw/mods/fml/common/FMLModContainer.java | 27 +++++++++++ .../cpw/mods/fml/common/INetworkHandler.java | 25 +++++++++++ common/cpw/mods/fml/common/ModContainer.java | 3 ++ server/cpw/mods/fml/server/FMLHandler.java | 35 +++++++++++++-- .../fml/server/ModLoaderModContainer.java | 17 +++++++ server/net/minecraft/src/BaseMod.java | 45 ++++++++++++++++++- server/net/minecraft/src/ModLoader.java | 27 +++-------- 8 files changed, 186 insertions(+), 25 deletions(-) create mode 100644 common/cpw/mods/fml/common/INetworkHandler.java diff --git a/common/cpw/mods/fml/common/FMLHooks.java b/common/cpw/mods/fml/common/FMLHooks.java index 1bb71e8888..9ae145e59f 100644 --- a/common/cpw/mods/fml/common/FMLHooks.java +++ b/common/cpw/mods/fml/common/FMLHooks.java @@ -13,10 +13,18 @@ */ package cpw.mods.fml.common; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + public class FMLHooks { private static final FMLHooks INSTANCE=new FMLHooks(); + private Map> channelList=new HashMap>(); + private Map modChannels=new HashMap(); + public void gameTickStart() { for (ModContainer mod : Loader.getModList()) { mod.tickStart(); @@ -35,4 +43,28 @@ public class FMLHooks { public static FMLHooks instance() { return INSTANCE; } + + public ModContainer getModForChannel(String channel) { + return modChannels.get(channel); + } + /** + * @param modLoaderModContainer + * @return + */ + public Set getChannelListFor(ModContainer container) { + return channelList.get(container); + } + + public void registerChannel(ModContainer container, String channelName) { + if (modChannels.containsKey(channelName)) { + Loader.log.severe(String.format("Mod %s tried to register network channel %s, already registered to %s", container, channelName, modChannels.get(channelName))); + throw new LoaderException(); + } + Set list=channelList.get(container); + if (list==null) { + list=new HashSet(); + channelList.put(container, list); + } + list.add(channelName); + } } diff --git a/common/cpw/mods/fml/common/FMLModContainer.java b/common/cpw/mods/fml/common/FMLModContainer.java index c33b911961..1fde1869ac 100644 --- a/common/cpw/mods/fml/common/FMLModContainer.java +++ b/common/cpw/mods/fml/common/FMLModContainer.java @@ -203,4 +203,31 @@ public class FMLModContainer implements ModContainer { public String toString() { return getSource(); } + + /* (non-Javadoc) + * @see cpw.mods.fml.common.ModContainer#wantsNetworkPackets() + */ + @Override + public boolean wantsNetworkPackets() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see cpw.mods.fml.common.ModContainer#getNetworkHandler() + */ + @Override + public INetworkHandler getNetworkHandler() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see cpw.mods.fml.common.ModContainer#ownsNetworkChannel(java.lang.String) + */ + @Override + public boolean ownsNetworkChannel(String channel) { + // TODO Auto-generated method stub + return false; + } } diff --git a/common/cpw/mods/fml/common/INetworkHandler.java b/common/cpw/mods/fml/common/INetworkHandler.java new file mode 100644 index 0000000000..489395e3df --- /dev/null +++ b/common/cpw/mods/fml/common/INetworkHandler.java @@ -0,0 +1,25 @@ +/* + * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package cpw.mods.fml.common; + + +/** + * @author cpw + * + */ +public interface INetworkHandler { + boolean onChat(Object... data); + void onPacket250Packet(Object... data); + void onLogin(Object... data); + boolean ownsChannel(String channelName); +} diff --git a/common/cpw/mods/fml/common/ModContainer.java b/common/cpw/mods/fml/common/ModContainer.java index 19d70f1008..a09f15dc36 100644 --- a/common/cpw/mods/fml/common/ModContainer.java +++ b/common/cpw/mods/fml/common/ModContainer.java @@ -41,4 +41,7 @@ public interface ModContainer { List getDependencies(); List getPreDepends(); List getPostDepends(); + boolean wantsNetworkPackets(); + INetworkHandler getNetworkHandler(); + boolean ownsNetworkChannel(String channel); } diff --git a/server/cpw/mods/fml/server/FMLHandler.java b/server/cpw/mods/fml/server/FMLHandler.java index cc5ed5785b..8de9feae0b 100644 --- a/server/cpw/mods/fml/server/FMLHandler.java +++ b/server/cpw/mods/fml/server/FMLHandler.java @@ -16,10 +16,6 @@ import java.util.ArrayList; import java.util.Random; import java.util.logging.Logger; -import cpw.mods.fml.common.FMLHooks; -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer; - import net.minecraft.server.MinecraftServer; import net.minecraft.src.BaseMod; import net.minecraft.src.BiomeGenBase; @@ -28,7 +24,14 @@ import net.minecraft.src.EntityPlayer; import net.minecraft.src.IChunkProvider; import net.minecraft.src.IInventory; import net.minecraft.src.ItemStack; +import net.minecraft.src.NetworkManager; +import net.minecraft.src.Packet1Login; +import net.minecraft.src.Packet250CustomPayload; +import net.minecraft.src.Packet3Chat; import net.minecraft.src.World; +import cpw.mods.fml.common.FMLHooks; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; public class FMLHandler { private static final FMLHandler INSTANCE=new FMLHandler(); @@ -170,4 +173,28 @@ public class FMLHandler { } } } + + public boolean handleChatPacket(Packet3Chat chat, EntityPlayer player) { + for (ModContainer mod : Loader.getModList()) { + if (mod.wantsNetworkPackets() && mod.getNetworkHandler().onChat(chat,player)) { + return true; + } + } + return false; + } + + public void handlePacket250(Packet250CustomPayload packet, EntityPlayer player) { + ModContainer mod = FMLHooks.instance().getModForChannel(packet.field_44005_a); + if (mod!=null) { + mod.getNetworkHandler().onPacket250Packet(packet, player); + } + } + + public void handleLogin(Packet1Login packet, NetworkManager networkManager) { + for (ModContainer mod : Loader.getModList()) { + if (mod.wantsNetworkPackets()) { + mod.getNetworkHandler().onLogin(packet, networkManager); + } + } + } } diff --git a/server/cpw/mods/fml/server/ModLoaderModContainer.java b/server/cpw/mods/fml/server/ModLoaderModContainer.java index c499baa60b..f8caea04b3 100644 --- a/server/cpw/mods/fml/server/ModLoaderModContainer.java +++ b/server/cpw/mods/fml/server/ModLoaderModContainer.java @@ -26,8 +26,10 @@ import java.util.StringTokenizer; import net.minecraft.src.BaseMod; import net.minecraft.src.MLProp; +import cpw.mods.fml.common.FMLHooks; import cpw.mods.fml.common.ICraftingHandler; import cpw.mods.fml.common.IDispenseHandler; +import cpw.mods.fml.common.INetworkHandler; import cpw.mods.fml.common.IPickupNotifier; import cpw.mods.fml.common.IWorldGenerator; import cpw.mods.fml.common.Loader; @@ -358,4 +360,19 @@ public class ModLoaderModContainer implements ModContainer { public String toString() { return modSource; } + + @Override + public boolean wantsNetworkPackets() { + return true; + } + + @Override + public INetworkHandler getNetworkHandler() { + return mod; + } + + @Override + public boolean ownsNetworkChannel(String channel) { + return FMLHooks.instance().getChannelListFor(this).contains(channel); + } } diff --git a/server/net/minecraft/src/BaseMod.java b/server/net/minecraft/src/BaseMod.java index 899ba2aaf0..846cfe8334 100644 --- a/server/net/minecraft/src/BaseMod.java +++ b/server/net/minecraft/src/BaseMod.java @@ -17,10 +17,11 @@ import java.util.Random; import net.minecraft.server.MinecraftServer; import cpw.mods.fml.common.ICraftingHandler; import cpw.mods.fml.common.IDispenseHandler; +import cpw.mods.fml.common.INetworkHandler; import cpw.mods.fml.common.IPickupNotifier; import cpw.mods.fml.common.IWorldGenerator; -public abstract class BaseMod implements IWorldGenerator, IPickupNotifier, IDispenseHandler, ICraftingHandler { +public abstract class BaseMod implements IWorldGenerator, IPickupNotifier, IDispenseHandler, ICraftingHandler, INetworkHandler { // CALLBACK MECHANISMS @Override public void onCrafting(Object... craftingParameters) { @@ -36,6 +37,20 @@ public abstract class BaseMod implements IWorldGenerator, IPickupNotifier, IDisp return dispenseEntity((World)data[0], x, y, z, xVelocity, zVelocity, (ItemStack)data[1]); } + @Override + public boolean onChat(Object... data) { + return onChatMessageReceived((EntityPlayer)data[1], (Packet3Chat)data[0]); + } + @Override + public void onLogin(Object... data) { + onClientLogin((Packet1Login)data[0],(NetworkManager)data[1]); + } + + @Override + public void onPacket250Packet(Object... data) { + onPacket250Received((EntityPlayer)data[1], (Packet250CustomPayload)data[0]); + } + @Override public void notifyPickup(Object... pickupData) { EntityItem item=(EntityItem) pickupData[0]; @@ -194,6 +209,34 @@ public abstract class BaseMod implements IWorldGenerator, IPickupNotifier, IDisp return getName()+" "+getVersion(); } + /** + * Called when a 250 packet is received on a channel registered to this mod + * + * @param source + * @param payload + */ + public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload) { + + } + + /** + * Called when a new client logs in. Ensure you register your Packet250 channels with them + * @param login + * @param data + */ + public void onClientLogin(Packet1Login login, NetworkManager data) { + + } + + /** + * Called when a chat message is received. Return true to stop further processing + * @param source + * @param chat + * @return + */ + public boolean onChatMessageReceived(EntityPlayer source, Packet3Chat chat) { + return false; + } // Spare client junk // ------- // void addRenderer(Map, Render> renderers); diff --git a/server/net/minecraft/src/ModLoader.java b/server/net/minecraft/src/ModLoader.java index 3f48f407b5..6c94876398 100644 --- a/server/net/minecraft/src/ModLoader.java +++ b/server/net/minecraft/src/ModLoader.java @@ -15,28 +15,13 @@ package net.minecraft.src; import java.util.List; import java.util.logging.Logger; +import net.minecraft.server.MinecraftServer; +import cpw.mods.fml.common.FMLHooks; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ReflectionHelper; import cpw.mods.fml.server.FMLHandler; import cpw.mods.fml.server.ModLoaderModContainer; - -import net.minecraft.server.MinecraftServer; -import net.minecraft.src.Achievement; -import net.minecraft.src.BiomeGenBase; -import net.minecraft.src.Block; -import net.minecraft.src.Entity; -import net.minecraft.src.EntityLiving; -import net.minecraft.src.EntityPlayer; -import net.minecraft.src.EnumCreatureType; -import net.minecraft.src.IChunkProvider; -import net.minecraft.src.IInventory; -import net.minecraft.src.ItemBlock; -import net.minecraft.src.ItemStack; -import net.minecraft.src.Packet250CustomPayload; -import net.minecraft.src.TileEntity; -import net.minecraft.src.World; - public class ModLoader { /** * @@ -232,7 +217,7 @@ public class ModLoader { } /** - * Currently unimplemented + * Remove a container and drop all the items in it on the ground around * @param world * @param x * @param y @@ -332,7 +317,7 @@ public class ModLoader { } /** - * Unimplemented on the server. New code that didn't exist prior to this implementation + * This method is a call in hook from modified external code. Implemented elsewhere. * @param packet */ @Deprecated @@ -379,11 +364,13 @@ public class ModLoader { } /** - * Unimplemented at present + * Register the mod for packets on this channel. This only registers the channel with Forge Mod Loader, not + * with clients connecting- use BaseMod.onClientLogin to tell them about your custom channel * @param mod * @param channel */ public static void registerPacketChannel(BaseMod mod, String channel) { + FMLHooks.instance().registerChannel(ModLoaderModContainer.findContainerFor(mod),channel); } /**