mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70f55c59c0 | ||
|
|
1c1716d833 | ||
|
|
d567f79652 | ||
|
|
ecd4e46a45 | ||
|
|
16fe495d18 | ||
|
|
4f70d23d0e | ||
|
|
290a3c94b7 | ||
|
|
9485dc5a96 | ||
|
|
e6abb69b0e | ||
|
|
e862052bb4 | ||
|
|
4071ad1278 | ||
|
|
60619643e6 | ||
|
|
b818769c1f | ||
|
|
12bc4bab0c | ||
|
|
8fccfa21df | ||
|
|
a697d043fc | ||
|
|
9d812f12cc | ||
|
|
869cf78e98 | ||
|
|
186680cd8c | ||
|
|
5aed6d995d | ||
|
|
3d7a665987 | ||
|
|
10a716969b | ||
|
|
0eb7180fc1 | ||
|
|
b1b4c61b80 | ||
|
|
359cfb5c98 | ||
|
|
8656fd50ce | ||
|
|
25a4dcb653 | ||
|
|
c90a853377 | ||
|
|
18069d8fd2 | ||
|
|
a40f4a75a9 | ||
|
|
5b6460b68c | ||
|
|
c0d1348e65 | ||
|
|
482c163344 | ||
|
|
221d1131b4 | ||
|
|
f19f426449 | ||
|
|
9dd9b6eb71 | ||
|
|
acb0b21d6d | ||
|
|
b17dd3c695 | ||
|
|
fa66ffaf3f | ||
|
|
b106420774 | ||
|
|
c971adb59b | ||
|
|
d6326deeb0 | ||
|
|
483667c919 | ||
|
|
8bef512803 | ||
|
|
501009c11f | ||
|
|
d3d430827f | ||
|
|
2d9b88bd52 | ||
|
|
93d5934ea7 | ||
|
|
180a279558 | ||
|
|
cf38461911 | ||
|
|
2c85539517 | ||
|
|
d651189581 | ||
|
|
f6a8cd556e | ||
|
|
3bde961dc7 | ||
|
|
6396beaef7 | ||
|
|
6bc6defb07 | ||
|
|
732861092f | ||
|
|
9fcc452ed3 | ||
|
|
26302a6ff2 | ||
|
|
62dbfb3837 | ||
|
|
b91cbe9794 | ||
|
|
93b8ba9576 | ||
|
|
23fdbbd03d | ||
|
|
d7a74d84ea | ||
|
|
58e6dd9794 | ||
|
|
907cf2d925 | ||
|
|
ee48a3673d | ||
|
|
c6f362b77f | ||
|
|
6e01c59635 | ||
|
|
d411f66903 | ||
|
|
0768dc1610 | ||
|
|
4c3db16842 | ||
|
|
805fd1dd90 | ||
|
|
c59996b24b | ||
|
|
e0a1e8293b | ||
|
|
e8af9c0233 | ||
|
|
a955d30d64 | ||
|
|
dbab3bb259 | ||
|
|
bd9c4ee99a | ||
|
|
a0cbd3755d | ||
|
|
12323e233f | ||
|
|
8a308db3d4 | ||
|
|
0583dc8b74 | ||
|
|
789a4a3659 | ||
|
|
a87d0451c8 | ||
|
|
82e9309d27 | ||
|
|
8deaa378c9 | ||
|
|
b5363e3552 | ||
|
|
28a10ac340 | ||
|
|
c349d51923 | ||
|
|
ef01745e09 | ||
|
|
c97d6a65d0 | ||
|
|
2062273504 | ||
|
|
6e6436ee41 | ||
|
|
38f4a22bc4 | ||
|
|
3a8b047e3c | ||
|
|
52483ee6bd | ||
|
|
dce1cbc096 | ||
|
|
46c563a9a8 | ||
|
|
1380c2ecce | ||
|
|
71a3818bdd | ||
|
|
e3a343c797 | ||
|
|
195b1a043e | ||
|
|
69e66c327f | ||
|
|
885637cc7d | ||
|
|
90a7c8f787 | ||
|
|
2171c0caa4 | ||
|
|
924a6f9254 | ||
|
|
ad4cffb0c6 | ||
|
|
cf77ffb89d | ||
|
|
b2fdcd7f1c | ||
|
|
094ce2ae18 | ||
|
|
e8cb2c1bfe | ||
|
|
9c6c56c49d | ||
|
|
0d5affede3 | ||
|
|
13f210f403 | ||
|
|
c61ad51883 | ||
|
|
c0842b0797 | ||
|
|
2851079ff0 | ||
|
|
5197524d1c | ||
|
|
78efd1acc6 | ||
|
|
eee0a99b88 | ||
|
|
10c96c394d | ||
|
|
07cc3fb2d9 | ||
|
|
e31f1433bf | ||
|
|
af06c97efd | ||
|
|
400de1d66e | ||
|
|
2a9285eee8 | ||
|
|
785bdde6bd | ||
|
|
071e2dc524 | ||
|
|
fc08d072a4 | ||
|
|
0019485aba | ||
|
|
e76f145b65 | ||
|
|
27d5937f4c | ||
|
|
868c4c5977 | ||
|
|
5a37929ceb | ||
|
|
b1dc2dbf8a | ||
|
|
ecfbef95c7 | ||
|
|
bfd8fbefee | ||
|
|
f8c36104ad | ||
|
|
e26230fb2d | ||
|
|
6417ad0a3c | ||
|
|
0f988d087c | ||
|
|
7c01b64aed | ||
|
|
03130c78a7 | ||
|
|
30ab326d2b | ||
|
|
8d1cba57f8 | ||
|
|
cbfd6c1a66 | ||
|
|
81cb3c82f4 | ||
|
|
e64296e109 | ||
|
|
5872b31781 | ||
|
|
51b801b1c6 | ||
|
|
9ef153c0b6 | ||
|
|
2e236faec7 | ||
|
|
129c356ecf | ||
|
|
d8316b0bdc | ||
|
|
1d3a92f3f1 | ||
|
|
81c858c719 | ||
|
|
341041aedb | ||
|
|
25256b2295 | ||
|
|
13874ba547 | ||
|
|
bde58add62 | ||
|
|
9112c63347 | ||
|
|
78fa2b8d78 | ||
|
|
6922c369f3 | ||
|
|
b0fd438a1d | ||
|
|
99f4f0c7d3 | ||
|
|
b09c1cd242 | ||
|
|
5ca3bf9362 | ||
|
|
c6a9884bde | ||
|
|
43825ca78e | ||
|
|
44eeadb211 | ||
|
|
7011da5fa9 | ||
|
|
c61ddfa9d1 | ||
|
|
e64b6dcb13 | ||
|
|
183dc236e4 | ||
|
|
ef5349dec2 | ||
|
|
b39afc0711 | ||
|
|
a8579b43ac | ||
|
|
fa92eca328 | ||
|
|
42165df29f | ||
|
|
9860569536 | ||
|
|
7aa48a167f | ||
|
|
6e3764da48 | ||
|
|
4d503d6925 | ||
|
|
8e04d40034 | ||
|
|
cb57cd02e0 | ||
|
|
22fe48e477 | ||
|
|
204f73cb05 | ||
|
|
28096abea5 | ||
|
|
2d7eb5cb7f | ||
|
|
e6d6932e21 | ||
|
|
406e5d64c0 | ||
|
|
13756aad9f | ||
|
|
c1a8b16f30 | ||
|
|
e3671285c3 |
No files matched your search
@@ -51,18 +51,15 @@
|
||||
</condition>
|
||||
<property name="mcp.obfoutput" location="${mcp.home}/reobf" />
|
||||
<property name="client.mcp.obfoutput" location="${mcp.obfoutput}/minecraft" />
|
||||
<property name="server.mcp.obfoutput" location="${mcp.obfoutput}/minecraft_server" />
|
||||
<property name="mcp.srcdir" location="${mcp.home}/src" />
|
||||
<property name="common.mcp.srcdir" location="${mcp.srcdir}/common" />
|
||||
<property name="client.mcp.srcdir" location="${mcp.srcdir}/minecraft" />
|
||||
<property name="server.mcp.srcdir" location="${mcp.srcdir}/minecraft_server" />
|
||||
<property name="clean.mcp.srcdir" location="${mcp.home}/src-base" />
|
||||
<property name="patch.mcp.srcdir" location="${mcp.home}/src-work" />
|
||||
<property name="tmp.mcp.srcdir" location="${mcp.home}/src-tmp" />
|
||||
<property name="renamed.mcp.srcdir" location="${mcp.home}/src-renamed" />
|
||||
<property name="common.src.dir" location="${basedir}/common" />
|
||||
<property name="client.src.dir" location="${basedir}/client" />
|
||||
<property name="server.src.dir" location="${basedir}/server" />
|
||||
<property name="patch.src.dir" location="${basedir}/patches" />
|
||||
<property name="fml.conf.dir" location="${basedir}/conf" />
|
||||
<condition property="version.build" value="${env.BUILD_NUMBER}" else="1">
|
||||
@@ -92,7 +89,7 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="buildandreobfmcp" depends="buildenvsetup,recompile">
|
||||
<target name="reobfuscate" depends="buildenvsetup,recompile">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
|
||||
<arg value="${mcp.home}/runtime/reobfuscate.py" />
|
||||
</exec>
|
||||
@@ -100,8 +97,6 @@
|
||||
<condition>
|
||||
<not>
|
||||
<and>
|
||||
<available file="${mcp.home}/temp/server.md5"/>
|
||||
<available file="${mcp.home}/temp/server_reobf.md5"/>
|
||||
<available file="${mcp.home}/temp/client.md5"/>
|
||||
<available file="${mcp.home}/temp/client_reobf.md5"/>
|
||||
</and>
|
||||
@@ -114,7 +109,7 @@
|
||||
<arg value="${basedir}/difflist.txt"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="recompile" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
|
||||
<arg value="${mcp.home}/runtime/recompile.py" />
|
||||
@@ -122,10 +117,7 @@
|
||||
<fail message="Compilation failed">
|
||||
<condition>
|
||||
<not>
|
||||
<and>
|
||||
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
|
||||
<available file="${mcp.home}/bin/minecraft_server/net/minecraft/server/MinecraftServer.class"/>
|
||||
</and>
|
||||
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
@@ -137,31 +129,15 @@
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-server" depends="buildenvsetup">
|
||||
<copy todir="${server.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<fileset dir="${server.src.dir}" includes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-common">
|
||||
<copy todir="${common.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<fileset dir="${common.src.dir}" includes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-source" depends="buildenvsetup,merge-client,merge-server,merge-common" />
|
||||
|
||||
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,buildandreobfmcp,makeversion">
|
||||
<antcall target="extract-built-jar">
|
||||
<param name="side" value="client" />
|
||||
</antcall>
|
||||
</target>
|
||||
<target name="merge-source" depends="buildenvsetup,merge-client,merge-common" />
|
||||
|
||||
<target name="build-server" depends="buildenvsetup,merge-server,merge-common,buildandreobfmcp,makeversion">
|
||||
<antcall target="extract-built-jar">
|
||||
<param name="side" value="server" />
|
||||
</antcall>
|
||||
</target>
|
||||
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion"/>
|
||||
|
||||
<target name="extract-built-jar">
|
||||
<side prop="output" src="mcp.obfoutput" side="${side}" />
|
||||
@@ -191,14 +167,13 @@
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build-universal">
|
||||
<target name="build-universal" depends="build-client">
|
||||
<property name="universal.jarname" value="${modname}-universal-${version}" />
|
||||
<mkdir dir="${basedir}/target" />
|
||||
<jar destfile="${basedir}/target/${universal.jarname}.zip">
|
||||
<jar destfile="${basedir}/target/${universal.jarname}.zip" duplicate="preserve">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
|
||||
</manifest>
|
||||
<fileset dir="${server.mcp.obfoutput}" includes="**/*.class" />
|
||||
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
|
||||
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
|
||||
@@ -228,7 +203,6 @@
|
||||
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt,commands.patch,mcp_merge.cfg" prefix="fml" />
|
||||
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/common" />
|
||||
<zipfileset dir="${client.src.dir}" includes="**/*.java" prefix="fml/client" />
|
||||
<zipfileset dir="${server.src.dir}" includes="**/*.java" prefix="fml/server" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/common" />
|
||||
<zipfileset dir="${common.src.dir}" includes="*.cfg" prefix="fml/common" />
|
||||
<zipfileset dir="${patch.src.dir}" includes="**/*.patch" prefix="fml/patches" />
|
||||
@@ -252,7 +226,7 @@
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="buildenvsetup,merge-server,merge-client,merge-common,build-server,build-client,build-universal,build-source-pack" />
|
||||
<target name="build" depends="buildenvsetup,merge-client,merge-common,build-client,build-universal,build-source-pack" />
|
||||
|
||||
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build"/>
|
||||
|
||||
@@ -273,10 +247,6 @@
|
||||
</condition>
|
||||
<fail if="do.not.continue">You have decided not to continue. This script will stop now.</fail>
|
||||
<echo>Preparing the MCP environment at ${mcp.home}</echo>
|
||||
<!--<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/download_fernflower.py" />
|
||||
<arg value="${mcp.home}"/>
|
||||
</exec>-->
|
||||
<antcall target="fmldecompile"/>
|
||||
<echo>Moving old patched sources at ${patch.mcp.srcdir} out of the way</echo>
|
||||
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
|
||||
@@ -297,7 +267,7 @@
|
||||
<antcall target="writeversion"/>
|
||||
<echo>Setup complete! You should now be able to open ${basedir}/eclipse as a workspace in eclipse and import/refresh the FML-Server and FML-Client projects</echo>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="fmldecompile" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
@@ -309,7 +279,7 @@
|
||||
<arg value="${basedir}" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="jenkinsfmldecompile" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
@@ -340,7 +310,7 @@
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="repatchclean" depends="buildenvsetup">
|
||||
<delete dir="${mcp.srcdir}"/>
|
||||
<copy todir="${mcp.srcdir}">
|
||||
@@ -378,7 +348,7 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-server,buildandreobfmcp">
|
||||
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-common,reobfuscate">
|
||||
<copy todir="${tmp.mcp.srcdir}">
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
|
||||
@@ -12,107 +12,55 @@
|
||||
*/
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.Dimension;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.CrashReport;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.NetClientHandler;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderManager;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.WorldClient;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.CrashReport;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.GameSettings;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.Item;
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.MLProp;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
import net.minecraft.src.NetClientHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet1Login;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Packet3Chat;
|
||||
import net.minecraft.src.Profiler;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.RenderManager;
|
||||
import net.minecraft.src.RenderPlayer;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.WorldClient;
|
||||
import net.minecraft.src.WorldType;
|
||||
import argo.jdom.JdomParser;
|
||||
import argo.jdom.JsonNode;
|
||||
import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
|
||||
import cpw.mods.fml.client.registry.ClientRegistry;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.DummyModContainer;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLDummyContainer;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.IFMLSidedHandler;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.ProxyInjector;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.SidedProxy;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.modloader.ModProperty;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import cpw.mods.fml.common.registry.IThrowableEntity;
|
||||
import cpw.mods.fml.common.registry.LanguageRegistry;
|
||||
|
||||
|
||||
/**
|
||||
@@ -146,8 +94,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
*/
|
||||
private Minecraft client;
|
||||
|
||||
|
||||
private boolean firstTick;
|
||||
/**
|
||||
* Called to start the whole game off from
|
||||
* {@link MinecraftServer#startServer}
|
||||
@@ -161,6 +107,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
|
||||
private boolean serverIsRunning;
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
private boolean loading;
|
||||
|
||||
public void beginMinecraftLoading(Minecraft minecraft)
|
||||
{
|
||||
if (minecraft.func_71355_q())
|
||||
@@ -170,6 +120,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
client = minecraft;
|
||||
ObfuscationReflectionHelper.detectObfuscation(World.class);
|
||||
TextureFXManager.instance().setClient(client);
|
||||
@@ -180,7 +131,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
Class<?> optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader());
|
||||
String optifineVersion = (String) optifineConfig.getField("VERSION").get(null);
|
||||
Map<String,Object> dummyOptifineMeta = ImmutableMap.<String,Object>builder().put("name", "Optifine").put("version", optifineVersion).build();
|
||||
ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info")).getMetadataForId("optifine", dummyOptifineMeta);
|
||||
ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info"),"optifine").getMetadataForId("optifine", dummyOptifineMeta);
|
||||
optifineContainer = new DummyModContainer(optifineMetadata);
|
||||
FMLLog.info("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion());
|
||||
}
|
||||
@@ -192,6 +143,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
{
|
||||
Loader.instance().loadMods();
|
||||
}
|
||||
catch (MissingModsException missing)
|
||||
{
|
||||
modsMissing = missing;
|
||||
}
|
||||
catch (LoaderException le)
|
||||
{
|
||||
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
|
||||
@@ -210,8 +165,13 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
* Also initializes key bindings
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void finishMinecraftLoading()
|
||||
{
|
||||
if (modsMissing != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Loader.instance().initializeMods();
|
||||
@@ -221,12 +181,23 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
|
||||
return;
|
||||
}
|
||||
LanguageRegistry.reloadLanguageTable();
|
||||
RenderingRegistry.instance().loadEntityRenderers((Map<Class<? extends Entity>, Render>)RenderManager.field_78727_a.field_78729_o);
|
||||
|
||||
KeyBindingRegistry.uploadKeyBindingsToGame(client.field_71474_y);
|
||||
loading = false;
|
||||
KeyBindingRegistry.instance().uploadKeyBindingsToGame(client.field_71474_y);
|
||||
}
|
||||
|
||||
// Mark this as a "first tick"
|
||||
firstTick = true;
|
||||
public void onInitializationComplete()
|
||||
{
|
||||
if (modsMissing != null)
|
||||
{
|
||||
client.func_71373_a(new GuiModsMissing(modsMissing));
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureFXManager.instance().loadTextures(client.field_71418_C.func_77292_e());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the server instance
|
||||
@@ -266,16 +237,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void profileStart(String profileLabel) {
|
||||
client.field_71424_I.func_76320_a(profileLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void profileEnd() {
|
||||
client.field_71424_I.func_76319_b();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mods
|
||||
*/
|
||||
@@ -316,22 +277,41 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket packet)
|
||||
public Entity spawnEntityIntoClientWorld(EntityRegistration er, EntitySpawnPacket packet)
|
||||
{
|
||||
WorldClient wc = client.field_71441_e;
|
||||
|
||||
Class<? extends Entity> cls = er.getEntityClass();
|
||||
|
||||
try
|
||||
{
|
||||
Entity entity = (Entity)(cls.getConstructor(World.class).newInstance(wc));
|
||||
Entity entity;
|
||||
if (er.hasCustomSpawning())
|
||||
{
|
||||
entity = er.doCustomSpawning(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
entity = (Entity)(cls.getConstructor(World.class).newInstance(wc));
|
||||
entity.field_70157_k = packet.entityId;
|
||||
entity.func_70012_b(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch);
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
entity.field_70118_ct = packet.rawX;
|
||||
entity.field_70117_cu = packet.rawY;
|
||||
entity.field_70116_cv = packet.rawZ;
|
||||
|
||||
if (entity instanceof IThrowableEntity)
|
||||
{
|
||||
Entity thrower = client.field_71439_g.field_70157_k == packet.throwerId ? client.field_71439_g : wc.func_73024_a(packet.throwerId);
|
||||
((IThrowableEntity)entity).setThrower(thrower);
|
||||
}
|
||||
|
||||
entity.field_70118_ct = packet.rawX;
|
||||
entity.field_70117_cu = packet.rawY;
|
||||
entity.field_70116_cv = packet.rawZ;
|
||||
|
||||
Entity parts[] = entity.func_70021_al();
|
||||
if (parts != null)
|
||||
@@ -343,13 +323,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
}
|
||||
|
||||
entity.field_70157_k = packet.entityId;
|
||||
entity.func_70056_a(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch, 1);
|
||||
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw;
|
||||
}
|
||||
|
||||
if (packet.metadata != null)
|
||||
{
|
||||
@@ -380,9 +353,16 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket packet)
|
||||
{
|
||||
Entity ent = client.field_71441_e.func_73024_a(packet.entityId);
|
||||
ent.field_70118_ct = packet.serverX;
|
||||
ent.field_70117_cu = packet.serverY;
|
||||
ent.field_70116_cv = packet.serverZ;
|
||||
if (ent != null)
|
||||
{
|
||||
ent.field_70118_ct = packet.serverX;
|
||||
ent.field_70117_cu = packet.serverY;
|
||||
ent.field_70116_cv = packet.serverZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Attempted to adjust the position of entity %d which is not present on the client", packet.entityId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -402,4 +382,43 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
{
|
||||
return client.func_71401_C();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Packet packet)
|
||||
{
|
||||
client.field_71439_g.field_71174_a.func_72552_c(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayMissingMods(ModMissingPacket modMissingPacket)
|
||||
{
|
||||
client.func_71373_a(new GuiModsMissingForServer(modMissingPacket));
|
||||
}
|
||||
|
||||
/**
|
||||
* If the client is in the midst of loading, we disable saving so that custom settings aren't wiped out
|
||||
* @return
|
||||
*/
|
||||
public boolean isLoading()
|
||||
{
|
||||
return loading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
((NetClientHandler)handler).fmlPacket131Callback(mapData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientCompatibilityLevel(byte compatibilityLevel)
|
||||
{
|
||||
NetClientHandler.setConnectionCompatibilityLevel(compatibilityLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getClientCompatibilityLevel()
|
||||
{
|
||||
return NetClientHandler.getConnectionCompatibilityLevel();
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,11 @@ import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
{
|
||||
@@ -31,7 +31,7 @@ public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
public int tileSizeMask = 15;
|
||||
public int tileSizeSquareMask = 255;
|
||||
public boolean errored = false;
|
||||
protected Logger log = FMLCommonHandler.instance().getFMLLogger();
|
||||
protected Logger log = FMLLog.getLogger();
|
||||
|
||||
public FMLTextureFX(int icon)
|
||||
{
|
||||
|
||||
@@ -16,15 +16,7 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.common.FMLModContainer;
|
||||
import cpw.mods.fml.common.FMLDummyContainer;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.FontRenderer;
|
||||
import net.minecraft.src.GuiButton;
|
||||
@@ -33,6 +25,11 @@ import net.minecraft.src.GuiSmallButton;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.Tessellator;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
@@ -103,6 +100,7 @@ public class GuiModList extends GuiScreen
|
||||
this.func_73732_a(this.field_73886_k, "Mod List", this.field_73880_f / 2, 16, 0xFFFFFF);
|
||||
int offset = this.listWidth + 20;
|
||||
if (selectedMod != null) {
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
if (!selectedMod.getMetadata().autogenerated) {
|
||||
int shifty = 35;
|
||||
if (!selectedMod.getMetadata().logoFile.isEmpty())
|
||||
@@ -125,7 +123,7 @@ public class GuiModList extends GuiScreen
|
||||
this.field_73886_k.func_78261_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
|
||||
shifty += 12;
|
||||
|
||||
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getMetadata().version, selectedMod.getVersion()), offset, shifty);
|
||||
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getDisplayVersion(), selectedMod.getVersion()), offset, shifty);
|
||||
shifty = drawLine(String.format("Mod State: %s", Loader.instance().getModState(selectedMod)), offset, shifty);
|
||||
if (!selectedMod.getMetadata().credits.isEmpty()) {
|
||||
shifty = drawLine(String.format("Credits: %s", selectedMod.getMetadata().credits), offset, shifty);
|
||||
@@ -142,6 +140,7 @@ public class GuiModList extends GuiScreen
|
||||
this.func_73732_a(this.field_73886_k, "No mod information found", offset, 65, 0xDDDDDD);
|
||||
this.func_73732_a(this.field_73886_k, "Ask your mod author to provide a mod mcmod.info file", offset, 75, 0xDDDDDD);
|
||||
}
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
super.func_73863_a(p_571_1_, p_571_2_, p_571_3_);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
|
||||
public class GuiModsMissing extends GuiErrorScreen
|
||||
{
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
public GuiModsMissing(MissingModsException modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
super.func_73866_w_();
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = 85 - modsMissing.missingMods.size() * 10;
|
||||
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=5;
|
||||
for (ArtifactVersion v : modsMissing.missingMods)
|
||||
{
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
}
|
||||
offset+=20;
|
||||
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.src.GuiButton;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.GuiSmallButton;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiModsMissingForServer extends GuiScreen
|
||||
{
|
||||
private ModMissingPacket modsMissing;
|
||||
|
||||
public GuiModsMissingForServer(ModMissingPacket modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
StringTranslate translations = StringTranslate.func_74808_a();
|
||||
this.field_73887_h.add(new GuiSmallButton(1, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void func_73875_a(GuiButton p_73875_1_)
|
||||
{
|
||||
if (p_73875_1_.field_73742_g && p_73875_1_.field_73741_f == 1)
|
||||
{
|
||||
FMLClientHandler.instance().getClient().func_71373_a(null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = 85 - modsMissing.getModList().size() * 10;
|
||||
this.func_73732_a(this.field_73886_k, "Forge Mod Loader could not connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 10;
|
||||
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 10;
|
||||
this.func_73732_a(this.field_73886_k, "They are required to play on this server", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 5;
|
||||
for (ArtifactVersion v : modsMissing.getModList())
|
||||
{
|
||||
offset += 10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
}
|
||||
super.func_73863_a(p_73863_1_, p_73863_2_, p_73863_3_);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.GuiButton;
|
||||
import net.minecraft.src.Tessellator;
|
||||
@@ -81,9 +82,10 @@ public abstract class GuiScrollingList
|
||||
protected void func_27257_b(int p_27257_1_, int p_27257_2_) {}
|
||||
|
||||
public int func_27256_c(int p_27256_1_, int p_27256_2_)
|
||||
|
||||
{
|
||||
int var3 = this.listWidth / 2 - 110;
|
||||
int var4 = this.listWidth / 2 + 110;
|
||||
int var3 = this.left + 1;
|
||||
int var4 = this.left + this.listWidth - 7;
|
||||
int var5 = p_27256_2_ - this.top - this.field_27261_r + (int)this.scrollDistance - 4;
|
||||
int var6 = var5 / this.slotHeight;
|
||||
return p_27256_1_ >= var3 && p_27256_1_ <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1;
|
||||
|
||||
@@ -16,15 +16,10 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.src.Tessellator;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.GuiLanguage;
|
||||
import net.minecraft.src.GuiSlot;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.Tessellator;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -78,15 +73,15 @@ public class GuiSlotModList extends GuiScrollingList
|
||||
ModContainer mc=mods.get(listIndex);
|
||||
if (Loader.instance().getModState(mc)==ModState.DISABLED)
|
||||
{
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 11), this.left + 3 , var3 + 22, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 10), this.left + 3 , var3 + 22, 0xFF2222);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFFFFFF);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 9), this.left + 3 , var3 + 22, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFFFFFF);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 10), this.left + 3 , var3 + 22, 0xCCCCCC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import net.minecraft.src.*;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
|
||||
public interface ITextureFX
|
||||
{
|
||||
|
||||
@@ -18,10 +18,8 @@ import java.util.BitSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.ModLoader;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -35,6 +33,9 @@ public class SpriteHelper
|
||||
BitSet slots =
|
||||
SpriteHelper.toBitSet(
|
||||
"0000000000000000" +
|
||||
"0000000000110000" +
|
||||
"0000000001100000" +
|
||||
"0000000001100000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
@@ -42,9 +43,6 @@ public class SpriteHelper
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000011111100" +
|
||||
"0000000011111111" +
|
||||
"0000000011111000" +
|
||||
"0000000111111100" +
|
||||
@@ -62,10 +60,10 @@ public class SpriteHelper
|
||||
"0000001000000000" +
|
||||
"0000001110000000" +
|
||||
"0000001000000000" +
|
||||
"1111111010000000" +
|
||||
"1111111010100000" +
|
||||
"1111111111111100" +
|
||||
"1111111111111111" +
|
||||
"1111101010000000" +
|
||||
"1111101010000000" +
|
||||
"1111101110000000" +
|
||||
"1111111111110000" +
|
||||
"1111111111111111" +
|
||||
"1111111111111111" +
|
||||
"0000000000000000");
|
||||
|
||||
@@ -18,22 +18,20 @@ import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
import net.minecraft.src.Profiler;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
public class TextureFXManager
|
||||
@@ -53,12 +51,12 @@ public class TextureFXManager
|
||||
private List<TextureFX> addedTextureFX = new ArrayList<TextureFX>();
|
||||
|
||||
private Minecraft client;
|
||||
|
||||
|
||||
void setClient(Minecraft client)
|
||||
{
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
||||
public boolean onUpdateTextureEffect(TextureFX effect)
|
||||
{
|
||||
ITextureFX ifx = (effect instanceof ITextureFX ? ((ITextureFX)effect) : null);
|
||||
@@ -69,8 +67,7 @@ public class TextureFXManager
|
||||
}
|
||||
|
||||
String name = effect.getClass().getSimpleName();
|
||||
FMLClientHandler.instance().profileStart(name);
|
||||
|
||||
client.field_71424_I.func_76320_a(name);
|
||||
try
|
||||
{
|
||||
if (!FMLClientHandler.instance().hasOptifine())
|
||||
@@ -85,10 +82,10 @@ public class TextureFXManager
|
||||
{
|
||||
ifx.setErrored(true);
|
||||
}
|
||||
FMLClientHandler.instance().profileEnd();
|
||||
client.field_71424_I.func_76319_b();
|
||||
return false;
|
||||
}
|
||||
FMLClientHandler.instance().profileEnd();
|
||||
client.field_71424_I.func_76319_b();
|
||||
|
||||
if (ifx != null)
|
||||
{
|
||||
@@ -242,10 +239,6 @@ public class TextureFXManager
|
||||
|
||||
|
||||
public void registerTextureOverrides(RenderEngine renderer) {
|
||||
for (ModContainer mod : Loader.instance().getActiveModList()) {
|
||||
registerAnimatedTexturesFor(mod);
|
||||
}
|
||||
|
||||
for (OverrideInfo animationOverride : animationSet) {
|
||||
renderer.func_78355_a(animationOverride.textureFX);
|
||||
addedTextureFX.add(animationOverride.textureFX);
|
||||
@@ -273,7 +266,7 @@ public class TextureFXManager
|
||||
/**
|
||||
* @param mod
|
||||
*/
|
||||
private void registerAnimatedTexturesFor(ModContainer mod)
|
||||
protected void registerAnimatedTexturesFor(ModContainer mod)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ import net.minecraft.src.Block;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
|
||||
@@ -1,18 +1,43 @@
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityClientPlayerMP;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderManager;
|
||||
|
||||
import com.google.common.base.Equivalences;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.MapDifference.ValueDifference;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
|
||||
public class ModLoaderClientHelper implements IModLoaderSidedHelper
|
||||
{
|
||||
@@ -24,40 +49,111 @@ public class ModLoaderClientHelper implements IModLoaderSidedHelper
|
||||
*/
|
||||
public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
|
||||
{
|
||||
int renderId=RenderingRegistry.instance().getNextAvailableRenderId();
|
||||
int renderId=RenderingRegistry.getNextAvailableRenderId();
|
||||
ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
|
||||
RenderingRegistry.instance().registerBlockHandler(bri);
|
||||
RenderingRegistry.registerBlockHandler(bri);
|
||||
return renderId;
|
||||
}
|
||||
|
||||
|
||||
public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
|
||||
{
|
||||
FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId());
|
||||
BaseMod mod = (BaseMod) mc.getMod();
|
||||
|
||||
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap();
|
||||
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.field_78727_a.field_78729_o);
|
||||
|
||||
mod.addRenderer(renderers);
|
||||
|
||||
for (Entry<Class<? extends Entity>, Render> e : renderers.entrySet())
|
||||
try
|
||||
{
|
||||
RenderingRegistry.instance().registerEntityRenderingHandler(e.getKey(), e.getValue());
|
||||
FMLLog.finest("Requesting renderers from basemod %s", mc.getModId());
|
||||
mod.addRenderer(renderers);
|
||||
FMLLog.finest("Received %d renderers from basemod %s", renderers.size(), mc.getModId());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
mod.registerAnimation(game);
|
||||
MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.field_78727_a.field_78729_o, renderers, Equivalences.identity());
|
||||
|
||||
for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
for (Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnRight().entrySet())
|
||||
{
|
||||
FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName());
|
||||
RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
for (Entry<Class<? extends Entity>, ValueDifference<Render>> e : difference.entriesDiffering().entrySet())
|
||||
{
|
||||
FMLLog.finest("Registering ModLoader entity rendering override for %s as instance of %s", e.getKey().getName(), e.getValue().rightValue().getClass().getName());
|
||||
RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue().rightValue());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
mod.registerAnimation(game);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
public ModLoaderClientHelper(Minecraft client)
|
||||
{
|
||||
this.client = client;
|
||||
ModLoaderHelper.sidedHelper = this;
|
||||
keyBindingContainers = Multimaps.newMultimap(Maps.<ModLoaderModContainer, Collection<ModLoaderKeyBindingHandler>>newHashMap(), new Supplier<Collection<ModLoaderKeyBindingHandler>>()
|
||||
{
|
||||
@Override
|
||||
public Collection<ModLoaderKeyBindingHandler> get()
|
||||
{
|
||||
return Collections.singleton(new ModLoaderKeyBindingHandler());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Minecraft client;
|
||||
private static Multimap<ModLoaderModContainer, ModLoaderKeyBindingHandler> keyBindingContainers;
|
||||
|
||||
@Override
|
||||
public void finishModLoading(ModLoaderModContainer mc)
|
||||
{
|
||||
handleFinishLoadingFor(mc, client);
|
||||
}
|
||||
|
||||
|
||||
public static void registerKeyBinding(BaseModProxy mod, KeyBinding keyHandler, boolean allowRepeat)
|
||||
{
|
||||
ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
|
||||
ModLoaderKeyBindingHandler handler = Iterables.getOnlyElement(keyBindingContainers.get(mlmc));
|
||||
handler.setModContainer(mlmc);
|
||||
handler.addKeyBinding(keyHandler, allowRepeat);
|
||||
KeyBindingRegistry.registerKeyBinding(handler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getClientGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
|
||||
{
|
||||
return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er)
|
||||
{
|
||||
return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.field_71441_e, input.scaledX, input.scaledY, input.scaledZ);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)mod).clientCustomPayload(client.field_71439_g.field_71174_a, packet);
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,19 @@
|
||||
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.src.KeyBinding;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import com.google.common.primitives.Booleans;
|
||||
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -33,61 +35,58 @@ import cpw.mods.fml.common.registry.TickRegistry;
|
||||
public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
|
||||
{
|
||||
private ModLoaderModContainer modContainer;
|
||||
private boolean downArmed;
|
||||
private boolean upArmed;
|
||||
private List<KeyBinding> helper;
|
||||
private boolean[] active = new boolean[0];
|
||||
private boolean[] mlRepeats = new boolean[0];
|
||||
private boolean[] armed = new boolean[0];
|
||||
|
||||
/**
|
||||
* @param keyHandler
|
||||
* @param allowRepeat
|
||||
* @param modContainer
|
||||
*/
|
||||
public ModLoaderKeyBindingHandler(KeyBinding keyBinding, boolean allowRepeat, ModLoaderModContainer modContainer)
|
||||
public ModLoaderKeyBindingHandler()
|
||||
{
|
||||
super(keyBinding, allowRepeat);
|
||||
this.modContainer=modContainer;
|
||||
super(new KeyBinding[0], new boolean[0]);
|
||||
}
|
||||
|
||||
public void onRenderEndTick()
|
||||
void setModContainer(ModLoaderModContainer modContainer)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(keyBinding);
|
||||
this.modContainer = modContainer;
|
||||
}
|
||||
|
||||
public void fireKeyEvent(KeyBinding kb)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(kb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyDown(EnumSet<TickType> type, boolean end, boolean repeats)
|
||||
public void keyDown(EnumSet<TickType> type, KeyBinding kb, boolean end, boolean repeats)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
upArmed = false;
|
||||
int idx = helper.indexOf(kb);
|
||||
if (type.contains(TickType.CLIENT))
|
||||
{
|
||||
downArmed = true;
|
||||
armed[idx] = true;
|
||||
}
|
||||
if (type.contains(TickType.RENDER) && downArmed)
|
||||
if (armed[idx] && type.contains(TickType.RENDER) && (!active[idx] || mlRepeats[idx]))
|
||||
{
|
||||
onRenderEndTick();
|
||||
downArmed = false;
|
||||
fireKeyEvent(kb);
|
||||
active[idx] = true;
|
||||
armed[idx] = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyUp(EnumSet<TickType> type, boolean end)
|
||||
public void keyUp(EnumSet<TickType> type, KeyBinding kb, boolean end)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
downArmed = false;
|
||||
if (type.contains(TickType.CLIENT))
|
||||
{
|
||||
upArmed = true;
|
||||
}
|
||||
if (type.contains(TickType.RENDER) && upArmed)
|
||||
{
|
||||
onRenderEndTick();
|
||||
upArmed = false;
|
||||
}
|
||||
int idx = helper.indexOf(kb);
|
||||
active[idx] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,6 +98,18 @@ public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return modContainer.getModId() +" KB "+keyBinding.field_74512_d;
|
||||
return modContainer.getModId() +" KB "+keyBindings[0].field_74512_d;
|
||||
}
|
||||
|
||||
void addKeyBinding(KeyBinding binding, boolean repeats)
|
||||
{
|
||||
this.keyBindings = ObjectArrays.concat(this.keyBindings, binding);
|
||||
this.repeatings = new boolean[this.keyBindings.length];
|
||||
Arrays.fill(this.repeatings, true);
|
||||
this.active = new boolean[this.keyBindings.length];
|
||||
this.armed = new boolean[this.keyBindings.length];
|
||||
this.mlRepeats = Booleans.concat(this.mlRepeats, new boolean[] { repeats });
|
||||
this.keyDown = new boolean[this.keyBindings.length];
|
||||
this.helper = Arrays.asList(this.keyBindings);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,8 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.TileEntity;
|
||||
import net.minecraft.src.TileEntityRenderer;
|
||||
import net.minecraft.src.TileEntitySpecialRenderer;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
|
||||
public class ClientRegistry
|
||||
|
||||
@@ -2,15 +2,16 @@ package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.src.GameSettings;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.src.GameSettings;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.ITickHandler;
|
||||
import cpw.mods.fml.common.Side;
|
||||
@@ -19,29 +20,79 @@ import cpw.mods.fml.common.registry.TickRegistry;
|
||||
|
||||
public class KeyBindingRegistry
|
||||
{
|
||||
/**
|
||||
* Register a KeyHandler to the game. This handler will be called on certain tick events
|
||||
* if any of its key is inactive or has recently changed state
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public static void registerKeyBinding(KeyHandler handler) {
|
||||
instance().keyHandlers.add(handler);
|
||||
if (!handler.isDummy)
|
||||
{
|
||||
TickRegistry.registerTickHandler(handler, Side.CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extend this class to register a KeyBinding and recieve callback
|
||||
* when the key binding is triggered
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static abstract class KeyHandler implements ITickHandler
|
||||
{
|
||||
protected KeyBinding keyBinding;
|
||||
protected boolean keyDown;
|
||||
protected boolean repeating;
|
||||
protected KeyBinding[] keyBindings;
|
||||
protected boolean[] keyDown;
|
||||
protected boolean[] repeatings;
|
||||
private boolean isDummy;
|
||||
|
||||
public KeyHandler(KeyBinding keyBinding, boolean repeating)
|
||||
/**
|
||||
* Pass an array of keybindings and a repeat flag for each one
|
||||
*
|
||||
* @param keyBindings
|
||||
* @param repeatings
|
||||
*/
|
||||
public KeyHandler(KeyBinding[] keyBindings, boolean[] repeatings)
|
||||
{
|
||||
this.keyBinding = keyBinding;
|
||||
this.repeating = repeating;
|
||||
assert keyBindings.length == repeatings.length : "You need to pass two arrays of identical length";
|
||||
this.keyBindings = keyBindings;
|
||||
this.repeatings = repeatings;
|
||||
this.keyDown = new boolean[keyBindings.length];
|
||||
}
|
||||
|
||||
public KeyBinding getKeyBinding()
|
||||
|
||||
/**
|
||||
* Register the keys into the system. You will do your own keyboard management elsewhere. No events will fire
|
||||
* if you use this method
|
||||
*
|
||||
* @param keyBindings
|
||||
*/
|
||||
public KeyHandler(KeyBinding[] keyBindings)
|
||||
{
|
||||
return this.keyBinding;
|
||||
this.keyBindings = keyBindings;
|
||||
this.isDummy = true;
|
||||
}
|
||||
|
||||
public KeyBinding[] getKeyBindings()
|
||||
{
|
||||
return this.keyBindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not to be overridden - KeyBindings are tickhandlers under the covers
|
||||
*/
|
||||
@Override
|
||||
public final void tickStart(EnumSet<TickType> type, Object... tickData)
|
||||
{
|
||||
keyTick(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not to be overridden - KeyBindings are tickhandlers under the covers
|
||||
*/
|
||||
@Override
|
||||
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
|
||||
{
|
||||
@@ -50,39 +101,81 @@ public class KeyBindingRegistry
|
||||
|
||||
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
|
||||
{
|
||||
int keyCode = keyBinding.field_74512_d;
|
||||
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
|
||||
if (state != keyDown || (state && repeating))
|
||||
for (int i = 0; i < keyBindings.length; i++)
|
||||
{
|
||||
if (state)
|
||||
KeyBinding keyBinding = keyBindings[i];
|
||||
int keyCode = keyBinding.field_74512_d;
|
||||
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
|
||||
if (state != keyDown[i] || (state && repeatings[i]))
|
||||
{
|
||||
keyDown(type, tickEnd, state!=keyDown);
|
||||
if (state)
|
||||
{
|
||||
keyDown(type, keyBinding, tickEnd, state!=keyDown[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUp(type, keyBinding, tickEnd);
|
||||
}
|
||||
if (tickEnd)
|
||||
{
|
||||
keyDown[i] = state;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUp(type, tickEnd);
|
||||
}
|
||||
keyDown = state;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void keyDown(EnumSet<TickType> types, boolean tickEnd, boolean isRepeat);
|
||||
public abstract void keyUp(EnumSet<TickType> types, boolean tickEnd);
|
||||
/**
|
||||
* Called when the key is first in the down position on any tick from the {@link #ticks()}
|
||||
* set. Will be called subsequently with isRepeat set to true
|
||||
*
|
||||
* @see #keyUp(EnumSet, boolean)
|
||||
*
|
||||
* @param types the type(s) of tick that fired when this key was first down
|
||||
* @param tickEnd was it an end or start tick which fired the key
|
||||
* @param isRepeat is it a repeat key event
|
||||
*/
|
||||
public abstract void keyDown(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd, boolean isRepeat);
|
||||
/**
|
||||
* Fired once when the key changes state from down to up
|
||||
*
|
||||
* @see #keyDown(EnumSet, boolean, boolean)
|
||||
*
|
||||
* @param types the type(s) of tick that fired when this key was first down
|
||||
* @param tickEnd was it an end or start tick which fired the key
|
||||
*/
|
||||
public abstract void keyUp(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd);
|
||||
|
||||
|
||||
/**
|
||||
* This is the list of ticks for which the key binding should trigger. The only
|
||||
* valid ticks are client side ticks, obviously.
|
||||
*
|
||||
* @see cpw.mods.fml.common.ITickHandler#ticks()
|
||||
*/
|
||||
public abstract EnumSet<TickType> ticks();
|
||||
}
|
||||
|
||||
private static List<KeyHandler> keyHandlers = Lists.newArrayList();
|
||||
private static final KeyBindingRegistry INSTANCE = new KeyBindingRegistry();
|
||||
|
||||
public static void registerKeyBinding(KeyHandler handler) {
|
||||
keyHandlers.add(handler);
|
||||
TickRegistry.registerTickHandler(handler, Side.CLIENT);
|
||||
private Set<KeyHandler> keyHandlers = Sets.newLinkedHashSet();
|
||||
|
||||
@Deprecated
|
||||
public static KeyBindingRegistry instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static void uploadKeyBindingsToGame(GameSettings settings)
|
||||
|
||||
public void uploadKeyBindingsToGame(GameSettings settings)
|
||||
{
|
||||
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
|
||||
for (KeyHandler key : keyHandlers)
|
||||
{
|
||||
harvestedBindings.add(key.keyBinding);
|
||||
for (KeyBinding kb : key.keyBindings)
|
||||
{
|
||||
harvestedBindings.add(kb);
|
||||
}
|
||||
}
|
||||
KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]);
|
||||
KeyBinding[] allKeys = new KeyBinding[settings.field_74324_K.length + modKeyBindings.length];
|
||||
|
||||
@@ -1,44 +1,136 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.RenderManager;
|
||||
import net.minecraft.src.RenderPlayer;
|
||||
import cpw.mods.fml.client.modloader.ModLoaderBlockRendererHandler;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
|
||||
import cpw.mods.fml.client.SpriteHelper;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class RenderingRegistry
|
||||
{
|
||||
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
|
||||
|
||||
private int nextRenderId = 30;
|
||||
private int nextRenderId = 32;
|
||||
|
||||
private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
|
||||
|
||||
private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
|
||||
|
||||
public int addNewArmourRendererPrefix(String armor)
|
||||
/**
|
||||
* Add a new armour prefix to the RenderPlayer
|
||||
*
|
||||
* @param armor
|
||||
* @return
|
||||
*/
|
||||
public static int addNewArmourRendererPrefix(String armor)
|
||||
{
|
||||
RenderPlayer.field_77110_j = ObjectArrays.concat(RenderPlayer.field_77110_j, armor);
|
||||
return RenderPlayer.field_77110_j.length - 1;
|
||||
}
|
||||
|
||||
public static RenderingRegistry instance()
|
||||
/**
|
||||
* Register an entity rendering handler. This will, after mod initialization, be inserted into the main
|
||||
* render map for entities
|
||||
*
|
||||
* @param entityClass
|
||||
* @param renderer
|
||||
*/
|
||||
public static void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
|
||||
{
|
||||
instance().entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a simple block rendering handler
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public static void registerBlockHandler(ISimpleBlockRenderingHandler handler)
|
||||
{
|
||||
instance().blockRenderers.put(handler.getRenderId(), handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the simple block rendering handler
|
||||
* This version will not call getRenderId on the passed in handler, instead using the supplied ID, so you
|
||||
* can easily re-use the same rendering handler for multiple IDs
|
||||
*
|
||||
* @param renderId
|
||||
* @param handler
|
||||
*/
|
||||
public static void registerBlockHandler(int renderId, ISimpleBlockRenderingHandler handler)
|
||||
{
|
||||
instance().blockRenderers.put(renderId, handler);
|
||||
}
|
||||
/**
|
||||
* Get the next available renderId from the block render ID list
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getNextAvailableRenderId()
|
||||
{
|
||||
return instance().nextRenderId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a texture override for the given path and return the used index
|
||||
*
|
||||
* @param fileToOverride
|
||||
* @param fileToAdd
|
||||
* @return
|
||||
*/
|
||||
public static int addTextureOverride(String fileToOverride, String fileToAdd)
|
||||
{
|
||||
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
|
||||
addTextureOverride(fileToOverride, fileToAdd, idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a texture override for the given path and index
|
||||
*
|
||||
* @param path
|
||||
* @param overlayPath
|
||||
* @param index
|
||||
*/
|
||||
public static void addTextureOverride(String path, String overlayPath, int index)
|
||||
{
|
||||
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and reserve a unique texture index for the supplied path
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static int getUniqueTextureIndex(String path)
|
||||
{
|
||||
return SpriteHelper.getUniqueSpriteIndex(path);
|
||||
}
|
||||
|
||||
@Deprecated public static RenderingRegistry instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private class EntityRendererInfo
|
||||
private static class EntityRendererInfo
|
||||
{
|
||||
public EntityRendererInfo(Class<? extends Entity> target, Render renderer)
|
||||
{
|
||||
@@ -49,20 +141,6 @@ public class RenderingRegistry
|
||||
private Render renderer;
|
||||
}
|
||||
|
||||
public void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
|
||||
{
|
||||
entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
|
||||
}
|
||||
|
||||
public void registerBlockHandler(ISimpleBlockRenderingHandler handler)
|
||||
{
|
||||
blockRenderers.put(handler.getRenderId(), handler);
|
||||
}
|
||||
|
||||
public int getNextAvailableRenderId()
|
||||
{
|
||||
return nextRenderId++;
|
||||
}
|
||||
/**
|
||||
* @param renderer
|
||||
* @param world
|
||||
@@ -108,6 +186,7 @@ public class RenderingRegistry
|
||||
for (EntityRendererInfo info : entityRenderers)
|
||||
{
|
||||
rendererMap.put(info.target, info.renderer);
|
||||
info.renderer.func_76976_a(RenderManager.field_78727_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,19 +12,17 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static cpw.mods.fml.common.Side.CLIENT;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.IConsoleHandler;
|
||||
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.IPlayerTracker;
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
|
||||
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModProxy
|
||||
{
|
||||
@@ -33,7 +31,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object... data)
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
boolean hasWorld = true;
|
||||
boolean hasWorld = mc.field_71441_e != null;
|
||||
// World and render ticks
|
||||
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT ) && hasWorld) {
|
||||
return onTickInGame((Float) data[0], mc);
|
||||
@@ -44,7 +42,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
public final boolean doTickInGUI(TickType tick, boolean tickEnd, Object... data)
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT)) {
|
||||
|
||||
boolean hasWorld = mc.field_71441_e != null;
|
||||
|
||||
if (tickEnd && ( tick==TickType.RENDER || ( tick==TickType.CLIENT && hasWorld))) {
|
||||
return onTickInGUI((Float) data[0], mc, mc.field_71462_r);
|
||||
}
|
||||
return true;
|
||||
@@ -177,9 +178,9 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void addRenderer(Map<Class<? extends Entity>, Render> renderers)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,9 +195,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
|
||||
@Override
|
||||
public int dispenseEntity(World world, ItemStack item, Random rnd, int x, int y, int z, int xVel, int zVel, double entX, double entY, double entZ)
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,6 +225,21 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to return a gui screen to display
|
||||
* @param player
|
||||
* @param containerID
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public GuiContainer getContainerGUI(EntityClientPlayerMP player, int containerID, int x, int y, int z)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of your mod. Defaults to the class name
|
||||
*
|
||||
@@ -250,6 +267,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void keyboardEvent(KeyBinding event)
|
||||
{
|
||||
|
||||
@@ -284,11 +302,18 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
* @param minecraftInstance the client
|
||||
* @return true to continue receiving ticks
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public boolean onTickInGame(float time, Minecraft minecraftInstance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onTickInGame(MinecraftServer minecraftServer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public boolean onTickInGUI(float tick, Minecraft game, GuiScreen gui)
|
||||
{
|
||||
return false;
|
||||
@@ -296,19 +321,18 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
/**
|
||||
* Only implemented on the client side
|
||||
* {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)}
|
||||
* {@link #serverChat(EntityPlayer, Packet3Chat)}
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
@Override
|
||||
public void receiveChatPacket(String text)
|
||||
public void clientChat(String text)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called on the client side
|
||||
* {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)}
|
||||
* Called client side to receive a custom payload for this mod
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
@@ -318,16 +342,19 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
// TODO
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void registerAnimation(Minecraft game)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
|
||||
{
|
||||
return false;
|
||||
@@ -339,6 +366,12 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverCustomPayload(NetServerHandler handler, Packet250CustomPayload packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverDisconnect() {
|
||||
|
||||
@@ -373,17 +406,6 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
return getName() + " " + getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a 250 packet is received on a channel registered to this mod
|
||||
*
|
||||
* @param source
|
||||
* @param payload
|
||||
*/
|
||||
@Override
|
||||
public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a chat message is received. Return true to stop further processing
|
||||
*
|
||||
@@ -391,20 +413,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
* @param chat
|
||||
* @return true if you want to consume the message so it is not available for further processing
|
||||
*/
|
||||
public boolean onChatMessageReceived(EntityPlayer source, Packet3Chat chat)
|
||||
@Override
|
||||
public void serverChat(NetServerHandler source, String message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Called when a server command is received
|
||||
* @param command
|
||||
* @return true if you want to consume the message so it is not available for further processing
|
||||
*/
|
||||
public boolean onServerCommand(String command, String sender, Object listener)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new client logs in.
|
||||
*
|
||||
@@ -428,11 +440,21 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
/**
|
||||
*
|
||||
* Called when a client changes dimensions on the server.
|
||||
*
|
||||
* @param player
|
||||
* Spawn the entity of the supplied type, if it is your mod's
|
||||
* @param entityId
|
||||
* @param world
|
||||
* @param scaledX
|
||||
* @param scaledY
|
||||
* @param scaledZ
|
||||
* @return
|
||||
*/
|
||||
public void onClientDimensionChanged(EntityPlayer player)
|
||||
@SideOnly(CLIENT)
|
||||
public Entity spawnEntity(int entityId, World world, double scaledX, double scaledY, double scaledZ)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clientCustomPayload(NetClientHandler handler, Packet250CustomPayload packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -19,10 +19,8 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
/**
|
||||
@@ -74,16 +72,19 @@ public class FMLRenderAccessLibrary
|
||||
TextureFXManager.instance().onTexturePackChange(engine, texturePack, textureFXList);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
|
||||
{
|
||||
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean renderItemAsFull3DBlock(int modelId)
|
||||
{
|
||||
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelId);
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
|
||||
@@ -12,17 +12,16 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static cpw.mods.fml.common.Side.CLIENT;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.SpriteHelper;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
@@ -34,15 +33,22 @@ import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.network.PacketDispatcher;
|
||||
import cpw.mods.fml.common.network.Player;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.registry.LanguageRegistry;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.server.FMLServerHandler;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ModLoader
|
||||
{
|
||||
public static final String fmlMarker = "This is an FML marker";
|
||||
@@ -79,24 +85,26 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers)
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void addAnimation(TextureFX anim)
|
||||
{
|
||||
TextureFXManager.instance().addAnimation(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is unimplemented in server versions to date.
|
||||
*
|
||||
* @param armor
|
||||
* @return
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int addArmor(String armor)
|
||||
{
|
||||
return RenderingRegistry.instance().addNewArmourRendererPrefix(armor);
|
||||
return RenderingRegistry.addNewArmourRendererPrefix(armor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,6 +117,15 @@ public class ModLoader
|
||||
GameRegistry.addBiome(biome);
|
||||
}
|
||||
|
||||
public static void addEntityTracker(BaseMod mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval, boolean sendVelocityInfo)
|
||||
{
|
||||
ModLoaderHelper.buildEntityTracker(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
|
||||
}
|
||||
|
||||
public static void addCommand(ICommand command)
|
||||
{
|
||||
ModLoaderHelper.addCommand(command);
|
||||
}
|
||||
/**
|
||||
* Add localization for the specified string
|
||||
*
|
||||
@@ -162,11 +179,10 @@ public class ModLoader
|
||||
* @param fileToAdd
|
||||
* @return
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int addOverride(String fileToOverride, String fileToAdd)
|
||||
{
|
||||
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
|
||||
addOverride(fileToOverride, fileToAdd, idx);
|
||||
return idx;
|
||||
return RenderingRegistry.addTextureOverride(fileToOverride, fileToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,9 +192,10 @@ public class ModLoader
|
||||
* @param overlayPath
|
||||
* @param index
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static void addOverride(String path, String overlayPath, int index)
|
||||
{
|
||||
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
|
||||
RenderingRegistry.addTextureOverride(path, overlayPath, index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,6 +231,16 @@ public class ModLoader
|
||||
GameRegistry.addSmelting(input, output, 1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new product to be smelted
|
||||
*
|
||||
* @param input
|
||||
* @param output
|
||||
*/
|
||||
public static void addSmelting(int input, ItemStack output, float experience)
|
||||
{
|
||||
GameRegistry.addSmelting(input, output, experience);
|
||||
}
|
||||
/**
|
||||
* Add a mob to the spawn list
|
||||
*
|
||||
@@ -272,9 +299,21 @@ public class ModLoader
|
||||
EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
|
||||
}
|
||||
|
||||
public static void addTrade(int profession, TradeEntry entry)
|
||||
{
|
||||
ModLoaderHelper.registerTrade(profession, entry);
|
||||
}
|
||||
/**
|
||||
* Send a packet from the client
|
||||
* @param packet
|
||||
*/
|
||||
public static void clientSendPacket(Packet packet)
|
||||
{
|
||||
PacketDispatcher.sendPacketToServer(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#tryDispensingEntity(World, double, double, double, byte, byte, ItemStack)}
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
@@ -370,14 +409,13 @@ public class ModLoader
|
||||
return FMLLog.getLogger();
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static Minecraft getMinecraftInstance()
|
||||
{
|
||||
return FMLClientHandler.instance().getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not the server
|
||||
* {@link FMLClientHandler#getServer()}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@@ -418,6 +456,7 @@ public class ModLoader
|
||||
* Stubbed method on the server to return a unique model id
|
||||
*
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
|
||||
{
|
||||
return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
|
||||
@@ -434,6 +473,7 @@ public class ModLoader
|
||||
return EntityRegistry.findGlobalUniqueEntityId();
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static int getUniqueSpriteIndex(String path)
|
||||
{
|
||||
return SpriteHelper.getUniqueSpriteIndex(path);
|
||||
@@ -452,6 +492,7 @@ public class ModLoader
|
||||
return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean isGUIOpen(Class<? extends GuiScreen> gui)
|
||||
{
|
||||
return FMLClientHandler.instance().getClient().field_71462_r != null && FMLClientHandler.instance().getClient().field_71462_r.equals(gui);
|
||||
@@ -477,6 +518,7 @@ public class ModLoader
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
|
||||
{
|
||||
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
|
||||
@@ -495,10 +537,12 @@ public class ModLoader
|
||||
* Call in from elsewhere. Unimplemented here.
|
||||
*/
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void onTick(float tick, Minecraft game)
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void openGUI(EntityPlayer player, GuiScreen gui)
|
||||
{
|
||||
FMLClientHandler.instance().displayGuiScreen(player, gui);
|
||||
@@ -521,12 +565,14 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
|
||||
{
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerAllTextureOverrides(RenderEngine cache)
|
||||
{
|
||||
}
|
||||
@@ -552,6 +598,10 @@ public class ModLoader
|
||||
GameRegistry.registerBlock(block, itemclass);
|
||||
}
|
||||
|
||||
public static void registerContainerID(BaseMod mod, int id)
|
||||
{
|
||||
ModLoaderHelper.buildGuiHelper(mod, id);
|
||||
}
|
||||
/**
|
||||
* Register a new entity ID
|
||||
*
|
||||
@@ -578,10 +628,10 @@ public class ModLoader
|
||||
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
|
||||
{
|
||||
ModLoaderModContainer mlmc=ModLoaderHelper.registerKeyHelper(mod);
|
||||
KeyBindingRegistry.registerKeyBinding(new ModLoaderKeyBindingHandler(keyHandler, allowRepeat, mlmc));
|
||||
ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -607,6 +657,7 @@ public class ModLoader
|
||||
GameRegistry.registerTileEntity(tileEntityClass, id);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
|
||||
{
|
||||
ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
|
||||
@@ -669,18 +720,21 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean renderBlockIsItemFull3D(int modelID)
|
||||
{
|
||||
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
|
||||
{
|
||||
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
|
||||
@@ -695,9 +749,13 @@ public class ModLoader
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet from client to server
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
public static void sendPacket(Packet packet) {
|
||||
// TODO
|
||||
// FMLClientHandler.instance().sendPacket(packet);
|
||||
PacketDispatcher.sendPacketToServer(packet);
|
||||
}
|
||||
/**
|
||||
* Send a chat message to the server
|
||||
@@ -712,11 +770,24 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
public static void serverSendPacket(NetServerHandler handler, Packet packet)
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
PacketDispatcher.sendPacketToPlayer(packet, (Player)handler.getPlayer());
|
||||
}
|
||||
}
|
||||
public static void serverOpenWindow(EntityPlayerMP player, Container container, int ID, int x, int y, int z)
|
||||
{
|
||||
ModLoaderHelper.openGui(ID, player, container, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that you want to receive ticks
|
||||
*
|
||||
@@ -765,7 +836,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#onItemCrafted(EntityPlayer, ItemStack, IInventory)}
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
@@ -778,7 +848,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#onItemSmelted(EntityPlayer, ItemStack)}
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
@@ -790,7 +859,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* Throw the offered exception. Likely will stop the game.
|
||||
* {@link FMLClientHandler#raiseException(Throwable, String, boolean)}
|
||||
*
|
||||
* @param message
|
||||
* @param e
|
||||
|
||||
@@ -18,12 +18,8 @@ import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
/**
|
||||
* A texture override for animations, it takes a vertical image of
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
@@ -22,8 +24,6 @@ import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class ModTextureStatic extends FMLTextureFX
|
||||
{
|
||||
@@ -33,30 +33,30 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
private int storedSize;
|
||||
private BufferedImage overrideData = null;
|
||||
private int needApply = 2;
|
||||
|
||||
|
||||
|
||||
|
||||
public ModTextureStatic(int icon, int target, BufferedImage image)
|
||||
{
|
||||
this(icon, 1, target, image);
|
||||
}
|
||||
|
||||
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
|
||||
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
|
||||
{
|
||||
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image);
|
||||
}
|
||||
|
||||
|
||||
public ModTextureStatic(int icon, int size, String target, BufferedImage image)
|
||||
{
|
||||
super(icon);
|
||||
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
|
||||
|
||||
|
||||
targetTex = target;
|
||||
storedSize = size;
|
||||
field_76849_e = size;
|
||||
field_76847_f = re.func_78341_b(target);
|
||||
overrideData = image;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
@@ -80,16 +80,17 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
public void func_783_a()
|
||||
|
||||
@Override
|
||||
public void func_76846_a()
|
||||
{
|
||||
if (oldanaglyph != field_76851_c)
|
||||
{
|
||||
update();
|
||||
}
|
||||
// This makes it so we only apply the texture to the target texture when we need to,
|
||||
//due to the fact that update is called when the Effect is first registered, we actually
|
||||
//need to wait for the next one.
|
||||
// This makes it so we only apply the texture to the target texture when we need to,
|
||||
//due to the fact that update is called when the Effect is first registered, we actually
|
||||
//need to wait for the next one.
|
||||
field_76849_e = (needApply == 0 ? 0 : storedSize);
|
||||
if (needApply > 0)
|
||||
{
|
||||
@@ -97,11 +98,12 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
}
|
||||
}
|
||||
|
||||
public void func_782_a(RenderEngine p_782_1_)
|
||||
@Override
|
||||
public void func_76845_a(RenderEngine p_76845_1_)
|
||||
{
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, p_782_1_.func_78341_b(targetTex));
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, p_76845_1_.func_78341_b(targetTex));
|
||||
}
|
||||
|
||||
|
||||
public void update()
|
||||
{
|
||||
needApply = 2;
|
||||
@@ -126,7 +128,7 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
|
||||
oldanaglyph = field_76851_c;
|
||||
}
|
||||
|
||||
|
||||
//Implementation of http://scale2x.sourceforge.net/algorithm.html
|
||||
public static BufferedImage scale2x(BufferedImage image)
|
||||
{
|
||||
@@ -170,9 +172,9 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ModTextureStatic %s @ %d", targetTex, field_76850_b);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
/**
|
||||
* Compatibility class for ModLoader -- do not use
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class TradeEntry
|
||||
{
|
||||
public final int id;
|
||||
public float chance;
|
||||
public boolean buying;
|
||||
public int min = 0;
|
||||
public int max = 0;
|
||||
|
||||
public TradeEntry(int id, float chance, boolean buying, int min, int max)
|
||||
{
|
||||
this.id = id;
|
||||
this.chance = chance;
|
||||
this.buying = buying;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public TradeEntry(int id, float chance, boolean buying)
|
||||
{
|
||||
this(id, chance, buying, 0, 0);
|
||||
}
|
||||
}
|
||||
+57
-12
@@ -9,7 +9,7 @@
|
||||
if not sys.platform.startswith('win'):
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
@@ -582,6 +584,9 @@
|
||||
@@ -584,6 +586,9 @@
|
||||
self.has_astyle_cfg = False
|
||||
if os.path.isfile(self.astyleconf):
|
||||
self.has_astyle_cfg = True
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
|
||||
"""Create the files necessary for RetroGuard"""
|
||||
@@ -779,7 +784,8 @@
|
||||
@@ -781,7 +786,8 @@
|
||||
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
|
||||
|
||||
if not os.path.exists(os.path.join(srclk[side], os.path.normpath(testlk[side] + '.java'))):
|
||||
@@ -29,7 +29,18 @@
|
||||
return True
|
||||
|
||||
def checkbins(self, side):
|
||||
@@ -1039,6 +1045,7 @@
|
||||
@@ -1029,6 +1035,10 @@
|
||||
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
pathlog = {CLIENT: self.clientrecomplog, SERVER: self.serverrecomplog}
|
||||
|
||||
+ if side == SERVER: #Disable server because FML recombines it into client
|
||||
+ self.logger.info('Server side recompiling skipped, this is normal')
|
||||
+ return
|
||||
+
|
||||
if not os.path.exists(pathbinlk[side]):
|
||||
os.makedirs(pathbinlk[side])
|
||||
|
||||
@@ -1041,6 +1051,7 @@
|
||||
all_files = True
|
||||
append_pattern = False
|
||||
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
|
||||
@@ -37,7 +48,7 @@
|
||||
dirs = ' '.join(pkglist)
|
||||
classpath = os.pathsep.join(cplk[side])
|
||||
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
|
||||
@@ -1060,7 +1067,7 @@
|
||||
@@ -1062,7 +1073,7 @@
|
||||
raise
|
||||
|
||||
def startserver(self):
|
||||
@@ -46,7 +57,7 @@
|
||||
classpath = [os.path.join('..', p) for p in classpath]
|
||||
classpath = os.pathsep.join(classpath)
|
||||
os.chdir(self.dirjars)
|
||||
@@ -1068,7 +1075,7 @@
|
||||
@@ -1070,7 +1081,7 @@
|
||||
self.runmc(forkcmd)
|
||||
|
||||
def startclient(self):
|
||||
@@ -55,7 +66,7 @@
|
||||
classpath = [os.path.join('..', p) for p in classpath]
|
||||
classpath = os.pathsep.join(classpath)
|
||||
natives = os.path.join('..', self.dirnatives)
|
||||
@@ -1195,20 +1202,20 @@
|
||||
@@ -1197,20 +1208,20 @@
|
||||
with open(self.csvmethods, 'rb') as fh:
|
||||
methodsreader = csv.DictReader(fh)
|
||||
for row in methodsreader:
|
||||
@@ -79,7 +90,7 @@
|
||||
names['params'][row['param']] = row['name']
|
||||
|
||||
regexps = {
|
||||
@@ -1238,6 +1245,11 @@
|
||||
@@ -1240,6 +1251,11 @@
|
||||
|
||||
# HINT: We pathwalk the sources
|
||||
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
|
||||
@@ -91,7 +102,7 @@
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
updatefile(os.path.normpath(os.path.join(path, cur_file)))
|
||||
return True
|
||||
@@ -1320,12 +1332,14 @@
|
||||
@@ -1322,12 +1338,14 @@
|
||||
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
|
||||
strip_comments(pathsrclk[side])
|
||||
@@ -106,7 +117,7 @@
|
||||
|
||||
def process_javadoc(self, side):
|
||||
"""Add CSV descriptions to methods and fields as javadoc"""
|
||||
@@ -1334,6 +1348,21 @@
|
||||
@@ -1336,6 +1354,21 @@
|
||||
if not self.has_doc_csv:
|
||||
self.logger.warning('!! javadoc disabled due to no csvs !!')
|
||||
return False
|
||||
@@ -128,7 +139,7 @@
|
||||
|
||||
#HINT: We read the relevant CSVs
|
||||
methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
|
||||
@@ -1342,13 +1371,13 @@
|
||||
@@ -1344,13 +1377,13 @@
|
||||
methods = {}
|
||||
for row in methodsreader:
|
||||
#HINT: Only include methods that have a non-empty description
|
||||
@@ -144,7 +155,7 @@
|
||||
fields[row['searge']] = row['desc'].replace('*/', '* /')
|
||||
|
||||
regexps = {
|
||||
@@ -1420,6 +1449,7 @@
|
||||
@@ -1422,12 +1455,13 @@
|
||||
|
||||
# HINT: We create the list of source directories based on the list of packages
|
||||
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
|
||||
@@ -152,7 +163,24 @@
|
||||
dirs = ' '.join(pkglist)
|
||||
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
|
||||
self.runcmd(forkcmd)
|
||||
@@ -1592,6 +1622,9 @@
|
||||
return True
|
||||
|
||||
- def gathermd5s(self, side, reobf=False):
|
||||
+ def gathermd5s(self, side, reobf=False, skip_fml=False):
|
||||
if not reobf:
|
||||
md5lk = {CLIENT: self.md5client, SERVER: self.md5server}
|
||||
else:
|
||||
@@ -1442,6 +1476,9 @@
|
||||
class_path = ''
|
||||
else:
|
||||
class_path += '/'
|
||||
+ if skip_fml:
|
||||
+ if class_path.startswith('cpw/'):
|
||||
+ continue
|
||||
for class_file in fnmatch.filter(filelist, '*.class'):
|
||||
class_name = class_path + os.path.splitext(class_file)[0]
|
||||
bin_file = os.path.normpath(os.path.join(path, class_file))
|
||||
@@ -1594,6 +1631,9 @@
|
||||
sys.exit(1)
|
||||
|
||||
for entry in newfiles:
|
||||
@@ -162,3 +190,20 @@
|
||||
if entry[3] == 'U':
|
||||
self.logger.info('Retrieving file from server : %s', entry[0])
|
||||
cur_file = os.path.normpath(entry[0])
|
||||
@@ -1614,6 +1654,9 @@
|
||||
md5reoblk = {CLIENT: self.md5reobfclient, SERVER: self.md5reobfserver}
|
||||
outpathlk = {CLIENT: self.srcmodclient, SERVER: self.srcmodserver}
|
||||
src = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
+
|
||||
+ if side == SERVER: #Noop out server side stuff
|
||||
+ return
|
||||
|
||||
# HINT: We need a table for the old md5 and the new ones
|
||||
md5table = {}
|
||||
@@ -1656,3 +1699,6 @@
|
||||
except IOError:
|
||||
self.logger.error('* File %s copy failed', in_class)
|
||||
|
||||
+def commands_sanity_check():
|
||||
+ print 'Commands patch applied successfully'
|
||||
+
|
||||
@@ -3,17 +3,17 @@ package cpw.mods.fml.common;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
|
||||
public class DummyModContainer implements ModContainer
|
||||
{
|
||||
private ModMetadata md;
|
||||
private ArtifactVersion processedVersion;
|
||||
|
||||
public DummyModContainer(ModMetadata md)
|
||||
{
|
||||
@@ -42,9 +42,9 @@ public class DummyModContainer implements ModContainer
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +108,11 @@ public class DummyModContainer implements ModContainer
|
||||
@Override
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
return null;
|
||||
if (processedVersion == null)
|
||||
{
|
||||
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
|
||||
}
|
||||
return processedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,4 +126,10 @@ public class DummyModContainer implements ModContainer
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return md.version;
|
||||
}
|
||||
}
|
||||
@@ -13,45 +13,36 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.CrashReport;
|
||||
import net.minecraft.src.DedicatedServer;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import net.minecraft.src.ServerListenThread;
|
||||
import net.minecraft.src.ThreadServerApplication;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.server.FMLServerHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -80,20 +71,24 @@ public class FMLCommonHandler
|
||||
|
||||
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
|
||||
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
|
||||
private Class<?> forge;
|
||||
private boolean noForge;
|
||||
private List<String> brandings;
|
||||
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
|
||||
|
||||
|
||||
public void beginLoading(IFMLSidedHandler handler)
|
||||
{
|
||||
sidedDelegate = handler;
|
||||
FMLLog.info("Attempting early MinecraftForge initialization");
|
||||
callForgeMethod("initialize");
|
||||
callForgeMethod("registerCrashCallable");
|
||||
FMLLog.info("Completed early MinecraftForge initialization");
|
||||
}
|
||||
|
||||
public void rescheduleTicks(Side side)
|
||||
{
|
||||
sidedDelegate.profileStart("modTickScheduling");
|
||||
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
|
||||
{
|
||||
@@ -103,19 +98,15 @@ public class FMLCommonHandler
|
||||
{
|
||||
return;
|
||||
}
|
||||
sidedDelegate.profileStart("modTickStart$"+ticks);
|
||||
for (IScheduledTickHandler ticker : scheduledTicks)
|
||||
{
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
|
||||
ticksToRun.removeAll(EnumSet.complementOf(ticks));
|
||||
if (!ticksToRun.isEmpty())
|
||||
{
|
||||
sidedDelegate.profileStart(ticker.getLabel());
|
||||
ticker.tickStart(ticksToRun, data);
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
}
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
|
||||
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
|
||||
@@ -126,19 +117,15 @@ public class FMLCommonHandler
|
||||
{
|
||||
return;
|
||||
}
|
||||
sidedDelegate.profileStart("modTickEnd$"+ticks);
|
||||
for (IScheduledTickHandler ticker : scheduledTicks)
|
||||
{
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
|
||||
ticksToRun.removeAll(EnumSet.complementOf(ticks));
|
||||
if (!ticksToRun.isEmpty())
|
||||
{
|
||||
sidedDelegate.profileStart(ticker.getLabel());
|
||||
ticker.tickEnd(ticksToRun, data);
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
}
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,6 +168,23 @@ public class FMLCommonHandler
|
||||
return sidedDelegate.getSide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the effective side for the context in the game. This is dependent
|
||||
* on thread analysis to try and determine whether the code is running in the
|
||||
* server or not. Use at your own risk
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Side getEffectiveSide()
|
||||
{
|
||||
Thread thr = Thread.currentThread();
|
||||
if ((thr instanceof ThreadServerApplication) || (thr instanceof ServerListenThread))
|
||||
{
|
||||
return Side.SERVER;
|
||||
}
|
||||
|
||||
return Side.CLIENT;
|
||||
}
|
||||
/**
|
||||
* Raise an exception
|
||||
*
|
||||
@@ -198,9 +202,6 @@ public class FMLCommonHandler
|
||||
}
|
||||
|
||||
|
||||
private Class<?> forge;
|
||||
private boolean noForge;
|
||||
private List<String> brandings;
|
||||
private Class<?> findMinecraftForge()
|
||||
{
|
||||
if (forge==null && !noForge)
|
||||
@@ -238,7 +239,12 @@ public class FMLCommonHandler
|
||||
{
|
||||
Builder brd = ImmutableList.<String>builder();
|
||||
brd.add(Loader.instance().getMCVersionString());
|
||||
brd.add(Loader.instance().getFMLVersionString());
|
||||
brd.add("FML v"+Loader.instance().getFMLVersionString());
|
||||
String forgeBranding = (String) callForgeMethod("getBrandingVersion");
|
||||
if (!Strings.isNullOrEmpty(forgeBranding))
|
||||
{
|
||||
brd.add(forgeBranding);
|
||||
}
|
||||
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
|
||||
try {
|
||||
Properties props=new Properties();
|
||||
@@ -330,9 +336,9 @@ public class FMLCommonHandler
|
||||
sidedDelegate.showGuiScreen(clientGuiElement);
|
||||
}
|
||||
|
||||
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket entitySpawnPacket)
|
||||
public Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket entitySpawnPacket)
|
||||
{
|
||||
return sidedDelegate.spawnEntityIntoClientWorld(cls, entitySpawnPacket);
|
||||
return sidedDelegate.spawnEntityIntoClientWorld(registration, entitySpawnPacket);
|
||||
}
|
||||
|
||||
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
|
||||
@@ -342,16 +348,7 @@ public class FMLCommonHandler
|
||||
|
||||
public void onServerStart(DedicatedServer dedicatedServer)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Done this way so that the client doesn't depend on server side handler
|
||||
Class<?> cls = Class.forName("cpw.mods.fml.server.FMLServerHandler", true, getClass().getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to load the FML server handler");
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
FMLServerHandler.instance();
|
||||
sidedDelegate.beginServerLoading(dedicatedServer);
|
||||
}
|
||||
|
||||
@@ -384,11 +381,31 @@ public class FMLCommonHandler
|
||||
|
||||
public void onPlayerPreTick(EntityPlayer player)
|
||||
{
|
||||
tickStart(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
|
||||
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
|
||||
tickStart(EnumSet.of(TickType.PLAYER), side, player);
|
||||
}
|
||||
|
||||
public void onPlayerPostTick(EntityPlayer player)
|
||||
{
|
||||
tickEnd(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
|
||||
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
|
||||
tickEnd(EnumSet.of(TickType.PLAYER), side, player);
|
||||
}
|
||||
|
||||
public void registerCrashCallable(ICrashCallable callable)
|
||||
{
|
||||
crashCallables.add(callable);
|
||||
}
|
||||
|
||||
public void enhanceCrashReport(CrashReport crashReport)
|
||||
{
|
||||
for (ICrashCallable call: crashCallables)
|
||||
{
|
||||
crashReport.func_71500_a(call.getLabel(), call);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
sidedDelegate.handleTinyPacket(handler, mapData);
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,12 @@ public class FMLLog
|
||||
|
||||
public static void log(Level level, String format, Object... data)
|
||||
{
|
||||
coreLog.log(level, String.format(format, data));
|
||||
coreLog.log(level, format, data);
|
||||
}
|
||||
|
||||
public static void log(Level level, Throwable ex, String format, Object... data)
|
||||
{
|
||||
coreLog.log(level, String.format(format, data), ex);
|
||||
coreLog.log(level, ex, format, data);
|
||||
}
|
||||
|
||||
public static void severe(String format, Object... data)
|
||||
|
||||
@@ -16,32 +16,30 @@ import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.Mod.Block;
|
||||
import cpw.mods.fml.common.Mod.Instance;
|
||||
import cpw.mods.fml.common.Mod.Metadata;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
@@ -51,7 +49,6 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
|
||||
@@ -64,9 +61,7 @@ public class FMLModContainer implements ModContainer
|
||||
private String className;
|
||||
private Map<String, Object> descriptor;
|
||||
private boolean enabled = true;
|
||||
private List<ArtifactVersion> requirements;
|
||||
private List<ArtifactVersion> dependencies;
|
||||
private List<ArtifactVersion> dependants;
|
||||
private String internalVersion;
|
||||
private boolean overridesMetadata;
|
||||
private EventBus eventBus;
|
||||
private LoadController controller;
|
||||
@@ -83,6 +78,7 @@ public class FMLModContainer implements ModContainer
|
||||
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
|
||||
.build();
|
||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||
private String annotationDependencies;
|
||||
|
||||
|
||||
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
||||
@@ -107,7 +103,7 @@ public class FMLModContainer implements ModContainer
|
||||
@Override
|
||||
public String getVersion()
|
||||
{
|
||||
return modMetadata.version;
|
||||
return internalVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,13 +130,35 @@ public class FMLModContainer implements ModContainer
|
||||
|
||||
if (overridesMetadata || !modMetadata.useDependencyInformation)
|
||||
{
|
||||
List<ArtifactVersion> requirements = Lists.newArrayList();
|
||||
Set<ArtifactVersion> requirements = Sets.newHashSet();
|
||||
List<ArtifactVersion> dependencies = Lists.newArrayList();
|
||||
List<ArtifactVersion> dependants = Lists.newArrayList();
|
||||
Loader.instance().computeDependencies((String) descriptor.get("dependencies"), requirements, dependencies, dependants);
|
||||
annotationDependencies = (String) descriptor.get("dependencies");
|
||||
Loader.instance().computeDependencies(annotationDependencies, requirements, dependencies, dependants);
|
||||
modMetadata.requiredMods = requirements;
|
||||
modMetadata.dependencies = dependencies;
|
||||
modMetadata.dependants = dependants;
|
||||
FMLLog.finest("Parsed dependency info : %s %s %s", requirements, dependencies, dependants);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.finest("Using mcmod dependency info : %s %s %s", modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants);
|
||||
}
|
||||
if (Strings.isNullOrEmpty(modMetadata.name))
|
||||
{
|
||||
FMLLog.info("Mod %s is missing the required element 'name'. Substituting %s", getModId(), getModId());
|
||||
modMetadata.name = getModId();
|
||||
}
|
||||
internalVersion = (String) descriptor.get("version");
|
||||
if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version))
|
||||
{
|
||||
FMLLog.warning("Mod %s is missing the required element 'version'. Falling back to metadata version %s", getModId(), modMetadata.version);
|
||||
modMetadata.version = internalVersion;
|
||||
}
|
||||
if (Strings.isNullOrEmpty(internalVersion))
|
||||
{
|
||||
FMLLog.warning("Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
|
||||
modMetadata.version = internalVersion = "1.0";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +169,7 @@ public class FMLModContainer implements ModContainer
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return modMetadata.requiredMods;
|
||||
}
|
||||
@@ -171,7 +189,7 @@ public class FMLModContainer implements ModContainer
|
||||
@Override
|
||||
public String getSortingRules()
|
||||
{
|
||||
return modMetadata.printableSortingRules();
|
||||
return ((overridesMetadata || !modMetadata.useDependencyInformation) ? Strings.nullToEmpty(annotationDependencies) : modMetadata.printableSortingRules());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,49 +225,48 @@ public class FMLModContainer implements ModContainer
|
||||
{
|
||||
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
|
||||
|
||||
for (Field f : clazz.getDeclaredFields())
|
||||
{
|
||||
for (Annotation a : f.getAnnotations())
|
||||
{
|
||||
f.setAccessible(true);
|
||||
anns.put(a.annotationType(), f);
|
||||
}
|
||||
}
|
||||
|
||||
for (Method m : clazz.getDeclaredMethods())
|
||||
{
|
||||
for (Annotation a : m.getAnnotations())
|
||||
{
|
||||
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
|
||||
if (modTypeAnnotations.containsKey(a.annotationType()))
|
||||
{
|
||||
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
|
||||
|
||||
if (Arrays.equals(m.getParameterTypes(), paramTypes))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
anns.put(a.annotationType(), m);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
|
||||
if (Arrays.equals(m.getParameterTypes(), paramTypes))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
anns.put(a.annotationType(), m);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return anns;
|
||||
}
|
||||
|
||||
private void processFieldAnnotations() throws Exception
|
||||
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
|
||||
{
|
||||
// Instance annotation
|
||||
for (Object o : annotations.get(Instance.class))
|
||||
{
|
||||
Field f = (Field) o;
|
||||
f.set(modInstance, modInstance);
|
||||
}
|
||||
SetMultimap<String, ASMData> annotations = asmDataTable.getAnnotationsFor(this);
|
||||
|
||||
for (Object o : annotations.get(Metadata.class))
|
||||
parseSimpleFieldAnnotation(annotations, Instance.class.getName(), new Function<ModContainer, Object>()
|
||||
{
|
||||
Field f = (Field) o;
|
||||
f.set(modInstance, modMetadata);
|
||||
}
|
||||
public Object apply(ModContainer mc)
|
||||
{
|
||||
return mc.getMod();
|
||||
}
|
||||
});
|
||||
parseSimpleFieldAnnotation(annotations, Metadata.class.getName(), new Function<ModContainer, Object>()
|
||||
{
|
||||
public Object apply(ModContainer mc)
|
||||
{
|
||||
return mc.getMetadata();
|
||||
}
|
||||
});
|
||||
|
||||
//TODO
|
||||
// for (Object o : annotations.get(Block.class))
|
||||
// {
|
||||
@@ -258,6 +275,62 @@ public class FMLModContainer implements ModContainer
|
||||
// }
|
||||
}
|
||||
|
||||
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
|
||||
{
|
||||
String[] annName = annotationClassName.split("\\.");
|
||||
String annotationName = annName[annName.length - 1];
|
||||
for (ASMData targets : annotations.get(annotationClassName))
|
||||
{
|
||||
String targetMod = (String) targets.getAnnotationInfo().get("value");
|
||||
Field f = null;
|
||||
Object injectedMod = null;
|
||||
ModContainer mc = this;
|
||||
boolean isStatic = false;
|
||||
Class<?> clz = modInstance.getClass();
|
||||
if (!Strings.isNullOrEmpty(targetMod))
|
||||
{
|
||||
if (Loader.isModLoaded(targetMod))
|
||||
{
|
||||
mc = Loader.instance().getIndexedModList().get(targetMod);
|
||||
}
|
||||
else
|
||||
{
|
||||
mc = null;
|
||||
}
|
||||
}
|
||||
if (mc != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader());
|
||||
f = clz.getDeclaredField(targets.getObjectName());
|
||||
f.setAccessible(true);
|
||||
isStatic = Modifier.isStatic(f.getModifiers());
|
||||
injectedMod = retreiver.apply(mc);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
FMLLog.log(Level.WARNING, e, "Attempting to load @%s in class %s for %s and failing", annotationName, targets.getClassName(), mc.getModId());
|
||||
}
|
||||
}
|
||||
if (f != null)
|
||||
{
|
||||
Object target = null;
|
||||
if (!isStatic)
|
||||
{
|
||||
target = modInstance;
|
||||
if (!modInstance.getClass().equals(clz))
|
||||
{
|
||||
FMLLog.warning("Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f.set(target, injectedMod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void constructMod(FMLConstructionEvent event)
|
||||
{
|
||||
@@ -273,7 +346,7 @@ public class FMLModContainer implements ModContainer
|
||||
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
|
||||
modInstance = clazz.newInstance();
|
||||
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
||||
processFieldAnnotations();
|
||||
processFieldAnnotations(event.getASMHarvestedData());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
@@ -325,4 +398,10 @@ public class FMLModContainer implements ModContainer
|
||||
{
|
||||
return isNetworkMod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return modMetadata.version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface ICrashCallable extends Callable<String>
|
||||
{
|
||||
String getLabel();
|
||||
}
|
||||
@@ -12,6 +12,8 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
@@ -21,13 +23,20 @@ public interface IDispenseHandler
|
||||
/**
|
||||
* Return -1 if you don't want to dispense anything. the other values seem to have specific meanings
|
||||
* to blockdispenser.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVelocity
|
||||
* @param zVelocity
|
||||
* @param data
|
||||
* @param world
|
||||
* @param item
|
||||
* @param random
|
||||
* @param entX
|
||||
* @param entY
|
||||
* @param entZ
|
||||
* @return
|
||||
*/
|
||||
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item);
|
||||
@Deprecated
|
||||
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IDispenserHandler
|
||||
{
|
||||
/**
|
||||
* Called to dispense an entity
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVelocity
|
||||
* @param zVelocity
|
||||
* @param world
|
||||
* @param item
|
||||
* @param random
|
||||
* @param entX
|
||||
* @param entY
|
||||
* @param entZ
|
||||
* @return
|
||||
*/
|
||||
int dispense(int x, int y, int z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ);
|
||||
}
|
||||
@@ -1,27 +1,19 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.DedicatedServer;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
import cpw.mods.fml.common.modloader.ModProperty;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
|
||||
public interface IFMLSidedHandler
|
||||
{
|
||||
void profileStart(String profileLabel);
|
||||
|
||||
void profileEnd();
|
||||
|
||||
List<String> getAdditionalBrandingInformation();
|
||||
|
||||
Side getSide();
|
||||
@@ -30,7 +22,7 @@ public interface IFMLSidedHandler
|
||||
|
||||
void showGuiScreen(Object clientGuiElement);
|
||||
|
||||
Entity spawnEntityIntoClientWorld(Class<? extends Entity> entityClass, EntitySpawnPacket packet);
|
||||
Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket packet);
|
||||
|
||||
void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket);
|
||||
|
||||
@@ -39,4 +31,14 @@ public interface IFMLSidedHandler
|
||||
void finishServerLoading();
|
||||
|
||||
MinecraftServer getServer();
|
||||
|
||||
void sendPacket(Packet packet);
|
||||
|
||||
void displayMissingMods(ModMissingPacket modMissingPacket);
|
||||
|
||||
void handleTinyPacket(NetHandler handler, Packet131MapData mapData);
|
||||
|
||||
void setClientCompatibilityLevel(byte compatibilityLevel);
|
||||
|
||||
byte getClientCompatibilityLevel();
|
||||
}
|
||||
@@ -13,7 +13,10 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
|
||||
public interface IPickupNotifier
|
||||
{
|
||||
void notifyPickup(Object... pickupData);
|
||||
void notifyPickup(EntityItem item, EntityPlayer player);
|
||||
}
|
||||
@@ -14,13 +14,19 @@
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IPlayerTracker
|
||||
{
|
||||
void onPlayerLogin(Object player);
|
||||
void onPlayerLogout(Object player);
|
||||
void onPlayerChangedDimension(Object player);
|
||||
void onPlayerLogin(EntityPlayer player);
|
||||
|
||||
void onPlayerLogout(EntityPlayer player);
|
||||
|
||||
void onPlayerChangedDimension(EntityPlayer player);
|
||||
|
||||
void onPlayerRespawn(EntityPlayer player);
|
||||
}
|
||||
@@ -31,8 +31,8 @@ public interface IWorldGenerator
|
||||
* Generate some world
|
||||
*
|
||||
* @param random the chunk specific {@link Random}.
|
||||
* @param chunkX the block X coordinate of this chunk.
|
||||
* @param chunkZ the block Z coordinate of this chunk.
|
||||
* @param chunkX the chunk X coordinate of this chunk.
|
||||
* @param chunkZ the chunk Z coordinate of this chunk.
|
||||
* @param world : additionalData[0] The minecraft {@link World} we're generating for.
|
||||
* @param generator : additionalData[1] The {@link IChunkProvider} that is generating.
|
||||
* @param chunkProvider : additionalData[2] {@link IChunkProvider} that is requesting the world generation.
|
||||
|
||||
@@ -2,6 +2,7 @@ package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
@@ -53,7 +54,7 @@ public class InjectedModContainer implements ModContainer
|
||||
wrappedContainer.setEnabledState(enabled);
|
||||
}
|
||||
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return wrappedContainer.getRequirements();
|
||||
}
|
||||
@@ -103,4 +104,10 @@ public class InjectedModContainer implements ModContainer
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return wrappedContainer.getDisplayVersion();
|
||||
}
|
||||
}
|
||||
@@ -8,23 +8,19 @@ import java.util.logging.Level;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||
|
||||
public class LoadController
|
||||
{
|
||||
@@ -36,7 +32,7 @@ public class LoadController
|
||||
private Multimap<String, Throwable> errors = ArrayListMultimap.create();
|
||||
private Map<String, ModContainer> modList;
|
||||
private List<ModContainer> activeModList = Lists.newArrayList();
|
||||
private String activeContainer;
|
||||
private ModContainer activeContainer;
|
||||
private BiMap<ModContainer, Object> modObjectList;
|
||||
|
||||
public LoadController(Loader loader)
|
||||
@@ -109,43 +105,55 @@ public class LoadController
|
||||
|
||||
public ModContainer activeContainer()
|
||||
{
|
||||
return activeContainer!=null ? modList.get(activeContainer) : null;
|
||||
return activeContainer;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void propogateStateMessage(FMLStateEvent stateEvent)
|
||||
{
|
||||
for (Map.Entry<String,EventBus> entry : eventChannels.entrySet())
|
||||
if (stateEvent instanceof FMLPreInitializationEvent)
|
||||
{
|
||||
activeContainer = entry.getKey();
|
||||
modObjectList = buildModObjectList();
|
||||
}
|
||||
for (ModContainer mc : activeModList)
|
||||
{
|
||||
activeContainer = mc;
|
||||
String modId = mc.getModId();
|
||||
stateEvent.applyModContainer(activeContainer());
|
||||
FMLLog.finer("Posting state event %s to mod %s", stateEvent, entry.getKey());
|
||||
entry.getValue().post(stateEvent);
|
||||
FMLLog.finer("State event %s delivered to mod %s", stateEvent, entry.getKey());
|
||||
FMLLog.finer("Posting state event %s to mod %s", stateEvent, modId);
|
||||
eventChannels.get(modId).post(stateEvent);
|
||||
FMLLog.finer("State event %s delivered to mod %s", stateEvent, modId);
|
||||
activeContainer = null;
|
||||
if (!errors.containsKey(entry.getKey()))
|
||||
if (!errors.containsKey(modId))
|
||||
{
|
||||
modStates.put(entry.getKey(), stateEvent.getModState());
|
||||
modStates.put(modId, stateEvent.getModState());
|
||||
}
|
||||
else
|
||||
{
|
||||
modStates.put(entry.getKey(), ModState.ERRORED);
|
||||
modStates.put(modId, ModState.ERRORED);
|
||||
}
|
||||
}
|
||||
if (stateEvent instanceof FMLConstructionEvent)
|
||||
{
|
||||
buildModObjectList();
|
||||
}
|
||||
}
|
||||
|
||||
public void buildModObjectList()
|
||||
public ImmutableBiMap<ModContainer, Object> buildModObjectList()
|
||||
{
|
||||
ImmutableBiMap.Builder<ModContainer, Object> builder = ImmutableBiMap.<ModContainer, Object>builder();
|
||||
for (ModContainer mc : activeModList)
|
||||
{
|
||||
builder.put(mc, mc.getMod());
|
||||
if (!mc.isImmutable() && mc.getMod()!=null)
|
||||
{
|
||||
builder.put(mc, mc.getMod());
|
||||
}
|
||||
if (mc.getMod()==null && !mc.isImmutable() && state!=LoaderState.CONSTRUCTING)
|
||||
{
|
||||
FMLLog.severe("There is a severe problem with %s - it appears not to have constructed correctly", mc.getModId());
|
||||
if (state != LoaderState.CONSTRUCTING)
|
||||
{
|
||||
this.errorOccurred(mc, new RuntimeException());
|
||||
}
|
||||
}
|
||||
}
|
||||
modObjectList = builder.build();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public void errorOccurred(ModContainer modContainer, Throwable exception)
|
||||
@@ -155,11 +163,10 @@ public class LoadController
|
||||
|
||||
public void printModStates(StringBuilder ret)
|
||||
{
|
||||
for (String modId : modStates.keySet())
|
||||
for (ModContainer mc : loader.getModList())
|
||||
{
|
||||
ModContainer mod = modList.get(modId);
|
||||
ret.append("\n\t").append(mod.getName()).append(" (").append(mod.getSource().getName()).append(") ");
|
||||
Joiner.on("->"). appendTo(ret, modStates.get(modId));
|
||||
ret.append("\n\t").append(mc.getModId()).append(" [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
|
||||
Joiner.on("->"). appendTo(ret, modStates.get(mc.getModId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,6 +195,16 @@ public class LoadController
|
||||
|
||||
public BiMap<ModContainer, Object> getModObjectList()
|
||||
{
|
||||
if (modObjectList == null)
|
||||
{
|
||||
FMLLog.severe("Detected an attempt by a mod %s to perform game activity during mod construction. This is a serious programming error.", activeContainer);
|
||||
return buildModObjectList();
|
||||
}
|
||||
return ImmutableBiMap.copyOf(modObjectList);
|
||||
}
|
||||
|
||||
public boolean isInState(LoaderState state)
|
||||
{
|
||||
return this.state == state;
|
||||
}
|
||||
}
|
||||
@@ -14,42 +14,43 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.CallableMinecraftVersion;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Splitter.MapSplitter;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Multiset.Entry;
|
||||
import com.google.common.collect.Multisets;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
import com.google.common.collect.TreeMultimap;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
import cpw.mods.fml.common.event.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.functions.ModIdFunction;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.common.toposort.ModSorter;
|
||||
import cpw.mods.fml.common.toposort.ModSortingException;
|
||||
import cpw.mods.fml.common.toposort.TopologicalSort;
|
||||
@@ -160,6 +161,12 @@ public class Loader
|
||||
private Loader()
|
||||
{
|
||||
modClassLoader = new ModClassLoader(getClass().getClassLoader());
|
||||
String actualMCVersion = new CallableMinecraftVersion(null).func_71493_a();
|
||||
if (!mccversion.equals(actualMCVersion))
|
||||
{
|
||||
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, actualMCVersion);
|
||||
throw new LoaderException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,14 +179,32 @@ public class Loader
|
||||
FMLLog.fine("Verifying mod requirements are satisfied");
|
||||
try
|
||||
{
|
||||
Map<String, ArtifactVersion> modVersions = Maps.newHashMap();
|
||||
for (ModContainer mod : mods)
|
||||
BiMap<String, ArtifactVersion> modVersions = HashBiMap.create();
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
modVersions.put(mod.getModId(), mod.getProcessedVersion());
|
||||
}
|
||||
|
||||
for (ModContainer mod : mods)
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new Function<ArtifactVersion, String>()
|
||||
{
|
||||
public String apply(ArtifactVersion v)
|
||||
{
|
||||
return v.getLabel();
|
||||
}
|
||||
});
|
||||
Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
|
||||
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
|
||||
if (!missingMods.isEmpty())
|
||||
{
|
||||
FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
|
||||
for (String modid : missingMods)
|
||||
{
|
||||
versionMissingMods.add(names.get(modid));
|
||||
}
|
||||
throw new MissingModsException(versionMissingMods);
|
||||
}
|
||||
ImmutableList<ArtifactVersion> allDeps = ImmutableList.<ArtifactVersion>builder().addAll(mod.getDependants()).addAll(mod.getDependencies()).build();
|
||||
for (ArtifactVersion v : allDeps)
|
||||
{
|
||||
@@ -187,21 +212,32 @@ public class Loader
|
||||
{
|
||||
if (!v.containsVersion(modVersions.get(v.getLabel())))
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "The mod %s (%s) requires mods %s to be available, one or more are not", mod.getModId(), mod.getName(), allDeps);
|
||||
throw new LoaderException();
|
||||
versionMissingMods.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!versionMissingMods.isEmpty())
|
||||
{
|
||||
FMLLog.severe("The mod %s (%s) requires mod versions %s to be available", mod.getModId(), mod.getName(), versionMissingMods);
|
||||
throw new MissingModsException(versionMissingMods);
|
||||
}
|
||||
}
|
||||
|
||||
FMLLog.fine("All mod requirements are satisfied");
|
||||
|
||||
ModSorter sorter = new ModSorter(mods, namedMods);
|
||||
ModSorter sorter = new ModSorter(getActiveModList(), namedMods);
|
||||
|
||||
try
|
||||
{
|
||||
FMLLog.fine("Sorting mods into an ordered list");
|
||||
mods = sorter.sort();
|
||||
List<ModContainer> sortedMods = sorter.sort();
|
||||
// Reset active list to the sorted list
|
||||
modController.getActiveModList().clear();
|
||||
modController.getActiveModList().addAll(sortedMods);
|
||||
// And inject the sorted list into the overall list
|
||||
mods.removeAll(sortedMods);
|
||||
sortedMods.addAll(mods);
|
||||
mods = sortedMods;
|
||||
FMLLog.fine("Mod sorting completed successfully");
|
||||
}
|
||||
catch (ModSortingException sortException)
|
||||
@@ -216,11 +252,11 @@ public class Loader
|
||||
finally
|
||||
{
|
||||
FMLLog.fine("Mod sorting data:");
|
||||
for (ModContainer mod : mods)
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
if (!mod.isImmutable())
|
||||
{
|
||||
FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules());
|
||||
FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), mod.getSortingRules());
|
||||
}
|
||||
}
|
||||
if (mods.size()==0)
|
||||
@@ -279,11 +315,46 @@ public class Loader
|
||||
discoverer.findModDirMods(canonicalModsDir);
|
||||
|
||||
mods.addAll(discoverer.identifyMods());
|
||||
identifyDuplicates(mods);
|
||||
namedMods = Maps.uniqueIndex(mods, new ModIdFunction());
|
||||
FMLLog.info("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 1 ? "s" : "");
|
||||
return discoverer;
|
||||
}
|
||||
|
||||
private class ModIdComparator implements Comparator<ModContainer>
|
||||
{
|
||||
@Override
|
||||
public int compare(ModContainer o1, ModContainer o2)
|
||||
{
|
||||
return o1.getModId().compareTo(o2.getModId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void identifyDuplicates(List<ModContainer> mods)
|
||||
{
|
||||
boolean foundDupe = false;
|
||||
TreeMultimap<ModContainer, File> dupsearch = TreeMultimap.create(new ModIdComparator(), Ordering.arbitrary());
|
||||
for (ModContainer mc : mods)
|
||||
{
|
||||
if (mc.getSource() != null)
|
||||
{
|
||||
dupsearch.put(mc, mc.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableMultiset<ModContainer> duplist = Multisets.copyHighestCountFirst(dupsearch.keys());
|
||||
for (Entry<ModContainer> e : duplist.entrySet())
|
||||
{
|
||||
if (e.getCount() > 1)
|
||||
{
|
||||
FMLLog.severe("Found a duplicate mod %s at %s", e.getElement().getModId(), dupsearch.get(e.getElement()));
|
||||
foundDupe = true;
|
||||
}
|
||||
}
|
||||
if (foundDupe) { throw new LoaderException(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@@ -365,9 +436,24 @@ public class Loader
|
||||
modController.transition(LoaderState.LOADING);
|
||||
ModDiscoverer disc = identifyMods();
|
||||
disableRequestedMods();
|
||||
modController.distributeStateMessage(FMLLoadEvent.class);
|
||||
sortModList();
|
||||
mods = ImmutableList.copyOf(mods);
|
||||
modController.distributeStateMessage(FMLLoadEvent.class);
|
||||
for (File nonMod : disc.getNonModLibs())
|
||||
{
|
||||
if (nonMod.isFile())
|
||||
{
|
||||
FMLLog.severe("FML has found a non-mod file %s in your mods directory. It will now be injected into your classpath. This could severe stability issues, it should be removed if possible.", nonMod.getName());
|
||||
try
|
||||
{
|
||||
modClassLoader.addFile(nonMod);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Encountered a weird problem with non-mod file injection : %s", nonMod.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
modController.transition(LoaderState.CONSTRUCTING);
|
||||
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, disc.getASMTable());
|
||||
modController.transition(LoaderState.PREINITIALIZATION);
|
||||
@@ -377,30 +463,30 @@ public class Loader
|
||||
|
||||
private void disableRequestedMods()
|
||||
{
|
||||
String disabledModList = System.getProperty("fml.modStates", "");
|
||||
FMLLog.fine("Received a system property request \'%s\'",disabledModList);
|
||||
String forcedModList = System.getProperty("fml.modStates", "");
|
||||
FMLLog.fine("Received a system property request \'%s\'",forcedModList);
|
||||
Map<String, String> sysPropertyStateList = Splitter.on(CharMatcher.anyOf(";:"))
|
||||
.omitEmptyStrings().trimResults().withKeyValueSeparator("=")
|
||||
.split(disabledModList);
|
||||
.split(forcedModList);
|
||||
FMLLog.fine("System property request managing the state of %d mods", sysPropertyStateList.size());
|
||||
Map<String, String> modStates = Maps.newHashMap();
|
||||
|
||||
File disabledModFile = new File(canonicalConfigDir, "fmlModState.properties");
|
||||
Properties disabledModListProperties = new Properties();
|
||||
if (disabledModFile.exists() && disabledModFile.isFile())
|
||||
File forcedModFile = new File(canonicalConfigDir, "fmlModState.properties");
|
||||
Properties forcedModListProperties = new Properties();
|
||||
if (forcedModFile.exists() && forcedModFile.isFile())
|
||||
{
|
||||
FMLLog.fine("Found a mod state file %s", disabledModFile.getName());
|
||||
FMLLog.fine("Found a mod state file %s", forcedModFile.getName());
|
||||
try
|
||||
{
|
||||
disabledModListProperties.load(new FileReader(disabledModFile));
|
||||
FMLLog.fine("Loaded states for %d mods from file", disabledModListProperties.size());
|
||||
forcedModListProperties.load(new FileReader(forcedModFile));
|
||||
FMLLog.fine("Loaded states for %d mods from file", forcedModListProperties.size());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.INFO, e, "An error occurred reading the fmlModState.properties file");
|
||||
}
|
||||
}
|
||||
modStates.putAll(Maps.fromProperties(disabledModListProperties));
|
||||
modStates.putAll(Maps.fromProperties(forcedModListProperties));
|
||||
modStates.putAll(sysPropertyStateList);
|
||||
FMLLog.fine("After merging, found state information for %d mods", modStates.size());
|
||||
|
||||
@@ -408,7 +494,7 @@ public class Loader
|
||||
{
|
||||
public Boolean apply(String input)
|
||||
{
|
||||
return !Boolean.parseBoolean(input);
|
||||
return Boolean.parseBoolean(input);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -430,7 +516,7 @@ public class Loader
|
||||
*/
|
||||
public static boolean isModLoaded(String modname)
|
||||
{
|
||||
return instance().namedMods.containsKey(modname);
|
||||
return instance().namedMods.containsKey(modname) && instance().modController.getModState(instance.namedMods.get(modname))!=ModState.DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -459,7 +545,7 @@ public class Loader
|
||||
*/
|
||||
public String getFMLVersionString()
|
||||
{
|
||||
return String.format("FML v%s.%s.%s.%s", major, minor, rev, build);
|
||||
return String.format("%s.%s.%s.%s", major, minor, rev, build);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -470,7 +556,7 @@ public class Loader
|
||||
return modClassLoader;
|
||||
}
|
||||
|
||||
public void computeDependencies(String dependencyString, List<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
|
||||
public void computeDependencies(String dependencyString, Set<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
|
||||
{
|
||||
if (dependencyString == null || dependencyString.length() == 0)
|
||||
{
|
||||
@@ -559,14 +645,20 @@ public class Loader
|
||||
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size()==1 ? "" : "s");
|
||||
}
|
||||
|
||||
public Callable getCallableCrashInformation()
|
||||
public ICrashCallable getCallableCrashInformation()
|
||||
{
|
||||
return new Callable<String>() {
|
||||
return new ICrashCallable() {
|
||||
@Override
|
||||
public String call() throws Exception
|
||||
{
|
||||
return getCrashInformation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return "FML";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -614,4 +706,14 @@ public class Loader
|
||||
{
|
||||
return getModObjectList().inverse();
|
||||
}
|
||||
|
||||
public ModContainer activeModContainer()
|
||||
{
|
||||
return modController.activeContainer();
|
||||
}
|
||||
|
||||
public boolean isInState(LoaderState state)
|
||||
{
|
||||
return modController.isInState(state);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import argo.jdom.JdomParser;
|
||||
import argo.jdom.JsonNode;
|
||||
@@ -14,7 +11,6 @@ import argo.jdom.JsonRootNode;
|
||||
import argo.saj.InvalidSyntaxException;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class MetadataCollection
|
||||
@@ -23,13 +19,13 @@ public class MetadataCollection
|
||||
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
|
||||
private int metadataVersion = 1;
|
||||
|
||||
public static MetadataCollection from(InputStream inputStream)
|
||||
public static MetadataCollection from(InputStream inputStream, String sourceName)
|
||||
{
|
||||
if (inputStream == null)
|
||||
{
|
||||
return new MetadataCollection();
|
||||
}
|
||||
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(inputStream);
|
||||
try
|
||||
{
|
||||
@@ -43,6 +39,11 @@ public class MetadataCollection
|
||||
return parseModInfo(root);
|
||||
}
|
||||
}
|
||||
catch (InvalidSyntaxException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "The mcmod.info file in %s cannot be parsed as valid JSON. It will be ignored", sourceName);
|
||||
return new MetadataCollection();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw Throwables.propagate(e);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class MissingModsException extends RuntimeException
|
||||
{
|
||||
|
||||
public Set<ArtifactVersion> missingMods;
|
||||
|
||||
public MissingModsException(Set<ArtifactVersion> missingMods)
|
||||
{
|
||||
this.missingMods = missingMods;
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartedEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
|
||||
|
||||
import net.minecraft.src.ItemBlock;
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
@@ -24,8 +23,9 @@ import java.util.logging.Level;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ModCandidate;
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.common.asm.ASMTransformer;
|
||||
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
/**
|
||||
@@ -79,4 +79,11 @@ public class ModClassLoader extends URLClassLoader
|
||||
{
|
||||
return STANDARD_LIBRARIES;
|
||||
}
|
||||
|
||||
public Class<? extends BaseModProxy> loadBaseModClass(String modClazzName) throws Exception
|
||||
{
|
||||
AccessTransformer transformer = (AccessTransformer)mainClassLoader.getTransformers().get(0);
|
||||
transformer.ensurePublicAccessFor(modClazzName);
|
||||
return (Class<? extends BaseModProxy>) Class.forName(modClazzName, true, this);
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,10 @@ package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
/**
|
||||
@@ -91,7 +91,7 @@ public interface ModContainer
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ArtifactVersion> getRequirements();
|
||||
Set<ArtifactVersion> getRequirements();
|
||||
|
||||
/**
|
||||
* A list of modids that should be loaded prior to this one. The special
|
||||
@@ -150,4 +150,6 @@ public interface ModContainer
|
||||
boolean isImmutable();
|
||||
|
||||
boolean isNetworkMod();
|
||||
|
||||
String getDisplayVersion();
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ModCandidate;
|
||||
import cpw.mods.fml.common.discovery.asm.ASMModParser;
|
||||
import cpw.mods.fml.common.discovery.asm.ModAnnotation;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
@@ -16,20 +17,38 @@ public class ModContainerFactory
|
||||
public static ModContainerFactory instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
public ModContainer build(ASMModParser modParser, File modSource)
|
||||
public ModContainer build(ASMModParser modParser, File modSource, ModCandidate container)
|
||||
{
|
||||
String className = modParser.getASMType().getClassName();
|
||||
if (modParser.isBaseMod() && modClass.matcher(className).find())
|
||||
if (modParser.isBaseMod(container.getRememberedBaseMods()) && modClass.matcher(className).find())
|
||||
{
|
||||
FMLLog.fine("Identified a BaseMod type mod %s", className);
|
||||
return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties());
|
||||
}
|
||||
else if (modClass.matcher(className).find())
|
||||
{
|
||||
FMLLog.fine("Identified a class %s following modloader naming convention but not directly a BaseMod or currently seen subclass", className);
|
||||
container.rememberModCandidateType(modParser);
|
||||
}
|
||||
else if (modParser.isBaseMod(container.getRememberedBaseMods()))
|
||||
{
|
||||
FMLLog.fine("Found a basemod %s of non-standard naming format", className);
|
||||
container.rememberBaseModType(className);
|
||||
}
|
||||
|
||||
// We warn if it's not a basemod instance -- compatibility requires it to be in net.minecraft.src *sigh*
|
||||
if (className.startsWith("net.minecraft.src.") && container.isClasspath() && !container.isMinecraftJar())
|
||||
{
|
||||
FMLLog.severe("FML has detected a mod that is using a package name based on 'net.minecraft.src' : %s. This is generally a severe programming error. "
|
||||
+ " There should be no mod code in the minecraft namespace. MOVE YOUR MOD! If you're in eclipse, select your source code and 'refactor' it into "
|
||||
+ "a new package. Go on. DO IT NOW!",className);
|
||||
}
|
||||
|
||||
for (ModAnnotation ann : modParser.getAnnotations())
|
||||
{
|
||||
if (ann.getASMType().equals(Type.getType(Mod.class)))
|
||||
{
|
||||
FMLLog.fine("Identified a FMLMod type mod %s", className);
|
||||
FMLLog.fine("Identified an FMLMod type mod %s", className);
|
||||
return new FMLModContainer(className, modSource, ann.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import static argo.jdom.JsonNodeBuilders.aStringBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import argo.jdom.JsonNode;
|
||||
import argo.jdom.JsonStringNode;
|
||||
@@ -35,12 +36,9 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.functions.ModNameFunction;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
|
||||
import static argo.jdom.JsonNodeBuilders.*;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
@@ -88,7 +86,7 @@ public class ModMetadata
|
||||
public List<ModContainer> childMods = Lists.newArrayList();
|
||||
|
||||
public boolean useDependencyInformation;
|
||||
public List<ArtifactVersion> requiredMods;
|
||||
public Set<ArtifactVersion> requiredMods;
|
||||
public List<ArtifactVersion> dependencies;
|
||||
public List<ArtifactVersion> dependants;
|
||||
public boolean autogenerated;
|
||||
@@ -101,6 +99,11 @@ public class ModMetadata
|
||||
{
|
||||
Map<JsonStringNode, Object> processedFields = Maps.transformValues(node.getFields(), new JsonStringConverter());
|
||||
modId = (String)processedFields.get(aStringBuilder("modid"));
|
||||
if (Strings.isNullOrEmpty(modId))
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "Found an invalid mod metadata file - missing modid");
|
||||
throw new LoaderException();
|
||||
}
|
||||
name = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("name")));
|
||||
description = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("description")));
|
||||
url = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("url")));
|
||||
@@ -109,10 +112,10 @@ public class ModMetadata
|
||||
version = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("version")));
|
||||
credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
|
||||
parent = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
|
||||
authorList = Optional.fromNullable((List<String>)processedFields.get(aStringBuilder("authorList"))).or(authorList);
|
||||
requiredMods = processReferences((List<String>)processedFields.get(aStringBuilder("requiredMods")));
|
||||
dependencies = processReferences((List<String>)processedFields.get(aStringBuilder("dependencies")));
|
||||
dependants = processReferences((List<String>)processedFields.get(aStringBuilder("dependants")));
|
||||
authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
|
||||
requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), HashSet.class);
|
||||
dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), ArrayList.class);
|
||||
dependants = processReferences(processedFields.get(aStringBuilder("dependants")), ArrayList.class);
|
||||
useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
|
||||
}
|
||||
|
||||
@@ -120,14 +123,23 @@ public class ModMetadata
|
||||
{
|
||||
}
|
||||
|
||||
private List<ArtifactVersion> processReferences(List<String> refs)
|
||||
private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
|
||||
{
|
||||
List<ArtifactVersion> res = Lists.newArrayList();
|
||||
T res = null;
|
||||
try
|
||||
{
|
||||
res = retType.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// unpossible
|
||||
}
|
||||
|
||||
if (refs == null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
for (String ref : refs)
|
||||
for (String ref : ((List<String>)refs))
|
||||
{
|
||||
res.add(VersionParser.parseVersionReference(ref));
|
||||
}
|
||||
@@ -156,6 +168,6 @@ public class ModMetadata
|
||||
|
||||
public String printableSortingRules()
|
||||
{
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,6 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
@@ -29,15 +22,12 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -49,6 +39,7 @@ import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
private static final boolean DEBUG = false;
|
||||
private class Modifier
|
||||
{
|
||||
public String name = "";
|
||||
@@ -58,13 +49,14 @@ public class AccessTransformer implements IClassTransformer
|
||||
public int targetAccess = 0;
|
||||
public boolean changeFinal = false;
|
||||
public boolean markFinal = false;
|
||||
protected boolean modifyClassVisibility;
|
||||
|
||||
private void setTargetAccess(String name)
|
||||
{
|
||||
if (name.startsWith("public")) targetAccess = ACC_PUBLIC;
|
||||
else if (name.startsWith("private")) targetAccess = ACC_PRIVATE;
|
||||
else if (name.startsWith("protected")) targetAccess = ACC_PROTECTED;
|
||||
|
||||
|
||||
if (name.endsWith("-f"))
|
||||
{
|
||||
changeFinal = true;
|
||||
@@ -118,25 +110,32 @@ public class AccessTransformer implements IClassTransformer
|
||||
return true;
|
||||
}
|
||||
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
|
||||
if (parts.size()>2 || parts.get(1).indexOf('.') == -1)
|
||||
if (parts.size()>2)
|
||||
{
|
||||
throw new RuntimeException("Invalid config file line "+ input);
|
||||
}
|
||||
Modifier m = new Modifier();
|
||||
m.setTargetAccess(parts.get(0));
|
||||
List<String> descriptor = Lists.newArrayList(Splitter.on(".").trimResults().split(parts.get(1)));
|
||||
String nameReference = descriptor.get(1);
|
||||
int parenIdx = nameReference.indexOf('(');
|
||||
if (parenIdx>0)
|
||||
if (descriptor.size() == 1)
|
||||
{
|
||||
m.desc = nameReference.substring(parenIdx);
|
||||
m.name = nameReference.substring(0,parenIdx);
|
||||
m.modifyClassVisibility = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.name = nameReference;
|
||||
String nameReference = descriptor.get(1);
|
||||
int parenIdx = nameReference.indexOf('(');
|
||||
if (parenIdx>0)
|
||||
{
|
||||
m.desc = nameReference.substring(parenIdx);
|
||||
m.name = nameReference.substring(0,parenIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.name = nameReference;
|
||||
}
|
||||
}
|
||||
modifiers.put(descriptor.get(0), m);
|
||||
modifiers.put(descriptor.get(0).replace('/', '.'), m);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -155,16 +154,31 @@ public class AccessTransformer implements IClassTransformer
|
||||
Collection<Modifier> mods = modifiers.get(name);
|
||||
for (Modifier m : mods)
|
||||
{
|
||||
if (m.modifyClassVisibility)
|
||||
{
|
||||
classNode.access = getFixedAccess(classNode.access, m);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (m.desc.isEmpty())
|
||||
{
|
||||
for (FieldNode n : (List<FieldNode>) classNode.fields)
|
||||
{
|
||||
if (n.name.equals(m.name))
|
||||
if (n.name.equals(m.name) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
System.out.println(String.format("Field: %s.%s %s -> %s", name, m.name, Integer.toBinaryString(m.oldAccess),
|
||||
Integer.toBinaryString(m.newAccess)));
|
||||
break;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Field: %s.%s %s -> %s", name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
}
|
||||
|
||||
if (!m.name.equals("*"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,11 +186,18 @@ public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
for (MethodNode n : (List<MethodNode>) classNode.methods)
|
||||
{
|
||||
if (n.name.equals(m.name) && n.desc.equals(m.desc))
|
||||
if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, m.name, m.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
break;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
}
|
||||
|
||||
if (!m.name.equals("*"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +236,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
default:
|
||||
throw new RuntimeException("The fuck?");
|
||||
}
|
||||
|
||||
|
||||
// Clear the "final" marker on fields only if specified in control field
|
||||
if (target.changeFinal && target.desc == "")
|
||||
{
|
||||
@@ -237,7 +258,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
if (args.length < 2)
|
||||
{
|
||||
System.out.println("Usage: AccessTransformer <JarPath> <MapFile> [MapFile2]... ");
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
boolean hasTransformer = false;
|
||||
@@ -259,7 +280,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
if (!hasTransformer)
|
||||
{
|
||||
System.out.println("Culd not find a valid transformer to perform");
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File orig = new File(args[0]);
|
||||
@@ -267,13 +288,13 @@ public class AccessTransformer implements IClassTransformer
|
||||
if (!orig.exists() && !temp.exists())
|
||||
{
|
||||
System.out.println("Could not find target jar: " + orig);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!orig.renameTo(temp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + orig + " -> " + temp);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -283,8 +304,9 @@ public class AccessTransformer implements IClassTransformer
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (!temp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + temp);
|
||||
@@ -386,4 +408,11 @@ public class AccessTransformer implements IClassTransformer
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ensurePublicAccessFor(String modClazzName)
|
||||
{
|
||||
Modifier m = new Modifier();
|
||||
m.setTargetAccess("public");
|
||||
m.modifyClassVisibility = true;
|
||||
modifiers.put(modClazzName, m);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,37 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
@@ -25,13 +45,14 @@ public class MCPMerger
|
||||
private static Hashtable<String, ClassInfo> servers = new Hashtable<String, ClassInfo>();
|
||||
private static HashSet<String> copyToServer = new HashSet<String>();
|
||||
private static HashSet<String> copyToClient = new HashSet<String>();
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length != 3)
|
||||
{
|
||||
System.out.println("Usage: AccessTransformer <MapFile> <minecraft.jar> <minecraft_server.jar>");
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File map_file = new File(args[0]);
|
||||
@@ -54,31 +75,31 @@ public class MCPMerger
|
||||
if (!client_jar.exists())
|
||||
{
|
||||
System.out.println("Could not find minecraft.jar: " + client_jar);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!server_jar.exists())
|
||||
{
|
||||
System.out.println("Could not find minecraft_server.jar: " + server_jar);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!client_jar.renameTo(client_jar_tmp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!server_jar.renameTo(server_jar_tmp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!readMapFile(map_file))
|
||||
{
|
||||
System.out.println("Could not read map file: " + map_file);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -88,6 +109,7 @@ public class MCPMerger
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!client_jar_tmp.delete())
|
||||
@@ -157,6 +179,8 @@ public class MCPMerger
|
||||
}
|
||||
Hashtable<String, ZipEntry> cClasses = getClassEntries(cInJar, cOutJar);
|
||||
Hashtable<String, ZipEntry> sClasses = getClassEntries(sInJar, sOutJar);
|
||||
HashSet<String> cAdded = new HashSet<String>();
|
||||
HashSet<String> sAdded = new HashSet<String>();
|
||||
|
||||
for (Entry<String, ZipEntry> entry : cClasses.entrySet())
|
||||
{
|
||||
@@ -168,12 +192,18 @@ public class MCPMerger
|
||||
{
|
||||
if (!copyToServer.contains(name))
|
||||
{
|
||||
copyEntry(cInJar, cEntry, cOutJar);
|
||||
copyClass(cInJar, cEntry, cOutJar, null, true);
|
||||
cAdded.add(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Copy class c->s : " + name);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println("Copy class c->s : " + name);
|
||||
}
|
||||
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
|
||||
cAdded.add(name);
|
||||
sAdded.add(name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -191,28 +221,40 @@ public class MCPMerger
|
||||
cOutJar.write(data);
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
cAdded.add(name);
|
||||
sAdded.add(name);
|
||||
}
|
||||
for (Entry<String, ZipEntry> entry : sClasses.entrySet())
|
||||
{
|
||||
if (!copyToClient.contains(entry.getKey()))
|
||||
{
|
||||
copyEntry(sInJar, entry.getValue(), sOutJar);
|
||||
copyClass(sInJar, entry.getValue(), null, sOutJar, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Copy class s->c : " + entry.getKey());
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println("Copy class s->c : " + entry.getKey());
|
||||
}
|
||||
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : new String[]{SideOnly.class.getName(), Side.class.getName()})
|
||||
{
|
||||
String eName = name.replace(".", "/");
|
||||
byte[] data = getClassBytes(name);
|
||||
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
|
||||
cOutJar.putNextEntry(newEntry);
|
||||
cOutJar.write(data);
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
if (!cAdded.contains(eName))
|
||||
{
|
||||
cOutJar.putNextEntry(newEntry);
|
||||
cOutJar.write(data);
|
||||
}
|
||||
if (!sAdded.contains(eName))
|
||||
{
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -245,18 +287,28 @@ public class MCPMerger
|
||||
ClassNode classNode = new ClassNode();
|
||||
|
||||
reader.accept(classNode, 0);
|
||||
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
|
||||
|
||||
if (!classNode.name.equals("ayn")) //Special case CodecMus so I dont have to make a new patch, anyone who uses this in production code is.. bad.
|
||||
{
|
||||
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
byte[] data = writer.toByteArray();
|
||||
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(data);
|
||||
outJar2.putNextEntry(newEntry);
|
||||
outJar2.write(data);
|
||||
if (outJar != null)
|
||||
{
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(data);
|
||||
}
|
||||
if (outJar2 != null)
|
||||
{
|
||||
outJar2.putNextEntry(newEntry);
|
||||
outJar2.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
private static AnnotationNode getSideAnn(boolean isClientOnly)
|
||||
@@ -282,7 +334,9 @@ public class MCPMerger
|
||||
String entryName = entry.getName();
|
||||
if (!entryName.endsWith(".class") || entryName.startsWith("."))
|
||||
{
|
||||
copyEntry(inFile, entry, outFile);
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outFile.putNextEntry(newEntry);
|
||||
outFile.write(readEntry(inFile, entry));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -291,12 +345,6 @@ public class MCPMerger
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private static void copyEntry(ZipFile inFile, ZipEntry entry, ZipOutputStream outFile) throws IOException
|
||||
{
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outFile.putNextEntry(newEntry);
|
||||
outFile.write(readEntry(inFile, entry));
|
||||
}
|
||||
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
|
||||
{
|
||||
return readFully(inFile.getInputStream(entry));
|
||||
@@ -444,7 +492,10 @@ public class MCPMerger
|
||||
mw.server = this.server | mw.server;
|
||||
this.client = this.client | mw.client;
|
||||
this.server = this.server | mw.server;
|
||||
System.out.printf(" eq: %s %s\n", this, mw);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf(" eq: %s %s\n", this, mw);
|
||||
}
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
@@ -486,13 +537,19 @@ public class MCPMerger
|
||||
serverName = sM.name;
|
||||
if (!serverName.equals(lastName) && cPos != cLen)
|
||||
{
|
||||
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
MethodWrapper mw = new MethodWrapper(sM);
|
||||
mw.server = true;
|
||||
allMethods.add(mw);
|
||||
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
sPos++;
|
||||
}
|
||||
while (sPos < sLen);
|
||||
@@ -507,13 +564,19 @@ public class MCPMerger
|
||||
clientName = cM.name;
|
||||
if (!clientName.equals(lastName) && sPos != sLen)
|
||||
{
|
||||
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
MethodWrapper mw = new MethodWrapper(cM);
|
||||
mw.client = true;
|
||||
allMethods.add(mw);
|
||||
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
cPos++;
|
||||
}
|
||||
while (cPos < cLen);
|
||||
@@ -524,7 +587,10 @@ public class MCPMerger
|
||||
|
||||
for (MethodWrapper mw : allMethods)
|
||||
{
|
||||
System.out.println(mw);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(mw);
|
||||
}
|
||||
cMethods.add(mw.node);
|
||||
sMethods.add(mw.node);
|
||||
if (mw.server && mw.client)
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
@@ -29,20 +16,14 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.LineProcessor;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
@@ -19,6 +18,7 @@ import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
public class SideTransformer implements IClassTransformer
|
||||
{
|
||||
private static String SIDE = FMLRelauncher.side();
|
||||
private static final boolean DEBUG = false;
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
@@ -27,13 +27,25 @@ public class SideTransformer implements IClassTransformer
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
if (remove((List<AnnotationNode>)classNode.visibleAnnotations, SIDE))
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Iterator<FieldNode> fields = classNode.fields.iterator();
|
||||
while(fields.hasNext())
|
||||
{
|
||||
FieldNode field = fields.next();
|
||||
if (remove((List<AnnotationNode>)field.visibleAnnotations, SIDE))
|
||||
{
|
||||
System.out.println("Removing Field: " + field.name);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
|
||||
}
|
||||
fields.remove();
|
||||
}
|
||||
}
|
||||
@@ -43,7 +55,10 @@ public class SideTransformer implements IClassTransformer
|
||||
MethodNode method = methods.next();
|
||||
if (remove((List<AnnotationNode>)method.visibleAnnotations, SIDE))
|
||||
{
|
||||
System.out.println("Removing Method: " + method.name + " " + method.desc);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
|
||||
}
|
||||
methods.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -10,12 +8,10 @@ import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
|
||||
@@ -3,17 +3,16 @@ package cpw.mods.fml.common.discovery;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModContainerFactory;
|
||||
@@ -54,12 +53,14 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
|
||||
try
|
||||
{
|
||||
FileInputStream fis = new FileInputStream(metadata);
|
||||
mc = MetadataCollection.from(fis);
|
||||
mc = MetadataCollection.from(fis,modDir.getName());
|
||||
fis.close();
|
||||
FMLLog.fine("Found an mcmod.info file in directory %s", modDir.getName());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
mc = MetadataCollection.from(null);
|
||||
mc = MetadataCollection.from(null,"");
|
||||
FMLLog.fine("No mcmod.info file found in directory %s", modDir.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +87,11 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
|
||||
modParser = new ASMModParser(fis);
|
||||
fis.close();
|
||||
}
|
||||
catch (LoaderException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "There was a problem reading the file %s - probably this is a corrupt file", file.getPath());
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagate(e);
|
||||
@@ -93,7 +99,7 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
|
||||
|
||||
modParser.validate();
|
||||
modParser.sendToTable(table, candidate);
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
|
||||
if (container!=null)
|
||||
{
|
||||
harvestedMods.add(container);
|
||||
|
||||
@@ -2,7 +2,7 @@ package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
@@ -10,6 +10,7 @@ import java.util.zip.ZipFile;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModContainerFactory;
|
||||
@@ -32,17 +33,32 @@ public class JarDiscoverer implements ITypeDiscoverer
|
||||
if (modInfo != null)
|
||||
{
|
||||
FMLLog.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName());
|
||||
mc = MetadataCollection.from(jar.getInputStream(modInfo));
|
||||
mc = MetadataCollection.from(jar.getInputStream(modInfo), candidate.getModContainer().getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("The mod container %s appears to be missing an mcmod.info file", candidate.getModContainer().getName());
|
||||
mc = MetadataCollection.from(null, "");
|
||||
}
|
||||
for (ZipEntry ze : Collections.list(jar.entries()))
|
||||
{
|
||||
Matcher match = classFile.matcher(ze.getName());
|
||||
if (match.matches())
|
||||
{
|
||||
ASMModParser modParser = new ASMModParser(jar.getInputStream(ze));
|
||||
ASMModParser modParser;
|
||||
try
|
||||
{
|
||||
modParser = new ASMModParser(jar.getInputStream(ze));
|
||||
}
|
||||
catch (LoaderException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "There was a problem reading the entry %s in the jar %s - probably a corrupt zip", ze.getName(), candidate.getModContainer().getPath());
|
||||
jar.close();
|
||||
throw e;
|
||||
}
|
||||
modParser.validate();
|
||||
modParser.sendToTable(table, candidate);
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
|
||||
if (container!=null)
|
||||
{
|
||||
table.addContainer(container);
|
||||
@@ -54,7 +70,7 @@ public class JarDiscoverer implements ITypeDiscoverer
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.warning("Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
|
||||
FMLLog.log(Level.WARNING, e, "Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -3,7 +3,11 @@ package cpw.mods.fml.common.discovery;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.asm.ASMModParser;
|
||||
|
||||
|
||||
public class ModCandidate
|
||||
@@ -12,16 +16,20 @@ public class ModCandidate
|
||||
private File modContainer;
|
||||
private ContainerType sourceType;
|
||||
private boolean classpath;
|
||||
private List<String> baseModTypes = Lists.newArrayList();
|
||||
private boolean isMinecraft;
|
||||
private List<ASMModParser> baseModCandidateTypes = Lists.newArrayListWithCapacity(1);
|
||||
|
||||
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType)
|
||||
{
|
||||
this(classPathRoot, modContainer, sourceType, false);
|
||||
this(classPathRoot, modContainer, sourceType, false, false);
|
||||
}
|
||||
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean classpath)
|
||||
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean isMinecraft, boolean classpath)
|
||||
{
|
||||
this.classPathRoot = classPathRoot;
|
||||
this.modContainer = modContainer;
|
||||
this.sourceType = sourceType;
|
||||
this.isMinecraft = isMinecraft;
|
||||
this.classpath = classpath;
|
||||
}
|
||||
|
||||
@@ -41,6 +49,36 @@ public class ModCandidate
|
||||
}
|
||||
public List<ModContainer> explore(ASMDataTable table)
|
||||
{
|
||||
return sourceType.findMods(this, table);
|
||||
List<ModContainer> mods = sourceType.findMods(this, table);
|
||||
if (!baseModCandidateTypes.isEmpty())
|
||||
{
|
||||
FMLLog.info("Attempting to reparse the mod container %s", getModContainer().getName());
|
||||
return sourceType.findMods(this, table);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mods;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isClasspath()
|
||||
{
|
||||
return classpath;
|
||||
}
|
||||
public void rememberBaseModType(String className)
|
||||
{
|
||||
baseModTypes.add(className);
|
||||
}
|
||||
public List<String> getRememberedBaseMods()
|
||||
{
|
||||
return baseModTypes;
|
||||
}
|
||||
public boolean isMinecraftJar()
|
||||
{
|
||||
return isMinecraft;
|
||||
}
|
||||
public void rememberModCandidateType(ASMModParser modParser)
|
||||
{
|
||||
baseModCandidateTypes.add(modParser);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,15 @@
|
||||
package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.common.collect.Tables;
|
||||
import com.google.common.collect.ImmutableTable.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.Table.Cell;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
@@ -54,6 +25,8 @@ public class ModDiscoverer
|
||||
|
||||
private ASMDataTable dataTable = new ASMDataTable();
|
||||
|
||||
private List<File> nonModLibs = Lists.newArrayList();
|
||||
|
||||
public void findClasspathMods(ModClassLoader modClassLoader)
|
||||
{
|
||||
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries()).addAll(RelaunchLibraryManager.getLibraries()).build();
|
||||
@@ -61,7 +34,7 @@ public class ModDiscoverer
|
||||
if (minecraftSources.length == 1 && minecraftSources[0].isFile())
|
||||
{
|
||||
FMLLog.fine("Minecraft is a file at %s, loading", minecraftSources[0].getAbsolutePath());
|
||||
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR));
|
||||
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR, true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -76,13 +49,13 @@ public class ModDiscoverer
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, true));
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, i==0, true));
|
||||
}
|
||||
}
|
||||
else if (minecraftSources[i].isDirectory())
|
||||
{
|
||||
FMLLog.fine("Found a minecraft related directory at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, true));
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, i==0, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +101,14 @@ public class ModDiscoverer
|
||||
try
|
||||
{
|
||||
List<ModContainer> mods = candidate.explore(dataTable);
|
||||
modList.addAll(mods);
|
||||
if (mods.isEmpty() && !candidate.isClasspath())
|
||||
{
|
||||
nonModLibs.add(candidate.getModContainer());
|
||||
}
|
||||
else
|
||||
{
|
||||
modList.addAll(mods);
|
||||
}
|
||||
}
|
||||
catch (LoaderException le)
|
||||
{
|
||||
@@ -148,4 +128,9 @@ public class ModDiscoverer
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
public List<File> getNonModLibs()
|
||||
{
|
||||
return nonModLibs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package cpw.mods.fml.common.discovery.asm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.BaseMod;
|
||||
|
||||
@@ -13,10 +15,10 @@ import org.objectweb.asm.Type;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ModCandidate;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
|
||||
public class ASMModParser
|
||||
{
|
||||
@@ -34,8 +36,16 @@ public class ASMModParser
|
||||
|
||||
public ASMModParser(InputStream stream) throws IOException
|
||||
{
|
||||
ClassReader reader = new ClassReader(stream);
|
||||
reader.accept(new ModClassVisitor(this), 0);
|
||||
try
|
||||
{
|
||||
ClassReader reader = new ClassReader(stream);
|
||||
reader.accept(new ModClassVisitor(this), 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, ex, "Unable to read a class file correctly");
|
||||
throw new LoaderException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void beginNewTypeName(String typeQName, int classVersion, String superClassQName)
|
||||
@@ -70,7 +80,7 @@ public class ASMModParser
|
||||
.add("classVersion", classVersion)
|
||||
.add("superName", asmSuperType.getClassName())
|
||||
.add("annotations", annotations)
|
||||
.add("isBaseMod", isBaseMod())
|
||||
.add("isBaseMod", isBaseMod(Collections.<String>emptyList()))
|
||||
.add("baseModProperties", baseModProperties)
|
||||
.toString();
|
||||
}
|
||||
@@ -104,9 +114,9 @@ public class ASMModParser
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean isBaseMod()
|
||||
public boolean isBaseMod(List<String> rememberedTypes)
|
||||
{
|
||||
return getASMSuperType().equals(Type.getType(BaseMod.class));
|
||||
return getASMSuperType().equals(Type.getType(BaseMod.class)) || rememberedTypes.contains(getASMSuperType().getClassName());
|
||||
}
|
||||
|
||||
public void setBaseModProperties(String foundProperties)
|
||||
@@ -135,13 +145,13 @@ public class ASMModParser
|
||||
public void addAnnotationEnumProperty(String name, String desc, String value)
|
||||
{
|
||||
annotations.getFirst().addEnumProperty(name, desc, value);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void endArray()
|
||||
{
|
||||
annotations.getFirst().endArray();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addSubAnnotation(String name, String desc)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package cpw.mods.fml.common.discovery.asm;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
@@ -16,32 +18,32 @@ public class ModClassVisitor extends ClassVisitor
|
||||
super(Opcodes.ASM4);
|
||||
this.discoverer = discoverer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
discoverer.beginNewTypeName(name, version, superName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
||||
{
|
||||
discoverer.startClassAnnotation(annotationName);
|
||||
return new ModAnnotationVisitor(discoverer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
|
||||
{
|
||||
return new ModFieldVisitor(name, discoverer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
if (discoverer.isBaseMod() && name.equals("getPriorities") && desc.equals(Type.getMethodDescriptor(Type.getType(String.class))))
|
||||
if (discoverer.isBaseMod(Collections.<String>emptyList()) && name.equals("getPriorities") && desc.equals(Type.getMethodDescriptor(Type.getType(String.class))))
|
||||
{
|
||||
return new ModMethodVisitor(name, discoverer);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.LinkedList;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Table;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModClassLoader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
|
||||
public class FMLConstructionEvent extends FMLStateEvent
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLLoadCompleteEvent extends FMLStateEvent
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLPostInitializationEvent extends FMLStateEvent
|
||||
@@ -15,4 +18,21 @@ public class FMLPostInitializationEvent extends FMLStateEvent
|
||||
return ModState.POSTINITIALIZED;
|
||||
}
|
||||
|
||||
public Object buildSoftDependProxy(String modId, String className)
|
||||
{
|
||||
if (Loader.isModLoaded(modId))
|
||||
{
|
||||
try
|
||||
{
|
||||
Class<?> clz = Class.forName(className,true,Loader.instance().getModClassLoader());
|
||||
return clz.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,10 @@ package cpw.mods.fml.common.event;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
|
||||
public class FMLPreInitializationEvent extends FMLStateEvent
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLServerStartedEvent extends FMLStateEvent
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.CommandHandler;
|
||||
import net.minecraft.src.ICommand;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLServerStartingEvent extends FMLStateEvent
|
||||
{
|
||||
|
||||
private Object server;
|
||||
|
||||
private MinecraftServer server;
|
||||
|
||||
public FMLServerStartingEvent(Object... data)
|
||||
{
|
||||
super(data);
|
||||
this.server = data[0];
|
||||
this.server = (MinecraftServer) data[0];
|
||||
}
|
||||
@Override
|
||||
public ModState getModState()
|
||||
@@ -19,4 +21,14 @@ public class FMLServerStartingEvent extends FMLStateEvent
|
||||
return ModState.AVAILABLE;
|
||||
}
|
||||
|
||||
public MinecraftServer getServer()
|
||||
{
|
||||
return server;
|
||||
}
|
||||
|
||||
public void registerServerCommand(ICommand command)
|
||||
{
|
||||
CommandHandler ch = (CommandHandler) getServer().func_71187_D();
|
||||
ch.func_71560_a(command);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLServerStoppingEvent extends FMLStateEvent
|
||||
|
||||
@@ -16,14 +16,20 @@ package cpw.mods.fml.common.modloader;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.WorldClient;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -71,13 +77,20 @@ public interface BaseModProxy
|
||||
|
||||
public abstract void onClientLogin(EntityPlayer player);
|
||||
|
||||
public abstract void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload);
|
||||
|
||||
public abstract void serverDisconnect();
|
||||
|
||||
public abstract void serverConnect(NetHandler handler);
|
||||
|
||||
public abstract void receiveCustomPacket(Packet250CustomPayload packet);
|
||||
|
||||
public abstract void receiveChatPacket(String text);
|
||||
public abstract void clientChat(String text);
|
||||
|
||||
public abstract void onItemPickup(EntityPlayer player, ItemStack item);
|
||||
|
||||
public abstract int dispenseEntity(World world, ItemStack item, Random rnd, int x, int y, int z, int xVel, int zVel, double entX,
|
||||
double entY, double entZ);
|
||||
|
||||
public abstract void serverCustomPayload(NetServerHandler handler, Packet250CustomPayload packet);
|
||||
|
||||
public abstract void serverChat(NetServerHandler source, String message);
|
||||
}
|
||||
@@ -1,8 +1,20 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
|
||||
public interface IModLoaderSidedHelper
|
||||
{
|
||||
|
||||
void finishModLoading(ModLoaderModContainer mc);
|
||||
|
||||
Object getClientGui(BaseModProxy mod, EntityPlayer player, int iD, int x, int y, int z);
|
||||
|
||||
Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration registration);
|
||||
|
||||
void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.Packet3Chat;
|
||||
import cpw.mods.fml.common.network.IChatListener;
|
||||
|
||||
public class ModLoaderChatListener implements IChatListener
|
||||
{
|
||||
|
||||
private BaseModProxy mod;
|
||||
|
||||
public ModLoaderChatListener(BaseModProxy mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet3Chat serverChat(NetHandler handler, Packet3Chat message)
|
||||
{
|
||||
mod.serverChat((NetServerHandler)handler, message.field_73476_b);
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet3Chat clientChat(NetHandler handler, Packet3Chat message)
|
||||
{
|
||||
mod.clientChat(message.field_73476_b);
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.World;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.IDispenserHandler;
|
||||
|
||||
public class ModLoaderDispenseHelper implements IDispenserHandler
|
||||
{
|
||||
|
||||
private BaseModProxy mod;
|
||||
|
||||
public ModLoaderDispenseHelper(BaseModProxy mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int dispense(int x, int y, int z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY,
|
||||
double entZ)
|
||||
{
|
||||
int ret = mod.dispenseEntity(world, item, random, x, y, z, xVelocity, zVelocity, entX, entY, entZ);
|
||||
return ret == 0 ? -1 : ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
|
||||
import net.minecraft.src.Entity;
|
||||
|
||||
public class ModLoaderEntitySpawnCallback implements Function<EntitySpawnPacket, Entity>
|
||||
{
|
||||
|
||||
private BaseModProxy mod;
|
||||
private EntityRegistration registration;
|
||||
private boolean isAnimal;
|
||||
|
||||
public ModLoaderEntitySpawnCallback(BaseModProxy mod, EntityRegistration er)
|
||||
{
|
||||
this.mod = mod;
|
||||
this.registration = er;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity apply(EntitySpawnPacket input)
|
||||
{
|
||||
return ModLoaderHelper.sidedHelper.spawnEntity(mod, input, registration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import net.minecraft.src.Container;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.World;
|
||||
import cpw.mods.fml.common.network.IGuiHandler;
|
||||
|
||||
public class ModLoaderGuiHelper implements IGuiHandler
|
||||
{
|
||||
|
||||
private BaseModProxy mod;
|
||||
private int id;
|
||||
private Container container;
|
||||
|
||||
ModLoaderGuiHelper(BaseModProxy mod, int id)
|
||||
{
|
||||
this.mod = mod;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
|
||||
{
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
|
||||
{
|
||||
return ModLoaderHelper.getClientSideGui(mod, player, ID, x, y, z);
|
||||
}
|
||||
|
||||
public void injectContainer(Container container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public Object getMod()
|
||||
{
|
||||
return mod;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,32 +17,53 @@ package cpw.mods.fml.common.modloader;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.src.BaseMod;
|
||||
|
||||
import net.minecraft.src.Container;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityDragon;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.IAnimals;
|
||||
import net.minecraft.src.ICommand;
|
||||
import net.minecraft.src.TradeEntry;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.ICraftingHandler;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.IDispenserHandler;
|
||||
import cpw.mods.fml.common.IFuelHandler;
|
||||
import cpw.mods.fml.common.IPickupNotifier;
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.network.IChatListener;
|
||||
import cpw.mods.fml.common.network.IConnectionHandler;
|
||||
import cpw.mods.fml.common.network.IGuiHandler;
|
||||
import cpw.mods.fml.common.network.IPacketHandler;
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler;
|
||||
import cpw.mods.fml.common.registry.VillagerRegistry;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ModLoaderHelper
|
||||
{
|
||||
private static Map<BaseMod, ModLoaderModContainer> notModCallbacks=new HashMap<BaseMod, ModLoaderModContainer>();
|
||||
|
||||
public static IModLoaderSidedHelper sidedHelper;
|
||||
public static void updateStandardTicks(BaseMod mod, boolean enable, boolean useClock)
|
||||
|
||||
private static Map<Integer, ModLoaderGuiHelper> guiHelpers = Maps.newHashMap();
|
||||
|
||||
public static void updateStandardTicks(BaseModProxy mod, boolean enable, boolean useClock)
|
||||
{
|
||||
ModLoaderModContainer mlmc = findOrBuildModContainer(mod);
|
||||
ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
|
||||
BaseModTicker ticker = mlmc.getGameTickHandler();
|
||||
EnumSet<TickType> ticks = ticker.ticks();
|
||||
// If we're enabled we get render ticks
|
||||
@@ -61,9 +82,9 @@ public class ModLoaderHelper
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateGUITicks(BaseMod mod, boolean enable, boolean useClock)
|
||||
public static void updateGUITicks(BaseModProxy mod, boolean enable, boolean useClock)
|
||||
{
|
||||
ModLoaderModContainer mlmc = findOrBuildModContainer(mod);
|
||||
ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
|
||||
EnumSet<TickType> ticks = mlmc.getGUITickHandler().ticks();
|
||||
// If we're enabled and we don't want clock ticks we get render ticks
|
||||
if (enable && !useClock) {
|
||||
@@ -81,34 +102,7 @@ public class ModLoaderHelper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
private static ModLoaderModContainer findOrBuildModContainer(BaseMod mod)
|
||||
{
|
||||
ModLoaderModContainer mlmc=(ModLoaderModContainer) FMLCommonHandler.instance().findContainerFor(mod);
|
||||
if (mlmc==null) {
|
||||
mlmc=notModCallbacks.get(mod);
|
||||
if (mlmc==null) {
|
||||
mlmc=new ModLoaderModContainer(mod);
|
||||
notModCallbacks.put(mod, mlmc);
|
||||
}
|
||||
}
|
||||
return mlmc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
public static ModLoaderModContainer registerKeyHelper(BaseMod mod)
|
||||
{
|
||||
ModLoaderModContainer mlmc=findOrBuildModContainer(mod);
|
||||
return mlmc;
|
||||
}
|
||||
|
||||
public static IPacketHandler buildPacketHandlerFor(BaseMod mod)
|
||||
public static IPacketHandler buildPacketHandlerFor(BaseModProxy mod)
|
||||
{
|
||||
return new ModLoaderPacketHandler(mod);
|
||||
}
|
||||
@@ -140,4 +134,73 @@ public class ModLoaderHelper
|
||||
{
|
||||
return new ModLoaderConnectionHandler(mod);
|
||||
}
|
||||
|
||||
public static IPickupNotifier buildPickupHelper(BaseModProxy mod)
|
||||
{
|
||||
return new ModLoaderPickupNotifier(mod);
|
||||
}
|
||||
|
||||
public static void buildGuiHelper(BaseModProxy mod, int id)
|
||||
{
|
||||
ModLoaderGuiHelper handler = new ModLoaderGuiHelper(mod, id);
|
||||
guiHelpers.put(id, handler);
|
||||
NetworkRegistry.instance().registerGuiHandler(mod, handler);
|
||||
}
|
||||
|
||||
public static void openGui(int id, EntityPlayer player, Container container, int x, int y, int z)
|
||||
{
|
||||
ModLoaderGuiHelper helper = guiHelpers.get(id);
|
||||
helper.injectContainer(container);
|
||||
player.openGui(helper.getMod(), id, player.field_70170_p, x, y, z);
|
||||
}
|
||||
|
||||
public static Object getClientSideGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
|
||||
{
|
||||
if (sidedHelper != null)
|
||||
{
|
||||
return sidedHelper.getClientGui(mod, player, ID, x, y, z);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IDispenserHandler buildDispenseHelper(BaseModProxy mod)
|
||||
{
|
||||
return new ModLoaderDispenseHelper(mod);
|
||||
}
|
||||
|
||||
|
||||
public static void buildEntityTracker(BaseModProxy mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval,
|
||||
boolean sendVelocityInfo)
|
||||
{
|
||||
EntityRegistration er = EntityRegistry.registerModLoaderEntity(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
|
||||
er.setCustomSpawning(new ModLoaderEntitySpawnCallback(mod, er), EntityDragon.class.isAssignableFrom(entityClass) || IAnimals.class.isAssignableFrom(entityClass));
|
||||
}
|
||||
|
||||
private static ModLoaderVillageTradeHandler[] tradeHelpers = new ModLoaderVillageTradeHandler[6];
|
||||
|
||||
public static void registerTrade(int profession, TradeEntry entry)
|
||||
{
|
||||
assert profession < tradeHelpers.length : "The profession is out of bounds";
|
||||
if (tradeHelpers[profession] == null)
|
||||
{
|
||||
tradeHelpers[profession] = new ModLoaderVillageTradeHandler();
|
||||
VillagerRegistry.instance().registerVillageTradeHandler(profession, tradeHelpers[profession]);
|
||||
}
|
||||
|
||||
tradeHelpers[profession].addTrade(entry);
|
||||
}
|
||||
|
||||
public static void addCommand(ICommand command)
|
||||
{
|
||||
ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
|
||||
if (mlmc!=null)
|
||||
{
|
||||
mlmc.addServerCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
public static IChatListener buildChatListener(BaseModProxy mod)
|
||||
{
|
||||
return new ModLoaderChatListener(mod);
|
||||
}
|
||||
}
|
||||
@@ -17,22 +17,20 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.AbstractCollection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.MLProp;
|
||||
import net.minecraft.src.ICommand;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -42,46 +40,37 @@ import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.IConsoleHandler;
|
||||
import cpw.mods.fml.common.ICraftingHandler;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.IFMLSidedHandler;
|
||||
import cpw.mods.fml.common.INetworkHandler;
|
||||
import cpw.mods.fml.common.IPickupNotifier;
|
||||
import cpw.mods.fml.common.IPlayerTracker;
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.LoadController;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.ModClassLoader;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.ModClassLoader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.ProxyInjector;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||
import cpw.mods.fml.common.network.NetworkMod;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.ProxyInjector;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
|
||||
public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
public BaseModProxy mod;
|
||||
private File modSource;
|
||||
public List<ArtifactVersion> requirements = Lists.newArrayList();
|
||||
public Set<ArtifactVersion> requirements = Sets.newHashSet();
|
||||
public ArrayList<ArtifactVersion> dependencies = Lists.newArrayList();
|
||||
public ArrayList<ArtifactVersion> dependants = Lists.newArrayList();
|
||||
private ContainerType sourceType;
|
||||
@@ -97,13 +86,14 @@ public class ModLoaderModContainer implements ModContainer
|
||||
private String sortingProperties;
|
||||
private ArtifactVersion processedVersion;
|
||||
private boolean isNetworkMod;
|
||||
private List<ICommand> serverCommands = Lists.newArrayList();
|
||||
|
||||
public ModLoaderModContainer(String className, File modSource, String sortingProperties)
|
||||
{
|
||||
this.modClazzName = className;
|
||||
this.modSource = modSource;
|
||||
this.modId = className.contains(".") ? className.substring(className.lastIndexOf('.')+1) : className;
|
||||
this.sortingProperties = sortingProperties;
|
||||
this.sortingProperties = Strings.isNullOrEmpty(sortingProperties) ? "" : sortingProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,7 +112,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
private void configureMod(Class<? extends BaseModProxy> modClazz, ASMDataTable asmData)
|
||||
{
|
||||
File configDir = Loader.instance().getConfigDir();
|
||||
File modConfig = new File(configDir, String.format("%s.cfg", modClazzName));
|
||||
File modConfig = new File(configDir, String.format("%s.cfg", getModId()));
|
||||
Properties props = new Properties();
|
||||
|
||||
boolean existingConfigFound = false;
|
||||
@@ -132,7 +122,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
try
|
||||
{
|
||||
FMLLog.fine("Reading existing configuration file for %s : %s", modClazzName, modConfig.getName());
|
||||
FMLLog.fine("Reading existing configuration file for %s : %s", getModId(), modConfig.getName());
|
||||
FileReader configReader = new FileReader(modConfig);
|
||||
props.load(configReader);
|
||||
configReader.close();
|
||||
@@ -159,6 +149,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
try
|
||||
{
|
||||
mlPropFields.add(new ModProperty(modClazz.getDeclaredField(dat.getObjectName()), dat.getAnnotationInfo()));
|
||||
FMLLog.finest("Found an MLProp field %s in %s", dat.getObjectName(), getModId());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -173,8 +164,9 @@ public class ModLoaderModContainer implements ModContainer
|
||||
FMLLog.info("The MLProp field %s in mod %s appears not to be static", property.field().getName(), getModId());
|
||||
continue;
|
||||
}
|
||||
FMLLog.finest("Considering MLProp field %s", property.field().getName());
|
||||
Field f = property.field();
|
||||
String propertyName = property.name().length() > 0 ? property.name() : f.getName();
|
||||
String propertyName = !Strings.nullToEmpty(property.name()).isEmpty() ? property.name() : f.getName();
|
||||
String propertyValue = null;
|
||||
Object defaultValue = null;
|
||||
|
||||
@@ -182,7 +174,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
defaultValue = f.get(null);
|
||||
propertyValue = props.getProperty(propertyName, extractValue(defaultValue));
|
||||
Object currentValue = parseValue(propertyValue, property, f.getType(), propertyName, modClazzName);
|
||||
Object currentValue = parseValue(propertyValue, property, f.getType(), propertyName);
|
||||
FMLLog.finest("Configuration for %s.%s found values default: %s, configured: %s, interpreted: %s", modClazzName, propertyName, defaultValue, propertyValue, currentValue);
|
||||
|
||||
if (currentValue != null && !currentValue.equals(defaultValue))
|
||||
@@ -212,7 +204,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
|
||||
comments.append(")");
|
||||
|
||||
if (property.info().length() > 0)
|
||||
if (!Strings.nullToEmpty(property.info()).isEmpty())
|
||||
{
|
||||
comments.append(" -- ").append(property.info());
|
||||
}
|
||||
@@ -230,22 +222,22 @@ public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
if (!mlPropFound && !existingConfigFound)
|
||||
{
|
||||
FMLLog.fine("No MLProp configuration for %s found or required. No file written", modClazzName);
|
||||
FMLLog.fine("No MLProp configuration for %s found or required. No file written", getModId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mlPropFound && existingConfigFound)
|
||||
{
|
||||
File mlPropBackup = new File(modConfig.getParent(),modConfig.getName()+".bak");
|
||||
FMLLog.fine("MLProp configuration file for %s found but not required. Attempting to rename file to %s", modClazzName, mlPropBackup.getName());
|
||||
FMLLog.fine("MLProp configuration file for %s found but not required. Attempting to rename file to %s", getModId(), mlPropBackup.getName());
|
||||
boolean renamed = modConfig.renameTo(mlPropBackup);
|
||||
if (renamed)
|
||||
{
|
||||
FMLLog.fine("Unused MLProp configuration file for %s renamed successfully to %s", modClazzName, mlPropBackup.getName());
|
||||
FMLLog.fine("Unused MLProp configuration file for %s renamed successfully to %s", getModId(), mlPropBackup.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Unused MLProp configuration file for %s renamed UNSUCCESSFULLY to %s", modClazzName, mlPropBackup.getName());
|
||||
FMLLog.fine("Unused MLProp configuration file for %s renamed UNSUCCESSFULLY to %s", getModId(), mlPropBackup.getName());
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -255,7 +247,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
FileWriter configWriter = new FileWriter(modConfig);
|
||||
props.store(configWriter, comments.toString());
|
||||
configWriter.close();
|
||||
FMLLog.fine("Configuration for %s written to %s", modClazzName, modConfig.getName());
|
||||
FMLLog.fine("Configuration for %s written to %s", getModId(), modConfig.getName());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -265,7 +257,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
}
|
||||
}
|
||||
|
||||
private Object parseValue(String val, ModProperty property, Class<?> type, String propertyName, String modConfigName)
|
||||
private Object parseValue(String val, ModProperty property, Class<?> type, String propertyName)
|
||||
{
|
||||
if (type.isAssignableFrom(String.class))
|
||||
{
|
||||
@@ -308,9 +300,10 @@ public class ModLoaderModContainer implements ModContainer
|
||||
throw new IllegalArgumentException(String.format("MLProp declared on %s of type %s, an unsupported type",propertyName, type.getName()));
|
||||
}
|
||||
|
||||
if (n.doubleValue() < property.min() || n.doubleValue() > property.max())
|
||||
double dVal = n.doubleValue();
|
||||
if ((property.min()!=Double.MIN_VALUE && dVal < property.min()) || (property.max()!=Double.MAX_VALUE && dVal > property.max()))
|
||||
{
|
||||
FMLLog.warning("Configuration for %s.%s found value %s outside acceptable range %s,%s", modConfigName,propertyName, n, property.min(), property.max());
|
||||
FMLLog.warning("Configuration for %s.%s found value %s outside acceptable range %s,%s", modClazzName,propertyName, n, property.min(), property.max());
|
||||
return null;
|
||||
}
|
||||
else
|
||||
@@ -394,7 +387,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return requirements;
|
||||
}
|
||||
@@ -457,7 +450,7 @@ public class ModLoaderModContainer implements ModContainer
|
||||
@Override
|
||||
public void bindMetadata(MetadataCollection mc)
|
||||
{
|
||||
Map<String, Object> dummyMetadata = ImmutableMap.<String,Object>builder().put("name", modId).put("version", "").build();
|
||||
Map<String, Object> dummyMetadata = ImmutableMap.<String,Object>builder().put("name", modId).put("version", "1.0").build();
|
||||
this.metadata = mc.getMetadataForId(modId, dummyMetadata);
|
||||
Loader.instance().computeDependencies(sortingProperties, getRequirements(), getDependencies(), getDependants());
|
||||
}
|
||||
@@ -494,10 +487,26 @@ public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
ModClassLoader modClassLoader = event.getModClassLoader();
|
||||
modClassLoader.addFile(modSource);
|
||||
Class<? extends BaseModProxy> modClazz = (Class<? extends BaseModProxy>) Class.forName(modClazzName, true, modClassLoader);
|
||||
EnumSet<TickType> ticks = EnumSet.noneOf(TickType.class);
|
||||
this.gameTickHandler = new BaseModTicker(ticks, false);
|
||||
this.guiTickHandler = new BaseModTicker(ticks.clone(), true);
|
||||
Class<? extends BaseModProxy> modClazz = (Class<? extends BaseModProxy>) modClassLoader.loadBaseModClass(modClazzName);
|
||||
configureMod(modClazz, event.getASMHarvestedData());
|
||||
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, modClazz, event.getASMHarvestedData());
|
||||
mod = (BaseModProxy)modClazz.newInstance();
|
||||
ModLoaderNetworkHandler dummyHandler = null;
|
||||
if (!isNetworkMod)
|
||||
{
|
||||
FMLLog.fine("Injecting dummy network mod handler for BaseMod %s", getModId());
|
||||
dummyHandler = new ModLoaderNetworkHandler(this);
|
||||
FMLNetworkHandler.instance().registerNetworkMod(dummyHandler);
|
||||
}
|
||||
Constructor<? extends BaseModProxy> ctor = modClazz.getConstructor();
|
||||
ctor.setAccessible(true);
|
||||
mod = modClazz.newInstance();
|
||||
if (dummyHandler != null)
|
||||
{
|
||||
dummyHandler.setBaseMod(mod);
|
||||
}
|
||||
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -512,9 +521,6 @@ public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
try
|
||||
{
|
||||
EnumSet<TickType> ticks = EnumSet.noneOf(TickType.class);
|
||||
this.gameTickHandler = new BaseModTicker(ticks, false);
|
||||
this.guiTickHandler = new BaseModTicker(ticks.clone(), true);
|
||||
this.gameTickHandler.setMod(mod);
|
||||
this.guiTickHandler.setMod(mod);
|
||||
TickRegistry.registerTickHandler(this.gameTickHandler, Side.CLIENT);
|
||||
@@ -522,6 +528,9 @@ public class ModLoaderModContainer implements ModContainer
|
||||
GameRegistry.registerWorldGenerator(ModLoaderHelper.buildWorldGenHelper(mod));
|
||||
GameRegistry.registerFuelHandler(ModLoaderHelper.buildFuelHelper(mod));
|
||||
GameRegistry.registerCraftingHandler(ModLoaderHelper.buildCraftingHelper(mod));
|
||||
GameRegistry.registerPickupHandler(ModLoaderHelper.buildPickupHelper(mod));
|
||||
GameRegistry.registerDispenserHandler(ModLoaderHelper.buildDispenseHelper(mod));
|
||||
NetworkRegistry.instance().registerChatListener(ModLoaderHelper.buildChatListener(mod));
|
||||
NetworkRegistry.instance().registerConnectionHandler(ModLoaderHelper.buildConnectionHelper(mod));
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -560,6 +569,20 @@ public class ModLoaderModContainer implements ModContainer
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void loadComplete(FMLLoadCompleteEvent complete)
|
||||
{
|
||||
ModLoaderHelper.finishModLoading(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void serverStarting(FMLServerStartingEvent evt)
|
||||
{
|
||||
for (ICommand cmd : serverCommands)
|
||||
{
|
||||
evt.registerServerCommand(cmd);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
@@ -581,4 +604,15 @@ public class ModLoaderModContainer implements ModContainer
|
||||
{
|
||||
return this.isNetworkMod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return metadata!=null ? metadata.version : getVersion();
|
||||
}
|
||||
|
||||
public void addServerCommand(ICommand command)
|
||||
{
|
||||
serverCommands .add(command);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.network.NetworkMod;
|
||||
import cpw.mods.fml.common.network.NetworkModHandler;
|
||||
|
||||
public class ModLoaderNetworkHandler extends NetworkModHandler
|
||||
{
|
||||
|
||||
private BaseModProxy baseMod;
|
||||
public ModLoaderNetworkHandler(ModLoaderModContainer mlmc)
|
||||
{
|
||||
super(mlmc, null);
|
||||
}
|
||||
|
||||
public void setBaseMod(BaseModProxy baseMod)
|
||||
{
|
||||
this.baseMod = baseMod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresClientSide()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresServerSide()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptVersion(String version)
|
||||
{
|
||||
return baseMod.getVersion().equals(version);
|
||||
}
|
||||
@Override
|
||||
public boolean isNetworkMod()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
@@ -10,9 +9,9 @@ import cpw.mods.fml.common.network.Player;
|
||||
|
||||
public class ModLoaderPacketHandler implements IPacketHandler
|
||||
{
|
||||
private BaseMod mod;
|
||||
private BaseModProxy mod;
|
||||
|
||||
public ModLoaderPacketHandler(BaseMod mod)
|
||||
public ModLoaderPacketHandler(BaseModProxy mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
@@ -22,11 +21,11 @@ public class ModLoaderPacketHandler implements IPacketHandler
|
||||
{
|
||||
if (player instanceof EntityPlayerMP)
|
||||
{
|
||||
mod.onPacket250Received((EntityPlayer) player, packet);
|
||||
mod.serverCustomPayload(((EntityPlayerMP)player).field_71135_a, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
mod.receiveCustomPacket(packet);
|
||||
ModLoaderHelper.sidedHelper.sendClientPacket(mod, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import cpw.mods.fml.common.IPickupNotifier;
|
||||
|
||||
public class ModLoaderPickupNotifier implements IPickupNotifier
|
||||
{
|
||||
|
||||
private BaseModProxy mod;
|
||||
|
||||
public ModLoaderPickupNotifier(BaseModProxy mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyPickup(EntityItem item, EntityPlayer player)
|
||||
{
|
||||
mod.onItemPickup(player, item.field_70294_a);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.src.EntityVillager;
|
||||
import net.minecraft.src.Item;
|
||||
import net.minecraft.src.MerchantRecipeList;
|
||||
import net.minecraft.src.TradeEntry;
|
||||
import cpw.mods.fml.common.registry.VillagerRegistry;
|
||||
import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler;
|
||||
|
||||
public class ModLoaderVillageTradeHandler implements IVillageTradeHandler
|
||||
{
|
||||
private List<TradeEntry> trades = Lists.newArrayList();
|
||||
|
||||
@Override
|
||||
public void manipulateTradesForVillager(EntityVillager villager, MerchantRecipeList recipeList, Random random)
|
||||
{
|
||||
for (TradeEntry ent : trades)
|
||||
{
|
||||
if (ent.buying)
|
||||
{
|
||||
VillagerRegistry.addEmeraldBuyRecipe(villager, recipeList, random, Item.field_77698_e[ent.id], ent.chance, ent.min, ent.max);
|
||||
}
|
||||
else
|
||||
{
|
||||
VillagerRegistry.addEmeraldSellRecipe(villager, recipeList, random, Item.field_77698_e[ent.id], ent.chance, ent.min, ent.max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addTrade(TradeEntry entry)
|
||||
{
|
||||
trades.add(entry);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import net.minecraft.src.ChunkProviderGenerate;
|
||||
import net.minecraft.src.ChunkProviderHell;
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
|
||||
public class ModLoaderWorldGenerator implements IWorldGenerator
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
package cpw.mods.fml.common.modloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -30,12 +29,12 @@ public class ModProperty
|
||||
private String name;
|
||||
private Field field;
|
||||
|
||||
public ModProperty(Field f, String info, double min, double max, String name)
|
||||
public ModProperty(Field f, String info, Double min, Double max, String name)
|
||||
{
|
||||
this.field = f;
|
||||
this.info = info;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.min = min != null ? min : Double.MIN_VALUE;
|
||||
this.max = max != null ? max : Double.MAX_VALUE;
|
||||
this.name = name;
|
||||
}
|
||||
public ModProperty(Field field, Map<String, Object> annotationInfo)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
public class EntitySpawnAdjustmentPacket extends FMLPacket
|
||||
{
|
||||
|
||||
|
||||
@@ -8,10 +8,16 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.DataWatcher;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.MathHelper;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.primitives.Bytes;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
@@ -20,13 +26,6 @@ import cpw.mods.fml.common.registry.EntityRegistry;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import cpw.mods.fml.common.registry.IThrowableEntity;
|
||||
import net.minecraft.src.DataWatcher;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.MathHelper;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
public class EntitySpawnPacket extends FMLPacket
|
||||
{
|
||||
@@ -76,7 +75,7 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
// yaw, pitch
|
||||
dat.writeByte((byte) (ent.field_70177_z * 256.0F / 360.0F));
|
||||
dat.writeByte((byte) (ent.field_70125_A * 256.0F / 360.0F));
|
||||
|
||||
|
||||
// head yaw
|
||||
if (ent instanceof EntityLiving)
|
||||
{
|
||||
@@ -96,9 +95,9 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
{
|
||||
// unpossible
|
||||
}
|
||||
|
||||
|
||||
dat.write(bos.toByteArray());
|
||||
|
||||
|
||||
if (ent instanceof IThrowableEntity)
|
||||
{
|
||||
Entity owner = ((IThrowableEntity)ent).getThrower();
|
||||
@@ -117,11 +116,14 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
dat.writeInt((int)(mY * 8000D));
|
||||
dat.writeInt((int)(mZ * 8000D));
|
||||
}
|
||||
else
|
||||
{
|
||||
dat.writeInt(0);
|
||||
}
|
||||
if (ent instanceof IEntityAdditionalSpawnData)
|
||||
{
|
||||
((IEntityAdditionalSpawnData)ent).writeSpawnData(dat);
|
||||
}
|
||||
|
||||
|
||||
return dat.toByteArray();
|
||||
}
|
||||
@@ -152,7 +154,7 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
{
|
||||
// Nope
|
||||
}
|
||||
dat.skipBytes(data.length - bis.available());
|
||||
dat.skipBytes(data.length - bis.available() - 27);
|
||||
throwerId = dat.readInt();
|
||||
if (throwerId != 0)
|
||||
{
|
||||
@@ -160,7 +162,7 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
speedScaledY = dat.readInt() / 8000D;
|
||||
speedScaledZ = dat.readInt() / 8000D;
|
||||
}
|
||||
|
||||
|
||||
this.dataStream = dat;
|
||||
return this;
|
||||
}
|
||||
@@ -170,7 +172,7 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
{
|
||||
NetworkModHandler nmh = handler.findNetworkModHandler(networkId);
|
||||
ModContainer mc = nmh.getContainer();
|
||||
|
||||
|
||||
EntityRegistration registration = EntityRegistry.instance().lookupModSpawn(mc, modEntityId);
|
||||
Class<? extends Entity> cls = registration.getEntityClass();
|
||||
if (cls == null)
|
||||
@@ -179,8 +181,8 @@ public class EntitySpawnPacket extends FMLPacket
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Entity entity = FMLCommonHandler.instance().spawnEntityIntoClientWorld(cls, this);
|
||||
|
||||
Entity entity = FMLCommonHandler.instance().spawnEntityIntoClientWorld(registration, this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,12 @@ package cpw.mods.fml.common.network;
|
||||
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_LIST_REQUEST;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -11,17 +16,21 @@ import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.EnumGameType;
|
||||
import net.minecraft.src.Item;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetLoginHandler;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import net.minecraft.src.Packet1Login;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Packet3Chat;
|
||||
import net.minecraft.src.ServerConfigurationManager;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.WorldType;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.hash.Hashing;
|
||||
|
||||
@@ -32,8 +41,8 @@ import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.network.FMLPacket.Type;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
|
||||
public class FMLNetworkHandler
|
||||
{
|
||||
@@ -41,6 +50,12 @@ public class FMLNetworkHandler
|
||||
private static final int PROTOCOL_VERSION = 0x1;
|
||||
private static final FMLNetworkHandler INSTANCE = new FMLNetworkHandler();
|
||||
|
||||
// List of states for connections from clients to server
|
||||
static final int LOGIN_RECEIVED = 1;
|
||||
static final int CONNECTION_VALID = 2;
|
||||
static final int FML_OUT_OF_DATE = -1;
|
||||
static final int MISSING_MODS_OR_VERSIONS = -2;
|
||||
|
||||
private Map<NetLoginHandler, Integer> loginStates = Maps.newHashMap();
|
||||
private Map<ModContainer, NetworkModHandler> networkModHandlers = Maps.newHashMap();
|
||||
|
||||
@@ -53,7 +68,6 @@ public class FMLNetworkHandler
|
||||
if (target.startsWith("MC|"))
|
||||
{
|
||||
handler.handleVanilla250Packet(packet);
|
||||
return;
|
||||
}
|
||||
if (target.equals("FML"))
|
||||
{
|
||||
@@ -102,15 +116,15 @@ public class FMLNetworkHandler
|
||||
if (handleVanillaLoginKick(netLoginHandler, server, address, userName))
|
||||
{
|
||||
// No FML on the client
|
||||
FMLRelaunchLog.fine("Connection from %s rejected - no FML packet received from client", userName);
|
||||
netLoginHandler.completeConnection("You don't have FML installed, or your installation is too old");
|
||||
FMLLog.fine("Connection from %s rejected - no FML packet received from client", userName);
|
||||
netLoginHandler.completeConnection("You don't have FML installed, you cannot connect to this server");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
// Are we ready to negotiate with the client?
|
||||
if (loginStates.get(netLoginHandler) == 1)
|
||||
switch (loginStates.get(netLoginHandler))
|
||||
{
|
||||
case LOGIN_RECEIVED:
|
||||
// mods can try and kick undesireables here
|
||||
String modKick = NetworkRegistry.instance().connectionReceived(netLoginHandler, netLoginHandler.field_72538_b);
|
||||
if (modKick != null)
|
||||
@@ -125,26 +139,28 @@ public class FMLNetworkHandler
|
||||
loginStates.remove(netLoginHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the "connection completed" flag so processing can continue
|
||||
NetLoginHandler.func_72531_a(netLoginHandler, false);
|
||||
// Send the mod list request packet to the client from the server
|
||||
netLoginHandler.field_72538_b.func_74429_a(getModListRequestPacket());
|
||||
loginStates.put(netLoginHandler, 2);
|
||||
}
|
||||
// We must be good to go - the ModIdentifiers packet was sent and the
|
||||
// continuation signal was indicated
|
||||
else if (loginStates.get(netLoginHandler) == 2)
|
||||
{
|
||||
loginStates.put(netLoginHandler, CONNECTION_VALID);
|
||||
break;
|
||||
case CONNECTION_VALID:
|
||||
netLoginHandler.completeConnection(null);
|
||||
loginStates.remove(netLoginHandler);
|
||||
}
|
||||
// We have to abort this connection - there was a negotiation problem
|
||||
// (most likely missing mods)
|
||||
else
|
||||
{
|
||||
break;
|
||||
case MISSING_MODS_OR_VERSIONS:
|
||||
netLoginHandler.completeConnection("The server requires mods that are absent or out of date on your client");
|
||||
loginStates.remove(netLoginHandler);
|
||||
break;
|
||||
case FML_OUT_OF_DATE:
|
||||
netLoginHandler.completeConnection("Your client is not running a new enough version of FML to connect to this server");
|
||||
loginStates.remove(netLoginHandler);
|
||||
break;
|
||||
default:
|
||||
netLoginHandler.completeConnection("There was a problem during FML negotiation");
|
||||
loginStates.remove(netLoginHandler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,18 +186,31 @@ public class FMLNetworkHandler
|
||||
|
||||
public static void handleLoginPacketOnServer(NetLoginHandler handler, Packet1Login login)
|
||||
{
|
||||
if (login.field_73561_a == FML_HASH && login.field_73558_e == PROTOCOL_VERSION)
|
||||
if (login.field_73561_a == FML_HASH)
|
||||
{
|
||||
FMLRelaunchLog.finest("Received valid FML login packet from %s", handler.field_72538_b.func_74430_c());
|
||||
instance().loginStates.put(handler, 1);
|
||||
if (login.field_73558_e == PROTOCOL_VERSION)
|
||||
{
|
||||
FMLLog.finest("Received valid FML login packet from %s", handler.field_72538_b.func_74430_c());
|
||||
instance().loginStates.put(handler, LOGIN_RECEIVED);
|
||||
}
|
||||
else if (login.field_73558_e != PROTOCOL_VERSION)
|
||||
{
|
||||
FMLLog.finest("Received incorrect FML (%x) login packet from %s", login.field_73558_e, handler.field_72538_b.func_74430_c());
|
||||
instance().loginStates.put(handler, FML_OUT_OF_DATE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLRelaunchLog.fine("Received invalid FML login packet %d, %d from %s", login.field_73561_a, login.field_73558_e,
|
||||
FMLLog.fine("Received invalid login packet (%x, %x) from %s", login.field_73561_a, login.field_73558_e,
|
||||
handler.field_72538_b.func_74430_c());
|
||||
}
|
||||
}
|
||||
|
||||
static void setHandlerState(NetLoginHandler handler, int state)
|
||||
{
|
||||
instance().loginStates.put(handler, state);
|
||||
}
|
||||
|
||||
public static FMLNetworkHandler instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
@@ -189,6 +218,8 @@ public class FMLNetworkHandler
|
||||
|
||||
public static Packet1Login getFMLFakeLoginPacket()
|
||||
{
|
||||
// Always reset compat to zero before sending our fake packet
|
||||
FMLCommonHandler.instance().getSidedDelegate().setClientCompatibilityLevel((byte) 0);
|
||||
Packet1Login fake = new Packet1Login();
|
||||
// Hash FML using a simple function
|
||||
fake.field_73561_a = FML_HASH;
|
||||
@@ -201,11 +232,7 @@ public class FMLNetworkHandler
|
||||
|
||||
public Packet250CustomPayload getModListRequestPacket()
|
||||
{
|
||||
Packet250CustomPayload pkt = new Packet250CustomPayload();
|
||||
pkt.field_73630_a = "FML";
|
||||
pkt.field_73629_c = FMLPacket.makePacket(MOD_LIST_REQUEST);
|
||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||
return pkt;
|
||||
return PacketDispatcher.getPacket("FML", FMLPacket.makePacket(MOD_LIST_REQUEST));
|
||||
}
|
||||
|
||||
public void registerNetworkMod(NetworkModHandler handler)
|
||||
@@ -248,6 +275,7 @@ public class FMLNetworkHandler
|
||||
public static void handlePlayerLogin(EntityPlayerMP player, NetServerHandler netHandler, NetworkManager manager)
|
||||
{
|
||||
NetworkRegistry.instance().playerLoggedIn(player, netHandler, manager);
|
||||
GameRegistry.onPlayerLogin(player);
|
||||
}
|
||||
|
||||
public Map<Integer, NetworkModHandler> getNetworkIdMap()
|
||||
@@ -259,8 +287,11 @@ public class FMLNetworkHandler
|
||||
{
|
||||
Map<String, ModContainer> mods = Loader.instance().getIndexedModList();
|
||||
NetworkModHandler handler = findNetworkModHandler(mods.get(key));
|
||||
handler.setNetworkId(value);
|
||||
networkIdLookup.put(value, handler);
|
||||
if (handler != null)
|
||||
{
|
||||
handler.setNetworkId(value);
|
||||
networkIdLookup.put(value, handler);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onClientConnectionToRemoteServer(NetHandler netClientHandler, String server, int port, NetworkManager networkManager)
|
||||
@@ -279,10 +310,6 @@ public class FMLNetworkHandler
|
||||
}
|
||||
|
||||
|
||||
public static void sendPacket(Player player, Packet packet)
|
||||
{
|
||||
}
|
||||
|
||||
public static void openGui(EntityPlayer player, Object mod, int modGuiId, World world, int x, int y, int z)
|
||||
{
|
||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
||||
@@ -316,20 +343,80 @@ public class FMLNetworkHandler
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Packet250CustomPayload pkt = new Packet250CustomPayload();
|
||||
pkt.field_73630_a = "FML";
|
||||
pkt.field_73629_c = FMLPacket.makePacket(Type.ENTITYSPAWN, er, entity);
|
||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||
return pkt;
|
||||
if (er.usesVanillaSpawning())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return PacketDispatcher.getPacket("FML", FMLPacket.makePacket(Type.ENTITYSPAWN, er, entity, instance().findNetworkModHandler(er.getContainer())));
|
||||
}
|
||||
|
||||
public static void makeEntitySpawnAdjustment(int entityId, EntityPlayerMP player, int serverX, int serverY, int serverZ)
|
||||
{
|
||||
Packet250CustomPayload pkt = new Packet250CustomPayload();
|
||||
pkt.field_73630_a = "FML";
|
||||
pkt.field_73629_c = FMLPacket.makePacket(Type.ENTITYSPAWNADJUSTMENT, entityId, serverX, serverY, serverZ);
|
||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||
|
||||
Packet250CustomPayload pkt = PacketDispatcher.getPacket("FML", FMLPacket.makePacket(Type.ENTITYSPAWNADJUSTMENT, entityId, serverX, serverY, serverZ));
|
||||
player.field_71135_a.func_72567_b(pkt);
|
||||
}
|
||||
|
||||
public static InetAddress computeLocalHost() throws IOException
|
||||
{
|
||||
InetAddress add = null;
|
||||
List<InetAddress> addresses = Lists.newArrayList();
|
||||
InetAddress localHost = InetAddress.getLocalHost();
|
||||
for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces()))
|
||||
{
|
||||
if (!ni.isLoopback() && ni.isUp())
|
||||
{
|
||||
addresses.addAll(Collections.list(ni.getInetAddresses()));
|
||||
if (addresses.contains(localHost))
|
||||
{
|
||||
add = localHost;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (add == null && !addresses.isEmpty())
|
||||
{
|
||||
for (InetAddress addr: addresses)
|
||||
{
|
||||
if (addr.getAddress().length == 4)
|
||||
{
|
||||
add = addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (add == null)
|
||||
{
|
||||
add = localHost;
|
||||
}
|
||||
return add;
|
||||
}
|
||||
|
||||
public static Packet3Chat handleChatMessage(NetHandler handler, Packet3Chat chat)
|
||||
{
|
||||
return NetworkRegistry.instance().handleChat(handler, chat);
|
||||
}
|
||||
|
||||
public static void handlePacket131Packet(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
if (handler instanceof NetServerHandler || mapData.field_73438_a != Item.field_77744_bd.field_77779_bT)
|
||||
{
|
||||
// Server side and not "map" packets are always handled by us
|
||||
NetworkRegistry.instance().handleTinyPacket(handler, mapData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to the net client handler implementation
|
||||
FMLCommonHandler.instance().handleTinyPacket(handler, mapData);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getCompatibilityLevel()
|
||||
{
|
||||
return PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
public static boolean vanillaLoginPacketCompatibility()
|
||||
{
|
||||
return FMLCommonHandler.instance().getSidedDelegate().getClientCompatibilityLevel() == 0;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,13 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import com.google.common.primitives.UnsignedBytes;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.Packet3Chat;
|
||||
|
||||
public interface IChatListener
|
||||
{
|
||||
/**
|
||||
* Called when there is a chat message received on the server
|
||||
* @param handler
|
||||
* @param message
|
||||
*/
|
||||
public Packet3Chat serverChat(NetHandler handler, Packet3Chat message);
|
||||
|
||||
/**
|
||||
* Called when there is a chat message recived on the client
|
||||
*
|
||||
* @param handler
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
public Packet3Chat clientChat(NetHandler handler, Packet3Chat message);
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetLoginHandler;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet1Login;
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
|
||||
public interface ITinyPacketHandler
|
||||
{
|
||||
void handle(NetHandler handler, Packet131MapData mapData);
|
||||
}
|
||||
@@ -1,23 +1,19 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.*;
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_IDENTIFIERS;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetLoginHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
public class ModIdentifiersPacket extends FMLPacket
|
||||
{
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.*;
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_LIST_REQUEST;
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_LIST_RESPONSE;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
@@ -17,6 +18,7 @@ import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
@@ -24,6 +26,7 @@ import cpw.mods.fml.common.ModContainer;
|
||||
public class ModListRequestPacket extends FMLPacket
|
||||
{
|
||||
private List<String> sentModList;
|
||||
private byte compatibilityLevel;
|
||||
|
||||
public ModListRequestPacket()
|
||||
{
|
||||
@@ -40,6 +43,7 @@ public class ModListRequestPacket extends FMLPacket
|
||||
{
|
||||
dat.writeUTF(mc.getModId());
|
||||
}
|
||||
dat.writeByte(FMLNetworkHandler.getCompatibilityLevel());
|
||||
return dat.toByteArray();
|
||||
}
|
||||
|
||||
@@ -53,6 +57,14 @@ public class ModListRequestPacket extends FMLPacket
|
||||
{
|
||||
sentModList.add(in.readUTF());
|
||||
}
|
||||
try
|
||||
{
|
||||
compatibilityLevel = in.readByte();
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
FMLLog.fine("No compatibility byte found - the server is too old");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -84,14 +96,23 @@ public class ModListRequestPacket extends FMLPacket
|
||||
|
||||
if (indexedModList.size()>0)
|
||||
{
|
||||
// TODO : handle client present but server absent mods
|
||||
for (Entry<String, ModContainer> e : indexedModList.entrySet())
|
||||
{
|
||||
if (e.getValue().isNetworkMod())
|
||||
{
|
||||
NetworkModHandler missingHandler = FMLNetworkHandler.instance().findNetworkModHandler(e.getValue());
|
||||
if (missingHandler.requiresServerSide())
|
||||
{
|
||||
// TODO : what should we do if a mod is marked "serverSideRequired"? Stop the connection?
|
||||
FMLLog.warning("The mod %s was not found on the server you connected to, but requested that the server side be present", e.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Packet250CustomPayload pkt = new Packet250CustomPayload();
|
||||
pkt.field_73630_a = "FML";
|
||||
pkt.field_73629_c = FMLPacket.makePacket(MOD_LIST_RESPONSE, modVersions, missingMods);
|
||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||
FMLLog.fine("The server has compatibility level %d", compatibilityLevel);
|
||||
FMLCommonHandler.instance().getSidedDelegate().setClientCompatibilityLevel(compatibilityLevel);
|
||||
|
||||
mgr.func_74429_a(pkt);
|
||||
mgr.func_74429_a(PacketDispatcher.getPacket("FML", FMLPacket.makePacket(MOD_LIST_RESPONSE, modVersions, missingMods)));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,18 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.*;
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_IDENTIFIERS;
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_LIST_RESPONSE;
|
||||
import static cpw.mods.fml.common.network.FMLPacket.Type.MOD_MISSING;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetLoginHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -16,11 +24,6 @@ import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetLoginHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
|
||||
public class ModListResponsePacket extends FMLPacket
|
||||
{
|
||||
private Map<String,String> modVersions;
|
||||
@@ -106,12 +109,16 @@ public class ModListResponsePacket extends FMLPacket
|
||||
if (missingClientMods.size()>0 || versionIncorrectMods.size() > 0)
|
||||
{
|
||||
pkt.field_73629_c = FMLPacket.makePacket(MOD_MISSING, missingClientMods, versionIncorrectMods);
|
||||
FMLLog.fine("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods);
|
||||
Logger.getLogger("Minecraft").info(String.format("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods));
|
||||
FMLLog.info("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods);
|
||||
// Mark this as bad
|
||||
FMLNetworkHandler.setHandlerState((NetLoginHandler) netHandler, FMLNetworkHandler.MISSING_MODS_OR_VERSIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
pkt.field_73629_c = FMLPacket.makePacket(MOD_IDENTIFIERS, netHandler);
|
||||
FMLLog.fine("User %s connecting with mods %s", userName, modVersions.keySet());
|
||||
Logger.getLogger("Minecraft").info(String.format("User %s connecting with mods %s", userName, modVersions.keySet()));
|
||||
FMLLog.info("User %s connecting with mods %s", userName, modVersions.keySet());
|
||||
}
|
||||
|
||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||
|
||||
@@ -2,12 +2,29 @@ package cpw.mods.fml.common.network;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
public class ModMissingPacket extends FMLPacket
|
||||
{
|
||||
|
||||
private List<ModData> missing;
|
||||
private List<ModData> badVersion;
|
||||
|
||||
public ModMissingPacket()
|
||||
{
|
||||
super(Type.MOD_MISSING);
|
||||
@@ -16,24 +33,76 @@ public class ModMissingPacket extends FMLPacket
|
||||
@Override
|
||||
public byte[] generatePacket(Object... data)
|
||||
{
|
||||
// TODO
|
||||
ByteArrayDataOutput dat = ByteStreams.newDataOutput();
|
||||
|
||||
List<String> missing = (List<String>) data[0];
|
||||
List<String> badVersion = (List<String>) data[1];
|
||||
|
||||
return new byte[0];
|
||||
dat.writeInt(missing.size());
|
||||
for (String missed : missing)
|
||||
{
|
||||
ModContainer mc = Loader.instance().getIndexedModList().get(missed);
|
||||
dat.writeUTF(missed);
|
||||
dat.writeUTF(mc.getVersion());
|
||||
}
|
||||
dat.writeInt(badVersion.size());
|
||||
for (String bad : badVersion)
|
||||
{
|
||||
ModContainer mc = Loader.instance().getIndexedModList().get(bad);
|
||||
dat.writeUTF(bad);
|
||||
dat.writeUTF(mc.getVersion());
|
||||
}
|
||||
return dat.toByteArray();
|
||||
}
|
||||
|
||||
private static class ModData
|
||||
{
|
||||
String modId;
|
||||
String modVersion;
|
||||
}
|
||||
@Override
|
||||
public FMLPacket consumePacket(byte[] data)
|
||||
{
|
||||
// TODO
|
||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||
int missingLen = dat.readInt();
|
||||
missing = Lists.newArrayListWithCapacity(missingLen);
|
||||
for (int i = 0; i < missingLen; i++)
|
||||
{
|
||||
ModData md = new ModData();
|
||||
md.modId = dat.readUTF();
|
||||
md.modVersion = dat.readUTF();
|
||||
missing.add(md);
|
||||
}
|
||||
int badVerLength = dat.readInt();
|
||||
badVersion = Lists.newArrayListWithCapacity(badVerLength);
|
||||
for (int i = 0; i < badVerLength; i++)
|
||||
{
|
||||
ModData md = new ModData();
|
||||
md.modId = dat.readUTF();
|
||||
md.modVersion = dat.readUTF();
|
||||
badVersion.add(md);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(NetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName)
|
||||
{
|
||||
// TODO
|
||||
FMLCommonHandler.instance().getSidedDelegate().displayMissingMods(this);
|
||||
}
|
||||
|
||||
public List<ArtifactVersion> getModList()
|
||||
{
|
||||
Builder<ArtifactVersion> builder = ImmutableList.<ArtifactVersion>builder();
|
||||
for (ModData md : missing)
|
||||
{
|
||||
builder.add(new DefaultArtifactVersion(md.modId, VersionRange.createFromVersion(md.modVersion, null)));
|
||||
}
|
||||
for (ModData md : badVersion)
|
||||
{
|
||||
builder.add(new DefaultArtifactVersion(md.modId, VersionRange.createFromVersion(md.modVersion, null)));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,9 +4,8 @@ import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@@ -24,7 +23,9 @@ public @interface NetworkMod
|
||||
*/
|
||||
boolean serverSideRequired() default false;
|
||||
/**
|
||||
* A list of Packet250 network channels to register for this mod
|
||||
* A list of Packet250 network channels to register for this mod - these channels
|
||||
* will be universal and will require a universal packethandler to handle them
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String[] channels() default {};
|
||||
@@ -36,23 +37,46 @@ public @interface NetworkMod
|
||||
|
||||
/**
|
||||
* A packet handler implementation for channels registered through this annotation
|
||||
* - this packet handler will be universal and handle both client and server
|
||||
* requests.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<? extends IPacketHandler> packetHandler() default NULL.class;
|
||||
|
||||
/**
|
||||
* A tiny packet handler implementation based on {@link Packet131MapData} for "small"
|
||||
* data packet loads.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<? extends ITinyPacketHandler> tinyPacketHandler() default NULL.class;
|
||||
/**
|
||||
* A connection handler implementation for this network mod
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<? extends IConnectionHandler> connectionHandler() default NULL.class;
|
||||
/**
|
||||
* A packet handler and channels to register for the client side
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SidedPacketHandler clientPacketHandlerSpec() default @SidedPacketHandler(channels = {}, packetHandler = NULL.class );
|
||||
|
||||
/**
|
||||
* A packet handler and channels to register for the server side
|
||||
* @return
|
||||
*/
|
||||
SidedPacketHandler serverPacketHandlerSpec() default @SidedPacketHandler(channels = {}, packetHandler = NULL.class );
|
||||
|
||||
/**
|
||||
* Special dummy class for handling stupid annotation default values
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
static interface NULL extends IPacketHandler, IConnectionHandler {};
|
||||
static interface NULL extends IPacketHandler, IConnectionHandler, ITinyPacketHandler {};
|
||||
|
||||
/**
|
||||
* A marker for a method that will be offered the client's version string
|
||||
* if more sophisticated version rejection handling is required:
|
||||
@@ -64,4 +88,15 @@ public @interface NetworkMod
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface VersionCheckHandler { }
|
||||
|
||||
/**
|
||||
* Bundles together a packet handler and it's associated channels for the sided packet handlers
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public @interface SidedPacketHandler {
|
||||
String[] channels();
|
||||
Class<? extends IPacketHandler> packetHandler();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +1,17 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import net.minecraft.src.Item;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
@@ -24,6 +20,12 @@ import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class NetworkModHandler
|
||||
{
|
||||
private static Object connectionHandlerDefaultValue;
|
||||
private static Object packetHandlerDefaultValue;
|
||||
private static Object clientHandlerDefaultValue;
|
||||
private static Object serverHandlerDefaultValue;
|
||||
private static Object tinyPacketHandlerDefaultValue;
|
||||
|
||||
private static int assignedIds = 1;
|
||||
|
||||
private int localId;
|
||||
@@ -34,6 +36,7 @@ public class NetworkModHandler
|
||||
private Method checkHandler;
|
||||
|
||||
private VersionRange acceptableRange;
|
||||
private ITinyPacketHandler tinyPacketHandler;
|
||||
|
||||
public NetworkModHandler(ModContainer container, NetworkMod modAnnotation)
|
||||
{
|
||||
@@ -41,6 +44,11 @@ public class NetworkModHandler
|
||||
this.mod = modAnnotation;
|
||||
this.localId = assignedIds++;
|
||||
this.networkId = this.localId;
|
||||
// Skip over the map object because it has special network id meaning
|
||||
if (Item.field_77744_bd.field_77779_bT == assignedIds)
|
||||
{
|
||||
assignedIds++;
|
||||
}
|
||||
}
|
||||
public NetworkModHandler(ModContainer container, Class<?> networkModClass, ASMDataTable table)
|
||||
{
|
||||
@@ -92,30 +100,31 @@ public class NetworkModHandler
|
||||
}
|
||||
}
|
||||
|
||||
if (!mod.packetHandler().getName().equals(NetworkMod.NULL.class.getName()))
|
||||
FMLLog.finest("Testing mod %s to very it can accept it's own version in a remote connection", container.getModId());
|
||||
boolean acceptsSelf = acceptVersion(container.getVersion());
|
||||
if (!acceptsSelf)
|
||||
{
|
||||
IPacketHandler instance;
|
||||
try
|
||||
{
|
||||
instance = mod.packetHandler().newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to create packet handler instance %s", mod.packetHandler().getName());
|
||||
throw new FMLNetworkException(e);
|
||||
}
|
||||
|
||||
for (String channel : mod.channels())
|
||||
{
|
||||
NetworkRegistry.instance().registerChannel(instance, channel);
|
||||
}
|
||||
FMLLog.severe("The mod %s appears to reject it's own version number (%s) in it's version handling. This is likely a severe bug in the mod!", container.getModId(), container.getVersion());
|
||||
}
|
||||
else if (mod.channels().length > 0)
|
||||
else
|
||||
{
|
||||
FMLLog.warning("The mod id %s attempted to register channels without specifying a valid packet handler", container.getModId());
|
||||
FMLLog.finest("The mod %s accepts it's own version (%s)", container.getModId(), container.getVersion());
|
||||
}
|
||||
|
||||
if (!mod.connectionHandler().getName().equals(NetworkMod.NULL.class.getName()))
|
||||
tryCreatingPacketHandler(container, mod.packetHandler(), mod.channels(), null);
|
||||
if (FMLCommonHandler.instance().getSide().isClient())
|
||||
{
|
||||
if (mod.clientPacketHandlerSpec() != getClientHandlerSpecDefaultValue())
|
||||
{
|
||||
tryCreatingPacketHandler(container, mod.clientPacketHandlerSpec().packetHandler(), mod.clientPacketHandlerSpec().channels(), Side.CLIENT);
|
||||
}
|
||||
}
|
||||
if (mod.serverPacketHandlerSpec() != getServerHandlerSpecDefaultValue())
|
||||
{
|
||||
tryCreatingPacketHandler(container, mod.serverPacketHandlerSpec().packetHandler(), mod.serverPacketHandlerSpec().channels(), Side.SERVER);
|
||||
}
|
||||
|
||||
if (mod.connectionHandler() != getConnectionHandlerDefaultValue())
|
||||
{
|
||||
IConnectionHandler instance;
|
||||
try
|
||||
@@ -130,8 +139,143 @@ public class NetworkModHandler
|
||||
|
||||
NetworkRegistry.instance().registerConnectionHandler(instance);
|
||||
}
|
||||
|
||||
if (mod.tinyPacketHandler()!=getTinyPacketHandlerDefaultValue())
|
||||
{
|
||||
try
|
||||
{
|
||||
tinyPacketHandler = mod.tinyPacketHandler().newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to create tiny packet handler instance %s", mod.tinyPacketHandler().getName());
|
||||
throw new FMLNetworkException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param container
|
||||
*/
|
||||
private void tryCreatingPacketHandler(ModContainer container, Class<? extends IPacketHandler> clazz, String[] channels, Side side)
|
||||
{
|
||||
if (side!=null && side.isClient() && ! FMLCommonHandler.instance().getSide().isClient())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (clazz!=getPacketHandlerDefaultValue())
|
||||
{
|
||||
if (channels.length==0)
|
||||
{
|
||||
FMLLog.log(Level.WARNING, "The mod id %s attempted to register a packet handler without specifying channels for it", container.getModId());
|
||||
}
|
||||
else
|
||||
{
|
||||
IPacketHandler instance;
|
||||
try
|
||||
{
|
||||
instance = clazz.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to create a packet handler instance %s for mod %s", clazz.getName(), container.getModId());
|
||||
throw new FMLNetworkException(e);
|
||||
}
|
||||
|
||||
for (String channel : channels)
|
||||
{
|
||||
NetworkRegistry.instance().registerChannel(instance, channel, side);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (channels.length > 0)
|
||||
{
|
||||
FMLLog.warning("The mod id %s attempted to register channels without specifying a packet handler", container.getModId());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private Object getConnectionHandlerDefaultValue()
|
||||
{
|
||||
try {
|
||||
if (connectionHandlerDefaultValue == null)
|
||||
{
|
||||
connectionHandlerDefaultValue = NetworkMod.class.getMethod("connectionHandler").getDefaultValue();
|
||||
}
|
||||
return connectionHandlerDefaultValue;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new RuntimeException("Derp?", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private Object getPacketHandlerDefaultValue()
|
||||
{
|
||||
try {
|
||||
if (packetHandlerDefaultValue == null)
|
||||
{
|
||||
packetHandlerDefaultValue = NetworkMod.class.getMethod("packetHandler").getDefaultValue();
|
||||
}
|
||||
return packetHandlerDefaultValue;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new RuntimeException("Derp?", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object getTinyPacketHandlerDefaultValue()
|
||||
{
|
||||
try {
|
||||
if (tinyPacketHandlerDefaultValue == null)
|
||||
{
|
||||
tinyPacketHandlerDefaultValue = NetworkMod.class.getMethod("tinyPacketHandler").getDefaultValue();
|
||||
}
|
||||
return tinyPacketHandlerDefaultValue;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new RuntimeException("Derp?", e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private Object getClientHandlerSpecDefaultValue()
|
||||
{
|
||||
try {
|
||||
if (clientHandlerDefaultValue == null)
|
||||
{
|
||||
clientHandlerDefaultValue = NetworkMod.class.getMethod("clientPacketHandlerSpec").getDefaultValue();
|
||||
}
|
||||
return clientHandlerDefaultValue;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new RuntimeException("Derp?", e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private Object getServerHandlerSpecDefaultValue()
|
||||
{
|
||||
try {
|
||||
if (serverHandlerDefaultValue == null)
|
||||
{
|
||||
serverHandlerDefaultValue = NetworkMod.class.getMethod("serverPacketHandlerSpec").getDefaultValue();
|
||||
}
|
||||
return serverHandlerDefaultValue;
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
throw new RuntimeException("Derp?", e);
|
||||
}
|
||||
}
|
||||
public boolean requiresClientSide()
|
||||
{
|
||||
return mod.clientSideRequired();
|
||||
@@ -194,4 +338,13 @@ public class NetworkModHandler
|
||||
{
|
||||
this.networkId = value;
|
||||
}
|
||||
|
||||
public boolean hasTinyPacketHandler()
|
||||
{
|
||||
return tinyPacketHandler != null;
|
||||
}
|
||||
public ITinyPacketHandler getTinyPacketHandler()
|
||||
{
|
||||
return tinyPacketHandler;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -16,9 +14,10 @@ import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetLoginHandler;
|
||||
import net.minecraft.src.NetServerHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import net.minecraft.src.Packet1Login;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.TcpConnection;
|
||||
import net.minecraft.src.Packet3Chat;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
@@ -26,19 +25,23 @@ import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.network.FMLPacket.Type;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class NetworkRegistry
|
||||
{
|
||||
|
||||
@@ -50,13 +53,16 @@ public class NetworkRegistry
|
||||
/**
|
||||
* A map of the packet handlers for packets
|
||||
*/
|
||||
private Multimap<String, IPacketHandler> packetHandlers = ArrayListMultimap.create();
|
||||
private Multimap<String, IPacketHandler> universalPacketHandlers = ArrayListMultimap.create();
|
||||
private Multimap<String, IPacketHandler> clientPacketHandlers = ArrayListMultimap.create();
|
||||
private Multimap<String, IPacketHandler> serverPacketHandlers = ArrayListMultimap.create();
|
||||
/**
|
||||
* A linked set of registered connection handlers
|
||||
*/
|
||||
private Set<IConnectionHandler> connectionHandlers = Sets.newLinkedHashSet();
|
||||
private Map<ModContainer, IGuiHandler> serverGuiHandlers = Maps.newHashMap();
|
||||
private Map<ModContainer, IGuiHandler> clientGuiHandlers = Maps.newHashMap();
|
||||
private List<IChatListener> chatListeners = Lists.newArrayList();
|
||||
|
||||
public static NetworkRegistry instance()
|
||||
{
|
||||
@@ -66,9 +72,9 @@ public class NetworkRegistry
|
||||
* Get the packet 250 channel registration string
|
||||
* @return
|
||||
*/
|
||||
byte[] getPacketRegistry()
|
||||
byte[] getPacketRegistry(Side side)
|
||||
{
|
||||
return Joiner.on('\0').join(packetHandlers.keySet()).getBytes(Charsets.UTF_8);
|
||||
return Joiner.on('\0').join(Iterables.concat(Arrays.asList("FML"),universalPacketHandlers.keySet(), side.isClient() ? clientPacketHandlers.keySet() : serverPacketHandlers.keySet())).getBytes(Charsets.UTF_8);
|
||||
}
|
||||
/**
|
||||
* Is the specified channel active for the player?
|
||||
@@ -87,7 +93,36 @@ public class NetworkRegistry
|
||||
*/
|
||||
public void registerChannel(IPacketHandler handler, String channelName)
|
||||
{
|
||||
packetHandlers.put(channelName, handler);
|
||||
if (Strings.isNullOrEmpty(channelName) || (channelName!=null && channelName.length()>16))
|
||||
{
|
||||
FMLLog.severe("Invalid channel name '%s' : %s", channelName, Strings.isNullOrEmpty(channelName) ? "Channel name is empty" : "Channel name is too long (16 chars is maximum)");
|
||||
throw new RuntimeException("Channel name is invalid");
|
||||
|
||||
}
|
||||
universalPacketHandlers.put(channelName, handler);
|
||||
}
|
||||
|
||||
public void registerChannel(IPacketHandler handler, String channelName, Side side)
|
||||
{
|
||||
if (side == null)
|
||||
{
|
||||
registerChannel(handler, channelName);
|
||||
return;
|
||||
}
|
||||
if (Strings.isNullOrEmpty(channelName) || (channelName!=null && channelName.length()>16))
|
||||
{
|
||||
FMLLog.severe("Invalid channel name '%s' : %s", channelName, Strings.isNullOrEmpty(channelName) ? "Channel name is empty" : "Channel name is too long (16 chars is maximum)");
|
||||
throw new RuntimeException("Channel name is invalid");
|
||||
|
||||
}
|
||||
if (side.isClient())
|
||||
{
|
||||
clientPacketHandlers.put(channelName, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
serverPacketHandlers.put(channelName, handler);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Activate the channel for the player
|
||||
@@ -116,13 +151,22 @@ public class NetworkRegistry
|
||||
connectionHandlers.add(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a chat listener
|
||||
* @param listener
|
||||
*/
|
||||
public void registerChatListener(IChatListener listener)
|
||||
{
|
||||
chatListeners.add(listener);
|
||||
}
|
||||
|
||||
void playerLoggedIn(EntityPlayerMP player, NetServerHandler netHandler, NetworkManager manager)
|
||||
{
|
||||
generateChannelRegistration(player, netHandler, manager);
|
||||
for (IConnectionHandler handler : connectionHandlers)
|
||||
{
|
||||
handler.playerLoggedIn((Player)player, netHandler, manager);
|
||||
}
|
||||
generateChannelRegistration(player, netHandler, manager);
|
||||
}
|
||||
|
||||
String connectionReceived(NetLoginHandler netHandler, NetworkManager manager)
|
||||
@@ -156,6 +200,7 @@ public class NetworkRegistry
|
||||
|
||||
void clientLoggedIn(NetHandler clientHandler, NetworkManager manager, Packet1Login login)
|
||||
{
|
||||
generateChannelRegistration(clientHandler.getPlayer(), clientHandler, manager);
|
||||
for (IConnectionHandler handler : connectionHandlers)
|
||||
{
|
||||
handler.clientLoggedIn(clientHandler, manager, login);
|
||||
@@ -174,7 +219,7 @@ public class NetworkRegistry
|
||||
{
|
||||
Packet250CustomPayload pkt = new Packet250CustomPayload();
|
||||
pkt.field_73630_a = "REGISTER";
|
||||
pkt.field_73629_c = getPacketRegistry();
|
||||
pkt.field_73629_c = getPacketRegistry(player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT);
|
||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||
manager.func_74429_a(pkt);
|
||||
}
|
||||
@@ -198,12 +243,10 @@ public class NetworkRegistry
|
||||
|
||||
private void handlePacket(Packet250CustomPayload packet, NetworkManager network, Player player)
|
||||
{
|
||||
if (activeChannels.containsEntry(player, packet.field_73630_a))
|
||||
String channel = packet.field_73630_a;
|
||||
for (IPacketHandler handler : Iterables.concat(universalPacketHandlers.get(channel), player instanceof EntityPlayerMP ? serverPacketHandlers.get(channel) : clientPacketHandlers.get(channel)))
|
||||
{
|
||||
for (IPacketHandler handler : packetHandlers.get(packet.field_73630_a))
|
||||
{
|
||||
handler.onPacketData(network, packet, player);
|
||||
}
|
||||
handler.onPacketData(network, packet, player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +280,11 @@ public class NetworkRegistry
|
||||
public void registerGuiHandler(Object mod, IGuiHandler handler)
|
||||
{
|
||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
||||
if (mc == null)
|
||||
{
|
||||
mc = Loader.instance().activeModContainer();
|
||||
FMLLog.log(Level.WARNING, "Mod %s attempted to register a gui network handler during a construction phase", mc.getModId());
|
||||
}
|
||||
NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler(mc);
|
||||
if (nmh == null)
|
||||
{
|
||||
@@ -276,4 +324,35 @@ public class NetworkRegistry
|
||||
IGuiHandler handler = clientGuiHandlers.get(mc);
|
||||
FMLCommonHandler.instance().showGuiScreen(handler.getClientGuiElement(modGuiId, player, world, x, y, z));
|
||||
}
|
||||
public Packet3Chat handleChat(NetHandler handler, Packet3Chat chat)
|
||||
{
|
||||
Side s = Side.CLIENT;
|
||||
if (handler instanceof NetServerHandler)
|
||||
{
|
||||
s = Side.SERVER;
|
||||
}
|
||||
for (IChatListener listener : chatListeners)
|
||||
{
|
||||
chat = s.isClient() ? listener.clientChat(handler, chat) : listener.serverChat(handler, chat);
|
||||
}
|
||||
|
||||
return chat;
|
||||
}
|
||||
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler((int)mapData.field_73438_a);
|
||||
if (nmh == null)
|
||||
{
|
||||
FMLLog.info("Received a tiny packet for network id %d that is not recognised here", mapData.field_73438_a);
|
||||
return;
|
||||
}
|
||||
if (nmh.hasTinyPacketHandler())
|
||||
{
|
||||
nmh.getTinyPacketHandler().handle(handler, mapData);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.info("Received a tiny packet for a network mod that does not accept tiny packets %s", nmh.getContainer().getModId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
public class OpenGuiPacket extends FMLPacket
|
||||
{
|
||||
private int windowId;
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
/**
|
||||
* A simple utility class to send packet 250 packets around the place
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class PacketDispatcher
|
||||
{
|
||||
public static Packet250CustomPayload getPacket(String type, byte[] data)
|
||||
{
|
||||
return new Packet250CustomPayload(type, data);
|
||||
}
|
||||
|
||||
public static void sendPacketToServer(Packet packet)
|
||||
{
|
||||
FMLCommonHandler.instance().getSidedDelegate().sendPacket(packet);
|
||||
}
|
||||
|
||||
public static void sendPacketToPlayer(Packet packet, Player player)
|
||||
{
|
||||
if (player instanceof EntityPlayerMP)
|
||||
{
|
||||
((EntityPlayerMP)player).field_71135_a.func_72567_b(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPacketToAllAround(double X, double Y, double Z, double range, int dimensionId, Packet packet)
|
||||
{
|
||||
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
if (server != null)
|
||||
{
|
||||
server.func_71203_ab().func_72393_a(X, Y, Z, range, dimensionId, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Attempt to send packet to all around without a server instance available");
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPacketToAllInDimension(Packet packet, int dimId)
|
||||
{
|
||||
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
if (server != null)
|
||||
{
|
||||
server.func_71203_ab().func_72396_a(packet, dimId);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Attempt to send packet to all in dimension without a server instance available");
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPacketToAllPlayers(Packet packet)
|
||||
{
|
||||
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
if (server != null)
|
||||
{
|
||||
server.func_71203_ab().func_72384_a(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Attempt to send packet to all in dimension without a server instance available");
|
||||
}
|
||||
}
|
||||
|
||||
public static Packet131MapData getTinyPacket(Object mod, short tag, byte[] data)
|
||||
{
|
||||
NetworkModHandler nmh = FMLNetworkHandler.instance().findNetworkModHandler(mod);
|
||||
return new Packet131MapData((short) nmh.getNetworkId(), tag, data);
|
||||
}
|
||||
}
|
||||
@@ -4,40 +4,55 @@ import java.util.BitSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityList;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityTracker;
|
||||
import net.minecraft.src.EnumCreatureType;
|
||||
import net.minecraft.src.SpawnListEntry;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.primitives.UnsignedBytes;
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
|
||||
public class EntityRegistry
|
||||
{
|
||||
|
||||
public class EntityRegistration
|
||||
{
|
||||
private Class<? extends Entity> entityClass;
|
||||
private ModContainer container;
|
||||
private String entityName;
|
||||
private int modId;
|
||||
public EntityRegistration(ModContainer mc, Class<? extends Entity> entityClass, String entityName, int id)
|
||||
private int trackingRange;
|
||||
private int updateFrequency;
|
||||
private boolean sendsVelocityUpdates;
|
||||
private Function<EntitySpawnPacket, Entity> customSpawnCallback;
|
||||
private boolean usesVanillaSpawning;
|
||||
public EntityRegistration(ModContainer mc, Class<? extends Entity> entityClass, String entityName, int id, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates)
|
||||
{
|
||||
this.container = mc;
|
||||
this.entityClass = entityClass;
|
||||
this.entityName = entityName;
|
||||
this.modId = id;
|
||||
this.trackingRange = trackingRange;
|
||||
this.updateFrequency = updateFrequency;
|
||||
this.sendsVelocityUpdates = sendsVelocityUpdates;
|
||||
}
|
||||
public Class<? extends Entity> getEntityClass()
|
||||
{
|
||||
@@ -55,41 +70,94 @@ public class EntityRegistry
|
||||
{
|
||||
return modId;
|
||||
}
|
||||
public int getTrackingRange()
|
||||
{
|
||||
return trackingRange;
|
||||
}
|
||||
public int getUpdateFrequency()
|
||||
{
|
||||
return updateFrequency;
|
||||
}
|
||||
public boolean sendsVelocityUpdates()
|
||||
{
|
||||
return sendsVelocityUpdates;
|
||||
}
|
||||
|
||||
public boolean usesVanillaSpawning()
|
||||
{
|
||||
return usesVanillaSpawning;
|
||||
}
|
||||
public boolean hasCustomSpawning()
|
||||
{
|
||||
return customSpawnCallback != null;
|
||||
}
|
||||
public Entity doCustomSpawning(EntitySpawnPacket packet) throws Exception
|
||||
{
|
||||
return customSpawnCallback.apply(packet);
|
||||
}
|
||||
public void setCustomSpawning(Function<EntitySpawnPacket, Entity> callable, boolean usesVanillaSpawning)
|
||||
{
|
||||
this.customSpawnCallback = callable;
|
||||
this.usesVanillaSpawning = usesVanillaSpawning;
|
||||
}
|
||||
}
|
||||
|
||||
private static final EntityRegistry INSTANCE = new EntityRegistry();
|
||||
|
||||
private BitSet availableIndicies;
|
||||
private ListMultimap<ModContainer, EntityRegistration> entityRegistrations = ArrayListMultimap.create();
|
||||
private BiMap<String,ModContainer> entityNames = HashBiMap.create();
|
||||
private Map<String,ModContainer> entityNames = Maps.newHashMap();
|
||||
private BiMap<Class<? extends Entity>, EntityRegistration> entityClassRegistrations = HashBiMap.create();
|
||||
public static EntityRegistry instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
private EntityRegistry()
|
||||
{
|
||||
availableIndicies = new BitSet(256);
|
||||
availableIndicies.set(0,255);
|
||||
availableIndicies.set(1,255);
|
||||
for (Object id : EntityList.field_75623_d.keySet())
|
||||
{
|
||||
availableIndicies.clear((Integer)id);
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerModEntity(Class<? extends Entity> entityClass, String entityName, int id, Object mod)
|
||||
|
||||
/**
|
||||
* Register the mod entity type with FML
|
||||
|
||||
* @param entityClass The entity class
|
||||
* @param entityName A unique name for the entity
|
||||
* @param id A mod specific ID for the entity
|
||||
* @param mod The mod
|
||||
* @param trackingRange The range at which MC will send tracking updates
|
||||
* @param updateFrequency The frequency of tracking updates
|
||||
* @param sendsVelocityUpdates Whether to send velocity information packets as well
|
||||
*/
|
||||
public static void registerModEntity(Class<? extends Entity> entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates)
|
||||
{
|
||||
instance().doModEntityRegistration(entityClass, entityName, id, mod);
|
||||
instance().doModEntityRegistration(entityClass, entityName, id, mod, trackingRange, updateFrequency, sendsVelocityUpdates);
|
||||
}
|
||||
private void doModEntityRegistration(Class<? extends Entity> entityClass, String entityName, int id, Object mod)
|
||||
|
||||
private void doModEntityRegistration(Class<? extends Entity> entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates)
|
||||
{
|
||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
||||
EntityRegistration er = new EntityRegistration(mc, entityClass, entityName, id);
|
||||
EntityRegistration er = new EntityRegistration(mc, entityClass, entityName, id, trackingRange, updateFrequency, sendsVelocityUpdates);
|
||||
try
|
||||
{
|
||||
entityClassRegistrations.put(entityClass, er);
|
||||
entityNames.put(entityName, mc);
|
||||
if (!EntityList.field_75626_c.containsKey(entityClass))
|
||||
{
|
||||
String entityModName = String.format("%s.%s", mc.getModId(), entityName);
|
||||
EntityList.field_75626_c.put(entityClass, entityModName);
|
||||
EntityList.field_75625_b.put(entityModName, entityClass);
|
||||
FMLLog.finest("Automatically registered mod %s entity %s as %s", mc.getModId(), entityName, entityModName);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Skipping automatic mod %s entity registration for already registered class %s", mc.getModId(), entityClass.getName());
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
@@ -101,21 +169,73 @@ public class EntityRegistry
|
||||
|
||||
public static void registerGlobalEntityID(Class <? extends Entity > entityClass, String entityName, int id)
|
||||
{
|
||||
instance().validateAndClaimId(id);
|
||||
if (EntityList.field_75626_c.containsKey(entityClass))
|
||||
{
|
||||
ModContainer activeModContainer = Loader.instance().activeModContainer();
|
||||
String modId = "unknown";
|
||||
if (activeModContainer != null)
|
||||
{
|
||||
modId = activeModContainer.getModId();
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("There is a rogue mod failing to register entities from outside the context of mod loading. This is incredibly dangerous and should be stopped.");
|
||||
}
|
||||
FMLLog.warning("The mod %s tried to register the entity class %s which was already registered - if you wish to override default naming for FML mod entities, register it here first", modId, entityClass);
|
||||
return;
|
||||
}
|
||||
id = instance().validateAndClaimId(id);
|
||||
EntityList.func_75618_a(entityClass, entityName, id);
|
||||
}
|
||||
|
||||
private void validateAndClaimId(int id)
|
||||
private int validateAndClaimId(int id)
|
||||
{
|
||||
if (!availableIndicies.get(id))
|
||||
// workaround for broken ML
|
||||
int realId = id;
|
||||
if (id < Byte.MIN_VALUE)
|
||||
{
|
||||
throw new RuntimeException(String.format("Unable to claim entity id %d", id));
|
||||
FMLLog.warning("Compensating for modloader out of range compensation by mod : entityId %d for mod %s is now %d", id, Loader.instance().activeModContainer().getModId(), realId);
|
||||
realId += 3000;
|
||||
}
|
||||
availableIndicies.clear(id);
|
||||
|
||||
if (realId < 0)
|
||||
{
|
||||
realId += Byte.MAX_VALUE;
|
||||
}
|
||||
try
|
||||
{
|
||||
UnsignedBytes.checkedCast(realId);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "The entity ID %d for mod %s is not an unsigned byte and may not work", id, Loader.instance().activeModContainer().getModId());
|
||||
}
|
||||
|
||||
if (!availableIndicies.get(realId))
|
||||
{
|
||||
FMLLog.severe("The mod %s has attempted to register an entity ID %d which is already reserved. This could cause severe problems", Loader.instance().activeModContainer().getModId(), id);
|
||||
}
|
||||
availableIndicies.clear(realId);
|
||||
return realId;
|
||||
}
|
||||
|
||||
public static void registerGlobalEntityID(Class <? extends Entity > entityClass, String entityName, int id, int backgroundEggColour, int foregroundEggColour)
|
||||
{
|
||||
if (EntityList.field_75626_c.containsKey(entityClass))
|
||||
{
|
||||
ModContainer activeModContainer = Loader.instance().activeModContainer();
|
||||
String modId = "unknown";
|
||||
if (activeModContainer != null)
|
||||
{
|
||||
modId = activeModContainer.getModId();
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("There is a rogue mod failing to register entities from outside the context of mod loading. This is incredibly dangerous and should be stopped.");
|
||||
}
|
||||
FMLLog.warning("The mod %s tried to register the entity class %s which was already registered - if you wish to override default naming for FML mod entities, register it here first", modId, entityClass);
|
||||
return;
|
||||
}
|
||||
instance().validateAndClaimId(id);
|
||||
EntityList.func_75614_a(entityClass, entityName, id, backgroundEggColour, foregroundEggColour);
|
||||
}
|
||||
@@ -126,7 +246,7 @@ public class EntityRegistry
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SpawnListEntry> spawns = biome.func_76747_a(typeOfCreature);
|
||||
|
||||
|
||||
for (SpawnListEntry entry : spawns)
|
||||
{
|
||||
//Adjusting an existing spawn entry
|
||||
@@ -138,7 +258,7 @@ public class EntityRegistry
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
spawns.add(new SpawnListEntry(entityClass, weightedProb, min, max));
|
||||
}
|
||||
}
|
||||
@@ -146,7 +266,7 @@ public class EntityRegistry
|
||||
public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
Class <? extends Entity > entityClazz = (Class<? extends Entity>) EntityList.field_75625_b.get(entityName);
|
||||
|
||||
|
||||
if (EntityLiving.class.isAssignableFrom(entityClazz))
|
||||
{
|
||||
addSpawn((Class <? extends EntityLiving >) entityClazz, weightedProb, min, max, spawnList, biomes);
|
||||
@@ -159,7 +279,7 @@ public class EntityRegistry
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<SpawnListEntry> spawns = biome.func_76747_a(typeOfCreature).iterator();
|
||||
|
||||
|
||||
while (spawns.hasNext())
|
||||
{
|
||||
SpawnListEntry entry = spawns.next();
|
||||
@@ -174,7 +294,7 @@ public class EntityRegistry
|
||||
public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
Class <? extends Entity > entityClazz = (Class<? extends Entity>) EntityList.field_75625_b.get(entityName);
|
||||
|
||||
|
||||
if (EntityLiving.class.isAssignableFrom(entityClazz))
|
||||
{
|
||||
removeSpawn((Class <? extends EntityLiving >) entityClazz, spawnList, biomes);
|
||||
@@ -194,7 +314,7 @@ public class EntityRegistry
|
||||
public EntityRegistration lookupModSpawn(Class<? extends Entity> clazz, boolean keepLooking)
|
||||
{
|
||||
Class<?> localClazz = clazz;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
EntityRegistration er = entityClassRegistrations.get(localClazz);
|
||||
@@ -206,7 +326,7 @@ public class EntityRegistry
|
||||
keepLooking = (!Object.class.equals(localClazz));
|
||||
}
|
||||
while (keepLooking);
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -222,4 +342,40 @@ public class EntityRegistry
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean tryTrackingEntity(EntityTracker entityTracker, Entity entity)
|
||||
{
|
||||
|
||||
EntityRegistration er = lookupModSpawn(entity.getClass(), true);
|
||||
if (er != null)
|
||||
{
|
||||
entityTracker.func_72785_a(entity, er.getTrackingRange(), er.getUpdateFrequency(), er.sendsVelocityUpdates());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* DO NOT USE THIS METHOD
|
||||
*
|
||||
* @param entityClass
|
||||
* @param entityTypeId
|
||||
* @param updateRange
|
||||
* @param updateInterval
|
||||
* @param sendVelocityInfo
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static EntityRegistration registerModLoaderEntity(Object mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval,
|
||||
boolean sendVelocityInfo)
|
||||
{
|
||||
String entityName = (String) EntityList.field_75626_c.get(entityClass);
|
||||
if (entityName == null)
|
||||
{
|
||||
throw new IllegalArgumentException(String.format("The ModLoader mod %s has tried to register an entity tracker for a non-existent entity type %s", Loader.instance().activeModContainer().getModId(), entityClass.getCanonicalName()));
|
||||
}
|
||||
instance().doModEntityRegistration(entityClass, entityName, entityTypeId, mod, updateRange, updateInterval, sendVelocityInfo);
|
||||
return instance().entityClassRegistrations.get(entityClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.registry;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
@@ -8,6 +7,7 @@ import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.CraftingManager;
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.FurnaceRecipes;
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
@@ -27,9 +27,14 @@ import com.google.common.collect.Sets;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ICraftingHandler;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.IDispenserHandler;
|
||||
import cpw.mods.fml.common.IFuelHandler;
|
||||
import cpw.mods.fml.common.IPickupNotifier;
|
||||
import cpw.mods.fml.common.IPlayerTracker;
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.Mod.Block;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
@@ -40,13 +45,30 @@ public class GameRegistry
|
||||
private static Set<IWorldGenerator> worldGenerators = Sets.newHashSet();
|
||||
private static List<IFuelHandler> fuelHandlers = Lists.newArrayList();
|
||||
private static List<ICraftingHandler> craftingHandlers = Lists.newArrayList();
|
||||
private static List<IDispenseHandler> dispenserHandlers = Lists.newArrayList();
|
||||
private static List<IDispenserHandler> dispenserHandlers = Lists.newArrayList();
|
||||
private static List<IPickupNotifier> pickupHandlers = Lists.newArrayList();
|
||||
private static List<IPlayerTracker> playerTrackers = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* Register a world generator - something that inserts new block types into the world
|
||||
*
|
||||
* @param generator
|
||||
*/
|
||||
public static void registerWorldGenerator(IWorldGenerator generator)
|
||||
{
|
||||
worldGenerators.add(generator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback hook for world gen - if your mod wishes to add extra mod related generation to the world
|
||||
* call this
|
||||
*
|
||||
* @param chunkX
|
||||
* @param chunkZ
|
||||
* @param world
|
||||
* @param chunkGenerator
|
||||
* @param chunkProvider
|
||||
*/
|
||||
public static void generateWorld(int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
|
||||
{
|
||||
long worldSeed = world.func_72905_C();
|
||||
@@ -61,17 +83,48 @@ public class GameRegistry
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerDispenserHandler(IDispenseHandler handler)
|
||||
public static void registerDispenserHandler(IDispenserHandler handler)
|
||||
{
|
||||
dispenserHandlers.add(handler);
|
||||
}
|
||||
|
||||
|
||||
public static int tryDispense(World world, double x, double y, double z, int xVelocity, int zVelocity, ItemStack item)
|
||||
/**
|
||||
* Register a handler for dispensers
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
@Deprecated
|
||||
public static void registerDispenserHandler(final IDispenseHandler handler)
|
||||
{
|
||||
for (IDispenseHandler handler : dispenserHandlers)
|
||||
registerDispenserHandler(new IDispenserHandler()
|
||||
{
|
||||
int dispensed = handler.dispense(x, y, z, xVelocity, zVelocity, world, item);
|
||||
|
||||
@Override
|
||||
public int dispense(int x, int y, int z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ)
|
||||
{
|
||||
return handler.dispense(x, y, z, xVelocity, zVelocity, world, item, random, entX, entY, entZ);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback hook for dispenser activities - if you add a block and want mods to be able
|
||||
* to extend their dispenser related activities to it call this
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVelocity
|
||||
* @param zVelocity
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public static int tryDispense(World world, int x, int y, int z, int xVelocity, int zVelocity, ItemStack item, Random random, double entX, double entY, double entZ)
|
||||
{
|
||||
for (IDispenserHandler handler : dispenserHandlers)
|
||||
{
|
||||
int dispensed = handler.dispense(x, y, z, xVelocity, zVelocity, world, item, random, entX, entY, entZ);
|
||||
if (dispensed>-1)
|
||||
{
|
||||
return dispensed;
|
||||
@@ -79,6 +132,14 @@ public class GameRegistry
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* Internal method for creating an @Block instance
|
||||
* @param container
|
||||
* @param type
|
||||
* @param annotation
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Object buildBlock(ModContainer container, Class<?> type, Block annotation) throws Exception
|
||||
{
|
||||
Object o = type.getConstructor(int.class).newInstance(findSpareBlockId());
|
||||
@@ -86,18 +147,37 @@ public class GameRegistry
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private and not yet working properly
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static int findSpareBlockId()
|
||||
{
|
||||
return BlockTracker.nextBlockId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a block with the world
|
||||
*
|
||||
*/
|
||||
public static void registerBlock(net.minecraft.src.Block block)
|
||||
{
|
||||
registerBlock(block, ItemBlock.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a block with the world, with the specified item class
|
||||
*
|
||||
* @param block
|
||||
* @param itemclass
|
||||
*/
|
||||
public static void registerBlock(net.minecraft.src.Block block, Class<? extends ItemBlock> itemclass)
|
||||
{
|
||||
if (Loader.instance().isInState(LoaderState.CONSTRUCTING))
|
||||
{
|
||||
FMLLog.warning("The mod %s is attempting to register a block whilst it it being constructed. This is bad modding practice - please use a proper mod lifecycle event.", Loader.instance().activeModContainer());
|
||||
}
|
||||
try
|
||||
{
|
||||
assert block != null : "registerBlock: block cannot be null";
|
||||
@@ -110,7 +190,7 @@ public class GameRegistry
|
||||
FMLLog.log(Level.SEVERE, e, "Caught an exception during block registration");
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
BlockTracker.reserveBlockId(block.field_71990_ca);
|
||||
blockRegistry.put(Loader.instance().activeModContainer(), (BlockProxy) block);
|
||||
}
|
||||
|
||||
public static void addRecipe(ItemStack output, Object... params)
|
||||
@@ -183,4 +263,45 @@ public class GameRegistry
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerPickupHandler(IPickupNotifier handler)
|
||||
{
|
||||
pickupHandlers.add(handler);
|
||||
}
|
||||
|
||||
public static void onPickupNotification(EntityPlayer player, EntityItem item)
|
||||
{
|
||||
for (IPickupNotifier notify : pickupHandlers)
|
||||
{
|
||||
notify.notifyPickup(item, player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerPlayerTracker(IPlayerTracker tracker)
|
||||
{
|
||||
playerTrackers.add(tracker);
|
||||
}
|
||||
|
||||
public static void onPlayerLogin(EntityPlayer player)
|
||||
{
|
||||
for(IPlayerTracker tracker : playerTrackers)
|
||||
tracker.onPlayerLogin(player);
|
||||
}
|
||||
|
||||
public static void onPlayerLogout(EntityPlayer player)
|
||||
{
|
||||
for(IPlayerTracker tracker : playerTrackers)
|
||||
tracker.onPlayerLogout(player);
|
||||
}
|
||||
|
||||
public static void onPlayerChangedDimension(EntityPlayer player)
|
||||
{
|
||||
for(IPlayerTracker tracker : playerTrackers)
|
||||
tracker.onPlayerChangedDimension(player);
|
||||
}
|
||||
|
||||
public static void onPlayerRespawn(EntityPlayer player)
|
||||
{
|
||||
for(IPlayerTracker tracker : playerTrackers)
|
||||
tracker.onPlayerRespawn(player);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 191 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user