From 2cf960b64d8414fcaba598296a46e8632f7c6070 Mon Sep 17 00:00:00 2001 From: Christian Weeks Date: Sat, 2 Jun 2012 15:13:55 -0400 Subject: [PATCH] Introduce a proxy side loader for mod use --- .../cpw/mods/fml/client/FMLClientHandler.java | 41 +-- .../mods/fml/client/OptifineModContainer.java | 239 +----------------- client/net/minecraft/src/SidedProxy.java | 39 +++ .../cpw/mods/fml/common/FMLCommonHandler.java | 27 +- .../cpw/mods/fml/common/FMLModContainer.java | 9 + .../cpw/mods/fml/common/IFMLSidedHandler.java | 5 +- common/cpw/mods/fml/common/Loader.java | 2 + common/cpw/mods/fml/common/ModContainer.java | 4 + common/cpw/mods/fml/common/ProxyInjector.java | 76 ++++++ common/cpw/mods/fml/common/Side.java | 35 +++ .../fml/common/modloader/ModLoaderHelper.java | 8 +- .../modloader/ModLoaderModContainer.java | 10 + .../cpw/mods/fml/server/FMLServerHandler.java | 47 ++-- server/net/minecraft/src/SidedProxy.java | 39 +++ 14 files changed, 290 insertions(+), 291 deletions(-) create mode 100644 client/net/minecraft/src/SidedProxy.java create mode 100644 common/cpw/mods/fml/common/ProxyInjector.java create mode 100644 common/cpw/mods/fml/common/Side.java create mode 100644 server/net/minecraft/src/SidedProxy.java diff --git a/client/cpw/mods/fml/client/FMLClientHandler.java b/client/cpw/mods/fml/client/FMLClientHandler.java index 338a95ff41..f95450725e 100644 --- a/client/cpw/mods/fml/client/FMLClientHandler.java +++ b/client/cpw/mods/fml/client/FMLClientHandler.java @@ -70,6 +70,7 @@ import net.minecraft.src.RenderBlocks; import net.minecraft.src.RenderEngine; import net.minecraft.src.RenderManager; import net.minecraft.src.RenderPlayer; +import net.minecraft.src.SidedProxy; import net.minecraft.src.StringTranslate; import net.minecraft.src.TextureFX; import net.minecraft.src.TexturePackBase; @@ -85,7 +86,9 @@ import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModContainer.TickType; import cpw.mods.fml.common.ModMetadata; +import cpw.mods.fml.common.ProxyInjector; import cpw.mods.fml.common.ReflectionHelper; +import cpw.mods.fml.common.Side; import cpw.mods.fml.common.modloader.ModLoaderHelper; import cpw.mods.fml.common.modloader.ModLoaderModContainer; import cpw.mods.fml.common.modloader.ModProperty; @@ -581,24 +584,6 @@ public class FMLClientHandler implements IFMLSidedHandler } } - /** - * Are we a server? - */ - @Override - public boolean isServer() - { - return false; - } - - /** - * Are we a client? - */ - @Override - public boolean isClient() - { - return true; - } - @Override public File getMinecraftRootDirectory() { @@ -1126,4 +1111,24 @@ public class FMLClientHandler implements IFMLSidedHandler return Collections.emptyList(); } } + + @Override + public Side getSide() + { + return Side.CLIENT; + } + + @Override + public ProxyInjector findSidedProxyOn(cpw.mods.fml.common.modloader.BaseMod mod) + { + for (Field f : mod.getClass().getDeclaredFields()) + { + if (f.isAnnotationPresent(SidedProxy.class)) + { + SidedProxy sp = f.getAnnotation(SidedProxy.class); + return new ProxyInjector(sp.clientSide(), sp.serverSide(), sp.bukkitSide(), f); + } + } + return null; + } } diff --git a/client/cpw/mods/fml/client/OptifineModContainer.java b/client/cpw/mods/fml/client/OptifineModContainer.java index 40ae4afa8a..944dca941d 100644 --- a/client/cpw/mods/fml/client/OptifineModContainer.java +++ b/client/cpw/mods/fml/client/OptifineModContainer.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import cpw.mods.fml.common.FMLModContainer; import cpw.mods.fml.common.IConsoleHandler; import cpw.mods.fml.common.ICraftingHandler; import cpw.mods.fml.common.IDispenseHandler; @@ -34,7 +35,7 @@ import cpw.mods.fml.common.ModMetadata; * @author cpw * */ -public class OptifineModContainer implements ModContainer +public class OptifineModContainer extends FMLModContainer { private String optifineVersion; private ModMetadata metadata; @@ -43,6 +44,7 @@ public class OptifineModContainer implements ModContainer */ public OptifineModContainer(Class optifineConfig) { + super("Optifine"); try { optifineVersion = (String) optifineConfig.getField("VERSION").get(null); @@ -53,246 +55,11 @@ public class OptifineModContainer implements ModContainer } } - @Override - public boolean wantsPreInit() - { - return false; - } - - @Override - public boolean wantsPostInit() - { - return false; - } - - @Override - public void preInit() - { - - } - - @Override - public void init() - { - - } - - @Override - public void postInit() - { - - } - @Override public String getName() { return "Optifine"; } - - @Override - public ModState getModState() - { - return ModState.AVAILABLE; - } - - @Override - public void nextState() - { - - } - - @Override - public void tickStart(TickType tick, Object... data) - { - - } - - @Override - public void tickEnd(TickType tick, Object... data) - { - - } - - @Override - public boolean matches(Object mod) - { - return false; - } - - @Override - public File getSource() - { - return new File("."); - } - - @Override - public String getSortingRules() - { - return ""; - } - - @Override - public Object getMod() - { - return null; - } - - @Override - public boolean generatesWorld() - { - return false; - } - - @Override - public IWorldGenerator getWorldGenerator() - { - return null; - } - - @Override - public int lookupFuelValue(int itemId, int itemDamage) - { - return 0; - } - - @Override - public boolean wantsPickupNotification() - { - return false; - } - - @Override - public IPickupNotifier getPickupNotifier() - { - return null; - } - - @Override - public boolean wantsToDispense() - { - return false; - } - - @Override - public IDispenseHandler getDispenseHandler() - { - return null; - } - - @Override - public boolean wantsCraftingNotification() - { - return false; - } - - @Override - public ICraftingHandler getCraftingHandler() - { - return null; - } - - @Override - public List getDependencies() - { - return Collections.emptyList(); - } - - @Override - public List getPreDepends() - { - return Collections.emptyList(); - } - - @Override - public List getPostDepends() - { - return Collections.emptyList(); - } - - @Override - public boolean wantsNetworkPackets() - { - return false; - } - - @Override - public INetworkHandler getNetworkHandler() - { - return null; - } - - @Override - public boolean ownsNetworkChannel(String channel) - { - return false; - } - - @Override - public boolean wantsConsoleCommands() - { - return false; - } - - @Override - public IConsoleHandler getConsoleHandler() - { - return null; - } - - @Override - public boolean wantsPlayerTracking() - { - return false; - } - - @Override - public IPlayerTracker getPlayerTracker() - { - return null; - } - - @Override - public List getKeys() - { - return null; - } - - @Override - public SourceType getSourceType() - { - return SourceType.CLASSPATH; - } - - @Override - public void setSourceType(SourceType type) - { - - } - - @Override - public ModMetadata getMetadata() - { - return metadata; - } - - @Override - public void setMetadata(ModMetadata meta) - { - this.metadata=meta; - } - - @Override - public void gatherRenderers(Map renderers) - { - - } - - @Override - public void requestAnimations() - { - - } - @Override public String getVersion() { diff --git a/client/net/minecraft/src/SidedProxy.java b/client/net/minecraft/src/SidedProxy.java new file mode 100644 index 0000000000..008d63d186 --- /dev/null +++ b/client/net/minecraft/src/SidedProxy.java @@ -0,0 +1,39 @@ +/* + * 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 net.minecraft.src; + +/** + * @author cpw + * + */ +public @interface SidedProxy +{ + /** + * The name of the client side class to load and populate + * @return + */ + String clientSide() default ""; + + /** + * The name of the server side class to load and populate + * @return + */ + String serverSide() default ""; + + /** + * The name of the a special bukkit plugin class to load and populate + */ + String bukkitSide() default ""; +} diff --git a/common/cpw/mods/fml/common/FMLCommonHandler.java b/common/cpw/mods/fml/common/FMLCommonHandler.java index 94b2b20501..108cc12a4b 100644 --- a/common/cpw/mods/fml/common/FMLCommonHandler.java +++ b/common/cpw/mods/fml/common/FMLCommonHandler.java @@ -371,20 +371,9 @@ public class FMLCommonHandler languagePack.putAll(langPack); } - /** - * @return - */ - public boolean isServer() + public Side getSide() { - return sidedDelegate.isServer(); - } - - /** - * @return - */ - public boolean isClient() - { - return sidedDelegate.isClient(); + return sidedDelegate.getSide(); } public void addAuxilliaryModContainer(ModContainer ticker) @@ -514,4 +503,16 @@ public class FMLCommonHandler return sidedDelegate; } + /** + * @param mod + */ + public void injectSidedProxyDelegate(ModContainer mod) + { + ProxyInjector injector = mod.findSidedProxy(); + if (injector != null) + { + injector.inject(mod, sidedDelegate.getSide()); + } + } + } diff --git a/common/cpw/mods/fml/common/FMLModContainer.java b/common/cpw/mods/fml/common/FMLModContainer.java index cb6ae44144..b6f74a5c12 100644 --- a/common/cpw/mods/fml/common/FMLModContainer.java +++ b/common/cpw/mods/fml/common/FMLModContainer.java @@ -397,4 +397,13 @@ public class FMLModContainer implements ModContainer // TODO Auto-generated method stub return null; } + /* (non-Javadoc) + * @see cpw.mods.fml.common.ModContainer#findSidedProxy() + */ + @Override + public ProxyInjector findSidedProxy() + { + // TODO Auto-generated method stub + return null; + } } diff --git a/common/cpw/mods/fml/common/IFMLSidedHandler.java b/common/cpw/mods/fml/common/IFMLSidedHandler.java index ad1124cfb4..2724bce76b 100644 --- a/common/cpw/mods/fml/common/IFMLSidedHandler.java +++ b/common/cpw/mods/fml/common/IFMLSidedHandler.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Properties; import java.util.logging.Logger; +import cpw.mods.fml.common.modloader.BaseMod; import cpw.mods.fml.common.modloader.ModProperty; public interface IFMLSidedHandler @@ -15,8 +16,6 @@ public interface IFMLSidedHandler File getMinecraftRootDirectory(); boolean isModLoaderMod(Class clazz); ModContainer loadBaseModMod(Class clazz, File canonicalFile); - boolean isServer(); - boolean isClient(); Object getMinecraftInstance(); String getCurrentLanguage(); Properties getCurrentLanguageTable(); @@ -26,4 +25,6 @@ public interface IFMLSidedHandler void profileEnd(); ModProperty getModLoaderPropertyFor(Field f); List getAdditionalBrandingInformation(); + Side getSide(); + ProxyInjector findSidedProxyOn(BaseMod mod); } diff --git a/common/cpw/mods/fml/common/Loader.java b/common/cpw/mods/fml/common/Loader.java index 487fbe623f..24f5b9886f 100644 --- a/common/cpw/mods/fml/common/Loader.java +++ b/common/cpw/mods/fml/common/Loader.java @@ -242,6 +242,8 @@ public class Loader if (mod.getMetadata()!=null) { mod.getMetadata().associate(namedMods); } + + FMLCommonHandler.instance().injectSidedProxyDelegate(mod); } log.fine("Mod pre-initialization complete"); } diff --git a/common/cpw/mods/fml/common/ModContainer.java b/common/cpw/mods/fml/common/ModContainer.java index b461a8d7a2..675c0e53a0 100644 --- a/common/cpw/mods/fml/common/ModContainer.java +++ b/common/cpw/mods/fml/common/ModContainer.java @@ -241,4 +241,8 @@ public interface ModContainer * @return */ String getVersion(); + /** + * @return + */ + ProxyInjector findSidedProxy(); } diff --git a/common/cpw/mods/fml/common/ProxyInjector.java b/common/cpw/mods/fml/common/ProxyInjector.java new file mode 100644 index 0000000000..6ef5564196 --- /dev/null +++ b/common/cpw/mods/fml/common/ProxyInjector.java @@ -0,0 +1,76 @@ +/* + * 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; + +import java.lang.reflect.Field; + +/** + * @author cpw + * + */ +public class ProxyInjector +{ + private String clientName; + private String serverName; + private String bukkitName; + private Field target; + + public ProxyInjector(String clientName, String serverName, String bukkitName, Field target) + { + this.clientName = clientName; + this.serverName = serverName; + this.bukkitName = bukkitName; + this.target = target; + } + + public boolean isValidFor(Side type) + { + if (type == Side.CLIENT) + { + return !this.clientName.isEmpty(); + } + else if (type == Side.SERVER) + { + return !this.serverName.isEmpty(); + } + else if (type == Side.BUKKIT) + { + return !this.bukkitName.isEmpty(); + } + return false; + } + + public void inject(ModContainer mod, Side side) + { + String targetType = side == Side.CLIENT ? clientName : serverName; + try + { + Object proxy=Class.forName(targetType, false, Loader.instance().getModClassLoader()).newInstance(); + if (target.getType().isAssignableFrom(proxy.getClass())) + { + target.set(mod.getMod(), proxy); + } else { + FMLCommonHandler.instance().getFMLLogger().severe(String.format("Attempted to load a proxy type %s into %s, but the types don't match", targetType, target.getName())); + throw new LoaderException(); + } + } + catch (Exception e) + { + FMLCommonHandler.instance().getFMLLogger().severe(String.format("An error occured trying to load a proxy type %s into %s", targetType, target.getName())); + FMLCommonHandler.instance().getFMLLogger().throwing("ProxyInjector", "inject", e); + throw new LoaderException(e); + } + } +} diff --git a/common/cpw/mods/fml/common/Side.java b/common/cpw/mods/fml/common/Side.java new file mode 100644 index 0000000000..18e3ba7c95 --- /dev/null +++ b/common/cpw/mods/fml/common/Side.java @@ -0,0 +1,35 @@ +/* + * 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; + +public enum Side { + CLIENT, SERVER, BUKKIT; + + /** + * @return + */ + public boolean isServer() + { + return !isClient(); + } + + /** + * @return + */ + public boolean isClient() + { + return this == CLIENT; + } +} \ No newline at end of file diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java b/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java index c9d0cb57b6..26006b5f10 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderHelper.java @@ -34,13 +34,13 @@ public class ModLoaderHelper ModLoaderModContainer mlmc = findOrBuildModContainer(mod); EnumSet ticks = mlmc.getTickTypes(); // If we're enabled and we don't want clock ticks we get render ticks - if (enable && !useClock && FMLCommonHandler.instance().isClient()) { + if (enable && !useClock && FMLCommonHandler.instance().getSide().isClient()) { ticks.add(TickType.RENDER); } else { ticks.remove(TickType.RENDER); } // If we're enabled but we want clock ticks, or we're server side we get world ticks - if (enable && (useClock || FMLCommonHandler.instance().isServer())) { + if (enable && (useClock || FMLCommonHandler.instance().getSide().isServer())) { ticks.add(TickType.WORLD); } else { ticks.remove(TickType.WORLD); @@ -56,13 +56,13 @@ public class ModLoaderHelper ModLoaderModContainer mlmc = findOrBuildModContainer(mod); EnumSet ticks = mlmc.getTickTypes(); // If we're enabled and we don't want clock ticks we get render ticks - if (enable && !useClock && FMLCommonHandler.instance().isClient()) { + if (enable && !useClock && FMLCommonHandler.instance().getSide().isClient()) { ticks.add(TickType.GUI); } else { ticks.remove(TickType.GUI); } // If we're enabled but we want clock ticks, or we're server side we get world ticks - if (enable && (useClock || FMLCommonHandler.instance().isServer())) { + if (enable && (useClock || FMLCommonHandler.instance().getSide().isServer())) { ticks.add(TickType.WORLDGUI); } else { ticks.remove(TickType.WORLDGUI); diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java index 2a81a5cb71..d5fc329cae 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java @@ -47,6 +47,7 @@ import cpw.mods.fml.common.ModContainer.ModState; import cpw.mods.fml.common.ModContainer.SourceType; import cpw.mods.fml.common.ModContainer.TickType; import cpw.mods.fml.common.ModMetadata; +import cpw.mods.fml.common.ProxyInjector; public class ModLoaderModContainer implements ModContainer { @@ -681,4 +682,13 @@ public class ModLoaderModContainer implements ModContainer { return mod!=null ? mod.getVersion() : "Not available"; } + + /* (non-Javadoc) + * @see cpw.mods.fml.common.ModContainer#findSidedProxy() + */ + @Override + public ProxyInjector findSidedProxy() + { + return FMLCommonHandler.instance().getSidedDelegate().findSidedProxyOn(mod); + } } diff --git a/server/cpw/mods/fml/server/FMLServerHandler.java b/server/cpw/mods/fml/server/FMLServerHandler.java index 9fca2b897a..b85741871a 100644 --- a/server/cpw/mods/fml/server/FMLServerHandler.java +++ b/server/cpw/mods/fml/server/FMLServerHandler.java @@ -42,6 +42,7 @@ import net.minecraft.src.Packet250CustomPayload; import net.minecraft.src.Packet3Chat; import net.minecraft.src.Profiler; import net.minecraft.src.ServerRegistry; +import net.minecraft.src.SidedProxy; import net.minecraft.src.StringTranslate; import net.minecraft.src.World; import net.minecraft.src.WorldType; @@ -50,7 +51,9 @@ import cpw.mods.fml.common.IFMLSidedHandler; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModMetadata; +import cpw.mods.fml.common.ProxyInjector; import cpw.mods.fml.common.ReflectionHelper; +import cpw.mods.fml.common.Side; import cpw.mods.fml.common.modloader.ModLoaderModContainer; import cpw.mods.fml.common.modloader.ModProperty; import cpw.mods.fml.common.registry.FMLRegistry; @@ -478,24 +481,6 @@ public class FMLServerHandler implements IFMLSidedHandler } } - /** - * Are we a server? - */ - @Override - public boolean isServer() - { - return true; - } - - /** - * Are we a client? - */ - @Override - public boolean isClient() - { - return false; - } - @Override public File getMinecraftRootDirectory() { @@ -645,4 +630,30 @@ public class FMLServerHandler implements IFMLSidedHandler { return null; } + + /* (non-Javadoc) + * @see cpw.mods.fml.common.IFMLSidedHandler#getSide() + */ + @Override + public Side getSide() + { + return Side.SERVER; + } + + /* (non-Javadoc) + * @see cpw.mods.fml.common.IFMLSidedHandler#findSidedProxyOn(cpw.mods.fml.common.modloader.BaseMod) + */ + @Override + public ProxyInjector findSidedProxyOn(cpw.mods.fml.common.modloader.BaseMod mod) + { + for (Field f : mod.getClass().getDeclaredFields()) + { + if (f.isAnnotationPresent(SidedProxy.class)) + { + SidedProxy sp = f.getAnnotation(SidedProxy.class); + return new ProxyInjector(sp.clientSide(), sp.serverSide(), sp.bukkitSide(), f); + } + } + return null; + } } diff --git a/server/net/minecraft/src/SidedProxy.java b/server/net/minecraft/src/SidedProxy.java new file mode 100644 index 0000000000..008d63d186 --- /dev/null +++ b/server/net/minecraft/src/SidedProxy.java @@ -0,0 +1,39 @@ +/* + * 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 net.minecraft.src; + +/** + * @author cpw + * + */ +public @interface SidedProxy +{ + /** + * The name of the client side class to load and populate + * @return + */ + String clientSide() default ""; + + /** + * The name of the server side class to load and populate + * @return + */ + String serverSide() default ""; + + /** + * The name of the a special bukkit plugin class to load and populate + */ + String bukkitSide() default ""; +}