    001    package cpw.mods.fml.client.modloader;
    002
    003    import java.util.Collection;
    004    import java.util.Collections;
    005    import java.util.Map;
    006    import java.util.Map.Entry;
    007    import java.util.logging.Level;
    008
    009    import net.minecraft.client.Minecraft;
    010    import net.minecraft.src.BaseMod;
    011    import net.minecraft.src.Entity;
    012    import net.minecraft.src.EntityClientPlayerMP;
    013    import net.minecraft.src.EntityPlayer;
    014    import net.minecraft.src.KeyBinding;
    015    import net.minecraft.src.NetClientHandler;
    016    import net.minecraft.src.NetHandler;
    017    import net.minecraft.src.INetworkManager;
    018    import net.minecraft.src.Packet250CustomPayload;
    019    import net.minecraft.src.Render;
    020    import net.minecraft.src.RenderManager;
    021
    022    import com.google.common.base.Equivalences;
    023    import com.google.common.base.Supplier;
    024    import com.google.common.base.Suppliers;
    025    import com.google.common.collect.Iterables;
    026    import com.google.common.collect.Iterators;
    027    import com.google.common.collect.MapDifference;
    028    import com.google.common.collect.MapDifference.ValueDifference;
    029    import com.google.common.collect.MapMaker;
    030    import com.google.common.collect.Maps;
    031    import com.google.common.collect.Multimap;
    032    import com.google.common.collect.Multimaps;
    033
    034    import cpw.mods.fml.client.FMLClientHandler;
    035    import cpw.mods.fml.client.registry.KeyBindingRegistry;
    036    import cpw.mods.fml.client.registry.RenderingRegistry;
    037    import cpw.mods.fml.common.FMLLog;
    038    import cpw.mods.fml.common.Loader;
    039    import cpw.mods.fml.common.modloader.BaseModProxy;
    040    import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
    041    import cpw.mods.fml.common.modloader.ModLoaderHelper;
    042    import cpw.mods.fml.common.modloader.ModLoaderModContainer;
    043    import cpw.mods.fml.common.network.EntitySpawnPacket;
    044    import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
    045
    046    public class ModLoaderClientHelper implements IModLoaderSidedHelper
    047    {
    048        public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
    049        {
    050            int renderId=RenderingRegistry.getNextAvailableRenderId();
    051            ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
    052            RenderingRegistry.registerBlockHandler(bri);
    053            return renderId;
    054        }
    055
    056
    057        public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
    058        {
    059            FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId());
    060            BaseMod mod = (BaseMod) mc.getMod();
    061
    062            Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.instance.entityRenderMap);
    063
    064            try
    065            {
    066                FMLLog.finest("Requesting renderers from basemod %s", mc.getModId());
    067                mod.addRenderer(renderers);
    068                FMLLog.finest("Received %d renderers from basemod %s", renderers.size(), mc.getModId());
    069            }
    070            catch (Exception e)
    071            {
    072                FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the addRenderer call. Continuing, but expect odd results", mc.getModId());
    073            }
    074
    075            MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.instance.entityRenderMap, renderers, Equivalences.identity());
    076
    077            for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
    078            {
    079                FMLLog.warning("The mod %s attempted to remove an entity renderer %s from the entity map. This will be ignored.", mc.getModId(), e.getKey().getName());
    080            }
    081
    082            for (Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnRight().entrySet())
    083            {
    084                FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName());
    085                RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue());
    086            }
    087
    088            for (Entry<Class<? extends Entity>, ValueDifference<Render>> e : difference.entriesDiffering().entrySet())
    089            {
    090                FMLLog.finest("Registering ModLoader entity rendering override for %s as instance of %s", e.getKey().getName(), e.getValue().rightValue().getClass().getName());
    091                RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue().rightValue());
    092            }
    093
    094            try
    095            {
    096                mod.registerAnimation(game);
    097            }
    098            catch (Exception e)
    099            {
    100                FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the registerAnimation call. Continuing, but expect odd results", mc.getModId());
    101            }
    102        }
    103
    104        public ModLoaderClientHelper(Minecraft client)
    105        {
    106            this.client = client;
    107            ModLoaderHelper.sidedHelper = this;
    108            keyBindingContainers = Multimaps.newMultimap(Maps.<ModLoaderModContainer, Collection<ModLoaderKeyBindingHandler>>newHashMap(), new Supplier<Collection<ModLoaderKeyBindingHandler>>()
    109            {
    110                @Override
    111                public Collection<ModLoaderKeyBindingHandler> get()
    112                {
    113                    return Collections.singleton(new ModLoaderKeyBindingHandler());
    114                }
    115            });
    116        }
    117
    118        private Minecraft client;
    119        private static Multimap<ModLoaderModContainer, ModLoaderKeyBindingHandler> keyBindingContainers;
    120
    121        @Override
    122        public void finishModLoading(ModLoaderModContainer mc)
    123        {
    124            handleFinishLoadingFor(mc, client);
    125        }
    126
    127
    128        public static void registerKeyBinding(BaseModProxy mod, KeyBinding keyHandler, boolean allowRepeat)
    129        {
    130            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
    131            ModLoaderKeyBindingHandler handler = Iterables.getOnlyElement(keyBindingContainers.get(mlmc));
    132            handler.setModContainer(mlmc);
    133            handler.addKeyBinding(keyHandler, allowRepeat);
    134            KeyBindingRegistry.registerKeyBinding(handler);
    135        }
    136
    137
    138        @Override
    139        public Object getClientGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
    140        {
    141            return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z);
    142        }
    143
    144
    145        @Override
    146        public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er)
    147        {
    148            return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.theWorld, input.scaledX, input.scaledY, input.scaledZ);
    149        }
    150
    151
    152        @Override
    153        public void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet)
    154        {
    155            ((net.minecraft.src.BaseMod)mod).clientCustomPayload(client.thePlayer.sendQueue, packet);
    156        }
    157
    158        private Map<INetworkManager,NetHandler> managerLookups = new MapMaker().weakKeys().weakValues().makeMap();
    159        @Override
    160        public void clientConnectionOpened(NetHandler netClientHandler, INetworkManager manager, BaseModProxy mod)
    161        {
    162            managerLookups.put(manager, netClientHandler);
    163            ((BaseMod)mod).clientConnect((NetClientHandler)netClientHandler);
    164        }
    165
    166
    167        @Override
    168        public boolean clientConnectionClosed(INetworkManager manager, BaseModProxy mod)
    169        {
    170            if (managerLookups.containsKey(manager))
    171            {
    172                ((BaseMod)mod).clientDisconnect((NetClientHandler) managerLookups.get(manager));
    173                return true;
    174            }
    175            return false;
    176        }
    177    }