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