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 }