Compare commits

...
101 Commits
Author SHA1 Message Date
Christian 3f15cd54c2 Functional client @ 1.6.1 2013-06-30 21:02:23 -04:00
Christian 12c928c538 Tweak commands patch 2013-06-30 19:33:47 -04:00
Christian 7406b38d8a 1.6.1 2013-06-30 16:50:30 -04:00
Christian ef646d3146 Merge branch '16launch' 2013-06-30 13:20:46 -04:00
Christian 18371bd8c9 Some fixes for updated mcp code 2013-06-30 13:17:20 -04:00
Christian e35e4b16ff More fixups 2013-06-30 09:04:50 -04:00
LexManos 3711da9c45 Another typo 2013-06-30 03:55:26 -07:00
LexManos 6a318ddb78 Fix typo in new packages. 2013-06-30 01:01:55 -07:00
LexManos 2766f9a293 Push conf folder for 1.6, Relied heavily on a yet-unreleased version of MCP. 2013-06-29 22:48:24 -07:00
Christian 2e3f2461fa More fixes, binpatching works 2013-06-29 15:16:18 -04:00
Christian 95f7345ff7 First draft of 1.6 update 2013-06-29 13:33:14 -04:00
Christian bc02f3e67b New mappings for marker 2013-06-29 09:20:59 -04:00
Christian 8db42c44bf Tweak missing mapping 2013-06-29 09:20:59 -04:00
LexManos 404e6f1cc0 Add support for alternative maven servers in libraries.
Also download sources for public libraries, and atach them in eclipse. DOCUMENTATION!! YAYA!
2013-06-29 02:54:29 -07:00
LexManos 5741f669d5 Base GenDiff off deobf data's class list instead of the merged jar. Add option to delete target files that generate patches. 2013-06-29 01:40:01 -07:00
LexManos 6a67149b16 Add Clean Server/Client launcher. Update Start.java to new Main class and login system. 2013-06-28 22:12:07 -07:00
LexManos c8d934bafd Update eclipse projects for new libraries dependancies, and update packages for new 1.6 classes. 2013-06-28 20:31:02 -07:00
LexManos 075e240303 Add suggestions output if it can. 2013-06-27 22:58:00 -07:00
LexManos d00665ee65 Fixed update_packages.py for new folder strcture. 2013-06-27 22:30:40 -07:00
LexManos ebb74a5f30 Add missing argument 2013-06-27 22:29:10 -07:00
LexManos 5b0117ec76 Re-wrote/orginized a lot of fml.py. Almost everything is re-written/moved.
This is done in preperation for MCP to roll out SpecialSource support and the new 1.6 structure.
Also done for my sanity while reading through the code.

Intruduced a new function. If there is a 'mcp_data' folder in the FML folder, it will be copied to the MCP work directory after MCP is extracted.
It DOES overwrite anything that already exists.
This is intended for places like BuildServer to place libraries/assets to prevent them from needing to be downloaded every version.

Introduced a dev-env json. Need to write the eclipse workspace references to the new libraries.
Out custom json includes asm and legacylauncher.

Added proper OptionParsing to decompile.py
2013-06-27 20:48:52 -07:00
Christian e06d9d0fbc Add a simple property annotation system for mods. 2013-06-27 08:40:31 -04:00
Christian ab91647546 Changed to the EventHandler annotation universally, documentation and stuff. 2013-06-26 14:52:56 -04:00
Christian b236a4a4db Fixes, so it builds again.. 2013-06-24 16:30:18 -04:00
Christian a480a83a98 Ignore binpatch 2013-06-24 16:03:54 -04:00
LexManos 3a9f123a16 Add filter support for MCPMerger, and filter out libraries from the server's 'fat jar'. 2013-06-23 23:06:25 -07:00
LexManos 8d27fb0692 Upgraded minecraft downloader to work with new launcher's asset/library system
New parameter:
  --no-assets: Disables the downloading of minecraft's asset tree, recomended that build servers supply this flag to prevent downloading of useless data.
2013-06-20 16:23:15 -07:00
Christian d369fe1c25 No more debug please 2013-06-15 01:11:29 -04:00
Christian 98b71f2dd4 Fix build script. Add a sample JSON file. You'll need the newest Launcher code to run this. 2013-06-14 21:00:15 -04:00
Christian fef0f6422d More fixups for new launcher model 2013-06-14 20:45:52 -04:00
Christian 2eb81ac88b Merge in binpatch and use launcher 2013-06-14 17:21:49 -04:00
Christian e02a91f008 More tweaks 2013-06-14 09:32:51 -04:00
Christian ced1b95155 Server side tested and working. Setup is complex atm. That will change. 2013-06-13 09:57:55 -04:00
Christian 8f910dfa5d First cut of runtime binary patching. Needs some work to actually test it in a real scenario.. 2013-06-12 08:53:10 -04:00
Christian 05a854cd2a Small tweaks to the mcp data. Nothing major.. 2013-06-11 14:47:23 -04:00
Christian 22738de028 Attempt to properly fix deadlock if the internal server derps. It should never hang now. Damn you fast computer.. 2013-06-11 14:41:19 -04:00
Christian cd0466395a Fix sysout with trailing messages after a newline 2013-06-06 11:52:15 -04:00
Christian 24c4056651 Add in an optional modid identifier for @SidedProxy. It's main use is when both scala and java @Mods reside in the
same package, and you want the @SidedProxy behaviour for a specific @Mod language type. In general it should not be needed otherwise.
2013-06-06 10:05:34 -04:00
Christian 59fe905695 Don't continue trying to send events to mods that depend on errored mods. 2013-06-04 13:59:04 -04:00
Christian 6f3da97365 Don't throw an exception if the scala adapter find a java proxy. I may add some distinguishers to @SidedProxy so you know which mod it's for. 2013-06-04 12:51:46 -04:00
Christian edc1fb24e2 Send the "suspect list", and print the suspect versions 2013-05-27 11:03:23 -04:00
Christian f1d68ed4c8 Throw the sorting exception 2013-05-27 10:46:22 -04:00
Christian ac97370f94 Add in a pretty sorting error screen 2013-05-27 10:28:00 -04:00
Christian 82e9de8641 More tweaks to the mod sorting code 2013-05-27 10:09:51 -04:00
Christian 843a13c1ab Try and clean up cycle detection output a bit 2013-05-27 09:25:50 -04:00
Christian 3bf50c4bbe Fix server side derp with Forge network packet handler 2013-05-21 11:01:50 -04:00
Christian 4922e90d81 Separate network mod config from setup. Allows for Forge Packet Handler nicety 2013-05-20 21:40:42 -04:00
cpw a3a920437f Merge pull request #230 from fnuecke/master
Alternative setter logic for @SidedProxy in Scala classes/mods.
2013-05-11 15:34:37 -07:00
LexManos 787c0c4a6a Don't spit error on LWJGL not supporting 4.3 just warning. 2013-05-11 10:55:39 -07:00
Florian Nücke 8517a824e5 Merge declaration and initialization of a variable. 2013-05-08 20:16:15 +02:00
Florian Nücke 2cca7aa759 Some more Scala @SidedProxy adjustments. Now properly supporting pure singletons, i.e.
object C {
  @SidedProxy(...)
  var proxy: P = null
}
Removed fallback, as all such singletons are properly handled by the new code now, and class implementations fall back to the code also used for plain Java mods.
2013-05-08 19:04:35 +02:00
Florian Nücke 23b070c7d0 Alternative @SidedProxy setter for Scala. 2013-05-08 05:36:28 +02:00
LexManos 49111e9c5c Add version detection to astyle and print error if it doesnt detect version 2.0+
Also fixed astyle's config for max-instatement-indent that sometimes caused crashes with certian versions of astyle.
2013-05-03 14:26:27 -07:00
cpw c0cca7f41d Merge pull request #227 from CovertJaguar/patch-1
Improved Entity Spawn Error
2013-04-29 22:10:53 -07:00
CovertJaguar 99bb50d8f8 Improved Entity Spawn Error 2013-04-29 20:41:20 -07:00
LexManos 00f00b17bf Fix scalac detection to actually use the located command instead of defaulting to 'scalac' 2013-04-28 16:35:23 -07:00
LexManos 62fdbad74c Update MCP's md5 for the fixed srg files. 2013-04-28 12:33:42 -07:00
Christian f0bba74a47 Update for minecraft 1.5.2 2013-04-27 01:24:06 -04:00
Christian cf9b5b445b Don't leave scala running in interactive mode. 2013-04-23 22:56:18 -04:00
LexManos aa200923f0 Fix patch derp. 2013-04-23 19:47:43 -07:00
Christian ddadf93ca1 Fix when an old scalac is present on the system to not fail the build 2013-04-23 22:43:51 -04:00
Christian 781c681216 Some fixups for scala compilation in MCP. Scala should now be compilable and reobfuscatable with srgnames in MCP. 2013-04-23 07:40:49 -04:00
Christian cfda7fc738 Fix URL for MCP 2013-04-23 07:22:25 -04:00
Christian 58ba24add2 Fix possible NPEs in GameData 2013-04-22 21:14:34 -04:00
Christian dcf069ca52 Attempt to reduce lines on the screen for id mismatch. Hopefully prevents game crashes. 2013-04-22 21:14:34 -04:00
cpw c3fda11d10 Merge pull request #225 from MarcinSc/master
Suggested fix for issue 221
2013-04-21 11:32:51 -07:00
Marcin Sciesinski 11ac46daeb Fixing the GameRegistry. Now it is possible to register a Block with a BlockItem using following code:
MyBlock myBlock = new MyBlock();
GameRegistry.registerBlock(myBlock, MyBlockItem.class, "myBlock");
where MyBlockItem class has one constructor with signature:
public MyBlockItem(int id, Block block)
2013-04-21 19:01:18 +01:00
Christian 2dcabe0123 Add a to string to fmlmodcontainer: should mean less derpy cyclic dependency data 2013-04-21 13:58:18 -04:00
cpw 42f1d87955 Merge pull request #224 from Glought/master
Fix for  Issue #223
2013-04-21 08:13:54 -07:00
Glought 334a76de75 Update FMLDeobfuscatingRemapper.java
Fixes a "Type mismath:cannot convert from element type Object to FieldNode" error at line 176.
2013-04-21 05:09:19 -07:00
Christian 677a6e578e Fix scala supporting SidedProxy. It should work now. 2013-04-20 23:31:22 -04:00
Christian a3b5eaacfd Fix a small modloader compatibility derp: closes #222 2013-04-20 22:55:56 -04:00
Christian b3d4ea05ec Fix possible NPE in findItemStack, closes #218 2013-04-17 07:55:33 -04:00
Christian 8f35adca7a Use more expressive language when a version specifier is a simple unbounded above condition 2013-04-16 13:46:55 -04:00
Christian 394f424185 Fix to output versions in crash logs 2013-04-16 13:46:55 -04:00
cpw ada52078c7 Merge pull request #216 from agaricusb/add-srgname
Add srgname to registerTileEntityWithAlternatives
2013-04-15 15:50:47 -07:00
Christian 0daf1a6df4 Merge branch 'agaricusb-fix-deobf-field' 2013-04-15 17:31:09 -04:00
Christian edffd04ed2 Add in some caching of the read field descriptions for efficiency 2013-04-15 17:30:35 -04:00
Agaricus 7aea09f4ca Add type info to properly deobfuscate overloaded fields. Fixes #210. 2013-04-14 16:54:11 -07:00
Agaricus 5673c1dd29 Add srgname to registerTileEntityWithAlternatives 2013-04-14 14:11:37 -07:00
Christian 1774e2bf30 MCP names update 2013-04-10 12:28:20 -04:00
LexManos 4836b3272a Re-worked the Texture patches, optifine helper function, and re-added support for dynamically rotating the texture for mod authors who do things horribly wrong. 2013-04-09 20:06:41 -07:00
Christian a31607ae7d Fix compilation derp, and clean up rotation helper. 2013-04-09 21:20:31 -04:00
Christian 57ad221cc6 And add the patches *sigh* 2013-04-09 20:26:10 -04:00
Christian 00c7883088 Very significant improvement in performance by using glSubImage to upload data. Inspired by frequent complaints about performance of hires
texture packs. They probably still need a beefy system but should work. Hopefully I can figure out why the subImage GL side copy isn't working
properly for an even more significant speed boost. But this gets things started.
2013-04-09 20:15:14 -04:00
LexManos 1de89525cc Fixed issue with instalation when java/javac commands had quotes. 2013-04-05 10:26:33 -07:00
LexManos 704a70902f Sanitize input to isRemappedClass to use '/' as a package seperator like the srg files. 2013-04-04 23:30:10 -07:00
LexManos 570faeb790 Added the ability to save transformed classes to disc for debugging. 2013-04-04 10:32:48 -07:00
Christian 8b8837c9ff Fix NPE when branding isn't present 2013-03-31 10:01:46 -04:00
Christian eff464cf0e And the core patches for that 2013-03-30 12:13:53 -04:00
Christian 26ccb9106e Change snooper/crash report brand handling. fmlbranding now loads another string! 2013-03-30 12:12:54 -04:00
Christian 0d84487412 Fix up derp in access transformer 2013-03-27 19:23:10 -04:00
Christian 2bc6a0666f Attempt to make any "default package" class public. This might fix problems with certain modloader mods that ship changes to vanilla classes. 2013-03-27 16:54:26 -04:00
Christian 82bc9f1b35 Add some information, and a log message letting you know it worked 2013-03-23 16:01:20 -04:00
Christian d73ac867df Add a mechanism to dump the registry- useful for mod developers. 2013-03-23 15:39:34 -04:00
Christian ede93d438f Validate supplied stack size 2013-03-23 15:10:13 -04:00
Christian 5e1949eb0e Clone the itemstack, and allow for passing in a stacksize 2013-03-23 14:58:25 -04:00
Christian 2d368c4c2e Itemstacks in the GameRegistry (manual registration by mods) 2013-03-23 14:48:57 -04:00
Christian d9db27275e Fix mismatch screen a bit. Should render more correctly now and
at least not be blank in a lot of circumstances..
2013-03-22 10:20:53 -04:00
cpw 591a25722b Merge pull request #208 from jrtc27/patch-1
Fixed FMLRelaunchLog's Newline Handling
2013-03-22 05:44:38 -07:00
James Clarke d1ff1967b5 Fixed FMLRelaunchLog's Newline Handling
System.out.println("\n") causes currentMessage to start with a newline character, which means idx will always be 0 from then on. Therefore if idx is 0 messages must still be logged, otherwise no more messages sent to stdout will be logged and they will just accumulate in currentMessage.
2013-03-22 09:19:39 +00:00
164 changed files with 39730 additions and 39007 deletions

No files matched your search

+3
View File
@@ -12,3 +12,6 @@ fmlbranding.properties
/mcp
/eclipse
/deobfuscation_data*.zip
/binpatch
/mcp_data/
/map_client.txt
+69
View File
@@ -0,0 +1,69 @@
{
"id": "FML152",
"time": "2013-03-20T12:00:00-04:00",
"releaseTime": "2013-03-20T12:00:00-04:00",
"type": "release",
"minecraftArguments": "${auth_player_name} ${auth_session} --gameDir ${game_directory} --assetsDir ${game_assets} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
"libraries": [
{
"name": "cpw.mods:fml:5.2"
},
{
"name": "net.minecraft:launchwrapper:1.3"
},
{
"name": "net.sf.jopt-simple:jopt-simple:4.5"
},
{
"name": "argo:argo:2.25_fixed"
},
{
"name": "org.ow2.asm:asm-all:4.1"
},
{
"name": "org.lwjgl.lwjgl:lwjgl:2.9.0"
},
{
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.0"
},
{
"name": "net.java.jinput:jinput:2.0.5"
},
{
"name": "org.bouncycastle:bcprov-jdk15on:1.47"
},
{
"name": "com.google.guava:guava:14.0"
},
{
"name": "net.java.jutils:jutils:1.0.0"
},
{
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.0",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows",
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
}
},
{
"name": "net.java.jinput:jinput-platform:2.0.5",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows",
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
}
}
],
"mainClass": "net.minecraft.launchwrapper.Launch"
}
+14
View File
@@ -9,6 +9,12 @@ included based on guidelines at
http://www.softwarefreedom.org/resources/2007/gpl-non-gpl-collaboration.html
with notices intact. The only change is a non-functional change of package name.
This software contains a partial repackaging of javaxdelta, a BSD licensed program for generating
binary differences and applying them, sourced from the subversion at http://sourceforge.net/projects/javaxdelta/
authored by genman, heikok, pivot.
The only changes are to replace some Trove collection types with standard Java collections, and repackaged.
=== MCP Data ===
This software includes data from the Minecraft Coder Pack (MCP), with kind permission
from them. The license to MCP data is not transitive - distribution of this data by
@@ -16,6 +22,14 @@ third parties requires independent licensing from the MCP team. This data is not
redistributable without permission from the MCP team.
=== Sharing ===
I grant permission for some parts of FML to be redistributed outside the terms of the LGPL, for the benefit of
the minecraft modding community. All contributions to these parts should be licensed under the same additional grant.
-- Runtime patcher --
License is granted to redistribute the runtime patcher code (common/cpw/mods/fml/patcher and subdirectories) under
any alternative open source license as classified by the OSI (http://opensource.org/licenses)
-- ASM transformers --
License is granted to redistribute the ASM transformer code (common/cpw/mods/fml/common/asm/ and subdirectories)
under any alternative open source license as classified by the OSI (http://opensource.org/licenses)
+135 -78
View File
@@ -15,8 +15,8 @@
<arg value="${mcp.home}" />
</exec>
<propertyfile file="fmlversion.properties">
<entry key="fmlbuild.build.number" type="int" value="${version.build}"/>
<entry key="fmlbuild.deobfuscation.hash" type="string" value="${deobf.checksum}"/>
<entry key="fmlbuild.build.number" type="int" value="${version.build}" />
<entry key="fmlbuild.deobfuscation.hash" type="string" value="${deobf.checksum}" />
</propertyfile>
</target>
@@ -30,15 +30,19 @@
<isset property="env.WORKSPACE" />
</condition>
<property name="fml.python.dir" location="${basedir}/python" />
<property name="fml.lzma.dir" location="${basedir}/lzmabin" />
<condition property="python.exe" value="${fml.python.dir}/python_fml" else="python">
<os family="Windows" />
</condition>
<condition property="mcp.exists">
<available file="${mcp.home}/runtime/commands.py"/>
<condition property="lzma.exe" value="${fml.lzma.dir}/xz.exe" else="xz">
<os family="Windows" />
</condition>
<condition property="mcp.exists">
<available file="${mcp.home}/runtime/commands.py" />
</condition>
<condition property="signature.exists">
<available file="${env.JENKINS_HOME}/fmlsigned.properties" />
</condition>
<condition property="signature.exists">
<available file="${env.JENKINS_HOME}/fmlsigned.properties"/>
</condition>
<property name="mcp.obfoutput" location="${mcp.home}/reobf" />
<property name="client.mcp.obfoutput" location="${mcp.obfoutput}/minecraft" />
<property name="mcp.srcdir" location="${mcp.home}/src" />
@@ -54,7 +58,7 @@
<condition property="version.build" value="${env.BUILD_NUMBER}" else="1">
<isset property="env.BUILD_NUMBER" />
</condition>
<available file="eclipse" property="eclipse.exists"/>
<available file="eclipse" property="eclipse.exists" />
</target>
<target name="makeversion" depends="buildenvsetup">
@@ -79,8 +83,11 @@
<target name="clean" depends="buildenvsetup,makeclean" if="mcp.exists">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${basedir}/decompile.py" />
<arg value="--mcp-dir" />
<arg value="${mcp.home}" />
<arg value="--fml-dir" />
<arg value="${basedir}" />
<arg value="--gen-conf" />
</exec>
</target>
@@ -89,19 +96,19 @@
<arg value="${mcp.home}/runtime/reobfuscate.py" />
</exec>
<fail message="Reobfuscation failed">
<condition>
<not>
<and>
<available file="${mcp.home}/temp/client.md5"/>
<available file="${mcp.home}/temp/client_reobf.md5"/>
</and>
</not>
</condition>
<condition>
<not>
<and>
<available file="${mcp.home}/temp/client.md5" />
<available file="${mcp.home}/temp/client_reobf.md5" />
</and>
</not>
</condition>
</fail>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${basedir}/generatechangedfilelist.py"/>
<arg value="${mcp.home}"/>
<arg value="${basedir}/difflist.txt"/>
<arg value="${basedir}/generatechangedfilelist.py" />
<arg value="${mcp.home}" />
<arg value="${basedir}/difflist.txt" />
</exec>
</target>
@@ -110,11 +117,11 @@
<arg value="${mcp.home}/runtime/recompile.py" />
</exec>
<fail message="Compilation failed">
<condition>
<not>
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
</not>
</condition>
<condition>
<not>
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class" />
</not>
</condition>
</fail>
</target>
@@ -132,7 +139,7 @@
<target name="merge-source" depends="buildenvsetup,merge-client,merge-common" />
<target name="build-universal" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion">
<target name="build-universal" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion,makebinpatches">
<condition property="universal.jarname" value="${modname}-universal-${version.minecraft}-${version}" else="${modname}-universal-${version.minecraft}-${version}-${version.branch}">
<equals arg1="${version.branch}" arg2="master" />
</condition>
@@ -140,19 +147,20 @@
<mkdir dir="${basedir}/target" />
<jar destfile="${basedir}/target/${universal.jarname}.zip" duplicate="preserve">
<manifest>
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
<attribute name="Class-Path" value="minecraft_server.jar"/>
<attribute name="Main-Class" value="cpw.mods.fml.relauncher.ServerLaunchWrapper" />
<attribute name="Class-Path" value="minecraft_server.jar:lib/guava-14.0-rc3.jar:lib/bcprov-jdk15on-148-src.zip:lib/asm-debug-all-4.1.jar:lib/scala-library.jar:lib/argo-3.2-src.jar" />
</manifest>
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" excludes="*.class"/>
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" excludes="*.class,net/minecraft/**/*.class" />
</jar>
<antcall target="signjar"/>
<zip update="true" destfile="${basedir}/target/${universal.jarname}.zip" >
<fileset dir="${client.mcp.obfoutput}" includes="*.class"/>
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
<antcall target="signjar" />
<zip update="true" destfile="${basedir}/target/${universal.jarname}.zip">
<fileset dir="${basedir}" includes="binpatches.pack.lzma,deobfuscation_data-${version.minecraft}.lzma"/>
<fileset dir="${client.mcp.obfoutput}" includes="*.class" />
<zipfileset dir="${basedir}" includes="fmlversion.properties" />
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" />
<zipfileset dir="${client.src.dir}" includes="mcp.png" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" />
<zipfileset dir="${client.src.dir}" includes="mcp.png" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt" />
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
<mappedresources>
<concat>
@@ -205,25 +213,31 @@
</target>
<target name="build-deobf-data" depends="makeversion">
<mkdir dir="build-tmp-deobf"/>
<mkdir dir="build-tmp-deobf" />
<copy todir="build-tmp-deobf">
<mappedresources>
<fileset dir="${mcp.home}/conf" includes="packaged.srg"/>
<globmapper from="packaged.srg" to="joined.srg"/>
<fileset dir="${mcp.home}/conf" includes="packaged.srg" />
<globmapper from="packaged.srg" to="deobfuscation_data-${version.minecraft}" />
</mappedresources>
</copy>
<touch millis="0" file="build-tmp-deobf/joined.srg"/>
<zip file="deobfuscation_data_${version.minecraft}.zip" encoding="UTF-8">
<fileset dir="build-tmp-deobf" includes="joined.srg"/>
</zip>
<checksum algorithm="SHA1" property="deobf.checksum" file="deobfuscation_data_${version.minecraft}.zip"/>
<antcall target="writeversion"/>
<exec executable="${lzma.exe}">
<arg line="--format=lzma"/>
<arg line="build-tmp-deobf/deobfuscation_data-${version.minecraft}"/>
<arg line="-v"/>
</exec>
<copy todir="${basedir}">
<fileset dir="build-tmp-deobf" includes="*.lzma" />
</copy>
<antcall target="writeversion" />
<delete dir="build-tmp-deobf" />
<zip destfile="deobfuscation_data-${version.minecraft}.jar" basedir="${basedir}">
<include name="deobfuscation_data-${version.minecraft}.lzma"/>
</zip>
</target>
<target name="build" depends="buildenvsetup,merge-client,merge-common,build-deobf-data,build-universal,build-source-pack" />
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build"/>
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build" />
<target name="patch" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${basedir}">
@@ -242,87 +256,91 @@
</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>
<antcall target="fmldecompile"/>
<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">
<fileset dir="${patch.mcp.srcdir}"/>
<fileset dir="${patch.mcp.srcdir}" />
</move>
<echo>Deleting old patch references at ${clean.mcp.srcdir}</echo>
<delete dir="${clean.mcp.srcdir}" failonerror="false"/>
<delete dir="${clean.mcp.srcdir}" failonerror="false" />
<echo>Creating new patch references at ${clean.mcp.srcdir}</echo>
<copy todir="${clean.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
<fileset dir="${mcp.srcdir}" />
</copy>
<antcall target="cleanargo"/>
<antcall target="patch"/>
<antcall target="cleanargo" />
<antcall target="patch" />
<echo>Creating clean patched references at ${patch.mcp.srcdir}</echo>
<copy todir="${patch.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
<fileset dir="${mcp.srcdir}" />
</copy>
<antcall target="writeversion"/>
<antcall target="makeeclipse"/>
<antcall target="writeversion" />
<antcall target="makeeclipse" />
<echo>Setup complete! You should now be able to open ${basedir}/eclipse as a workspace in eclipse and import/refresh the FML project</echo>
</target>
<target name="fmldecompile" depends="buildenvsetup,makeclean">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/decompile.py" />
<arg value="--mcp-dir" />
<arg value="${mcp.home}" />
<arg value="--fml-dir" />
<arg value="${basedir}" />
<arg value="--gen-conf" />
</exec>
</target>
<target name="jenkinsfmldecompile" depends="buildenvsetup,makeclean">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/decompile.py" />
<arg value="--mcp-dir" />
<arg value="${mcp.home}" />
<arg value="--fml-dir" />
<arg value="${basedir}" />
<arg value="-no_gen_conf" />
</exec>
</target>
<target name="repatch" depends="buildenvsetup,checkpatches">
<echo>Moving old patched sources at ${mcp.home}/src-work out of the way</echo>
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
<fileset dir="${patch.mcp.srcdir}"/>
<fileset dir="${patch.mcp.srcdir}" />
</move>
<delete dir="${mcp.srcdir}"/>
<delete dir="${mcp.srcdir}" />
<copy todir="${mcp.srcdir}">
<fileset dir="${clean.mcp.srcdir}"/>
<fileset dir="${clean.mcp.srcdir}" />
</copy>
<antcall target="cleanargo"/>
<antcall target="cleanargo" />
<antcall target="patch"/>
<antcall target="patch" />
<copy todir="${patch.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
<fileset dir="${mcp.srcdir}" />
</copy>
</target>
<target name="repatchclean" depends="buildenvsetup">
<delete dir="${mcp.srcdir}"/>
<delete dir="${mcp.srcdir}" />
<copy todir="${mcp.srcdir}">
<fileset dir="${clean.mcp.srcdir}"/>
<fileset dir="${clean.mcp.srcdir}" />
</copy>
<antcall target="cleanargo"/>
<antcall target="cleanargo" />
<antcall target="patch"/>
<antcall target="patch" />
</target>
<target name="cleanargo" depends="buildenvsetup">
<delete dir="${client.mcp.srcdir}/argo"/>
<delete dir="${client.mcp.srcdir}/org"/>
<delete dir="${client.mcp.srcdir}/argo" />
<delete dir="${client.mcp.srcdir}/org" />
</target>
<target name="checkpatches" depends="buildenvsetup">
<uptodate property="checkUptodate.uptodate">
<srcfiles dir="${patch.mcp.srcdir}" includes="**/*.java">
<present targetdir="${patch.src.dir}">
<globmapper from="*.java" to="*.java.patch"/>
<globmapper from="*.java" to="*.java.patch" />
</present>
</srcfiles>
<globmapper from="*.java" to="${patch.src.dir}/*.java.patch"/>
<globmapper from="*.java" to="${patch.src.dir}/*.java.patch" />
</uptodate>
<fail unless="checkUptodate.uptodate">
A patch is out of date. Update your patches!
@@ -332,8 +350,8 @@
<target name="updatepatches" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/update_patches.py" />
<arg value="${mcp.home}"/>
<arg value="${basedir}"/>
<arg value="${mcp.home}" />
<arg value="${basedir}" />
</exec>
</target>
@@ -341,30 +359,69 @@
<echo>
Extracting fresh eclipse workspace to ${basedir}/eclipse
</echo>
<unzip src="${basedir}/eclipse-workspace-dev.zip" dest="${basedir}"/>
<unzip src="${basedir}/eclipse-workspace-dev.zip" dest="${basedir}" />
</target>
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-common,reobfuscate">
<copy todir="${tmp.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
<fileset dir="${mcp.srcdir}" />
</copy>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/updatenames.py" />
<arg value="-f" />
</exec>
<copy todir="${renamed.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
<fileset dir="${mcp.srcdir}" />
</copy>
<move todir="${mcp.srcdir}">
<fileset dir="${tmp.mcp.srcdir}"/>
<fileset dir="${tmp.mcp.srcdir}" />
</move>
</target>
<target name="signjar" depends="buildenvsetup,makeversion" if="signature.exists">
<condition property="universal.jarname" value="${modname}-universal-${version.minecraft}-${version}" else="${modname}-universal-${version.minecraft}-${version}-${version.branch}">
<equals arg1="${version.branch}" arg2="master" />
</condition>
<property file="${env.JENKINS_HOME}/fmlsigned.properties" prefix="sign"/>
<echo>${env.JENKINS_HOME} ${universal.jarname} ${sign.KEYPASS}</echo>
<signjar alias="FML" jar="${basedir}/target/${universal.jarname}.zip" keypass="${sign.KEYPASS}" keystore="${env.JENKINS_HOME}/${sign.KEYSTORE}" storepass="${sign.STOREPASS}" verbose="true"/>
<property file="${env.JENKINS_HOME}/fmlsigned.properties" prefix="sign" />
<echo>${env.JENKINS_HOME} ${universal.jarname} ${sign.KEYPASS}</echo>
<signjar alias="FML" jar="${basedir}/target/${universal.jarname}.zip" keypass="${sign.KEYPASS}" keystore="${env.JENKINS_HOME}/${sign.KEYSTORE}" storepass="${sign.STOREPASS}" verbose="true" />
</target>
<target name="makebinpatches" depends="buildenvsetup,makeversion">
<path id="diffset.libs">
<pathelement path="${mcp.home}/jars/libraries/com/google/guava/guava/14.0/guava-14.0.jar"/>
<pathelement path="${mcp.home}/jars/libraries/org/ow2/asm/asm-all/4.1/asm-all-4.1.jar"/>
<pathelement path="${mcp.home}/jars/libraries/lzma/lzma/0.0.1/lzma-0.0.1.jar"/>
<pathelement path="${mcp.obfoutput}/minecraft"/>
</path>
<delete dir="${basedir}/binpatch" verbose="true"/>
<java classname="cpw.mods.fml.common.patcher.GenDiffSet" classpathref="diffset.libs">
<arg path="${mcp.home}/jars/versions/${version.minecraft}/${version.minecraft}.jar.backup"/>
<arg path="${mcp.obfoutput}/minecraft"/>
<arg path="${basedir}/deobfuscation_data-${version.minecraft}.lzma"/>
<arg path="${basedir}/binpatch/client"/>
<arg value="false"/>
</java>
<java classname="cpw.mods.fml.common.patcher.GenDiffSet" classpathref="diffset.libs">
<arg path="${mcp.home}/jars/minecraft_server.${version.minecraft}.jar.backup"/>
<arg path="${mcp.obfoutput}/minecraft"/>
<arg path="${basedir}/deobfuscation_data-${version.minecraft}.lzma"/>
<arg path="${basedir}/binpatch/server"/>
<arg value="true"/>
</java>
<mkdir dir="binpatch-tmp"/>
<zip destfile="binpatch-tmp/binpatches.jar" basedir="${basedir}">
<include name="binpatch/**/*.binpatch"/>
</zip>
<apply executable="pack200">
<arg line="--no-gzip"/>
<arg line="binpatch-tmp/binpatches.pack"/>
<fileset dir="binpatch-tmp" includes="binpatches.jar"/>
</apply>
<apply executable="${lzma.exe}">
<arg line="--format=lzma"/>
<arg line="-v"/>
<fileset dir="binpatch-tmp" includes="binpatches.pack"/>
</apply>
<move file="binpatch-tmp/binpatches.pack.lzma" todir="${basedir}"/>
<delete dir="binpatch-tmp" failonerror="false"/>
</target>
</project>
@@ -71,6 +71,7 @@ import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.common.registry.IThrowableEntity;
import cpw.mods.fml.common.registry.ItemData;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.common.toposort.ModSortingException;
import cpw.mods.fml.relauncher.Side;
@@ -113,6 +114,8 @@ public class FMLClientHandler implements IFMLSidedHandler
private MissingModsException modsMissing;
private ModSortingException modSorting;
private boolean loading;
private WrongMinecraftVersionException wrongMC;
@@ -171,6 +174,10 @@ public class FMLClientHandler implements IFMLSidedHandler
{
modsMissing = missing;
}
catch (ModSortingException sorting)
{
modSorting = sorting;
}
catch (CustomModLoadingErrorDisplayException custom)
{
FMLLog.log(Level.SEVERE, custom, "A custom exception was thrown by a mod, the game will now halt");
@@ -197,7 +204,7 @@ public class FMLClientHandler implements IFMLSidedHandler
@SuppressWarnings("deprecation")
public void finishMinecraftLoading()
{
if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null)
if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null || modSorting!=null)
{
return;
}
@@ -237,14 +244,18 @@ public class FMLClientHandler implements IFMLSidedHandler
{
client.func_71373_a(new GuiDupesFound(dupesFound));
}
else if (customError != null)
else if (modSorting != null)
{
client.func_71373_a(new GuiSortingProblem(modSorting));
}
else if (customError != null)
{
client.func_71373_a(new GuiCustomModLoadingErrorScreen(customError));
}
else
{
// Force renderengine to reload and re-initialize all textures
client.field_71446_o.func_78352_b();
// client.field_71446_o.func_78352_b();
// TextureFXManager.instance().loadTextures(client.field_71418_C.func_77292_e());
}
}
@@ -528,4 +539,15 @@ public class FMLClientHandler implements IFMLSidedHandler
// Show error screen
warnIDMismatch(s, false);
}
/**
* Is this GUI type open?
*
* @param gui The type of GUI to test for
* @return if a GUI of this type is open
*/
public boolean isGUIOpen(Class<? extends GuiScreen> gui)
{
return client.field_71462_r != null && client.field_71462_r.getClass().equals(gui);
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -21,6 +21,7 @@ public class GuiCustomModLoadingErrorScreen extends GuiErrorScreen
private CustomModLoadingErrorDisplayException customException;
public GuiCustomModLoadingErrorScreen(CustomModLoadingErrorDisplayException customException)
{
super(null,null);
this.customException = customException;
}
@Override
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -29,6 +29,7 @@ public class GuiDupesFound extends GuiErrorScreen
public GuiDupesFound(DuplicateModsFoundException dupes)
{
super(null,null);
this.dupes = dupes;
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -17,6 +17,7 @@ import java.util.Map.Entry;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiYesNo;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.StringTranslate;
import com.google.common.collect.Lists;
@@ -37,13 +38,13 @@ public class GuiIdMismatchScreen extends GuiYesNo {
field_73942_a = this;
for (Entry<Integer, ItemData> entry : idDifferences.entriesOnlyOnLeft().entrySet())
{
missingIds.add(String.format("ID %d (ModID: %s, type %s) is missing", entry.getValue().getItemId(), entry.getValue().getModId(), entry.getValue().getItemType()));
missingIds.add(String.format("ID %d from Mod %s is missing", entry.getValue().getItemId(), entry.getValue().getModId(), entry.getValue().getItemType()));
}
for (Entry<Integer, ValueDifference<ItemData>> entry : idDifferences.entriesDiffering().entrySet())
{
ItemData world = entry.getValue().leftValue();
ItemData game = entry.getValue().rightValue();
mismatchedIds.add(String.format("ID %d is mismatched. World: (ModID: %s, type %s, ordinal %d) Game (ModID: %s, type %s, ordinal %d)", world.getItemId(), world.getModId(), world.getItemType(), world.getOrdinal(), game.getModId(), game.getItemType(), game.getOrdinal()));
mismatchedIds.add(String.format("ID %d is mismatched between world and game", world.getItemId()));
}
this.allowContinue = allowContinue;
}
@@ -62,37 +63,44 @@ public class GuiIdMismatchScreen extends GuiYesNo {
{
field_73887_h.remove(0);
}
int offset = Math.max(85 - missingIds.size() * 10 + mismatchedIds.size() * 30, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found world ID mismatches", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
int offset = Math.max(85 - (missingIds.size() + mismatchedIds.size()) * 10, 30);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found ID mismatches", this.field_73880_f / 2, 10, 0xFFFFFF);
this.func_73732_a(this.field_73886_k, "Complete details are in the log file", this.field_73880_f / 2, 20, 0xFFFFFF);
int maxLines = 20;
for (String s: missingIds) {
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
offset += 10;
maxLines --;
if (maxLines < 0) break;
if (offset >= this.field_73881_g - 30) break;
}
for (String s: mismatchedIds) {
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
offset += 10;
if (maxLines > 0 && offset < this.field_73881_g - 30)
{
for (String s: mismatchedIds) {
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
offset += 10;
maxLines --;
if (maxLines < 0) break;
if (offset >= this.field_73881_g - 30) break;
}
}
offset += 10;
if (allowContinue)
{
this.func_73732_a(this.field_73886_k, "Do you wish to continue loading?", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
this.func_73732_a(this.field_73886_k, "Do you wish to continue loading?", this.field_73880_f / 2, this.field_73881_g - 30, 0xFFFFFF);
}
else
{
this.func_73732_a(this.field_73886_k, "You cannot connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
this.func_73732_a(this.field_73886_k, "You cannot connect to this server", this.field_73880_f / 2, this.field_73881_g - 30, 0xFFFFFF);
}
// super.super. Grrr
for (int var4 = 0; var4 < this.field_73887_h.size(); ++var4)
{
GuiButton var5 = (GuiButton)this.field_73887_h.get(var4);
var5.field_73743_d = Math.min(offset + 10, this.field_73881_g - 20);
var5.field_73743_d = this.field_73881_g - 20;
if (!allowContinue)
{
var5.field_73746_c = this.field_73880_f / 2 - 75;
var5.field_73744_e = StringTranslate.func_74808_a().func_74805_b("gui.done");
var5.field_73744_e = I18n.func_135053_a("gui.done");
}
var5.func_73737_a(this.field_73882_e, p_73863_1_, p_73863_2_);
}
+4 -3
View File
@@ -23,6 +23,7 @@ import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSmallButton;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.StringTranslate;
import org.lwjgl.opengl.GL11;
@@ -80,8 +81,7 @@ public class GuiModList extends GuiScreen
listWidth=Math.max(listWidth,getFontRenderer().func_78256_a(mod.getVersion()) + 10);
}
listWidth=Math.min(listWidth, 150);
StringTranslate translations = StringTranslate.func_74808_a();
this.field_73887_h.add(new GuiSmallButton(6, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
this.field_73887_h.add(new GuiSmallButton(6, this.field_73880_f / 2 - 75, this.field_73881_g - 38, I18n.func_135053_a("gui.done")));
this.modList=new GuiSlotModList(this, mods, listWidth);
this.modList.registerScrollButtons(this.field_73887_h, 7, 8);
}
@@ -120,7 +120,8 @@ public class GuiModList extends GuiScreen
if (!logoFile.isEmpty())
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.field_73882_e.field_71446_o.func_98187_b(logoFile);
// TODO
// this.field_73882_e.field_71446_o.func_98187_b(logoFile);
Dimension dim = TextureFXManager.instance().getTextureDimensions(logoFile);
double scaleX = dim.width / 200.0;
double scaleY = dim.height / 65.0;
+12 -1
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -15,6 +15,7 @@ package cpw.mods.fml.client;
import net.minecraft.client.gui.GuiErrorScreen;
import cpw.mods.fml.common.MissingModsException;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
public class GuiModsMissing extends GuiErrorScreen
{
@@ -23,6 +24,7 @@ public class GuiModsMissing extends GuiErrorScreen
public GuiModsMissing(MissingModsException modsMissing)
{
super(null,null);
this.modsMissing = modsMissing;
}
@@ -43,6 +45,15 @@ public class GuiModsMissing extends GuiErrorScreen
for (ArtifactVersion v : modsMissing.missingMods)
{
offset+=10;
if (v instanceof DefaultArtifactVersion)
{
DefaultArtifactVersion dav = (DefaultArtifactVersion)v;
if (dav.getRange() != null && dav.getRange().isUnboundedAbove())
{
this.func_73732_a(this.field_73886_k, String.format("%s : minimum version required is %s", v.getLabel(), dav.getRange().getLowerBoundString()), this.field_73880_f / 2, offset, 0xEEEEEE);
continue;
}
}
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;
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -15,6 +15,7 @@ package cpw.mods.fml.client;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSmallButton;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.StringTranslate;
import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.versioning.ArtifactVersion;
@@ -31,8 +32,7 @@ public class GuiModsMissingForServer extends GuiScreen
@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")));
this.field_73887_h.add(new GuiSmallButton(1, this.field_73880_f / 2 - 75, this.field_73881_g - 38, I18n.func_135053_a("gui.done")));
}
@Override
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -15,6 +15,7 @@ package cpw.mods.fml.client;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.Tessellator;
@@ -264,7 +265,7 @@ public abstract class GuiScrollingList
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_FOG);
Tessellator var18 = Tessellator.field_78398_a;
this.client.field_71446_o.func_98187_b("/gui/background.png");
this.client.field_71446_o.func_110577_a(Gui.field_110325_k);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
float var17 = 32.0F;
var18.func_78382_b();
@@ -397,7 +398,7 @@ public abstract class GuiScrollingList
private void overlayBackground(int p_22239_1_, int p_22239_2_, int p_22239_3_, int p_22239_4_)
{
Tessellator var5 = Tessellator.field_78398_a;
this.client.field_71446_o.func_98187_b("/gui/background.png");
this.client.field_71446_o.func_110577_a(Gui.field_110325_k);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
float var6 = 32.0F;
var5.func_78382_b();
@@ -0,0 +1,48 @@
package cpw.mods.fml.client;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.toposort.ModSortingException;
import cpw.mods.fml.common.toposort.ModSortingException.SortingExceptionData;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import net.minecraft.client.gui.GuiScreen;
public class GuiSortingProblem extends GuiScreen {
private ModSortingException modSorting;
private SortingExceptionData<ModContainer> failedList;
public GuiSortingProblem(ModSortingException modSorting)
{
this.modSorting = modSorting;
this.failedList = modSorting.getExceptionData();
}
@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 = Math.max(85 - (failedList.getVisitedNodes().size() + 3) * 10, 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, "A mod sorting cycle was detected and loading cannot continue", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("The first mod in the cycle is %s", failedList.getFirstBadNode()), this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "The remainder of the cycle involves these mods", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
for (ModContainer mc : failedList.getVisitedNodes())
{
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s : before: %s, after: %s", mc.toString(), mc.getDependants(), mc.getDependencies()), 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);
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -22,6 +22,7 @@ public class GuiWrongMinecraft extends GuiErrorScreen
private WrongMinecraftVersionException wrongMC;
public GuiWrongMinecraft(WrongMinecraftVersionException wrongMC)
{
super(null,null);
this.wrongMC = wrongMC;
}
@Override
@@ -1,29 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import java.awt.Dimension;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.texturepacks.ITexturePack;
public interface ITextureFX
{
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions);
public void onTextureDimensionsUpdate(int width, int height);
public void setErrored(boolean errored);
public boolean getErrored();
}
@@ -20,10 +20,14 @@ import java.util.Map;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.ContextCapabilities;
import org.lwjgl.opengl.GLContext;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderEngine;
public class TextureFXManager
{
@@ -34,24 +38,26 @@ public class TextureFXManager
private Map<Integer,TextureHolder> texturesById = Maps.newHashMap();
private Map<String, TextureHolder> texturesByName = Maps.newHashMap();
// private TextureHelper helper;
void setClient(Minecraft client)
{
this.client = client;
}
public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
{
InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
if (image==null) {
throw new RuntimeException(String.format("The requested image path %s is not found",path));
}
BufferedImage result=ImageIO.read(image);
if (result==null)
{
throw new RuntimeException(String.format("The requested image path %s appears to be corrupted",path));
}
return result;
}
// public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
// {
// InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
// if (image==null) {
// throw new RuntimeException(String.format("The requested image path %s is not found",path));
// }
// BufferedImage result=ImageIO.read(image);
// if (result==null)
// {
// throw new RuntimeException(String.format("The requested image path %s appears to be corrupted",path));
// }
// return result;
// }
//
public static TextureFXManager instance()
{
return INSTANCE;
@@ -102,4 +108,35 @@ public class TextureFXManager
{
return texturesByName.containsKey(texture) ? new Dimension(texturesByName.get(texture).x, texturesByName.get(texture).y) : new Dimension(1,1);
}
// public TextureHelper getHelper()
// {
// if (helper == null)
// {
// ContextCapabilities capabilities = GLContext.getCapabilities();
// boolean has43 = false;
// try
// {
// has43 = capabilities.getClass().getField("GL_ARB_copy_image").getBoolean(capabilities);
// }
// catch (Exception e)
// {
// //e.printStackTrace();
// // NOOP - LWJGL needs updating
// FMLLog.info("Forge Mod Loader has detected an older LWJGL version, new advanced texture animation features are disabled");
// }
//// if (has43 && Boolean.parseBoolean(System.getProperty("fml.useGL43","true")))
//// {
//// FMLLog.info("Using the new OpenGL 4.3 advanced capability for animations");
//// helper = new OpenGL43TextureHelper();
//// }
//// else
// {
// FMLLog.info("Not using advanced OpenGL 4.3 advanced capability for animations : OpenGL 4.3 is %s", has43 ? "available" : "not available");
//// helper = new CopySubimageTextureHelper();
// }
// }
// return helper;
// }
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -48,9 +48,8 @@ public class RenderingRegistry
*/
public static int addNewArmourRendererPrefix(String armor)
{
RenderPlayer.field_77110_j = ObjectArrays.concat(RenderPlayer.field_77110_j, armor);
RenderBiped.field_82424_k = RenderPlayer.field_77110_j;
return RenderPlayer.field_77110_j.length - 1;
RenderBiped.field_82424_k = ObjectArrays.concat(RenderBiped.field_82424_k, armor);
return RenderBiped.field_82424_k.length - 1;
}
/**
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -19,8 +19,6 @@ import java.util.logging.Logger;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.texturepacks.ITexturePack;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.TextureFXManager;
@@ -70,4 +68,9 @@ public class FMLRenderAccessLibrary
{
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelId);
}
// public static void doTextureCopy(Texture atlas, Texture source, int targetX, int targetY)
// {
// TextureFXManager.instance().getHelper().doTextureCopy(atlas, source, targetX, targetY);
// }
}
+11 -14
View File
@@ -26,7 +26,6 @@ import net.minecraft.client.*;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.settings.KeyBinding;
@@ -541,7 +540,7 @@ public class ModLoader
@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);
return FMLClientHandler.instance().isGUIOpen(gui);
}
/**
@@ -564,11 +563,11 @@ public class ModLoader
{
}
@SideOnly(CLIENT)
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
{
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
}
// @SideOnly(CLIENT)
// public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
// {
// return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
// }
/**
* Call in from elsewhere. Unimplemented here.
@@ -616,11 +615,11 @@ public class ModLoader
return keys;
}
@Deprecated
@SideOnly(CLIENT)
public static void registerAllTextureOverrides(RenderEngine cache)
{
}
// @Deprecated
// @SideOnly(CLIENT)
// public static void registerAllTextureOverrides(RenderEngine cache)
// {
// }
/**
* Register a new block
@@ -810,14 +809,12 @@ public class ModLoader
@Deprecated
public static void serverChat(String text)
{
//TODO
}
@Deprecated
@SideOnly(CLIENT)
public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
{
//TODO
}
public static void serverSendPacket(NetServerHandler handler, Packet packet)
+13 -95
View File
@@ -1,24 +1,15 @@
--- commands.py
+++ commands.py
@@ -58,6 +58,8 @@
def reallyrmtree(path):
+ if os.path.isfile(os.path.join(path, 'asm-4.1.tar.gz')): #Check if asm exists, indicating the libs folder, if so, don't delete it
+ return
if not sys.platform.startswith('win'):
if os.path.exists(path):
shutil.rmtree(path)
@@ -139,6 +141,8 @@
@@ -139,6 +139,8 @@
fieldnames = csvreader.fieldnames
return set(fieldnames)
+def commands_sanity_check():
+ print 'Commands patch applied successfully'
+ print ' Commands patch applied successfully'
class Commands(object):
"""Contains the commands and initialisation for a full mcp run"""
@@ -796,6 +800,8 @@
@@ -943,6 +945,8 @@
binlk = {CLIENT: self.binclient, SERVER: self.binserver}
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
@@ -27,17 +18,17 @@
if not os.path.exists(os.path.join(binlk[side], os.path.normpath(testlk[side] + '.class'))):
return False
return True
@@ -1037,6 +1043,9 @@
@@ -1274,6 +1278,9 @@
pathbinlk = {CLIENT: self.binclient, SERVER: self.binserver}
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
pathlog = {CLIENT: self.clientrecomplog, SERVER: self.serverrecomplog}
+
+ if side == SERVER: #Warn about server because FML recombines it into client
+ self.logger.info('Server side recompiling might be skipped, this is normal, do not complain to FML/Forge team about server side.')
+
if not os.path.exists(pathbinlk[side]):
os.makedirs(pathbinlk[side])
@@ -1070,7 +1079,7 @@
@@ -1331,7 +1338,7 @@
raise
def startserver(self):
@@ -46,7 +37,7 @@
classpath = [os.path.join('..', p) for p in classpath]
classpath = os.pathsep.join(classpath)
os.chdir(self.dirjars)
@@ -1078,7 +1087,7 @@
@@ -1339,7 +1346,7 @@
self.runmc(forkcmd)
def startclient(self):
@@ -55,47 +46,7 @@
classpath = [os.path.join('..', p) for p in classpath]
classpath = os.pathsep.join(classpath)
natives = os.path.join('..', self.dirnatives)
@@ -1205,20 +1214,20 @@
with open(self.csvmethods, 'rb') as fh:
methodsreader = csv.DictReader(fh)
for row in methodsreader:
- if int(row['side']) == side:
+ if int(row['side']) == side or int(row['side']) == 2:
if row['name'] != row['searge']:
names['methods'][row['searge']] = row['name']
with open(self.csvfields, 'rb') as fh:
fieldsreader = csv.DictReader(fh)
for row in fieldsreader:
- if int(row['side']) == side:
+ if int(row['side']) == side or int(row['side']) == 2:
if row['name'] != row['searge']:
names['fields'][row['searge']] = row['name']
if self.has_param_csv:
with open(self.csvparams, 'rb') as fh:
paramsreader = csv.DictReader(fh)
for row in paramsreader:
- if int(row['side']) == side:
+ if int(row['side']) == side or int(row['side']) == 2:
names['params'][row['param']] = row['name']
regexps = {
@@ -1352,13 +1361,13 @@
methods = {}
for row in methodsreader:
#HINT: Only include methods that have a non-empty description
- if int(row['side']) == side and row['desc']:
+ if (int(row['side']) == side or int(row['side']) == 2) and row['desc']:
methods[row['searge']] = row['desc'].replace('*/', '* /')
fields = {}
for row in fieldsreader:
#HINT: Only include fields that have a non-empty description
- if int(row['side']) == side and row['desc']:
+ if (int(row['side']) == side or int(row['side']) == 2) and row['desc']:
fields[row['searge']] = row['desc'].replace('*/', '* /')
regexps = {
@@ -1435,7 +1444,7 @@
@@ -1696,7 +1703,7 @@
self.runcmd(forkcmd)
return True
@@ -104,7 +55,7 @@
if not reobf:
md5lk = {CLIENT: self.md5client, SERVER: self.md5server}
else:
@@ -1450,6 +1459,9 @@
@@ -1711,6 +1718,9 @@
class_path = ''
else:
class_path += '/'
@@ -114,40 +65,7 @@
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))
@@ -1546,6 +1558,8 @@
if not os.path.exists(outpathlk[side]):
os.makedirs(outpathlk[side])
+ reserved = ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9']
+
# HINT: We extract the modified class files
with closing(zipfile.ZipFile(jarlk[side])) as zipjar:
for in_class in trgclasses:
@@ -1559,6 +1573,23 @@
out_class = out_class.replace(self.nullpkg, '')
if out_class[0] == '/':
out_class = out_class[1:]
+
+ rename = False
+ for res in reserved:
+ if out_class.upper().startswith(res):
+ rename = True
+ break
+
+ if rename:
+ try:
+ f = open(os.path.join(outpathlk[side], '_' + out_class), 'wb')
+ f.write(zipjar.read(out_class))
+ f.close()
+ self.logger.info('> Outputted %s to %s as %s', in_class.ljust(35), outpathlk[side], '_' + out_class)
+ except IOError:
+ self.logger.error('* File %s failed extracting for %s', out_class, in_class)
+ continue
+
try:
zipjar.extract(out_class, outpathlk[side])
self.logger.info('> Outputted %s to %s as %s', in_class.ljust(35), outpathlk[side], out_class)
@@ -1605,6 +1636,9 @@
@@ -1883,6 +1893,9 @@
sys.exit(1)
for entry in newfiles:
@@ -157,7 +75,7 @@
if entry[3] == 'U':
self.logger.info('Retrieving file from server : %s', entry[0])
cur_file = os.path.normpath(entry[0])
@@ -1625,6 +1659,9 @@
@@ -1903,6 +1916,9 @@
md5reoblk = {CLIENT: self.md5reobfclient, SERVER: self.md5reobfserver}
outpathlk = {CLIENT: self.srcmodclient, SERVER: self.srcmodserver}
src = {CLIENT: self.srcclient, SERVER: self.srcserver}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -16,6 +16,7 @@ import java.io.File;
import java.security.cert.Certificate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.eventbus.EventBus;
@@ -28,12 +29,17 @@ public class DummyModContainer implements ModContainer
{
private ModMetadata md;
private ArtifactVersion processedVersion;
private String label;
public DummyModContainer(ModMetadata md)
{
this.md = md;
}
public DummyModContainer(String label)
{
this.label = label;
}
public DummyModContainer()
{
}
@@ -157,4 +163,16 @@ public class DummyModContainer implements ModContainer
{
return null;
}
@Override
public String toString()
{
return md != null ? getModId() : "Dummy Container ("+label+") @" + System.identityHashCode(this);
}
@Override
public Map<String, String> getCustomModProperties()
{
return EMPTY_PROPERTIES;
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -38,6 +38,7 @@ import net.minecraft.world.World;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
@@ -244,12 +245,9 @@ public class FMLCommonHandler
{
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
}
try {
Properties props=new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
brd.add(props.getProperty("fmlbranding"));
} catch (Exception ex) {
// Ignore - no branding file found
if (Loader.instance().getFMLBrandingProperties().containsKey("fmlbranding"))
{
brd.add(Loader.instance().getFMLBrandingProperties().get("fmlbranding"));
}
int tModCount = Loader.instance().getModList().size();
int aModCount = Loader.instance().getActiveModList().size();
@@ -467,6 +465,25 @@ public class FMLCommonHandler
public void handleServerStopped()
{
MinecraftServer server = getMinecraftServerInstance();
Loader.instance().serverStopped();
// FORCE the internal server to stop: hello optifine workaround!
if (server!=null) ObfuscationReflectionHelper.setPrivateValue(MinecraftServer.class, server, false, "field_71316_v", "u", "serverStopped");
}
public String getModName()
{
List<String> modNames = Lists.newArrayListWithExpectedSize(3);
modNames.add("fml");
if (!noForge)
{
modNames.add("forge");
}
if (Loader.instance().getFMLBrandingProperties().containsKey("snooperbranding"))
{
modNames.add(Loader.instance().getFMLBrandingProperties().get("snooperbranding"));
}
return Joiner.on(',').join(modNames);
}
}
+72 -37
View File
@@ -38,8 +38,10 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
@@ -47,6 +49,7 @@ import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.Mod.CustomProperty;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.Metadata;
import cpw.mods.fml.common.discovery.ASMDataTable;
@@ -83,7 +86,6 @@ public class FMLModContainer implements ModContainer
private boolean overridesMetadata;
private EventBus eventBus;
private LoadController controller;
private Multimap<Class<? extends Annotation>, Object> annotations;
private DefaultArtifactVersion processedVersion;
private boolean isNetworkMod;
@@ -107,35 +109,17 @@ public class FMLModContainer implements ModContainer
private Certificate certificate;
private String modLanguage;
private ILanguageAdapter languageAdapter;
private ListMultimap<Class<? extends FMLEvent>,Method> eventMethods;
private Map<String, String> customModProperties;
public static interface ILanguageAdapter {
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader) throws Exception;
}
public static class ScalaAdapter implements ILanguageAdapter {
@Override
public Object getNewInstance(FMLModContainer container, Class<?> scalaObjectClass, ClassLoader classLoader) throws Exception
{
System.out.println("Scala class : "+ scalaObjectClass);
Class<?> sObjectClass = Class.forName(scalaObjectClass.getName()+"$",true,classLoader);
return sObjectClass.getField("MODULE$").get(null);
}
}
public static class JavaAdapter implements ILanguageAdapter {
@Override
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader) throws Exception
{
return objectClass.newInstance();
}
}
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
{
this.className = className;
this.source = modSource;
this.descriptor = modDescriptor;
this.modLanguage = (String) modDescriptor.get("modLanguage");
this.languageAdapter = "scala".equals(modLanguage) ? new ScalaAdapter() : new JavaAdapter();
this.languageAdapter = "scala".equals(modLanguage) ? new ILanguageAdapter.ScalaAdapter() : new ILanguageAdapter.JavaAdapter();
this.eventMethods = ArrayListMultimap.create();
}
private ILanguageAdapter getLanguageAdapter()
@@ -333,10 +317,9 @@ public class FMLModContainer implements ModContainer
}
}
private Multimap<Class<? extends Annotation>, Object> gatherAnnotations(Class<?> clazz) throws Exception
private Method gatherAnnotations(Class<?> clazz) throws Exception
{
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
Method factoryMethod = null;
for (Method m : clazz.getDeclaredMethods())
{
for (Annotation a : m.getAnnotations())
@@ -344,20 +327,47 @@ public class FMLModContainer implements ModContainer
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);
eventMethods.put(modTypeAnnotations.get(a.annotationType()), m);
}
else
{
FMLLog.log(getModId(), Level.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));
}
}
else if (a.annotationType().equals(Mod.EventHandler.class))
{
if (m.getParameterTypes().length == 1 && modAnnotationTypes.containsKey(m.getParameterTypes()[0]))
{
m.setAccessible(true);
eventMethods.put((Class<? extends FMLEvent>) m.getParameterTypes()[1],m);
}
else
{
FMLLog.log(getModId(), Level.SEVERE,"The mod %s appears to have an invalid event annotation %s. This annotation can only apply to methods with recognized event arguments - it will not be called", getModId(), a.annotationType().getSimpleName());
}
}
else if (a.annotationType().equals(Mod.InstanceFactory.class))
{
if (Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 0 && factoryMethod == null)
{
m.setAccessible(true);
factoryMethod = m;
}
else if (!(Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 0))
{
FMLLog.log(getModId(), Level.SEVERE, "The InstanceFactory annotation can only apply to a static method, taking zero arguments - it will be ignored on %s(%s)", m.getName(), Arrays.asList(m.getParameterTypes()));
}
else if (factoryMethod != null)
{
FMLLog.log(getModId(), Level.SEVERE, "The InstanceFactory annotation can only be used once, the application to %s(%s) will be ignored", m.getName(), Arrays.asList(m.getParameterTypes()));
}
}
}
}
return anns;
return factoryMethod;
}
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
@@ -482,14 +492,30 @@ public class FMLModContainer implements ModContainer
}
}
annotations = gatherAnnotations(clazz);
CustomProperty[] props = (CustomProperty[]) descriptor.get("customProperties");
if (props!=null && props.length > 0)
{
com.google.common.collect.ImmutableMap.Builder<String, String> builder = ImmutableMap.<String,String>builder();
for (CustomProperty p : props)
{
builder.put(p.k(),p.v());
}
customModProperties = builder.build();
}
else
{
customModProperties = EMPTY_PROPERTIES;
}
Method factoryMethod = gatherAnnotations(clazz);
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
modInstance = getLanguageAdapter().getNewInstance(this,clazz, modClassLoader);
modInstance = getLanguageAdapter().getNewInstance(this,clazz, modClassLoader, factoryMethod);
if (fingerprintNotPresent)
{
eventBus.post(new FMLFingerprintViolationEvent(source.isDirectory(), source, ImmutableSet.copyOf(this.sourceFingerprints), expectedFingerprint));
}
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide(), getLanguageAdapter());
processFieldAnnotations(event.getASMHarvestedData());
}
catch (Throwable e)
@@ -502,23 +528,20 @@ public class FMLModContainer implements ModContainer
@Subscribe
public void handleModStateEvent(FMLEvent event)
{
Class<? extends Annotation> annotation = modAnnotationTypes.get(event.getClass());
if (annotation == null)
if (!eventMethods.containsKey(event.getClass()))
{
return;
}
try
{
for (Object o : annotations.get(annotation))
for (Method m : eventMethods.get(event.getClass()))
{
Method m = (Method) o;
m.invoke(modInstance, event);
}
}
catch (Throwable t)
{
controller.errorOccurred(this, t);
Throwables.propagateIfPossible(t);
}
}
@@ -560,4 +583,16 @@ public class FMLModContainer implements ModContainer
{
return certificate;
}
@Override
public String toString()
{
return "FMLMod:"+getModId()+"{"+getVersion()+"}";
}
@Override
public Map<String, String> getCustomModProperties()
{
return customModProperties;
}
}
@@ -0,0 +1,197 @@
package cpw.mods.fml.common;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.relauncher.Side;
public interface ILanguageAdapter {
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader, Method factoryMarkedAnnotation) throws Exception;
public boolean supportsStatics();
public void setProxy(Field target, Class<?> proxyTarget, Object proxy) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException;
public void setInternalProxies(ModContainer mod, Side side, ClassLoader loader);
public static class ScalaAdapter implements ILanguageAdapter {
@Override
public Object getNewInstance(FMLModContainer container, Class<?> scalaObjectClass, ClassLoader classLoader, Method factoryMarkedAnnotation) throws Exception
{
Class<?> sObjectClass = Class.forName(scalaObjectClass.getName()+"$",true,classLoader);
return sObjectClass.getField("MODULE$").get(null);
}
@Override
public boolean supportsStatics()
{
return false;
}
@Override
public void setProxy(Field target, Class<?> proxyTarget, Object proxy) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException
{
try
{
// Get the actual singleton class. The two variants are from
// whether the @SidedProxy is declared in a the class block
// of the object directly, or in the object block, i.e.
// whether it's:
// class ModName {
// @SidedProxy ...
// }
// object ModName extends ModName {}
// which leads to us getting the outer class, or
// object ModName {
// @SidedProxy ...
// }
// which leads to us getting the inner class.
if (!proxyTarget.getName().endsWith("$"))
{
// Get internal class generated by Scala.
proxyTarget = Class.forName(proxyTarget.getName() + "$", true, proxyTarget.getClassLoader());
}
}
catch (ClassNotFoundException e)
{
// Not a singleton, look for @Instance field as a fallback.
FMLLog.log(Level.INFO, e, "An error occured trying to load a proxy into %s.%s. Did you declare your mod as 'class' instead of 'object'?", proxyTarget.getSimpleName(), target.getName());
return;
}
// Get the instance via the MODULE$ field which is
// automatically generated by the Scala compiler for
// singletons.
Object targetInstance = proxyTarget.getField("MODULE$").get(null);
try
{
// Find setter function. We do it this way because we can't
// necessarily use proxyTarget.getMethod(proxy.getClass()), as
// it might be a subclass and not the exact parameter type.
// All fields are private in Scala, wrapped by a getter and
// setter named <fieldname> and <fieldname>_$eq. To those
// familiar with scala.reflect.BeanProperty: these will always
// be there, set<Fieldname> and get<Fieldname> will always
// only be generated *additionally*.
final String setterName = target.getName() + "_$eq";
for (Method setter : proxyTarget.getMethods())
{
Class<?>[] setterParameters = setter.getParameterTypes();
if (setterName.equals(setter.getName()) &&
// Some more validation.
setterParameters.length == 1 &&
setterParameters[0].isAssignableFrom(proxy.getClass()))
{
// Here goes nothing...
setter.invoke(targetInstance, proxy);
return;
}
}
}
catch (InvocationTargetException e)
{
FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", proxyTarget.getSimpleName(), target.getName());
throw new LoaderException(e);
}
// If we come here we could not find a setter for this proxy.
FMLLog.severe("Failed loading proxy into %s.%s, could not find setter function. Did you declare the field with 'val' instead of 'var'?", proxyTarget.getSimpleName(), target.getName());
throw new LoaderException();
}
@Override
public void setInternalProxies(ModContainer mod, Side side, ClassLoader loader)
{
// For Scala mods, we want to enable authors to write them like so:
// object ModName {
// @SidedProxy(...)
// var proxy: ModProxy = null
// }
// For this to work, we have to search inside the inner class Scala
// generates for singletons, which is in called ModName$. These are
// not automatically handled, because the mod discovery code ignores
// internal classes.
// Note that it is alternatively possible to write this like so:
// class ModName {
// @SidedProxy(...)
// var proxy: ModProxy = null
// }
// object ModName extends ModName { ... }
// which will fall back to the normal injection code which calls
// setProxy in turn.
// Get the actual mod implementation, which will be the inner class
// if we have a singleton.
Class<?> proxyTarget = mod.getMod().getClass();
if (proxyTarget.getName().endsWith("$"))
{
// So we have a singleton class, check if there are targets.
for (Field target : proxyTarget.getDeclaredFields())
{
// This will not turn up anything if the alternative
// approach was taken (manually declaring the class).
// So we don't initialize the field twice.
if (target.getAnnotation(SidedProxy.class) != null)
{
String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
try
{
Object proxy = Class.forName(targetType, true, loader).newInstance();
if (!target.getType().isAssignableFrom(proxy.getClass()))
{
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, proxyTarget.getSimpleName(), target.getName());
throw new LoaderException();
}
setProxy(target, proxyTarget, proxy);
}
catch (Exception e) {
FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", proxyTarget.getSimpleName(), target.getName());
throw new LoaderException(e);
}
}
}
}
else
{
FMLLog.finer("Mod does not appear to be a singleton.");
}
}
}
public static class JavaAdapter implements ILanguageAdapter {
@Override
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader, Method factoryMarkedMethod) throws Exception
{
if (factoryMarkedMethod != null)
{
return factoryMarkedMethod.invoke(null);
}
else
{
return objectClass.newInstance();
}
}
@Override
public boolean supportsStatics()
{
return true;
}
@Override
public void setProxy(Field target, Class<?> proxyTarget, Object proxy) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
SecurityException
{
target.set(null, proxy);
}
@Override
public void setInternalProxies(ModContainer mod, Side side, ClassLoader loader)
{
// Nothing to do here.
}
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -15,6 +15,7 @@ package cpw.mods.fml.common;
import java.io.File;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.eventbus.EventBus;
@@ -25,7 +26,7 @@ import cpw.mods.fml.common.versioning.VersionRange;
public class InjectedModContainer implements ModContainer
{
private File source;
private ModContainer wrappedContainer;
public final ModContainer wrappedContainer;
public InjectedModContainer(ModContainer mc, File source)
{
@@ -148,4 +149,16 @@ public class InjectedModContainer implements ModContainer
{
return wrappedContainer.getSigningCertificate();
}
@Override
public String toString()
{
return "Wrapped{"+wrappedContainer.toString()+"}";
}
@Override
public Map<String, String> getCustomModProperties()
{
return wrappedContainer.getCustomModProperties();
}
}
+45 -19
View File
@@ -13,15 +13,18 @@
package cpw.mods.fml.common;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
@@ -36,6 +39,8 @@ import cpw.mods.fml.common.event.FMLEvent;
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.functions.ArtifactVersionNameFunction;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class LoadController
{
@@ -99,11 +104,11 @@ public class LoadController
}
}
public void transition(LoaderState desiredState)
public void transition(LoaderState desiredState, boolean forceState)
{
LoaderState oldState = state;
state = state.transition(!errors.isEmpty());
if (state != desiredState)
if (state != desiredState && !forceState)
{
Throwable toThrow = null;
FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState);
@@ -142,6 +147,12 @@ public class LoadController
throw new LoaderException(toThrow);
}
}
else if (state != desiredState && forceState)
{
FMLLog.info("The state engine was in incorrect state %s and forced into state %s. Errors may have been discarded.", state, desiredState);
forceState(desiredState);
}
}
public ModContainer activeContainer()
@@ -158,23 +169,38 @@ public class LoadController
}
for (ModContainer mc : activeModList)
{
activeContainer = mc;
String modId = mc.getModId();
stateEvent.applyModContainer(activeContainer());
FMLLog.log(modId, Level.FINEST, "Sending event %s to mod %s", stateEvent.getEventType(), modId);
eventChannels.get(modId).post(stateEvent);
FMLLog.log(modId, Level.FINEST, "Sent event %s to mod %s", stateEvent.getEventType(), modId);
activeContainer = null;
if (stateEvent instanceof FMLStateEvent)
sendEventToModContainer(stateEvent, mc);
}
}
private void sendEventToModContainer(FMLEvent stateEvent, ModContainer mc)
{
String modId = mc.getModId();
Collection<String> requirements = Collections2.transform(mc.getRequirements(),new ArtifactVersionNameFunction());
for (ArtifactVersion av : mc.getDependencies())
{
if (av.getLabel()!= null && requirements.contains(av.getLabel()) && modStates.containsEntry(av.getLabel(),ModState.ERRORED))
{
if (!errors.containsKey(modId))
{
modStates.put(modId, ((FMLStateEvent)stateEvent).getModState());
}
else
{
modStates.put(modId, ModState.ERRORED);
}
FMLLog.log(modId, Level.SEVERE, "Skipping event %s and marking errored mod %s since required dependency %s has errored", stateEvent.getEventType(), modId, av.getLabel());
modStates.put(modId, ModState.ERRORED);
return;
}
}
activeContainer = mc;
stateEvent.applyModContainer(activeContainer());
FMLLog.log(modId, Level.FINEST, "Sending event %s to mod %s", stateEvent.getEventType(), modId);
eventChannels.get(modId).post(stateEvent);
FMLLog.log(modId, Level.FINEST, "Sent event %s to mod %s", stateEvent.getEventType(), modId);
activeContainer = null;
if (stateEvent instanceof FMLStateEvent)
{
if (!errors.containsKey(modId))
{
modStates.put(modId, ((FMLStateEvent)stateEvent).getModState());
}
else
{
modStates.put(modId, ModState.ERRORED);
}
}
}
@@ -216,7 +242,7 @@ public class LoadController
{
for (ModContainer mc : loader.getModList())
{
ret.append("\n\t").append(mc.getModId()).append(" [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
ret.append("\n\t").append(mc.getModId()).append("{").append(mc.getVersion()).append("} [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
Joiner.on("->"). appendTo(ret, modStates.get(mc.getModId()));
}
}
+58 -30
View File
@@ -13,6 +13,7 @@
package cpw.mods.fml.common;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -26,15 +27,20 @@ import java.util.concurrent.Callable;
import java.util.logging.Level;
import net.minecraft.crash.CallableMinecraftVersion;
import net.minecraft.item.ItemStack;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableListMultimap.Builder;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.Iterables;
@@ -47,17 +53,21 @@ 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.Table;
import com.google.common.collect.TreeMultimap;
import com.google.common.io.Files;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.discovery.ModDiscoverer;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.functions.ArtifactVersionNameFunction;
import cpw.mods.fml.common.functions.ModIdFunction;
import cpw.mods.fml.common.modloader.BaseModProxy;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.toposort.ModSorter;
import cpw.mods.fml.common.toposort.ModSortingException;
import cpw.mods.fml.common.toposort.ModSortingException.SortingExceptionData;
import cpw.mods.fml.common.toposort.TopologicalSort;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
@@ -144,6 +154,7 @@ public class Loader
private static File minecraftDir;
private static List<String> injectedContainers;
private File loggingProperties;
private ImmutableMap<String, String> fmlBrandingProperties;
public static Loader instance()
{
@@ -204,13 +215,7 @@ public class Loader
FMLLog.severe("The mod %s does not wish to run in Minecraft version %s. You will have to remove it to play.", mod.getModId(), getMCVersionString());
throw new WrongMinecraftVersionException(mod);
}
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new Function<ArtifactVersion, String>()
{
public String apply(ArtifactVersion v)
{
return v.getLabel();
}
});
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new ArtifactVersionNameFunction());
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
if (!missingMods.isEmpty())
@@ -260,10 +265,15 @@ public class Loader
catch (ModSortingException sortException)
{
FMLLog.severe("A dependency cycle was detected in the input mod set so an ordering cannot be determined");
FMLLog.severe("The visited mod list is %s", sortException.getExceptionData().getVisitedNodes());
FMLLog.severe("The first mod in the cycle is %s", sortException.getExceptionData().getFirstBadNode());
SortingExceptionData<ModContainer> exceptionData = sortException.getExceptionData();
FMLLog.severe("The first mod in the cycle is %s", exceptionData.getFirstBadNode());
FMLLog.severe("The mod cycle involves");
for (ModContainer mc : exceptionData.getVisitedNodes())
{
FMLLog.severe("%s : before: %s, after: %s", mc.toString(), mc.getDependants(), mc.getDependencies());
}
FMLLog.log(Level.SEVERE, sortException, "The full error");
throw new LoaderException(sortException);
throw sortException;
}
}
finally
@@ -466,7 +476,7 @@ public class Loader
mods = Lists.newArrayList();
namedMods = Maps.newHashMap();
modController = new LoadController(this);
modController.transition(LoaderState.LOADING);
modController.transition(LoaderState.LOADING, false);
ModDiscoverer disc = identifyMods();
disableRequestedMods();
FMLLog.fine("Reloading logging properties from %s", loggingProperties.getPath());
@@ -490,7 +500,7 @@ public class Loader
}
}
}
modController.transition(LoaderState.CONSTRUCTING);
modController.transition(LoaderState.CONSTRUCTING, false);
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, disc.getASMTable());
FMLLog.fine("Mod signature data");
for (ModContainer mod : getActiveModList())
@@ -501,9 +511,9 @@ public class Loader
{
FMLLog.fine("No user mod signature data found");
}
modController.transition(LoaderState.PREINITIALIZATION);
modController.transition(LoaderState.PREINITIALIZATION, false);
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, disc.getASMTable(), canonicalConfigDir);
modController.transition(LoaderState.INITIALIZATION);
modController.transition(LoaderState.INITIALIZATION, false);
}
private void disableRequestedMods()
@@ -679,13 +689,15 @@ public class Loader
{
// Mod controller should be in the initialization state here
modController.distributeStateMessage(LoaderState.INITIALIZATION);
modController.transition(LoaderState.POSTINITIALIZATION);
modController.transition(LoaderState.POSTINITIALIZATION, false);
// Construct the "mod object table" so mods can refer to it in IMC and postinit
GameData.buildModObjectTable();
modController.distributeStateMessage(FMLInterModComms.IMCEvent.class);
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
modController.transition(LoaderState.AVAILABLE);
modController.transition(LoaderState.AVAILABLE, false);
modController.distributeStateMessage(LoaderState.AVAILABLE);
// Dump the custom registry data map, if necessary
GameData.dumpRegistry(minecraftDir);
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size()==1 ? "" : "s");
}
@@ -726,7 +738,7 @@ public class Loader
try
{
modController.distributeStateMessage(LoaderState.SERVER_STARTING, server);
modController.transition(LoaderState.SERVER_STARTING);
modController.transition(LoaderState.SERVER_STARTING, false);
}
catch (Throwable t)
{
@@ -739,13 +751,13 @@ public class Loader
public void serverStarted()
{
modController.distributeStateMessage(LoaderState.SERVER_STARTED);
modController.transition(LoaderState.SERVER_STARTED);
modController.transition(LoaderState.SERVER_STARTED, false);
}
public void serverStopping()
{
modController.distributeStateMessage(LoaderState.SERVER_STOPPING);
modController.transition(LoaderState.SERVER_STOPPING);
modController.transition(LoaderState.SERVER_STOPPING, false);
}
public BiMap<ModContainer, Object> getModObjectList()
@@ -784,16 +796,8 @@ public class Loader
public void serverStopped()
{
modController.distributeStateMessage(LoaderState.SERVER_STOPPED);
try
{
modController.transition(LoaderState.SERVER_STOPPED);
}
catch (LoaderException e)
{
modController.forceState(LoaderState.SERVER_STOPPED);
// Discard any exceptions here - they mask other, real, exceptions
}
modController.transition(LoaderState.AVAILABLE);
modController.transition(LoaderState.SERVER_STOPPED, true);
modController.transition(LoaderState.AVAILABLE, true);
}
public boolean serverAboutToStart(Object server)
@@ -801,7 +805,7 @@ public class Loader
try
{
modController.distributeStateMessage(LoaderState.SERVER_ABOUT_TO_START, server);
modController.transition(LoaderState.SERVER_ABOUT_TO_START);
modController.transition(LoaderState.SERVER_ABOUT_TO_START, false);
}
catch (Throwable t)
{
@@ -810,4 +814,28 @@ public class Loader
}
return true;
}
public Map<String,String> getFMLBrandingProperties()
{
if (fmlBrandingProperties == null)
{
Properties loaded = new Properties();
try
{
loaded.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
}
catch (Exception e)
{
// File not found - ignore
}
fmlBrandingProperties = Maps.fromProperties(loaded);
}
return fmlBrandingProperties;
}
public Map<String,String> getCustomModProperties(String modId)
{
return getIndexedModList().get(modId).getCustomModProperties();
}
}
+167 -9
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -18,12 +18,57 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import net.minecraft.item.ItemBlock;
import net.minecraft.network.packet.Packet250CustomPayload;
import cpw.mods.fml.common.event.FMLFingerprintViolationEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerAboutToStartEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppedEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.registry.GameRegistry;
/**
* The new mod style in FML 1.3
* This defines a Mod to FML.
* Any class found with this annotation applied will be loaded as a Mod. The instance that is loaded will
* represent the mod to other Mods in the system. It will be sent various subclasses of {@link FMLEvent}
* at pre-defined times during the loading of the game, based on where you have applied the {@link EventHandler}
* annotation.
*
* This annotation is usually paired with a second annotation {@link NetworkMod}, which declares the
* network related properties of this mod.
*
* <p>This is a simple example of a Mod. It has the modId of "MyModId", the name of "My example mod", it is
* version 1.0, and depends on FML being loaded. It has the {@link NetworkMod} annotation as well, declaring it uses channel
* "MyModChannel" and {@link IPacketHandler} class PacketHandler.
* <pre>{@code
* package mymod;
* // Declare that this is a mod with modId "MyModId", name "My example mod", version "1.0" and dependency on FML.
* {@literal @}Mod(modId="MyModId",name="My example mod",version="1.0",dependencies="required-after:FML")
* // Declare that this is a network mod using the {@link Packet250CustomPayload} channel "MyModChannel", required on the client if it's present
* // on the server, with {@link IPacketHandler} class PacketHandler.
* {@literal @}NetworkMod(channels = { "MyModChannel" }, clientSideRequired = true, serverSideRequired = false, packetHandler = PacketHandler.class)
* public class MyMod {
* // Populate this field with the instance of the mod created by FML
* {@literal @}Instance("MyModId")
* public MyMod instance;
*
* // Mark this method for receiving an {@link FMLEvent} (in this case, it's the {@link FMLPreInitializationEvent})
* {@literal @}EventHandler public void preInit(FMLPreInitializationEvent event)
* {
* // Do stuff in pre-init phase (read config, create blocks and items, register them)
* }
* }
* </pre>
*
* @author cpw
*
@@ -65,10 +110,14 @@ public @interface Mod
* An optional bukkit plugin that will be injected into the bukkit plugin framework if
* this mod is loaded into the FML framework and the bukkit coremod is present.
* Instances of the bukkit plugin can be obtained via the {@link BukkitPluginRef} annotation on fields.
*
* This may be implemented by a bukkit integration. It is not provided with vanilla FML or MinecraftForge.
*
* @return The name of the plugin to load for this mod
*/
String bukkitPlugin() default "";
/**
* NOT YET IMPLEMENTED.</br>
* Mods that this mod will <strong>not</strong> load with.
* An optional comma separated string of (+|-)(*|modid[@value]) which specify mods that
* this mod will refuse to load with, resulting in the game failing to start.
@@ -98,34 +147,109 @@ public @interface Mod
*
* @return A string listing modids to exclude from loading with this mod.
*/
@Deprecated
String modExclusionList() default "";
/**
* Specifying this field allows for a mod to expect a signed jar with a fingerprint matching this value.
* The fingerprint should be SHA-1 encoded, lowercase with ':' removed. An empty value indicates that
* the mod is not expecting to be signed.
*
* Any incorrectness of the fingerprint, be it missing or wrong, will result in the {@link FingerprintWarning}
* method firing <i>prior to any other event on the mod</i>.
* Any incorrectness of the fingerprint, be it missing or wrong, will result in the {@link FMLFingerprintViolationEvent}
* event firing <i>prior to any other event on the mod</i>.
*
* @return A certificate fingerprint that is expected for this mod.
*/
String certificateFingerprint() default "";
/**
* The language the mod is authored in. This will be used to control certain libraries being downloaded.
* The language the mod is authored in. This will be used to control certain compatibility behaviours for this mod.
* Valid values are currently "java", "scala"
*
* @return The language the mod is authored in
*/
String modLanguage() default "java";
/**
* NOT YET IMPLEMENTED. </br>
* An optional ASM hook class, that can be used to apply ASM to classes loaded from this mod. It is also given
* the ASM tree of the class declaring {@link Mod} to with what it will.
* the ASM tree of the class declaring {@link Mod} to do with what it will.
*
* @return The name of a class to be loaded and executed. Must implement {@link IASMHook}.
*/
@Deprecated
String asmHookClass() default "";
/**
* A list of custom properties for this mod. Completely up to the mod author if/when they
* want to put anything in here.
* @return an optional list of custom properties
*/
CustomProperty[] customProperties() default {};
/**
* A custom key => value property pair for use with {@link Mod#customProperties()}
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface CustomProperty
{
/**
* A key. Should be unique.
* @return A key
*/
String k();
/**
* A value. Can be anything.
* @return A value
*/
String v();
}
/**
* Marks the associated method as handling an FML lifecycle event.
* The method must have a single parameter, one of the following types. This annotation
* replaces the multiple different annotations that previously were used.
*
* Current event classes. This first section is standard lifecycle events. They are dispatched
* at various phases as the game starts. Each event should have information useful to that
* phase of the lifecycle. They are fired in this order.
*
* These suggestions are mostly just suggestions on what to do in each event.
* <ul>
* <li> {@link FMLPreInitializationEvent} : Run before anything else. Read your config, create blocks,
* items, etc, and register them with the {@link GameRegistry}.</li>
* <li> {@link FMLInitializationEvent} : Do your mod setup. Build whatever data structures you care about. Register recipes,
* send {@link FMLInterModComms} messages to other mods.</li>
* <li> {@link FMLPostInitializationEvent} : Handle interaction with other mods, complete your setup based on this.</li>
* </ul>
* <p>These are the server lifecycle events. They are fired whenever a server is running, or about to run. Each time a server
* starts they will be fired in this sequence.
* <ul>
* <li> {@link FMLServerAboutToStartEvent} : Use if you need to handle something before the server has even been created.</li>
* <li> {@link FMLServerStartingEvent} : Do stuff you need to do to set up the server. register commands, tweak the server.</li>
* <li> {@link FMLServerStartedEvent} : Do what you need to with the running server.</li>
* <li> {@link FMLServerStoppingEvent} : Do what you need to before the server has started it's shutdown sequence.</li>
* <li> {@link FMLServerStoppedEvent} : Do whatever cleanup you need once the server has shutdown. Generally only useful
* on the integrated server.</li>
* </ul>
* The second set of events are more specialized, for receiving notification of specific
* information.
* <ul>
* <li> {@link FMLFingerprintViolationEvent} : Sent just before {@link FMLPreInitializationEvent}
* if something is wrong with your mod signature</li>
* <li> {@link IMCEvent} : Sent just after {@link FMLInitializationEvent} if you have IMC messages waiting
* from other mods</li>
* </ul>
*
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EventHandler{}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as to be called at if there is something wrong with the certificate fingerprint of
* the mod's jar, or it is missing, or otherwise a problem.
* @author cpw
@@ -133,72 +257,90 @@ public @interface Mod
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface FingerprintWarning {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "pre-initialization" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface PreInit {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "initialization" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface Init {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "post-initialization" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface PostInit {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "server-about-to-start" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface ServerAboutToStart {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "server-starting" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface ServerStarting {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "server-started" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface ServerStarted {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "server-stopping" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface ServerStopping {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as being called at the "server-stopped" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface ServerStopped {}
/**
* Deprecated for {@link EventHandler}<br/>
* Mark the designated method as the receiver for {@link FMLInterModComms} messages
* Called between {@link Init} and {@link PostInit}
* @author cpw
@@ -206,9 +348,11 @@ public @interface Mod
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface IMCCallback {}
/**
* Populate the annotated field with the mod instance.
* Populate the annotated field with the mod instance based on the specified ModId. This can be used
* to retrieve instances of other mods.
* @author cpw
*
*/
@@ -234,12 +378,14 @@ public @interface Mod
String value() default "";
}
/**
* Populate the annotated field with an instance of the Block as specified
* NOT IMPLEMENTED AND SCHEDULED FOR REMOVAL.<br/>
* Populate the annotated field with an instance of the Block as specified. This never worked. It will be removed.
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Deprecated
public @interface Block {
/**
* The block's name
@@ -251,12 +397,14 @@ public @interface Mod
Class<?> itemTypeClass() default ItemBlock.class;
}
/**
* Populate the annotated field with an Item
* NOT IMPLEMENTED AND SCHEDULED FOR REMOVAL.<br/>
* Populate the annotated field with an Item. This never worked. It will be removed.
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Deprecated
public @interface Item {
/**
* The name of the item
@@ -267,4 +415,14 @@ public @interface Mod
*/
String typeClass();
}
/**
* Mod instance factory method. Should return an instance of the mod. Applies only to static methods on the same class as {@link Mod}.
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InstanceFactory {
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -20,12 +20,13 @@ import java.net.URLClassLoader;
import java.util.List;
import java.util.logging.Level;
import net.minecraft.launchwrapper.LaunchClassLoader;
import com.google.common.collect.ImmutableList;
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;
/**
* A simple delegating class loader used to load mods into the system
@@ -37,16 +38,16 @@ import cpw.mods.fml.relauncher.RelaunchClassLoader;
public class ModClassLoader extends URLClassLoader
{
private static final List<String> STANDARD_LIBRARIES = ImmutableList.of("jinput.jar", "lwjgl.jar", "lwjgl_util.jar");
private RelaunchClassLoader mainClassLoader;
private LaunchClassLoader mainClassLoader;
public ModClassLoader(ClassLoader parent) {
super(new URL[0], null);
this.mainClassLoader = (RelaunchClassLoader)parent;
this.mainClassLoader = (LaunchClassLoader)parent;
}
public void addFile(File modFile) throws MalformedURLException
{
URL url = modFile.toURI().toURL();
URL url = modFile.toURI().toURL();
mainClassLoader.addURL(url);
}
+6 -1
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -15,8 +15,10 @@ package cpw.mods.fml.common;
import java.io.File;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
@@ -131,4 +133,7 @@ public interface ModContainer
VersionRange acceptableMinecraftVersionRange();
Certificate getSigningCertificate();
public static final Map<String,String> EMPTY_PROPERTIES = ImmutableMap.of();
Map<String,String> getCustomModProperties();
}
+16 -5
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -17,6 +17,8 @@ import java.lang.reflect.Modifier;
import java.util.Set;
import java.util.logging.Level;
import com.google.common.base.Strings;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.relauncher.Side;
@@ -27,7 +29,7 @@ import cpw.mods.fml.relauncher.Side;
*/
public class ProxyInjector
{
public static void inject(ModContainer mod, ASMDataTable data, Side side)
public static void inject(ModContainer mod, ASMDataTable data, Side side, ILanguageAdapter languageAdapter)
{
FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
@@ -46,10 +48,16 @@ public class ProxyInjector
throw new LoaderException();
}
String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
SidedProxy annotation = target.getAnnotation(SidedProxy.class);
if (!Strings.isNullOrEmpty(annotation.modId()) && !annotation.modId().equals(mod.getModId()))
{
FMLLog.fine("Skipping proxy injection for %s.%s since it is not for mod %s", targ.getClassName(), targ.getObjectName(), mod.getModId());
continue;
}
String targetType = side.isClient() ? annotation.clientSide() : annotation.serverSide();
Object proxy=Class.forName(targetType, true, mcl).newInstance();
if ((target.getModifiers() & Modifier.STATIC) == 0 )
if (languageAdapter.supportsStatics() && (target.getModifiers() & Modifier.STATIC) == 0 )
{
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName());
throw new LoaderException();
@@ -59,7 +67,7 @@ public class ProxyInjector
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName());
throw new LoaderException();
}
target.set(null, proxy);
languageAdapter.setProxy(target, proxyTarget, proxy);
}
catch (Exception e)
{
@@ -67,5 +75,8 @@ public class ProxyInjector
throw new LoaderException(e);
}
}
// Allow language specific proxy injection.
languageAdapter.setInternalProxies(mod, side, mcl);
}
}
+33 -1
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -18,6 +18,29 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Sided proxies are loaded based on the specific environment they find themselves loaded into.
* They are used to ensure that client-specific code (such as GUIs) is only loaded into the game
* on the client side.
* It is applied to static fields of a class, anywhere in your mod code. FML will scan
* and load any classes with this annotation at mod construction time.
*
* <p>
* This example will load a CommonProxy on the server side, and a ClientProxy on the client side.
*
* <pre>{@code
* public class MySidedProxyHolder {
* {@literal @}SidedProxy(modId="MyModId",clientSide="mymod.ClientProxy", serverSide="mymod.CommonProxy")
* public static CommonProxy proxy;
* }
*
* public class CommonProxy {
* // Common or server stuff here that needs to be overridden on the client
* }
*
* public class ClientProxy extends CommonProxy {
* // Override common stuff with client specific stuff here
* }
* </pre>
* @author cpw
*
*/
@@ -35,8 +58,17 @@ public @interface SidedProxy
*/
String serverSide() default "";
@Deprecated
/**
* Not implemented
* The name of a special bukkit plugin class to load and populate
*/
String bukkitSide() default "";
/**
* The (optional) name of a mod to load this proxy for. This will help ensure correct behaviour when loading a combined
* scala/java mod package. It is almost never going to be required, unless you ship both Scala and Java {@link Mod} content
* in a single jar.
*/
String modId() default "";
}
@@ -5,13 +5,15 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
@@ -19,7 +21,6 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import cpw.mods.fml.common.registry.BlockProxy;
import cpw.mods.fml.relauncher.IClassTransformer;
public class ASMTransformer implements IClassTransformer
{
@@ -30,10 +30,13 @@ import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import javax.swing.JOptionPane;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
@@ -41,9 +44,10 @@ import org.objectweb.asm.Opcodes;
import cpw.mods.fml.common.CertificateHelper;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.common.patcher.ClassPatchManager;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
public class FMLSanityChecker implements IFMLCallHook
{
@@ -68,7 +72,7 @@ public class FMLSanityChecker implements IFMLCallHook
}
}
private RelaunchClassLoader cl;
private LaunchClassLoader cl;
@Override
public Void call() throws Exception
@@ -137,8 +141,11 @@ public class FMLSanityChecker implements IFMLCallHook
@Override
public void injectData(Map<String, Object> data)
{
cl = (RelaunchClassLoader) data.get("classLoader");
FMLDeobfuscatingRemapper.INSTANCE.setup((File)data.get("mcLocation"), cl, (String) data.get("deobfuscationFileName"));
cl = (LaunchClassLoader) data.get("classLoader");
File mcDir = (File)data.get("mcLocation");
FMLDeobfuscatingRemapper.INSTANCE.setup(mcDir, cl, (String) data.get("deobfuscationFileName"));
File binpatches = new File(mcDir,"binpatch");
ClassPatchManager.INSTANCE.setup(FMLLaunchHandler.side());
}
}
@@ -32,6 +32,8 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@@ -48,7 +50,7 @@ import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.relauncher.IClassTransformer;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
public class AccessTransformer implements IClassTransformer
{
@@ -152,6 +154,7 @@ public class AccessTransformer implements IClassTransformer
return true;
}
});
System.out.printf("Loaded %d rules from AccessTransformer config file %s\n", modifiers.size(), rulesFile);
}
@SuppressWarnings("unchecked")
@@ -163,7 +166,7 @@ public class AccessTransformer implements IClassTransformer
if (DEBUG)
{
System.out.printf("Considering all methods and fields on %s (%s): %b\n", name, transformedName, makeAllPublic);
FMLRelaunchLog.fine("Considering all methods and fields on %s (%s): %b\n", name, transformedName, makeAllPublic);
}
if (!makeAllPublic && !modifiers.containsKey(name)) { return bytes; }
@@ -5,13 +5,16 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers;
import net.minecraft.launchwrapper.IClassNameTransformer;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
@@ -20,8 +23,6 @@ import org.objectweb.asm.tree.ClassNode;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.common.asm.transformers.deobf.FMLRemappingAdapter;
import cpw.mods.fml.relauncher.IClassNameTransformer;
import cpw.mods.fml.relauncher.IClassTransformer;
public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer {
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -58,6 +58,7 @@ public class MCPMerger
private static HashSet<String> copyToServer = new HashSet<String>();
private static HashSet<String> copyToClient = new HashSet<String>();
private static HashSet<String> dontAnnotate = new HashSet<String>();
private static HashSet<String> dontProcess = new HashSet<String>();
private static final boolean DEBUG = false;
public static void main(String[] args)
@@ -71,9 +72,8 @@ public class MCPMerger
File map_file = new File(args[0]);
File client_jar = new File(args[1]);
File server_jar = new File(args[2]);
File client_jar_tmp = new File(args[1] + ".MergeBack");
File server_jar_tmp = new File(args[2] + ".MergeBack");
File client_jar_tmp = new File(args[1] + ".backup_merge");
File server_jar_tmp = new File(args[2] + ".backup_merge");
if (client_jar_tmp.exists() && !client_jar_tmp.delete())
{
@@ -150,12 +150,13 @@ public class MCPMerger
line = line.split("#")[0];
char cmd = line.charAt(0);
line = line.substring(1).trim();
switch (cmd)
{
case '!': dontAnnotate.add(line); break;
case '<': copyToClient.add(line); break;
case '>': copyToServer.add(line); break;
case '>': copyToServer.add(line); break;
case '^': dontProcess.add(line); break;
}
}
@@ -344,8 +345,20 @@ public class MCPMerger
outFile.putNextEntry(entry);
continue;
}
String entryName = entry.getName();
if (!entryName.endsWith(".class") || entryName.startsWith("."))
boolean filtered = false;
for (String filter : dontProcess)
{
if (entryName.startsWith(filter))
{
filtered = true;
break;
}
}
if (filtered || !entryName.endsWith(".class") || entryName.startsWith("."))
{
ZipEntry newEntry = new ZipEntry(entry.getName());
outFile.putNextEntry(newEntry);
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -26,6 +26,8 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@@ -39,8 +41,6 @@ import com.google.common.collect.Lists;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
import cpw.mods.fml.relauncher.IClassTransformer;
public class MarkerTransformer implements IClassTransformer
{
private ListMultimap<String, String> markers = ArrayListMultimap.create();
@@ -0,0 +1,13 @@
package cpw.mods.fml.common.asm.transformers;
import net.minecraft.launchwrapper.IClassTransformer;
import cpw.mods.fml.common.patcher.ClassPatchManager;
public class PatchingTransformer implements IClassTransformer {
@Override
public byte[] transform(String name, String transformedName, byte[] bytes)
{
return ClassPatchManager.INSTANCE.applyPatch(name, transformedName, bytes);
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -15,6 +15,8 @@ package cpw.mods.fml.common.asm.transformers;
import java.util.Iterator;
import java.util.List;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
@@ -23,13 +25,12 @@ import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import cpw.mods.fml.relauncher.FMLRelauncher;
import cpw.mods.fml.relauncher.IClassTransformer;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.SideOnly;
public class SideTransformer implements IClassTransformer
{
private static String SIDE = FMLRelauncher.side();
private static String SIDE = FMLLaunchHandler.side().name();
private static final boolean DEBUG = false;
@SuppressWarnings("unchecked")
@Override
@@ -13,6 +13,7 @@
package cpw.mods.fml.common.asm.transformers.deobf;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -23,9 +24,12 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.commons.Remapper;
@@ -38,7 +42,9 @@ import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -48,7 +54,8 @@ import com.google.common.io.InputSupplier;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
public class FMLDeobfuscatingRemapper extends Remapper {
public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper();
@@ -62,7 +69,7 @@ public class FMLDeobfuscatingRemapper extends Remapper {
private Map<String,Map<String,String>> fieldNameMaps;
private Map<String,Map<String,String>> methodNameMaps;
private RelaunchClassLoader classLoader;
private LaunchClassLoader classLoader;
private FMLDeobfuscatingRemapper()
{
@@ -70,17 +77,61 @@ public class FMLDeobfuscatingRemapper extends Remapper {
mcpNameBiMap=ImmutableBiMap.of();
}
public void setup(File mcDir, RelaunchClassLoader classLoader, String deobfFileName)
public void setupLoadOnly(String deobfFileName, boolean loadAll)
{
try
{
File mapData = new File(deobfFileName);
LZMAInputSupplier zis = new LZMAInputSupplier(new FileInputStream(mapData));
InputSupplier<InputStreamReader> srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8);
List<String> srgList = CharStreams.readLines(srgSupplier);
rawMethodMaps = Maps.newHashMap();
rawFieldMaps = Maps.newHashMap();
Builder<String, String> builder = ImmutableBiMap.<String,String>builder();
Builder<String, String> mcpBuilder = ImmutableBiMap.<String,String>builder();
Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults();
for (String line : srgList)
{
String[] parts = Iterables.toArray(splitter.split(line),String.class);
String typ = parts[0];
if ("CL".equals(typ))
{
parseClass(builder, parts);
parseMCPClass(mcpBuilder,parts);
}
else if ("MD".equals(typ) && loadAll)
{
parseMethod(parts);
}
else if ("FD".equals(typ) && loadAll)
{
parseField(parts);
}
}
classNameBiMap = builder.build();
// Special case some mappings for modloader mods
mcpBuilder.put("BaseMod","net/minecraft/src/BaseMod");
mcpBuilder.put("ModLoader","net/minecraft/src/ModLoader");
mcpBuilder.put("EntityRendererProxy","net/minecraft/src/EntityRendererProxy");
mcpBuilder.put("MLProp","net/minecraft/src/MLProp");
mcpBuilder.put("TradeEntry","net/minecraft/src/TradeEntry");
mcpNameBiMap = mcpBuilder.build();
}
catch (IOException ioe)
{
Logger.getLogger("FML").log(Level.SEVERE, "An error occurred loading the deobfuscation map data", ioe);
}
methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size());
fieldNameMaps = Maps.newHashMapWithExpectedSize(rawFieldMaps.size());
}
public void setup(File mcDir, LaunchClassLoader classLoader, String deobfFileName)
{
this.classLoader = classLoader;
try
{
File libDir = new File(mcDir, "lib");
File mapData = new File(libDir, deobfFileName);
mapData = mapData.getCanonicalFile();
ZipFile mapZip = new ZipFile(mapData);
ZipEntry classData = mapZip.getEntry("joined.srg");
ZipInputSupplier zis = new ZipInputSupplier(mapZip, classData);
InputStream classData = getClass().getResourceAsStream(deobfFileName);
LZMAInputSupplier zis = new LZMAInputSupplier(classData);
InputSupplier<InputStreamReader> srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8);
List<String> srgList = CharStreams.readLines(srgSupplier);
rawMethodMaps = Maps.newHashMap();
@@ -125,7 +176,8 @@ public class FMLDeobfuscatingRemapper extends Remapper {
public boolean isRemappedClass(String className)
{
return classNameBiMap.containsKey(className) || mcpNameBiMap.containsKey(className);
className = className.replace('.', '/');
return classNameBiMap.containsKey(className) || mcpNameBiMap.containsKey(className) || (!classNameBiMap.isEmpty() && className.indexOf('/') == -1);
}
private void parseField(String[] parts)
@@ -141,7 +193,46 @@ public class FMLDeobfuscatingRemapper extends Remapper {
{
rawFieldMaps.put(cl, Maps.<String,String>newHashMap());
}
rawFieldMaps.get(cl).put(oldName, newName);
rawFieldMaps.get(cl).put(oldName + ":" + getFieldType(cl, oldName), newName);
rawFieldMaps.get(cl).put(oldName + ":null", newName);
}
/*
* Cache the field descriptions for classes so we don't repeatedly reload the same data again and again
*/
private Map<String,Map<String,String>> fieldDescriptions = Maps.newHashMap();
private String getFieldType(String owner, String name)
{
if (fieldDescriptions.containsKey(owner))
{
return fieldDescriptions.get(owner).get(name);
}
synchronized (fieldDescriptions)
{
try
{
byte[] classBytes = classLoader.getClassBytes(owner);
if (classBytes == null)
{
return null;
}
ClassReader cr = new ClassReader(classBytes);
ClassNode classNode = new ClassNode();
cr.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
Map<String,String> resMap = Maps.newHashMap();
for (FieldNode fieldNode : (List<FieldNode>) classNode.fields) {
resMap.put(fieldNode.name, fieldNode.desc);
}
fieldDescriptions.put(owner, resMap);
return resMap.get(name);
}
catch (IOException e)
{
FMLLog.log(Level.SEVERE,e, "A critical exception occured reading a class file %s", owner);
}
return null;
}
}
private void parseClass(Builder<String, String> builder, String[] parts)
@@ -180,7 +271,7 @@ public class FMLDeobfuscatingRemapper extends Remapper {
return name;
}
Map<String, String> fieldMap = getFieldMap(owner);
return fieldMap!=null && fieldMap.containsKey(name) ? fieldMap.get(name) : name;
return fieldMap!=null && fieldMap.containsKey(name+":"+desc) ? fieldMap.get(name+":"+desc) : name;
}
@Override
@@ -319,4 +410,9 @@ public class FMLDeobfuscatingRemapper extends Remapper {
fieldNameMaps.put(name, ImmutableMap.copyOf(fieldMap));
// System.out.printf("Maps: %s %s\n", name, methodMap);
}
public Set<String> getObfedClasses()
{
return ImmutableSet.copyOf(classNameBiMap.keySet());
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -17,22 +17,22 @@ import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import LZMA.LzmaInputStream;
import com.google.common.io.InputSupplier;
public class ZipInputSupplier implements InputSupplier<InputStream> {
private ZipFile zipFile;
private ZipEntry zipEntry;
public class LZMAInputSupplier implements InputSupplier<InputStream> {
private InputStream compressedData;
public ZipInputSupplier(ZipFile zip, ZipEntry entry)
public LZMAInputSupplier(InputStream compressedData)
{
this.zipFile = zip;
this.zipEntry = entry;
this.compressedData = compressedData;
}
@Override
public InputStream getInput() throws IOException
{
return zipFile.getInputStream(zipEntry);
return new LzmaInputStream(this.compressedData);
}
}
@@ -27,7 +27,7 @@ import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.ModClassLoader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.RelaunchLibraryManager;
import cpw.mods.fml.relauncher.CoreModManager;
public class ModDiscoverer
{
@@ -41,7 +41,7 @@ public class ModDiscoverer
public void findClasspathMods(ModClassLoader modClassLoader)
{
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries()).addAll(RelaunchLibraryManager.getLibraries()).build();
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries()).addAll(CoreModManager.getLibraries()).build();
File[] minecraftSources = modClassLoader.getParentSources();
if (minecraftSources.length == 1 && minecraftSources[0].isFile())
{
@@ -0,0 +1,12 @@
package cpw.mods.fml.common.functions;
import com.google.common.base.Function;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class ArtifactVersionNameFunction implements Function<ArtifactVersion, String> {
public String apply(ArtifactVersion v)
{
return v.getLabel();
}
}
@@ -0,0 +1,18 @@
package cpw.mods.fml.common.launcher;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import net.minecraft.launchwrapper.LaunchClassLoader;
public class FMLServerTweaker extends FMLTweaker {
@Override
public String getLaunchTarget()
{
return "net.minecraft.server.MinecraftServer";
}
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader)
{
FMLLaunchHandler.configureForServerLaunch(classLoader, this);
}
}
@@ -0,0 +1,99 @@
package cpw.mods.fml.common.launcher;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.common.base.Throwables;
import com.google.common.collect.ObjectArrays;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import net.minecraft.launchwrapper.ITweaker;
import net.minecraft.launchwrapper.LaunchClassLoader;
public class FMLTweaker implements ITweaker {
private List<String> args;
private File gameDir;
private File assetsDir;
private String profile;
private static URI jarLocation;
private String[] array;
@Override
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile)
{
this.args = args;
this.gameDir = (gameDir == null ? new File(".") : gameDir);
this.assetsDir = assetsDir;
this.profile = profile;
try
{
jarLocation = getClass().getProtectionDomain().getCodeSource().getLocation().toURI();
}
catch (URISyntaxException e)
{
Logger.getLogger("FMLTWEAK").log(Level.SEVERE, "Missing URI information for FML tweak");
throw Throwables.propagate(e);
}
}
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader)
{
classLoader.addTransformerExclusion("cpw.mods.fml.repackage.");
classLoader.addTransformerExclusion("cpw.mods.fml.relauncher.");
classLoader.addTransformerExclusion("cpw.mods.fml.common.asm.transformers.");
classLoader.addClassLoaderExclusion("LZMA.");
FMLLaunchHandler.configureForClientLaunch(classLoader, this);
}
@Override
public String getLaunchTarget()
{
return "net.minecraft.client.main.Main";
}
@Override
public String[] getLaunchArguments()
{
String[] array = args.toArray(new String[args.size()]);
if (gameDir != null)
{
array = ObjectArrays.concat(gameDir.getAbsolutePath(),array);
array = ObjectArrays.concat("--gameDir",array);
}
if (assetsDir != null)
{
array = ObjectArrays.concat(assetsDir.getAbsolutePath(),array);
array = ObjectArrays.concat("--assetsDir",array);
}
if (profile != null)
{
array = ObjectArrays.concat(profile,array);
array = ObjectArrays.concat("--version",array);
}
else
{
array = ObjectArrays.concat("UnknownFMLProfile",array);
array = ObjectArrays.concat("--version",array);
}
return array;
}
public File getGameDir()
{
return gameDir;
}
public static URI getJarLocation()
{
return jarLocation;
}
}
@@ -40,6 +40,7 @@ import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.ILanguageAdapter;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderException;
@@ -496,7 +497,7 @@ public class ModLoaderModContainer implements ModContainer
{
dummyHandler.setBaseMod(mod);
}
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide(), new ILanguageAdapter.JavaAdapter());
}
catch (Exception e)
{
@@ -614,4 +615,10 @@ public class ModLoaderModContainer implements ModContainer
{
return null;
}
@Override
public Map<String, String> getCustomModProperties()
{
return EMPTY_PROPERTIES;
}
}
@@ -184,8 +184,7 @@ public class EntitySpawnPacket extends FMLPacket
ModContainer mc = nmh.getContainer();
EntityRegistration registration = EntityRegistry.instance().lookupModSpawn(mc, modEntityId);
Class<? extends Entity> cls = registration.getEntityClass();
if (cls == null)
if (registration == null || registration.getEntityClass() == null)
{
FMLLog.log(Level.WARNING, "Missing mod entity information for %s : %d", mc.getModId(), modEntityId);
return;
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -41,6 +41,7 @@ import com.google.common.hash.Hashing;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.InjectedModContainer;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.discovery.ASMDataTable;
@@ -269,6 +270,10 @@ public class FMLNetworkHandler
public NetworkModHandler findNetworkModHandler(Object mc)
{
if (mc instanceof InjectedModContainer)
{
return networkModHandlers.get(((InjectedModContainer)mc).wrappedContainer);
}
if (mc instanceof ModContainer)
{
return networkModHandlers.get(mc);
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -96,6 +96,10 @@ public class NetworkModHandler
}
}
configureNetworkMod(container);
}
protected void configureNetworkMod(ModContainer container)
{
if (this.checkHandler == null)
{
String versionBounds = mod.versionBounds();
@@ -0,0 +1,23 @@
package cpw.mods.fml.common.patcher;
public class ClassPatch {
public final String name;
public final String sourceClassName;
public final String targetClassName;
public final boolean existsAtTarget;
public final byte[] patch;
public ClassPatch(String name, String sourceClassName, String targetClassName, boolean existsAtTarget, byte[] patch)
{
this.name = name;
this.sourceClassName = sourceClassName;
this.targetClassName = targetClassName;
this.existsAtTarget = existsAtTarget;
this.patch = patch;
}
@Override
public String toString()
{
return String.format("%s : %s => %s (%b) size %d", name, sourceClassName, targetClassName, existsAtTarget, patch.length);
}
}
@@ -0,0 +1,170 @@
package cpw.mods.fml.common.patcher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.security.CodeSource;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.logging.Level;
import java.util.regex.Pattern;
import LZMA.LzmaInputStream;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.launcher.FMLTweaker;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.repackage.com.nothome.delta.GDiffPatcher;
public class ClassPatchManager {
public static final ClassPatchManager INSTANCE = new ClassPatchManager();
private GDiffPatcher patcher = new GDiffPatcher();
private ListMultimap<String, ClassPatch> patches;
private ClassPatchManager()
{
}
public byte[] applyPatch(String name, String mappedName, byte[] inputData)
{
if (patches == null)
{
return inputData;
}
List<ClassPatch> list = patches.get(name);
if (list.isEmpty())
{
return inputData;
}
for (ClassPatch patch: list)
{
if (!patch.targetClassName.equals(mappedName))
{
FMLLog.warning("Binary patch found %s for wrong class %s", patch.targetClassName, mappedName);
}
if (!patch.existsAtTarget && (inputData == null || inputData.length == 0))
{
inputData = new byte[0];
}
else if (!patch.existsAtTarget)
{
FMLLog.warning("Patcher expecting empty class data file for %s, but received non-empty", patch.targetClassName);
}
synchronized (patcher)
{
try
{
inputData = patcher.patch(inputData, patch.patch);
}
catch (IOException e)
{
FMLLog.log(Level.SEVERE, e, "Encountered problem runtime patching class %s", name);
continue;
}
}
}
FMLLog.fine("Successfully applied runtime patches for %s", mappedName);
return inputData;
}
public void setup(Side side)
{
Pattern binpatchMatcher = Pattern.compile(String.format("binpatch/%s/.*.binpatch", side.toString().toLowerCase(Locale.ENGLISH)));
JarInputStream jis;
try
{
InputStream binpatchesCompressed = getClass().getResourceAsStream("/binpatches.pack.lzma");
if (binpatchesCompressed==null)
{
FMLRelaunchLog.log(Level.SEVERE, "The binary patch set is missing. Things are probably about to go very wrong.");
return;
}
LzmaInputStream binpatchesDecompressed = new LzmaInputStream(binpatchesCompressed);
ByteArrayOutputStream jarBytes = new ByteArrayOutputStream();
JarOutputStream jos = new JarOutputStream(jarBytes);
Pack200.newUnpacker().unpack(binpatchesDecompressed, jos);
jis = new JarInputStream(new ByteArrayInputStream(jarBytes.toByteArray()));
}
catch (Exception e)
{
FMLRelaunchLog.log(Level.SEVERE, e, "Error occurred reading binary patches. Problems may occur");
throw Throwables.propagate(e);
}
patches = ArrayListMultimap.create();
do
{
try
{
JarEntry entry = jis.getNextJarEntry();
if (entry == null)
{
break;
}
if (binpatchMatcher.matcher(entry.getName()).matches())
{
ClassPatch cp = readPatch(entry, jis);
if (cp != null)
{
patches.put(cp.sourceClassName, cp);
}
}
else
{
jis.closeEntry();
}
}
catch (IOException e)
{
}
} while (true);
FMLLog.fine("Read %d binary patches", patches.size());
FMLLog.fine("Patch list :\n\t%s", Joiner.on("\t\n").join(patches.asMap().entrySet()));
}
private ClassPatch readPatch(JarEntry patchEntry, JarInputStream jis)
{
FMLLog.finest("Reading patch data from %s", patchEntry.getName());
ByteArrayDataInput input;
try
{
input = ByteStreams.newDataInput(ByteStreams.toByteArray(jis));
}
catch (IOException e)
{
FMLLog.log(Level.WARNING, e, "Unable to read binpatch file %s - ignoring", patchEntry.getName());
return null;
}
String name = input.readUTF();
String sourceClassName = input.readUTF();
String targetClassName = input.readUTF();
boolean exists = input.readBoolean();
int patchLength = input.readInt();
byte[] patchBytes = new byte[patchLength];
input.readFully(patchBytes);
return new ClassPatch(name, sourceClassName, targetClassName, exists, patchBytes);
}
}
@@ -0,0 +1,5 @@
package cpw.mods.fml.common.patcher;
public class ClassPatchingTransformer {
}
@@ -0,0 +1,95 @@
package cpw.mods.fml.common.patcher;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.repackage.com.nothome.delta.Delta;
public class GenDiffSet {
private static final List<String> RESERVED_NAMES = Arrays.asList("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9");
public static void main(String[] args) throws IOException
{
String sourceJar = args[0]; //Clean Vanilla jar minecraft.jar or minecraft_server.jar
String targetDir = args[1]; //Directory containing obfed output classes, typically mcp/reobf/minecraft
String deobfData = args[2]; //Path to FML's deobfusication_data.lzma
String outputDir = args[3]; //Path to place generated .binpatch
String killTarget = args[4]; //"true" if we should destroy the target file if it generated a successful .binpatch
Logger.getLogger("GENDIFF").log(Level.INFO, String.format("Creating patches at %s for %s from %s", outputDir, sourceJar, targetDir));
Delta delta = new Delta();
FMLDeobfuscatingRemapper remapper = FMLDeobfuscatingRemapper.INSTANCE;
remapper.setupLoadOnly(deobfData, false);
JarFile sourceZip = new JarFile(sourceJar);
boolean kill = killTarget.equalsIgnoreCase("true");
File f = new File(outputDir);
f.mkdirs();
for (String name : remapper.getObfedClasses())
{
// Logger.getLogger("GENDIFF").info(String.format("Evaluating path for data :%s",name));
String fileName = name;
String jarName = name;
if (RESERVED_NAMES.contains(name.toUpperCase(Locale.ENGLISH)))
{
fileName = "_"+name;
}
File targetFile = new File(targetDir, fileName.replace('/', File.separatorChar) + ".class");
jarName = jarName+".class";
if (targetFile.exists())
{
String sourceClassName = name.replace('/', '.');
String targetClassName = remapper.map(name).replace('/', '.');
JarEntry entry = sourceZip.getJarEntry(jarName);
byte[] vanillaBytes = entry != null ? ByteStreams.toByteArray(sourceZip.getInputStream(entry)) : new byte[0];
byte[] patchedBytes = Files.toByteArray(targetFile);
byte[] diff = delta.compute(vanillaBytes, patchedBytes);
ByteArrayDataOutput diffOut = ByteStreams.newDataOutput(diff.length + 50);
// Original name
diffOut.writeUTF(name);
// Source name
diffOut.writeUTF(sourceClassName);
// Target name
diffOut.writeUTF(targetClassName);
// exists at original
diffOut.writeBoolean(entry != null);
// length of patch
diffOut.writeInt(diff.length);
// patch
diffOut.write(diff);
File target = new File(outputDir, targetClassName+".binpatch");
target.getParentFile().mkdirs();
Files.write(diffOut.toByteArray(), target);
Logger.getLogger("GENDIFF").info(String.format("Wrote patch for %s (%s) at %s",name, targetClassName, target.getAbsolutePath()));
if (kill)
{
targetFile.delete();
Logger.getLogger("GENDIFF").info(String.format(" Deleted target: %s", targetFile.toString()));
}
}
}
sourceZip.close();
}
}
@@ -25,11 +25,17 @@ import java.util.logging.Level;
import net.minecraft.block.Block;
import net.minecraft.block.BlockSand;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.ImmutableTable.Builder;
@@ -40,6 +46,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
import com.google.common.io.Files;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
@@ -54,6 +61,7 @@ public class GameData {
private static boolean shouldContinue = true;
private static boolean isSaveValid = true;
private static ImmutableTable<String, String, Integer> modObjectTable;
private static Table<String, String, ItemStack> customItemStacks = HashBasedTable.create();
private static Map<String,String> ignoredMods;
private static boolean isModIgnoredForIdValidation(String modId)
@@ -277,7 +285,7 @@ public class GameData {
}
static Item findItem(String modId, String name)
{
if (modObjectTable == null)
if (modObjectTable == null || !modObjectTable.contains(modId, name))
{
return null;
}
@@ -293,10 +301,65 @@ public class GameData {
}
Integer blockId = modObjectTable.get(modId, name);
if (blockId >= Block.field_71973_m.length)
if (blockId == null || blockId >= Block.field_71973_m.length)
{
return null;
}
return Block.field_71973_m[blockId];
}
static ItemStack findItemStack(String modId, String name)
{
ItemStack is = customItemStacks.get(modId, name);
if (is == null)
{
Item i = findItem(modId, name);
if (i != null)
{
is = new ItemStack(i, 0 ,0);
}
}
if (is == null)
{
Block b = findBlock(modId, name);
if (b != null)
{
is = new ItemStack(b, 0, Short.MAX_VALUE);
}
}
return is;
}
static void registerCustomItemStack(String name, ItemStack itemStack)
{
customItemStacks.put(Loader.instance().activeModContainer().getModId(), name, itemStack);
}
public static void dumpRegistry(File minecraftDir)
{
if (customItemStacks == null)
{
return;
}
if (Boolean.valueOf(System.getProperty("fml.dumpRegistry", "false")).booleanValue())
{
ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
for (String modId : customItemStacks.rowKeySet())
{
builder.putAll(modId, customItemStacks.row(modId).keySet());
}
File f = new File(minecraftDir, "itemStackRegistry.csv");
MapJoiner mapJoiner = Joiner.on("\n").withKeyValueSeparator(",");
try
{
Files.write(mapJoiner.join(builder.build().entries()), f, Charsets.UTF_8);
FMLLog.log(Level.INFO, "Dumped item registry data to %s", f.getAbsolutePath());
}
catch (IOException e)
{
FMLLog.log(Level.SEVERE, e, "Failed to write registry data to %s", f.getAbsolutePath());
}
}
}
}
@@ -221,7 +221,7 @@ public class GameRegistry
}
catch (NoSuchMethodException e)
{
itemCtor = itemclass.getConstructor(int.class, Block.class);
itemCtor = itemclass.getConstructor(int.class, net.minecraft.block.Block.class);
i = itemCtor.newInstance(blockItemId, block);
}
GameRegistry.registerItem(i,name, modId);
@@ -275,7 +275,7 @@ public class GameRegistry
public static void registerTileEntityWithAlternatives(Class<? extends TileEntity> tileEntityClass, String id, String... alternatives)
{
TileEntity.func_70306_a(tileEntityClass, id);
Map<String,Class> teMappings = ObfuscationReflectionHelper.getPrivateValue(TileEntity.class, null, "field_70326_a", "a");
Map<String,Class> teMappings = ObfuscationReflectionHelper.getPrivateValue(TileEntity.class, null, "field_" + "70326_a", "field_70326_a", "a");
for (String s: alternatives)
{
if (!teMappings.containsKey(s))
@@ -394,4 +394,40 @@ public class GameRegistry
{
return GameData.findItem(modId, name);
}
/**
* Manually register a custom item stack with FML for later tracking. It is automatically scoped with the active modid
*
* @param name The name to register it under
* @param itemStack The itemstack to register
*/
public static void registerCustomItemStack(String name, ItemStack itemStack)
{
GameData.registerCustomItemStack(name, itemStack);
}
/**
* Lookup an itemstack based on mod and name. It will create "default" itemstacks from blocks and items if no
* explicit itemstack is found.
*
* If it is built from a block, the metadata is by default the "wildcard" value.
*
* Custom itemstacks can be dumped from minecraft by setting the system property fml.dumpRegistry to true
* (-Dfml.dumpRegistry=true on the command line will work)
*
* @param modId The modid of the stack owner
* @param name The name of the stack
* @param stackSize The size of the stack returned
* @return The custom itemstack or null if no such itemstack was found
*/
public static ItemStack findItemStack(String modId, String name, int stackSize)
{
ItemStack foundStack = GameData.findItemStack(modId, name);
if (foundStack != null)
{
ItemStack is = foundStack.func_77946_l();
is.field_77994_a = Math.min(stackSize, is.func_77976_d());
return is;
}
return null;
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -28,6 +28,7 @@ import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.StringTranslate;
@@ -45,7 +46,7 @@ public class LanguageRegistry
public String getStringLocalization(String key)
{
return getStringLocalization(key, StringTranslate.func_74808_a().func_74811_c());
return getStringLocalization(key, Minecraft.func_71410_x().func_135016_M().func_135041_c().func_135034_a());
}
public String getStringLocalization(String key, String lang)
@@ -93,9 +94,9 @@ public class LanguageRegistry
public static void reloadLanguageTable()
{
// reload language table by forcing lang to null and reloading the properties file
String lang = StringTranslate.func_74808_a().func_74811_c();
StringTranslate.func_74808_a().func_74810_a(lang, true);
// // reload language table by forcing lang to null and reloading the properties file
// String lang = StringTranslate.func_74808_a().func_74811_c();
// StringTranslate.func_74808_a().func_74810_a(lang, true);
}
@@ -120,17 +121,17 @@ public class LanguageRegistry
instance().addNameForObject(objectToName, "en_US", name);
}
public void loadLanguageTable(Properties languagePack, String lang)
public void loadLanguageTable(Map field_135032_a, String lang)
{
Properties usPack=modLanguageData.get("en_US");
if (usPack!=null) {
languagePack.putAll(usPack);
field_135032_a.putAll(usPack);
}
Properties langPack=modLanguageData.get(lang);
if (langPack==null) {
return;
}
languagePack.putAll(langPack);
field_135032_a.putAll(langPack);
}
public void loadLocalization(String localizationFile, String lang, boolean isXML)
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -19,6 +19,7 @@ import java.util.Random;
import java.util.Collection;
import java.util.Collections;
import net.minecraft.client.resources.ResourceLocation;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.item.Item;
import net.minecraft.util.Tuple;
@@ -32,6 +33,8 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Registry for villager trading control
@@ -45,8 +48,9 @@ public class VillagerRegistry
private Multimap<Integer, IVillageTradeHandler> tradeHandlers = ArrayListMultimap.create();
private Map<Class<?>, IVillageCreationHandler> villageCreationHandlers = Maps.newHashMap();
private Map<Integer, String> newVillagers = Maps.newHashMap();
private List<Integer> newVillagerIds = Lists.newArrayList();
@SideOnly(Side.CLIENT)
private Map<Integer, ResourceLocation> newVillagers;
/**
* Allow access to the {@link net.minecraft.world.gen.structure.StructureVillagePieces} array controlling new village
@@ -110,21 +114,33 @@ public class VillagerRegistry
return INSTANCE;
}
/**
* Register your villager id
* @param id
*/
public void registerVillagerId(int id)
{
if (newVillagerIds.contains(id))
{
FMLLog.severe("Attempt to register duplicate villager id %d", id);
throw new RuntimeException();
}
newVillagerIds.add(id);
}
/**
* Register a new skin for a villager type
*
* @param villagerId
* @param villagerSkin
*/
public void registerVillagerType(int villagerId, String villagerSkin)
@SideOnly(Side.CLIENT)
public void registerVillagerSkin(int villagerId, ResourceLocation villagerSkin)
{
if (newVillagers.containsKey(villagerId))
if (newVillagers == null)
{
FMLLog.severe("Attempt to register duplicate villager id %d", villagerId);
throw new RuntimeException();
newVillagers = Maps.newHashMap();
}
newVillagers.put(villagerId, villagerSkin);
newVillagerIds.add(villagerId);
}
/**
@@ -154,7 +170,8 @@ public class VillagerRegistry
* @param villagerType
* @param defaultSkin
*/
public static String getVillagerSkin(int villagerType, String defaultSkin)
@SideOnly(Side.CLIENT)
public static ResourceLocation getVillagerSkin(int villagerType, ResourceLocation defaultSkin)
{
if (instance().newVillagers.containsKey(villagerType))
{
@@ -32,10 +32,10 @@ public class ModSorter
{
private DirectedGraph<ModContainer> modGraph;
private ModContainer beforeAll = new DummyModContainer();
private ModContainer afterAll = new DummyModContainer();
private ModContainer before = new DummyModContainer();
private ModContainer after = new DummyModContainer();
private ModContainer beforeAll = new DummyModContainer("BeforeAll");
private ModContainer afterAll = new DummyModContainer("AfterAll");
private ModContainer before = new DummyModContainer("Before");
private ModContainer after = new DummyModContainer("After");
public ModSorter(List<ModContainer> modList, Map<String, ModContainer> nameLookup)
{
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -25,6 +25,11 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import cpw.mods.fml.common.FMLLog;
/**
* Topological sort for mod loading
*
@@ -174,8 +179,14 @@ public class TopologicalSort
return;
}
System.out.printf("%s: %s\n%s\n%s\n", node, sortedResult, visitedNodes, expandedNodes);
throw new ModSortingException("There was a cycle detected in the input graph, sorting is not possible", node, visitedNodes);
FMLLog.severe("Mod Sorting failed.");
FMLLog.severe("Visting node %s", node);
FMLLog.severe("Current sorted list : %s", sortedResult);
FMLLog.severe("Visited set for this node : %s", visitedNodes);
FMLLog.severe("Explored node set : %s", expandedNodes);
SetView<T> cycleList = Sets.difference(visitedNodes, expandedNodes);
FMLLog.severe("Likely cycle is in : %s", cycleList);
throw new ModSortingException("There was a cycle detected in the input graph, sorting is not possible", node, cycleList);
}
// Visit this node
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -98,4 +98,9 @@ public class DefaultArtifactVersion implements ArtifactVersion
{
return label == null ? comparableVersion.toString() : label + ( unbounded ? "" : "@" + range);
}
public VersionRange getRange()
{
return range;
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -549,4 +549,15 @@ public class VersionRange
hash = 31 * hash + ( restrictions == null ? 0 : restrictions.hashCode() );
return hash;
}
public boolean isUnboundedAbove()
{
return restrictions.size() == 1 && restrictions.get(0).getUpperBound() == null && !restrictions.get(0).isUpperBoundInclusive();
}
public String getLowerBoundString()
{
return restrictions.size() == 1 ? restrictions.get(0).getLowerBound().getVersionString() : "";
}
}
@@ -1,23 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
public class ArgsWrapper
{
public ArgsWrapper(String[] args)
{
this.args=args;
}
public String[] args;
}
@@ -37,11 +37,13 @@ import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.logging.Level;
import net.minecraft.launchwrapper.LaunchClassLoader;
import cpw.mods.fml.common.CertificateHelper;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;
public class RelaunchLibraryManager
public class CoreModManager
{
private static String[] rootPlugins = { "cpw.mods.fml.relauncher.FMLCorePlugin" , "net.minecraftforge.classloading.FMLForgePlugin" };
private static List<String> loadedLibraries = new ArrayList<String>();
@@ -50,12 +52,12 @@ public class RelaunchLibraryManager
private static List<ILibrarySet> libraries;
private static boolean deobfuscatedEnvironment;
public static void handleLaunch(File mcDir, RelaunchClassLoader actualClassLoader)
public static void handleLaunch(File mcDir, LaunchClassLoader classLoader)
{
try
{
// Are we in a 'decompiled' environment?
byte[] bs = actualClassLoader.getClassBytes("net.minecraft.world.World");
byte[] bs = classLoader.getClassBytes("net.minecraft.world.World");
if (bs != null)
{
FMLRelaunchLog.info("Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation");
@@ -72,17 +74,13 @@ public class RelaunchLibraryManager
}
pluginLocations = new HashMap<IFMLLoadingPlugin, File>();
loadPlugins = new ArrayList<IFMLLoadingPlugin>();
libraries = new ArrayList<ILibrarySet>();
for (String s : rootPlugins)
{
try
{
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) Class.forName(s, true, actualClassLoader).newInstance();
FMLRelaunchLog.finest("Adding coremod for loading %s", s);
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) Class.forName(s, true, classLoader).newInstance();
loadPlugins.add(plugin);
for (String libName : plugin.getLibraryRequestClass())
{
libraries.add((ILibrarySet) Class.forName(libName, true, actualClassLoader).newInstance());
}
}
catch (Exception e)
{
@@ -107,14 +105,14 @@ public class RelaunchLibraryManager
FMLRelaunchLog.info("Found a command line coremod : %s", s);
try
{
actualClassLoader.addTransformerExclusion(s);
Class<?> coreModClass = Class.forName(s, true, actualClassLoader);
classLoader.addTransformerExclusion(s);
Class<?> coreModClass = Class.forName(s, true, classLoader);
TransformerExclusions trExclusions = coreModClass.getAnnotation(IFMLLoadingPlugin.TransformerExclusions.class);
if (trExclusions!=null)
{
for (String st : trExclusions.value())
{
actualClassLoader.addTransformerExclusion(st);
classLoader.addTransformerExclusion(st);
}
}
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance();
@@ -123,7 +121,7 @@ public class RelaunchLibraryManager
{
for (String libName : plugin.getLibraryRequestClass())
{
libraries.add((ILibrarySet) Class.forName(libName, true, actualClassLoader).newInstance());
libraries.add((ILibrarySet) Class.forName(libName, true, classLoader).newInstance());
}
}
}
@@ -133,7 +131,7 @@ public class RelaunchLibraryManager
throw new RuntimeException(e);
}
}
discoverCoreMods(mcDir, actualClassLoader, loadPlugins, libraries);
discoverCoreMods(mcDir, classLoader, loadPlugins, libraries);
List<Throwable> caughtErrors = new ArrayList<Throwable>();
try
@@ -149,6 +147,7 @@ public class RelaunchLibraryManager
return;
}
libraries = new ArrayList<ILibrarySet>();
for (ILibrarySet lib : libraries)
{
for (int i=0; i<lib.getLibraries().length; i++)
@@ -213,7 +212,7 @@ public class RelaunchLibraryManager
try
{
actualClassLoader.addURL(libFile.toURI().toURL());
classLoader.addURL(libFile.toURI().toURL());
loadedLibraries.add(libName);
}
catch (MalformedURLException e)
@@ -268,14 +267,15 @@ public class RelaunchLibraryManager
{
for (String xformClass : plug.getASMTransformerClass())
{
actualClassLoader.registerTransformer(xformClass);
FMLRelaunchLog.finest("Registering transformer %s", xformClass);
classLoader.registerTransformer(xformClass);
}
}
}
// Deobfuscation transformer, always last
if (!deobfuscatedEnvironment)
{
actualClassLoader.registerTransformer("cpw.mods.fml.common.asm.transformers.DeobfuscationTransformer");
classLoader.registerTransformer("cpw.mods.fml.common.asm.transformers.DeobfuscationTransformer");
}
downloadMonitor.updateProgressString("Running coremod plugins");
Map<String,Object> data = new HashMap<String,Object>();
@@ -292,10 +292,10 @@ public class RelaunchLibraryManager
{
try
{
IFMLCallHook call = (IFMLCallHook) Class.forName(setupClass, true, actualClassLoader).newInstance();
IFMLCallHook call = (IFMLCallHook) Class.forName(setupClass, true, classLoader).newInstance();
Map<String,Object> callData = new HashMap<String, Object>();
callData.put("mcLocation", mcDir);
callData.put("classLoader", actualClassLoader);
callData.put("classLoader", classLoader);
callData.put("coremodLocation", pluginLocations.get(plugin));
callData.put("deobfuscationFileName", FMLInjectionData.debfuscationDataName());
call.injectData(callData);
@@ -317,7 +317,7 @@ public class RelaunchLibraryManager
try
{
downloadMonitor.updateProgressString("Validating minecraft");
Class<?> loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, actualClassLoader);
Class<?> loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, classLoader);
Method m = loaderClazz.getMethod("injectData", Object[].class);
m.invoke(null, (Object)FMLInjectionData.data());
m = loaderClazz.getMethod("instance");
@@ -333,7 +333,7 @@ public class RelaunchLibraryManager
}
}
private static void discoverCoreMods(File mcDir, RelaunchClassLoader classLoader, List<IFMLLoadingPlugin> loadPlugins, List<ILibrarySet> libraries)
private static void discoverCoreMods(File mcDir, LaunchClassLoader classLoader, List<IFMLLoadingPlugin> loadPlugins, List<ILibrarySet> libraries)
{
downloadMonitor.updateProgressString("Discovering coremods");
File coreMods = setupCoreModDir(mcDir);
@@ -5,13 +5,15 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
import java.util.logging.Level;
public class DummyDownloader implements IDownloadDisplay
{
@@ -46,8 +48,7 @@ public class DummyDownloader implements IDownloadDisplay
@Override
public void updateProgressString(String string, Object... data)
{
// TODO Auto-generated method stub
FMLRelaunchLog.log(Level.FINE, string, data);
}
@Override
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -26,6 +26,7 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
public String[] getASMTransformerClass()
{
return new String[] {
"cpw.mods.fml.common.asm.transformers.PatchingTransformer",
"cpw.mods.fml.common.asm.transformers.AccessTransformer",
"cpw.mods.fml.common.asm.transformers.MarkerTransformer",
"cpw.mods.fml.common.asm.transformers.SideTransformer",
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -20,6 +20,8 @@ import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import net.minecraft.launchwrapper.LaunchClassLoader;
public class FMLInjectionData
{
static File minecraftHome;
@@ -33,7 +35,7 @@ public class FMLInjectionData
public static List<String> containers = new ArrayList<String>();
static void build(File mcHome, RelaunchClassLoader classLoader)
static void build(File mcHome, LaunchClassLoader classLoader)
{
minecraftHome = mcHome;
InputStream stream = classLoader.getResourceAsStream("fmlversion.properties");
@@ -62,7 +64,7 @@ public class FMLInjectionData
static String debfuscationDataName()
{
return "deobfuscation_data_"+mccversion+".zip";
return "/deobfuscation_data-"+mccversion+".lzma";
}
public static Object[] data()
{
@@ -0,0 +1,118 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
import java.applet.Applet;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.launcher.FMLTweaker;
import net.minecraft.launchwrapper.LaunchClassLoader;
public class FMLLaunchHandler
{
private static FMLLaunchHandler INSTANCE;
static Side side;
private LaunchClassLoader classLoader;
private FMLTweaker tweaker;
private File minecraftHome;
public static void configureForClientLaunch(LaunchClassLoader loader, FMLTweaker tweaker)
{
instance(loader, tweaker).setupClient();
}
public static void configureForServerLaunch(LaunchClassLoader loader, FMLTweaker tweaker)
{
instance(loader, tweaker).setupServer();
}
private static FMLLaunchHandler instance(LaunchClassLoader launchLoader, FMLTweaker tweaker)
{
if (INSTANCE == null)
{
INSTANCE = new FMLLaunchHandler(launchLoader, tweaker);
}
return INSTANCE;
}
private FMLLaunchHandler(LaunchClassLoader launchLoader, FMLTweaker tweaker)
{
this.classLoader = launchLoader;
this.tweaker = tweaker;
this.minecraftHome = tweaker.getGameDir();
this.classLoader.addClassLoaderExclusion("cpw.mods.fml.relauncher.");
this.classLoader.addClassLoaderExclusion("net.minecraftforge.classloading.");
this.classLoader.addTransformerExclusion("cpw.mods.fml.common.asm.transformers.deobf.");
this.classLoader.addTransformerExclusion("cpw.mods.fml.common.patcher.");
}
private void showWindow(boolean showIt)
{
if (CoreModManager.downloadMonitor != null) { return; }
CoreModManager.downloadMonitor = new DummyDownloader();
}
private void setupClient()
{
showWindow(true);
FMLRelaunchLog.logFileNamePattern = "ForgeModLoader-client-%g.log";
side = Side.CLIENT;
setupHome();
}
private void setupServer()
{
showWindow(false);
FMLRelaunchLog.logFileNamePattern = "ForgeModLoader-server-%g.log";
side = Side.SERVER;
setupHome();
}
private void setupHome()
{
FMLInjectionData.build(minecraftHome, classLoader);
FMLRelaunchLog.minecraftHome = minecraftHome;
FMLRelaunchLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft %s loading", FMLInjectionData.major, FMLInjectionData.minor,
FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion, FMLInjectionData.mcpversion);
FMLRelaunchLog.info("Java is %s, version %s, running on %s:%s:%s, installed at %s", System.getProperty("java.vm.name"), System.getProperty("java.version"), System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"), System.getProperty("java.home"));
FMLRelaunchLog.fine("Java classpath at launch is %s", System.getProperty("java.class.path"));
FMLRelaunchLog.fine("Java library path at launch is %s", System.getProperty("java.library.path"));
try
{
CoreModManager.handleLaunch(minecraftHome, classLoader);
}
catch (Throwable t)
{
t.printStackTrace();
FMLRelaunchLog.log(Level.SEVERE, t, "An error occurred trying to configure the minecraft home at %s for Forge Mod Loader", minecraftHome.getAbsolutePath());
throw Throwables.propagate(t);
}
}
public static Side side()
{
return side;
}
}
@@ -28,6 +28,10 @@ import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import net.minecraft.launchwrapper.LogWrapper;
import com.google.common.base.Throwables;
public class FMLRelaunchLog
{
@@ -113,7 +117,7 @@ public class FMLRelaunchLog
// Are we longer than just the line separator?
int lastIdx = -1;
int idx = currentMessage.indexOf("\n",lastIdx+1);
while (idx > 0)
while (idx >= 0)
{
log.log(Level.INFO, currentMessage.substring(lastIdx+1,idx));
lastIdx = idx;
@@ -121,7 +125,9 @@ public class FMLRelaunchLog
}
if (lastIdx >= 0)
{
String rem = currentMessage.substring(lastIdx+1);
currentMessage.setLength(0);
currentMessage.append(rem);
}
}
}
@@ -144,6 +150,8 @@ public class FMLRelaunchLog
private static FMLLogFormatter formatter;
static String logFileNamePattern;
private FMLRelaunchLog()
{
}
@@ -157,6 +165,7 @@ public class FMLRelaunchLog
globalLogger.setLevel(Level.OFF);
log.myLog = Logger.getLogger("ForgeModLoader");
LogWrapper.retarget(log.myLog);
Logger stdOut = Logger.getLogger("STDOUT");
stdOut.setParent(log.myLog);
@@ -170,7 +179,7 @@ public class FMLRelaunchLog
formatter = new FMLLogFormatter();
try
{
File logPath = new File(minecraftHome, FMLRelauncher.logFileNamePattern);
File logPath = new File(minecraftHome, logFileNamePattern);
fileHandler = new FileHandler(logPath.getPath(), 0, 3)
{
public synchronized void close() throws SecurityException {
@@ -178,8 +187,9 @@ public class FMLRelaunchLog
}
};
}
catch (Exception e)
catch (Throwable t)
{
throw Throwables.propagate(t);
}
resetLoggingHandlers();
@@ -1,335 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
import java.applet.Applet;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
public class FMLRelauncher
{
private static FMLRelauncher INSTANCE;
public static String logFileNamePattern;
private static String side;
private RelaunchClassLoader classLoader;
private Object newApplet;
private Class<? super Object> appletClass;
JDialog popupWindow;
public static void handleClientRelaunch(ArgsWrapper wrap)
{
logFileNamePattern = "ForgeModLoader-client-%g.log";
side = "CLIENT";
instance().relaunchClient(wrap);
}
public static void handleServerRelaunch(ArgsWrapper wrap)
{
logFileNamePattern = "ForgeModLoader-server-%g.log";
side = "SERVER";
instance().relaunchServer(wrap);
}
static FMLRelauncher instance()
{
if (INSTANCE == null)
{
INSTANCE = new FMLRelauncher();
}
return INSTANCE;
}
private FMLRelauncher()
{
URLClassLoader ucl = (URLClassLoader) getClass().getClassLoader();
classLoader = new RelaunchClassLoader(ucl.getURLs());
}
private void showWindow(boolean showIt)
{
if (RelaunchLibraryManager.downloadMonitor != null) { return; }
try
{
if (showIt)
{
RelaunchLibraryManager.downloadMonitor = new Downloader();
popupWindow = (JDialog) RelaunchLibraryManager.downloadMonitor.makeDialog();
}
else
{
RelaunchLibraryManager.downloadMonitor = new DummyDownloader();
}
}
catch (Throwable e)
{
if (RelaunchLibraryManager.downloadMonitor == null)
{
RelaunchLibraryManager.downloadMonitor = new DummyDownloader();
e.printStackTrace();
}
else
{
RelaunchLibraryManager.downloadMonitor.makeHeadless();
}
popupWindow = null;
}
}
private void relaunchClient(ArgsWrapper wrap)
{
showWindow(true);
// Now we re-inject the home into the "new" minecraft under our control
Class<? super Object> client;
try
{
File minecraftHome = computeExistingClientHome();
setupHome(minecraftHome);
client = setupNewClientHome(minecraftHome);
}
finally
{
if (popupWindow != null)
{
popupWindow.setVisible(false);
popupWindow.dispose();
}
}
if (RelaunchLibraryManager.downloadMonitor.shouldStopIt())
{
System.exit(1);
}
try
{
ReflectionHelper.findMethod(client, null, new String[] { "fmlReentry" }, ArgsWrapper.class).invoke(null, wrap);
}
catch (Exception e)
{
e.printStackTrace();
// Hmmm
}
}
private Class<? super Object> setupNewClientHome(File minecraftHome)
{
Class<? super Object> client = ReflectionHelper.getClass(classLoader, "net.minecraft.client.Minecraft");
ReflectionHelper.setPrivateValue(client, null, minecraftHome,
"field_" + "71463_am" /*Separate that so that MCP's updatenames does not replace it*/,
"an", "minecraftDir");
return client;
}
private void relaunchServer(ArgsWrapper wrap)
{
showWindow(false);
// Now we re-inject the home into the "new" minecraft under our control
Class<? super Object> server;
File minecraftHome = new File(".");
setupHome(minecraftHome);
server = ReflectionHelper.getClass(classLoader, "net.minecraft.server.MinecraftServer");
try
{
ReflectionHelper.findMethod(server, null, new String[] { "fmlReentry" }, ArgsWrapper.class).invoke(null, wrap);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void setupHome(File minecraftHome)
{
FMLInjectionData.build(minecraftHome, classLoader);
FMLRelaunchLog.minecraftHome = minecraftHome;
FMLRelaunchLog.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft %s loading", FMLInjectionData.major, FMLInjectionData.minor,
FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion, FMLInjectionData.mcpversion);
FMLRelaunchLog.info("Java is %s, version %s, running on %s:%s:%s, installed at %s", System.getProperty("java.vm.name"), System.getProperty("java.version"), System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"), System.getProperty("java.home"));
FMLRelaunchLog.fine("Java classpath at launch is %s", System.getProperty("java.class.path"));
FMLRelaunchLog.fine("Java library path at launch is %s", System.getProperty("java.library.path"));
try
{
RelaunchLibraryManager.handleLaunch(minecraftHome, classLoader);
}
catch (Throwable t)
{
if (popupWindow != null)
{
try
{
String logFile = new File(minecraftHome, "ForgeModLoader-client-0.log").getCanonicalPath();
JOptionPane.showMessageDialog(popupWindow, String.format(
"<html><div align=\"center\"><font size=\"+1\">There was a fatal error starting up minecraft and FML</font></div><br/>"
+ "Minecraft cannot launch in it's current configuration<br/>"
+ "Please consult the file <i><a href=\"file:///%s\">%s</a></i> for further information</html>", logFile, logFile),
"Fatal FML error", JOptionPane.ERROR_MESSAGE);
}
catch (Exception ex)
{
// ah well, we tried
}
}
throw new RuntimeException(t);
}
}
/**
* @return the location of the client home
*/
private File computeExistingClientHome()
{
Class<? super Object> mcMaster = ReflectionHelper.getClass(getClass().getClassLoader(), "net.minecraft.client.Minecraft");
// If we get the system property we inject into the old MC, setup the
// dir, then pull the value
String str = System.getProperty("minecraft.applet.TargetDirectory");
if (str != null)
{
str = str.replace('/', File.separatorChar);
ReflectionHelper.setPrivateValue(mcMaster, null, new File(str), "minecraftDir", "an", "minecraftDir");
}
// We force minecraft to setup it's homedir very early on so we can
// inject stuff into it
Method setupHome = ReflectionHelper.findMethod(mcMaster, null, new String[] { "func_71380_b", "getMinecraftDir", "b" });
try
{
setupHome.invoke(null);
}
catch (Exception e)
{
// Hmmm
}
File minecraftHome = ReflectionHelper.getPrivateValue(mcMaster, null, "field_71463_am", "an", "minecraftDir");
return minecraftHome;
}
public static void appletEntry(Applet minecraftApplet)
{
side = "CLIENT";
logFileNamePattern = "ForgeModLoader-client-%g.log";
instance().relaunchApplet(minecraftApplet);
}
private void relaunchApplet(Applet minecraftApplet)
{
showWindow(true);
if (minecraftApplet.getClass().getClassLoader() == classLoader)
{
if (popupWindow != null)
{
popupWindow.setVisible(false);
popupWindow.dispose();
}
try
{
newApplet = minecraftApplet;
appletClass = ReflectionHelper.getClass(classLoader, "net.minecraft.client.MinecraftApplet");
ReflectionHelper.findMethod(appletClass, newApplet, new String[] { "fmlInitReentry" }).invoke(newApplet);
return;
}
catch (Exception e)
{
System.out.println("FMLRelauncher.relaunchApplet");
e.printStackTrace();
throw new RuntimeException(e);
}
}
File mcDir = computeExistingClientHome();
setupHome(mcDir);
setupNewClientHome(mcDir);
Class<? super Object> parentAppletClass = ReflectionHelper.getClass(getClass().getClassLoader(), "java.applet.Applet");
try
{
appletClass = ReflectionHelper.getClass(classLoader, "net.minecraft.client.MinecraftApplet");
newApplet = appletClass.newInstance();
Object appletContainer = ReflectionHelper.getPrivateValue(ReflectionHelper.getClass(getClass().getClassLoader(), "java.awt.Component"),
minecraftApplet, "parent");
String launcherClassName = System.getProperty("minecraft.applet.WrapperClass", "net.minecraft.Launcher");
Class<? super Object> launcherClass = ReflectionHelper.getClass(getClass().getClassLoader(), launcherClassName);
if (launcherClass.isInstance(appletContainer))
{
ReflectionHelper.findMethod(ReflectionHelper.getClass(getClass().getClassLoader(), "java.awt.Container"), minecraftApplet,
new String[] { "removeAll" }).invoke(appletContainer);
ReflectionHelper.findMethod(launcherClass, appletContainer, new String[] { "replace" }, parentAppletClass).invoke(appletContainer, newApplet);
}
else
{
FMLRelaunchLog.severe("Found unknown applet parent %s, unable to inject!\n", appletContainer.getClass().getName());
throw new RuntimeException();
}
}
catch (Exception e)
{
throw new RuntimeException(e);
}
finally
{
if (popupWindow != null)
{
popupWindow.setVisible(false);
popupWindow.dispose();
}
}
}
public static void appletStart(Applet applet)
{
instance().startApplet(applet);
}
private void startApplet(Applet applet)
{
if (applet.getClass().getClassLoader() == classLoader)
{
if (popupWindow != null)
{
popupWindow.setVisible(false);
popupWindow.dispose();
}
if (RelaunchLibraryManager.downloadMonitor.shouldStopIt())
{
System.exit(1);
}
try
{
ReflectionHelper.findMethod(appletClass, newApplet, new String[] { "fmlStartReentry" }).invoke(newApplet);
}
catch (Exception e)
{
System.out.println("FMLRelauncher.startApplet");
e.printStackTrace();
throw new RuntimeException(e);
}
}
return;
}
public static String side()
{
return side;
}
}
@@ -1,19 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
public interface IClassNameTransformer {
public String remapClassName(String name);
public String unmapClassName(String name);
}
@@ -1,18 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
public interface IClassTransformer
{
public byte[] transform(String name, String transformedName, byte[] bytes);
}
@@ -32,6 +32,7 @@ public interface IFMLLoadingPlugin
*
* @return a list of classes that implement the ILibrarySet interface
*/
@Deprecated
String[] getLibraryRequestClass();
/**
* Return a list of classes that implements the IClassTransformer interface
@@ -1,411 +0,0 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.relauncher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.security.CodeSigner;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes.Name;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import cpw.mods.fml.common.FMLLog;
public class RelaunchClassLoader extends URLClassLoader
{
private List<URL> sources;
private ClassLoader parent;
private List<IClassTransformer> transformers;
private Map<String, Class> cachedClasses;
private Set<String> invalidClasses;
private Set<String> classLoaderExceptions = new HashSet<String>();
private Set<String> transformerExceptions = new HashSet<String>();
private Map<Package,Manifest> packageManifests = new HashMap<Package,Manifest>();
private IClassNameTransformer renameTransformer;
private static Manifest EMPTY = new Manifest();
private ThreadLocal<byte[]> loadBuffer = new ThreadLocal<byte[]>();
private static final String[] RESERVED = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
private static final boolean DEBUG_CLASSLOADING = Boolean.parseBoolean(System.getProperty("fml.debugClassLoading", "false"));
private static final boolean DEBUG_CLASSLOADING_FINER = DEBUG_CLASSLOADING && Boolean.parseBoolean(System.getProperty("fml.debugClassLoadingFiner", "false"));
public RelaunchClassLoader(URL[] sources)
{
super(sources, null);
this.sources = new ArrayList<URL>(Arrays.asList(sources));
this.parent = getClass().getClassLoader();
this.cachedClasses = new HashMap<String,Class>(1000);
this.invalidClasses = new HashSet<String>(1000);
this.transformers = new ArrayList<IClassTransformer>(2);
// ReflectionHelper.setPrivateValue(ClassLoader.class, null, this, "scl");
Thread.currentThread().setContextClassLoader(this);
// standard classloader exclusions
addClassLoaderExclusion("java.");
addClassLoaderExclusion("sun.");
addClassLoaderExclusion("org.lwjgl.");
addClassLoaderExclusion("cpw.mods.fml.relauncher.");
addClassLoaderExclusion("net.minecraftforge.classloading.");
// standard transformer exclusions
addTransformerExclusion("javax.");
addTransformerExclusion("argo.");
addTransformerExclusion("org.objectweb.asm.");
addTransformerExclusion("com.google.common.");
addTransformerExclusion("org.bouncycastle.");
addTransformerExclusion("cpw.mods.fml.common.asm.transformers.deobf.");
}
public void registerTransformer(String transformerClassName)
{
try
{
IClassTransformer transformer = (IClassTransformer) loadClass(transformerClassName).newInstance();
transformers.add(transformer);
if (transformer instanceof IClassNameTransformer && renameTransformer == null)
{
renameTransformer = (IClassNameTransformer) transformer;
}
}
catch (Exception e)
{
FMLRelaunchLog.log(Level.SEVERE, e, "A critical problem occured registering the ASM transformer class %s", transformerClassName);
}
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException
{
if (invalidClasses.contains(name))
{
throw new ClassNotFoundException(name);
}
for (String st : classLoaderExceptions)
{
if (name.startsWith(st))
{
return parent.loadClass(name);
}
}
if (cachedClasses.containsKey(name))
{
return cachedClasses.get(name);
}
for (String st : transformerExceptions)
{
if (name.startsWith(st))
{
try
{
Class<?> cl = super.findClass(name);
cachedClasses.put(name, cl);
return cl;
}
catch (ClassNotFoundException e)
{
invalidClasses.add(name);
throw e;
}
}
}
try
{
CodeSigner[] signers = null;
String transformedName = transformName(name);
String untransformedName = untransformName(name);
int lastDot = untransformedName.lastIndexOf('.');
String pkgname = lastDot == -1 ? "" : untransformedName.substring(0, lastDot);
String fName = untransformedName.replace('.', '/').concat(".class");
String pkgPath = pkgname.replace('.', '/');
URLConnection urlConnection = findCodeSourceConnectionFor(fName);
if (urlConnection instanceof JarURLConnection && lastDot > -1 && !untransformedName.startsWith("net.minecraft."))
{
JarURLConnection jarUrlConn = (JarURLConnection)urlConnection;
JarFile jf = jarUrlConn.getJarFile();
if (jf != null && jf.getManifest() != null)
{
Manifest mf = jf.getManifest();
JarEntry ent = jf.getJarEntry(fName);
Package pkg = getPackage(pkgname);
getClassBytes(untransformedName);
signers = ent.getCodeSigners();
if (pkg == null)
{
pkg = definePackage(pkgname, mf, jarUrlConn.getJarFileURL());
packageManifests.put(pkg, mf);
}
else
{
if (pkg.isSealed() && !pkg.isSealed(jarUrlConn.getJarFileURL()))
{
FMLLog.severe("The jar file %s is trying to seal already secured path %s", jf.getName(), pkgname);
}
else if (isSealed(pkgname, mf))
{
FMLLog.severe("The jar file %s has a security seal for path %s, but that path is defined and not secure", jf.getName(), pkgname);
}
}
}
}
else if (lastDot > -1 && !untransformedName.startsWith("net.minecraft."))
{
Package pkg = getPackage(pkgname);
if (pkg == null)
{
pkg = definePackage(pkgname, null, null, null, null, null, null, null);
packageManifests.put(pkg, EMPTY);
}
else if (pkg.isSealed())
{
FMLLog.severe("The URL %s is defining elements for sealed path %s", urlConnection.getURL(), pkgname);
}
}
byte[] basicClass = getClassBytes(untransformedName);
byte[] transformedClass = runTransformers(untransformedName, transformedName, basicClass);
Class<?> cl = defineClass(transformedName, transformedClass, 0, transformedClass.length, (urlConnection == null ? null : new CodeSource(urlConnection.getURL(), signers)));
cachedClasses.put(transformedName, cl);
return cl;
}
catch (Throwable e)
{
invalidClasses.add(name);
if (DEBUG_CLASSLOADING)
{
FMLLog.log(Level.FINEST, e, "Exception encountered attempting classloading of %s", name);
}
throw new ClassNotFoundException(name, e);
}
}
private String untransformName(String name)
{
if (renameTransformer != null)
{
return renameTransformer.unmapClassName(name);
}
else
{
return name;
}
}
private String transformName(String name)
{
if (renameTransformer != null)
{
return renameTransformer.remapClassName(name);
}
else
{
return name;
}
}
private boolean isSealed(String path, Manifest man)
{
Attributes attr = man.getAttributes(path);
String sealed = null;
if (attr != null) {
sealed = attr.getValue(Name.SEALED);
}
if (sealed == null) {
if ((attr = man.getMainAttributes()) != null) {
sealed = attr.getValue(Name.SEALED);
}
}
return "true".equalsIgnoreCase(sealed);
}
private URLConnection findCodeSourceConnectionFor(String name)
{
URL res = findResource(name);
if (res != null)
{
try
{
return res.openConnection();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
else
{
return null;
}
}
private byte[] runTransformers(String name, String transformedName, byte[] basicClass)
{
if (DEBUG_CLASSLOADING_FINER)
{
FMLRelaunchLog.finest("Beginning transform of %s (%s) Start Length: %d", name, transformedName, (basicClass == null ? 0 : basicClass.length));
for (IClassTransformer transformer : transformers)
{
String transName = transformer.getClass().getName();
FMLRelaunchLog.finest("Before Transformer %s: %d", transName, (basicClass == null ? 0 : basicClass.length));
basicClass = transformer.transform(name, transformedName, basicClass);
FMLRelaunchLog.finest("After Transformer %s: %d", transName, (basicClass == null ? 0 : basicClass.length));
}
FMLRelaunchLog.finest("Ending transform of %s (%s) Start Length: %d", name, transformedName, (basicClass == null ? 0 : basicClass.length));
}
else
{
for (IClassTransformer transformer : transformers)
{
basicClass = transformer.transform(name, transformedName, basicClass);
}
}
return basicClass;
}
@Override
public void addURL(URL url)
{
super.addURL(url);
sources.add(url);
}
public List<URL> getSources()
{
return sources;
}
private byte[] readFully(InputStream stream)
{
try
{
byte[] buf = loadBuffer.get();
if (buf == null)
{
loadBuffer.set(new byte[1 << 12]);
buf = loadBuffer.get();
}
int r, totalLength = 0;
while ((r = stream.read(buf, totalLength, buf.length - totalLength)) != -1)
{
totalLength += r;
if (totalLength >= buf.length - 1)
{
byte[] oldbuf = buf;
buf = new byte[ oldbuf.length + (1 << 12 )];
System.arraycopy(oldbuf, 0, buf, 0, oldbuf.length);
}
}
byte[] result = new byte[totalLength];
System.arraycopy(buf, 0, result, 0, totalLength);
return result;
}
catch (Throwable t)
{
FMLRelaunchLog.log(Level.WARNING, t, "Problem loading class");
return new byte[0];
}
}
public List<IClassTransformer> getTransformers()
{
return Collections.unmodifiableList(transformers);
}
private void addClassLoaderExclusion(String toExclude)
{
classLoaderExceptions.add(toExclude);
}
void addTransformerExclusion(String toExclude)
{
transformerExceptions.add(toExclude);
}
public byte[] getClassBytes(String name) throws IOException
{
if (name.indexOf('.') == -1)
{
for (String res : RESERVED)
{
if (name.toUpperCase(Locale.ENGLISH).startsWith(res))
{
byte[] data = getClassBytes("_" + name);
if (data != null)
{
return data;
}
}
}
}
InputStream classStream = null;
try
{
URL classResource = findResource(name.replace('.', '/').concat(".class"));
if (classResource == null)
{
if (DEBUG_CLASSLOADING)
{
FMLLog.finest("Failed to find class resource %s", name.replace('.', '/').concat(".class"));
}
return null;
}
classStream = classResource.openStream();
if (DEBUG_CLASSLOADING)
{
FMLLog.finest("Loading class %s from resource %s", name, classResource.toString());
}
return readFully(classStream);
}
finally
{
if (classStream != null)
{
try
{
classStream.close();
}
catch (IOException e)
{
// Swallow the close exception
}
}
}
}
}
@@ -0,0 +1,32 @@
package cpw.mods.fml.relauncher;
import java.io.File;
import java.net.URLClassLoader;
import java.util.logging.Level;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import com.google.common.base.Throwables;
public class ServerLaunchWrapper {
/**
* @param args
*/
public static void main(String[] args)
{
new ServerLaunchWrapper().run(args);
}
private ServerLaunchWrapper()
{
}
private void run(String[] args)
{
Launch.main(args);
}
}
+2 -2
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -13,7 +13,7 @@
package cpw.mods.fml.relauncher;
public enum Side {
CLIENT, SERVER, BUKKIT;
CLIENT, SERVER;
/**
* @return If this is the server environment
+16 -1
View File
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -17,7 +17,22 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cpw.mods.fml.common.SidedProxy;
/**
* Marks the associated element as being only available on a certain {@link Side}. This is
* generally meant for internal Forge and FML use only and should only be used on mod classes
* when other more common mechanisms, such as using a {@link SidedProxy} fail to work.
*
* Note, this will <em>only</em> apply to the direct element marked. This code:
* <code> @SideOnly public MyField field = new MyField();</code> will <strong>not</strong> work, as the initializer
* is a separate piece of code to the actual field declaration, and will not be able to find
* it's field on the wrong side.
*
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface SideOnly
@@ -0,0 +1,97 @@
/*
* ByteArraySeekableSource.java
*
* Created on May 17, 2006, 12:41 PM
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Wraps a byte buffer as a source
*/
public class ByteBufferSeekableSource implements SeekableSource {
private ByteBuffer bb;
private ByteBuffer cur;
/**
* Constructs a new ByteArraySeekableSource.
*/
public ByteBufferSeekableSource(byte[] source) {
this(ByteBuffer.wrap(source));
}
/**
* Constructs a new ByteArraySeekableSource.
*/
public ByteBufferSeekableSource(ByteBuffer bb) {
if (bb == null)
throw new NullPointerException("bb");
this.bb = bb;
bb.rewind();
try {
seek(0);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void seek(long pos) throws IOException {
cur = bb.slice();
if (pos > cur.limit())
throw new IOException("pos " + pos + " cannot seek " + cur.limit());
cur.position((int) pos);
}
public int read(ByteBuffer dest) throws IOException {
if (!cur.hasRemaining())
return -1;
int c = 0;
while (cur.hasRemaining() && dest.hasRemaining()) {
dest.put(cur.get());
c++;
}
return c;
}
public void close() throws IOException {
bb = null;
cur = null;
}
/**
* Returns a debug <code>String</code>.
*/
@Override
public String toString()
{
return "BBSeekable" +
" bb=" + this.bb.position() + "-" + bb.limit() +
" cur=" + this.cur.position() + "-" + cur.limit() +
"";
}
}
@@ -0,0 +1,162 @@
/*
*
* Copyright (c) 2001 Torgeir Veimo
* Copyright (c) 2002 Nicolas PERIDONT
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* Checksum computation class.
*/
public class Checksum {
static final boolean debug = false;
private Map<Long,Integer> checksums = Maps.newHashMap();
private static final char single_hash[] = {
/* Random numbers generated using SLIB's pseudo-random number generator. */
0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46,
0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602,
0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6,
0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a,
0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58,
0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b,
0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94,
0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176,
0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743,
0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6,
0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227,
0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d,
0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a,
0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31,
0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9,
0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6,
0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f,
0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f,
0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49,
0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037,
0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad,
0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f,
0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d,
0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b,
0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624,
0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272,
0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806,
0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050,
0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113,
0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2,
0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25,
0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5
};
/**
* Initialize checksums for source. The checksum for the <code>chunkSize</code> bytes at offset
* <code>chunkSize</code> * i is inserted into a hash map.
*/
public Checksum(SeekableSource source, int chunkSize) throws IOException {
ByteBuffer bb = ByteBuffer.allocate(chunkSize * 2);
int count = 0;
while (true) {
source.read(bb);
bb.flip();
if (bb.remaining() < chunkSize)
break;
while (bb.remaining() >= chunkSize) {
long queryChecksum = queryChecksum0(bb, chunkSize);
checksums.put(queryChecksum, count++);
}
bb.compact();
}
}
/**
* Finds the checksum computed from the buffer.
* Marks, gets, then resets the buffer.
*/
public static long queryChecksum(ByteBuffer bb, int len) {
bb.mark();
long sum = queryChecksum0(bb, len);
bb.reset();
return sum;
}
private static long queryChecksum0(ByteBuffer bb, int len) {
int high = 0; int low = 0;
for (int i = 0; i < len; i++) {
low += single_hash[bb.get()+128];
high += low;
}
return ((high & 0xffff) << 16) | (low & 0xffff);
}
/**
* Increments a checksum.
* @param checksum initial checksum
* @param out byte leaving view
* @param in byte entering view
* @param chunkSize size of chunks
* @return new checksum
*/
public static long incrementChecksum(long checksum, byte out, byte in, int chunkSize) {
char old_c = single_hash[out+128];
char new_c = single_hash[in+128];
int low = ((int)((checksum) & 0xffff) - old_c + new_c) & 0xffff;
int high = ((int)((checksum) >> 16) - (old_c * chunkSize) + low) & 0xffff;
return (high << 16) | (low & 0xffff);
}
/**
* 256 random hash values.
*/
public static char[] getSingleHash() {
return single_hash;
}
/**
* Finds the index of a checksum.
*/
public int findChecksumIndex(long hashf) {
if (!checksums.containsKey(hashf))
return -1;
return checksums.get(hashf);
}
/**
* Returns a debug <code>String</code>.
*/
@Override
public String toString()
{
return super.toString() +
" checksums=" + this.checksums;
}
}
@@ -0,0 +1,75 @@
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* For debugging patch generation.
*/
public class DebugDiffWriter implements DiffWriter {
private ByteArrayOutputStream os = new ByteArrayOutputStream();
/**
* Constructs a new DebugDiffWriter.
*/
public DebugDiffWriter() {}
public void addCopy(long offset, int length) throws IOException {
if (os.size() > 0)
writeBuf();
System.err.println("COPY off: " + offset + ", len: " + length);
}
public void addData(byte b) throws IOException {
os.write(b);
writeBuf();
}
private void writeBuf() {
System.err.print("DATA: ");
byte[] ba = os.toByteArray();
for (int ix = 0; ix < ba.length; ix++) {
if (ba[ix] == '\n')
System.err.print("\\n");
else
System.err.print(String.valueOf((char)((char) ba[ix])));
//System.err.print("0x" + Integer.toHexString(buf[ix]) + " "); // hex output
}
System.err.println("");
os.reset();
}
public void flush() throws IOException {
System.err.println("FLUSH");
}
public void close() throws IOException {
System.err.println("CLOSE");
}
}
@@ -0,0 +1,446 @@
/*
*
* Copyright (c) 2001 Torgeir Veimo
* Copyright (c) 2002 Nicolas PERIDONT
* Bug Fixes: Daniel Morrione [email protected]
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* Change Log:
* iiimmddyyn nnnnn Description
* ---------- ----- -------------------------------------------------------
* gls100603a Fixes from Torgeir Veimo and Dan Morrione
* gls110603a Stream not being closed thus preventing a file from
* being subsequently deleted.
* gls031504a Error being written to stderr rather than throwing exception
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
/**
* Class for computing deltas against a source.
* The source file is read by blocks and a hash is computed per block.
* Then the target is scanned for matching blocks.
* <p/>
* This class is not thread safe. Use one instance per thread.
* <p/>
* This class should support files over 4GB in length, although you must
* use a larger checksum size, such as 1K, as all checksums use "int" indexing.
* Newer versions may eventually support paging in/out of checksums.
*/
public class Delta {
/**
* Debug flag.
*/
final static boolean debug = false;
/**
* Default size of 16.
* For "Lorem ipsum" text files (see the tests) the ideal size is about 14.
* Any smaller and the patch size becomes actually be larger.
* <p>
* Use a size like 64 or 128 for large files.
*/
public static final int DEFAULT_CHUNK_SIZE = 1<<4;
/**
* Chunk Size.
*/
private int S;
private SourceState source;
private TargetState target;
private DiffWriter output;
/**
* Constructs a new Delta.
* In the future, additional constructor arguments will set the algorithm details.
*/
public Delta() {
setChunkSize(DEFAULT_CHUNK_SIZE);
}
/**
* Sets the chunk size used.
* Larger chunks are faster and use less memory, but create larger patches
* as well.
*
* @param size
*/
public void setChunkSize(int size) {
if (size <= 0)
throw new IllegalArgumentException("Invalid size");
S = size;
}
/**
* Compares the source bytes with target bytes, writing to output.
*/
public void compute(byte source[], byte target[], OutputStream output)
throws IOException {
compute(new ByteBufferSeekableSource(source),
new ByteArrayInputStream(target),
new GDiffWriter(output));
}
/**
* Compares the source bytes with target bytes, returning output.
*/
public byte[] compute(byte source[], byte target[])
throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
compute(source, target, os);
return os.toByteArray();
}
/**
* Compares the source bytes with target input, writing to output.
*/
public void compute(byte[] sourceBytes, InputStream inputStream,
DiffWriter diffWriter) throws IOException
{
compute(new ByteBufferSeekableSource(sourceBytes),
inputStream, diffWriter);
}
/**
* Compares the source file with a target file, writing to output.
*
* @param output will be closed
*/
public void compute(File sourceFile, File targetFile, DiffWriter output)
throws IOException {
RandomAccessFileSeekableSource source = new RandomAccessFileSeekableSource(new RandomAccessFile(sourceFile, "r"));
InputStream is = new BufferedInputStream(new FileInputStream(targetFile));
try {
compute(source, is, output);
} finally {
source.close();
is.close();
}
}
/**
* Compares the source with a target, writing to output.
*
* @param output will be closed
*/
public void compute(SeekableSource seekSource, InputStream targetIS, DiffWriter output)
throws IOException {
if (debug) {
debug("using match length S = " + S);
}
source = new SourceState(seekSource);
target = new TargetState(targetIS);
this.output = output;
if (debug)
debug("checksums " + source.checksum);
while (!target.eof()) {
debug("!target.eof()");
int index = target.find(source);
if (index != -1) {
if (debug)
debug("found hash " + index);
long offset = (long)index * S;
source.seek(offset);
int match = target.longestMatch(source);
if (match >= S) {
if (debug)
debug("output.addCopy("+offset+","+match+")");
output.addCopy(offset, match);
} else {
// move the position back according to how much we can't copy
target.tbuf.position(target.tbuf.position() - match);
addData();
}
} else {
addData();
}
}
output.close();
}
private void addData() throws IOException {
int i = target.read();
if (debug)
debug("addData " + Integer.toHexString(i));
if (i == -1)
return;
output.addData((byte)i);
}
class SourceState {
private Checksum checksum;
private SeekableSource source;
public SourceState(SeekableSource source) throws IOException {
checksum = new Checksum(source, S);
this.source = source;
source.seek(0);
}
public void seek(long index) throws IOException {
source.seek(index);
}
/**
* Returns a debug <code>String</code>.
*/
@Override
public String toString()
{
return "Source"+
" checksum=" + this.checksum +
" source=" + this.source +
"";
}
}
class TargetState {
private ReadableByteChannel c;
private ByteBuffer tbuf = ByteBuffer.allocate(blocksize());
private ByteBuffer sbuf = ByteBuffer.allocate(blocksize());
private long hash;
private boolean hashReset = true;
private boolean eof;
TargetState(InputStream targetIS) throws IOException {
c = Channels.newChannel(targetIS);
tbuf.limit(0);
}
private int blocksize() {
return Math.min(1024 * 16, S * 4);
}
/**
* Returns the index of the next N bytes of the stream.
*/
public int find(SourceState source) throws IOException {
if (eof)
return -1;
sbuf.clear();
sbuf.limit(0);
if (hashReset) {
debug("hashReset");
while (tbuf.remaining() < S) {
tbuf.compact();
int read = c.read(tbuf);
tbuf.flip();
if (read == -1) {
debug("target ending");
return -1;
}
}
hash = Checksum.queryChecksum(tbuf, S);
hashReset = false;
}
if (debug)
debug("hash " + hash + " " + dump());
return source.checksum.findChecksumIndex(hash);
}
public boolean eof() {
return eof;
}
/**
* Reads a byte.
* @throws IOException
*/
public int read() throws IOException {
if (tbuf.remaining() <= S) {
readMore();
if (!tbuf.hasRemaining()) {
eof = true;
return -1;
}
}
byte b = tbuf.get();
if (tbuf.remaining() >= S) {
byte nchar = tbuf.get( tbuf.position() + S -1 );
hash = Checksum.incrementChecksum(hash, b, nchar, S);
} else {
debug("out of char");
}
return b & 0xFF;
}
/**
* Returns the longest match length at the source location.
*/
public int longestMatch(SourceState source) throws IOException {
debug("longestMatch");
int match = 0;
hashReset = true;
while (true) {
if (!sbuf.hasRemaining()) {
sbuf.clear();
int read = source.source.read(sbuf);
sbuf.flip();
if (read == -1)
return match;
}
if (!tbuf.hasRemaining()) {
readMore();
if (!tbuf.hasRemaining()) {
debug("target ending");
eof = true;
return match;
}
}
if (sbuf.get() != tbuf.get()) {
tbuf.position(tbuf.position() - 1);
return match;
}
match++;
}
}
private void readMore() throws IOException {
if (debug)
debug("readMore " + tbuf);
tbuf.compact();
c.read(tbuf);
tbuf.flip();
}
void hash() {
hash = Checksum.queryChecksum(tbuf, S);
}
/**
* Returns a debug <code>String</code>.
*/
@Override
public String toString()
{
return "Target[" +
" targetBuff=" + dump() + // this.tbuf +
" sourceBuff=" + this.sbuf +
" hashf=" + this.hash +
" eof=" + this.eof +
"]";
}
private String dump() { return dump(tbuf); }
private String dump(ByteBuffer bb) {
return getTextDump(bb);
}
private void append(StringBuffer sb, int value) {
char b1 = (char)((value >> 4) & 0x0F);
char b2 = (char)((value) & 0x0F);
sb.append( Character.forDigit(b1, 16) );
sb.append( Character.forDigit(b2, 16) );
}
public String getTextDump(ByteBuffer bb)
{
StringBuffer sb = new StringBuffer(bb.remaining() * 2);
bb.mark();
while (bb.hasRemaining()) {
int val = bb.get();
if (val > 32 && val < 127)
sb.append(" ").append((char)val);
else
append(sb, val);
}
bb.reset();
return sb.toString();
}
}
/**
* Creates a patch using file names.
*/
public static void main(String argv[]) throws Exception {
if (argv.length != 3) {
System.err.println("usage Delta [-d] source target [output]");
System.err.println("either -d or an output filename must be specified.");
System.err.println("aborting..");
return;
}
DiffWriter output = null;
File sourceFile = null;
File targetFile = null;
if (argv[0].equals("-d")) {
sourceFile = new File(argv[1]);
targetFile = new File(argv[2]);
output = new DebugDiffWriter();
} else {
sourceFile = new File(argv[0]);
targetFile = new File(argv[1]);
output =
new GDiffWriter(
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(new File(argv[2])))));
}
if (sourceFile.length() > Integer.MAX_VALUE
|| targetFile.length() > Integer.MAX_VALUE) {
System.err.println(
"source or target is too large, max length is "
+ Integer.MAX_VALUE);
System.err.println("aborting..");
return;
}
Delta d = new Delta();
d.compute(sourceFile, targetFile, output);
output.flush();
output.close();
if (debug) //gls031504a
System.out.println("finished generating delta");
}
private void debug(String s) {
if (debug)
System.err.println(s);
}
}
@@ -0,0 +1,57 @@
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.Closeable;
import java.io.IOException;
/**
* Interface for DIFF writers.
*/
public interface DiffWriter extends Closeable {
/**
* Add a GDIFF copy instruction.
*/
public void addCopy(long offset, int length) throws IOException;
/**
* Add a GDIFF data instruction.
* Implementors should buffer the data.
*/
public void addData(byte b) throws IOException;
/**
* Flushes to output, e.g. any data added.
*/
public void flush() throws IOException;
/**
* Closes this stream.
* Note that {@link Diff} will invoke this method at the end.
*/
public void close() throws IOException;
}
@@ -0,0 +1,245 @@
/*
*
* Copyright (c) 2001 Torgeir Veimo
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_INT_INT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_INT_UBYTE;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_INT_USHORT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_LONG_INT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_USHORT_INT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_USHORT_UBYTE;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.COPY_USHORT_USHORT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.DATA_INT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.DATA_MAX;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.DATA_USHORT;
import static cpw.mods.fml.repackage.com.nothome.delta.GDiffWriter.EOF;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
/**
* This class patches an input file with a GDIFF patch fil�e.
*
* The patch file follows the GDIFF file specification available at
* {@link http://www.w3.org/TR/NOTE-gdiff-19970901.html}.
*/
public class GDiffPatcher {
private ByteBuffer buf = ByteBuffer.allocate(1024);
private byte buf2[] = buf.array();
/**
* Constructs a new GDiffPatcher.
*/
public GDiffPatcher() {
}
/**
* Patches to an output file.
*/
public void patch(File sourceFile, File patchFile, File outputFile)
throws IOException
{
RandomAccessFileSeekableSource source =new RandomAccessFileSeekableSource(new RandomAccessFile(sourceFile, "r"));
InputStream patch = new FileInputStream(patchFile);
OutputStream output = new FileOutputStream(outputFile);
try {
patch(source, patch, output);
} catch (IOException e) {
throw e;
} finally {
source.close();
patch.close();
output.close();
}
}
/**
* Patches to an output stream.
*/
public void patch(byte[] source, InputStream patch, OutputStream output) throws IOException {
patch(new ByteBufferSeekableSource(source), patch, output);
}
/**
* Patches in memory, returning the patch result.
*/
public byte[] patch(byte[] source, byte[] patch) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
patch(source, new ByteArrayInputStream(patch), os);
return os.toByteArray();
}
/**
* Patches to an output stream.
*/
public void patch(SeekableSource source, InputStream patch, OutputStream out) throws IOException {
DataOutputStream outOS = new DataOutputStream(out);
DataInputStream patchIS = new DataInputStream(patch);
// the magic string is 'd1 ff d1 ff' + the version number
if (patchIS.readUnsignedByte() != 0xd1 ||
patchIS.readUnsignedByte() != 0xff ||
patchIS.readUnsignedByte() != 0xd1 ||
patchIS.readUnsignedByte() != 0xff ||
patchIS.readUnsignedByte() != 0x04) {
throw new PatchException("magic string not found, aborting!");
}
while (true) {
int command = patchIS.readUnsignedByte();
if (command == EOF)
break;
int length;
int offset;
if (command <= DATA_MAX) {
append(command, patchIS, outOS);
continue;
}
switch (command) {
case DATA_USHORT: // ushort, n bytes following; append
length = patchIS.readUnsignedShort();
append(length, patchIS, outOS);
break;
case DATA_INT: // int, n bytes following; append
length = patchIS.readInt();
append(length, patchIS, outOS);
break;
case COPY_USHORT_UBYTE:
offset = patchIS.readUnsignedShort();
length = patchIS.readUnsignedByte();
copy(offset, length, source, outOS);
break;
case COPY_USHORT_USHORT:
offset = patchIS.readUnsignedShort();
length = patchIS.readUnsignedShort();
copy(offset, length, source, outOS);
break;
case COPY_USHORT_INT:
offset = patchIS.readUnsignedShort();
length = patchIS.readInt();
copy(offset, length, source, outOS);
break;
case COPY_INT_UBYTE:
offset = patchIS.readInt();
length = patchIS.readUnsignedByte();
copy(offset, length, source, outOS);
break;
case COPY_INT_USHORT:
offset = patchIS.readInt();
length = patchIS.readUnsignedShort();
copy(offset, length, source, outOS);
break;
case COPY_INT_INT:
offset = patchIS.readInt();
length = patchIS.readInt();
copy(offset, length, source, outOS);
break;
case COPY_LONG_INT:
long loffset = patchIS.readLong();
length = patchIS.readInt();
copy(loffset, length, source, outOS);
break;
default:
throw new IllegalStateException("command " + command);
}
}
outOS.flush();
}
private void copy(long offset, int length, SeekableSource source, OutputStream output)
throws IOException
{
source.seek(offset);
while (length > 0) {
int len = Math.min(buf.capacity(), length);
buf.clear().limit(len);
int res = source.read(buf);
if (res == -1)
throw new EOFException("in copy " + offset + " " + length);
output.write(buf.array(), 0, res);
length -= res;
}
}
private void append(int length, InputStream patch, OutputStream output) throws IOException {
while (length > 0) {
int len = Math.min(buf2.length, length);
int res = patch.read(buf2, 0, len);
if (res == -1)
throw new EOFException("cannot read " + length);
output.write(buf2, 0, res);
length -= res;
}
}
/**
* Simple command line tool to patch a file.
*/
public static void main(String argv[]) {
if (argv.length != 3) {
System.err.println("usage GDiffPatch source patch output");
System.err.println("aborting..");
return;
}
try {
File sourceFile = new File(argv[0]);
File patchFile = new File(argv[1]);
File outputFile = new File(argv[2]);
if (sourceFile.length() > Integer.MAX_VALUE ||
patchFile.length() > Integer.MAX_VALUE) {
System.err.println("source or patch is too large, max length is " + Integer.MAX_VALUE);
System.err.println("aborting..");
return;
}
GDiffPatcher patcher = new GDiffPatcher();
patcher.patch(sourceFile, patchFile, outputFile);
System.out.println("finished patching file");
} catch (Exception ioe) { //gls031504a
System.err.println("error while patching: " + ioe);
}
}
}
@@ -0,0 +1,174 @@
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Outputs a diff following the GDIFF file specification available at
* http://www.w3.org/TR/NOTE-gdiff-19970901.html.
*/
public class GDiffWriter implements DiffWriter {
/**
* Max length of a chunk.
*/
public static final int CHUNK_SIZE = Short.MAX_VALUE;
public static final byte EOF = 0;
/**
* Max length for single length data encode.
*/
public static final int DATA_MAX = 246;
public static final int DATA_USHORT = 247;
public static final int DATA_INT = 248;
public static final int COPY_USHORT_UBYTE = 249;
public static final int COPY_USHORT_USHORT = 250;
public static final int COPY_USHORT_INT = 251;
public static final int COPY_INT_UBYTE = 252;
public static final int COPY_INT_USHORT = 253;
public static final int COPY_INT_INT = 254;
public static final int COPY_LONG_INT = 255;
private ByteArrayOutputStream buf = new ByteArrayOutputStream();
private boolean debug = false;
private DataOutputStream output = null;
/**
* Constructs a new GDiffWriter.
*/
public GDiffWriter(DataOutputStream os) throws IOException {
this.output = os;
// write magic string "d1 ff d1 ff 04"
output.writeByte(0xd1);
output.writeByte(0xff);
output.writeByte(0xd1);
output.writeByte(0xff);
output.writeByte(0x04);
}
/**
* Constructs a new GDiffWriter.
*/
public GDiffWriter(OutputStream output) throws IOException {
this(new DataOutputStream(output));
}
public void addCopy(long offset, int length) throws IOException {
writeBuf();
//output debug data
if (debug)
System.err.println("COPY off: " + offset + ", len: " + length);
// output real data
if (offset > Integer.MAX_VALUE) {
// Actually, we don't support longer files than int.MAX_VALUE at the moment..
output.writeByte(COPY_LONG_INT);
output.writeLong(offset);
output.writeInt(length);
} else if (offset < 65536) {
if (length < 256) {
output.writeByte(COPY_USHORT_UBYTE);
output.writeShort((int)offset);
output.writeByte(length);
} else if (length > 65535) {
output.writeByte(COPY_USHORT_INT);
output.writeShort((int)offset);
output.writeInt(length);
} else {
output.writeByte(COPY_USHORT_USHORT);
output.writeShort((int)offset);
output.writeShort(length);
}
} else {
if (length < 256) {
output.writeByte(COPY_INT_UBYTE);
output.writeInt((int)offset);
output.writeByte(length);
} else if (length > 65535) {
output.writeByte(COPY_INT_INT);
output.writeInt((int)offset);
output.writeInt(length);
} else {
output.writeByte(COPY_INT_USHORT);
output.writeInt((int)offset);
output.writeShort(length);
}
}
}
/**
* Adds a data byte.
*/
public void addData(byte b) throws IOException {
buf.write(b);
if (buf.size() >= CHUNK_SIZE)
writeBuf();
}
private void writeBuf() throws IOException {
if (buf.size() > 0) {
if (buf.size() <= DATA_MAX) {
output.writeByte(buf.size());
} else if (buf.size() <= 65535) {
output.writeByte(DATA_USHORT);
output.writeShort(buf.size());
} else {
output.writeByte(DATA_INT);
output.writeInt(buf.size());
}
buf.writeTo(output);
buf.reset();
}
}
/**
* Flushes accumulated data bytes, if any.
*/
public void flush() throws IOException
{
writeBuf();
output.flush();
}
/**
* Writes the final EOF byte, closes the underlying stream.
*/
public void close() throws IOException {
this.flush();
output.write((byte)EOF);
output.close();
}
}
@@ -0,0 +1,51 @@
/*
* PatchException.java
*
* Created on June 6, 2006, 9:34 PM
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.IOException;
/**
* Thrown when a patch is invalid.
*/
public class PatchException extends IOException {
private static final long serialVersionUID = 1;
/**
* Creates a new instance of <code>PatchException</code> without detail message.
*/
public PatchException() {
}
/**
* Constructs an instance of <code>PatchException</code> with the specified detail message.
* @param msg the detail message.
*/
public PatchException(String msg) {
super(msg);
}
}
@@ -0,0 +1,75 @@
/*
* RandomAccessFileSeekableSource.java
*
* Created on May 17, 2006, 1:45 PM
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
/**
* Wraps a random access file.
*/
public class RandomAccessFileSeekableSource implements SeekableSource {
private RandomAccessFile raf;
/**
* Constructs a new RandomAccessFileSeekableSource.
* @param raf
*/
public RandomAccessFileSeekableSource(RandomAccessFile raf) {
if (raf == null)
throw new NullPointerException("raf");
this.raf = raf;
}
public void seek(long pos) throws IOException {
raf.seek(pos);
}
public int read(byte[] b, int off, int len) throws IOException {
return raf.read(b, off, len);
}
public long length() throws IOException {
return raf.length();
}
public void close() throws IOException {
raf.close();
}
public int read(ByteBuffer bb) throws IOException {
int c = raf.read(bb.array(), bb.position(), bb.remaining());
if (c == -1)
return -1;
bb.position(bb.position() + c);
return c;
}
}
@@ -0,0 +1,51 @@
/*
* SeekableSource.java
*
* Created on May 17, 2006, 12:33 PM
* Copyright (c) 2006 Heiko Klein
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package cpw.mods.fml.repackage.com.nothome.delta;
import java.io.Closeable;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
/**
* For sources of random-access data, such as {@link RandomAccessFile}.
*/
public interface SeekableSource extends Closeable {
/**
* Sets the position for the next {@link #read(ByteBuffer)}.
*/
void seek(long pos) throws IOException ;
/**
* Reads up to {@link ByteBuffer#remaining()} bytes from the source,
* returning the number of bytes read, or -1 if no bytes were read
* and EOF was reached.
*/
int read(ByteBuffer bb) throws IOException;
}
+44 -41
View File
@@ -1,73 +1,76 @@
#Main FML Access Transformer configuration file
# TileEntity addMapping
public aqp.a(Ljava/lang/Class;Ljava/lang/String;)V #MD:TileEntity/func_70306_a
public asi.a(Ljava/lang/Class;Ljava/lang/String;)V #MD:TileEntity/func_70306_a
# EntityList addMappings
public mv.a(Ljava/lang/Class;Ljava/lang/String;I)V #MD:EntityList/func_75618_a
public mv.a(Ljava/lang/Class;Ljava/lang/String;III)V #MD:EntityList/func_75614_a
public mv.b #FD:EntityList/field_75625_b #nameToClassMap
public mv.c #FD:EntityList/field_75626_c #classToNameMap
public mv.d #FD:EntityList/field_75623_d #idToClassMap
public nq.a(Ljava/lang/Class;Ljava/lang/String;I)V #MD:EntityList/func_75618_a
public nq.a(Ljava/lang/Class;Ljava/lang/String;III)V #MD:EntityList/func_75614_a
public nq.b #FD:EntityList/field_75625_b #nameToClassMap
public nq.c #FD:EntityList/field_75626_c #classToNameMap
public nq.d #FD:EntityList/field_75623_d #idToClassMap
# RenderEngine
#public bba.h #FD:RenderEngine/field_78367_h #textureList # -- MISSING MAPPING # -- MISSING MAPPING
public bgf.g #FD:RenderEngine/field_78366_k #texturePack
#public bge.g #FD:RenderEngine/field_78366_k #texturePack # -- MISSING MAPPING
# RenderManager
public bgz.q #FD:RenderManager/field_78729_o #renderers
public bga.q #FD:RenderManager/field_78729_o #renderers
# RenderBlocks - everything
public bgg.* #FD:RenderBlocks/*
public bgg.*() #MD:RenderBlocks/*
public bfg.* #FD:RenderBlocks/*
public bfg.*() #MD:RenderBlocks/*
#RenderPlayer
public-f bhu.h #FD:RenderPlayer/field_77110_j #armorlist
#public-f bht.h #FD:RenderPlayer/field_77110_j #armorlist # -- MISSING MAPPING
#RenderBiped
public-f bhh.k #FD:RenderBiped/field_82424_k #armorlist
public-f bgj.l #FD:RenderBiped/field_82424_k #armorlist
#StringTranslate
public bp.b #FD:StringTranslate/field_74815_b
public bp.e #FD:StringTranslate/field_74813_d
#public bp.b #FD:StringTranslate/field_74815_b # -- MISSING MAPPING
#public bp.e #FD:StringTranslate/field_74813_d # -- MISSING MAPPING
# TileEntityRenderer
public bje.m #FD:TileEntityRenderer/field_76966_m
public bis.m #FD:TileEntityRenderer/field_76966_m
# CraftingManager - make the add recipe methods public
public yk.a(Lwm;[Ljava/lang/Object;)Lyn; #MD:CraftingManager/func_92103_a
public yk.b(Lwm;[Ljava/lang/Object;)V #MD:CraftingManager/func_77596_b
public aaa.a(Lxz;[Ljava/lang/Object;)Laad; #MD:CraftingManager/func_92103_a
public aaa.b(Lxz;[Ljava/lang/Object;)V #MD:CraftingManager/func_77596_b
# WeightedRandomItem
public lo.a #FD:WeightedRandomItem/field_76292_a #probability
public mg.a #FD:WeightedRandomItem/field_76292_a #probability
# ItemStack
#public+f tv.c #FD:ItemStack/field_77993_c #itemId
# StatBase
public ka.a #FD:StatBase/field_75978_a #statName
public kr.a #FD:StatBase/field_75978_a #statName
# NetLoginHandler
public jf.a(Ljf;Z)Z #MD:NetLoginHandler/func_72531_a #'complete connection'
public jf.g #FD:NetLoginHandler/field_72543_h #userName
public jv.a(Ljv;Z)Z #MD:NetLoginHandler/func_72531_a #'complete connection'
public jv.g #FD:NetLoginHandler/field_72543_h #userName
# EntityPlayerMP getNextWindowId
public jc.cr()V #MD:EntityPlayerMP/func_71117_bO
public jc.cu #FD:EntityPlayerMP/field_71139_cq
public js.bJ()V #MD:EntityPlayerMP/func_71117_bO
public js.bX #FD:EntityPlayerMP/field_71139_cq
# EntityAITaskEntry
public oo #CL:EntityAITaskEntry
public pr #CL:EntityAITaskEntry
# EntityAITasks
public on.a #FD:EntityAITasks/field_75782_a #taskList
public pq.a #FD:EntityAITasks/field_75782_a #taskList
# BlockChest
public aln.m(Laab;III)Z #MD:BlockChest/func_72292_n #isOcelotBlockingChest
public and.m(Labr;III)Z #MD:BlockChest/func_72292_n #isOcelotBlockingChest
# EntityLiving
public ng.aU #FD:EntityLiving/field_70736_aM #carryoverDamage
public ng.bo #FD:EntityLiving/field_70714_bg #tasks
public ng.bG #FD:EntityLiving/field_70703_bu #isJumping
#public ng.aU #FD:EntityLiving/field_70736_aM #carryoverDamage # -- MISSING MAPPING
public od.c #FD:EntityLiving/field_70714_bg #tasks
#public ng.bG #FD:EntityLiving/field_70703_bu #isJumping # -- MISSING MAPPING
# EntityAIOcelotSit
protected pa.a(Laab;III)Z #MD:EntityAIOcelotSit/func_75398_a #nearestSittableBlock
protected pa.f()Z #MD:EntityAIOcelotSit/func_75399_f #isblocksittable
protected qd.a(Labr;III)Z #MD:EntityAIOcelotSit/func_75398_a #nearestSittableBlock
protected qd.f()Z #MD:EntityAIOcelotSit/func_75399_f #isblocksittable
# CallableMinecraftVersion - sanity check the MC version
public c #CL:CallableMinecraftVersion
public c.<init>(Lb;)V #MD:CallableMinecraftVersion/<init>(Lnet/minecraft/src/CrashReport;) #constructor
# EntityAnimal
public qh.d #FD:EntityAnimal/field_70881_d #inLove
public rm.bp #FD:EntityAnimal/field_70881_d #inLove
# WorldType
public aal.<init>(ILjava/lang/String;)V #MD:WorldType/<init>(ILjava/lang/String;)
public aal.<init>(ILjava/lang/String;I)V #MD:WorldType/<init>(ILjava/lang/String;I)
public acb.<init>(ILjava/lang/String;)V #MD:WorldType/<init>(ILjava/lang/String;)
public acb.<init>(ILjava/lang/String;I)V #MD:WorldType/<init>(ILjava/lang/String;I)
# ComponentVillage
public ahp #CL:ComponentVillage
public ajf #CL:ComponentVillage
# EntityVillager - minmax lists
public sm.a(Lzr;ILjava/util/Random;F)V #MD:EntityVillager/func_70948_a #addBuy
public sm.b(Lzr;ILjava/util/Random;F)V #MD:EntityVillager/func_70949_b #addSell
public sm.bP #FD:EntityVillager/field_70958_bB
public sm.bQ #FD:EntityVillager/field_70960_bC
public tw.a(Labh;ILjava/util/Random;F)V #MD:EntityVillager/func_70948_a #addBuy
public tw.b(Labh;ILjava/util/Random;F)V #MD:EntityVillager/func_70949_b #addSell
public tw.bB #FD:EntityVillager/field_70958_bB
public tw.bC #FD:EntityVillager/field_70960_bC
# GuiButtonMerchant
public azi #CL:GuiButtonMerchant
public axo #CL:GuiButtonMerchant
protected awk.a #FD:GuiYesNo/field_73942_a #guiScreen
protected auo.a #FD:GuiYesNo/field_73942_a #guiScreen
# Minecraft
public atn.C #FD:Minecraft/field_71425_J #running
public atn.M #FD:Minecraft/field_71446_o # textureManager
+3 -3
View File
@@ -2,11 +2,11 @@
# Only runs at runtime because it's not necessary at compile time
# has deobf and obf mappings so it runs OK in mcp
# entityplayer -> network/player
sq cpw/mods/fml/common/network/Player
ua cpw/mods/fml/common/network/Player
net.minecraft.entity.player.EntityPlayer cpw/mods/fml/common/network/Player
# block -> blockproxy
apa cpw/mods/fml/common/registry/BlockProxy
aqs cpw/mods/fml/common/registry/BlockProxy
net.minecraft.block.Block cpw/mods/fml/common/registry/BlockProxy
# item -> itemproxy
wk cpw/mods/fml/common/registry/ItemProxy
xx cpw/mods/fml/common/registry/ItemProxy
net.minecraft.item.Item cpw/mods/fml/common/registry/ItemProxy
+2 -2
View File
@@ -3,8 +3,8 @@
"modid": "mcp",
"name": "Minecraft Coder Pack",
"description": "Modding toolkit to decompile and deobfuscate the Minecraft client and server files.",
"version": "7.44",
"mcversion": "1.5.1",
"version": "7.51",
"mcversion": "1.5.2",
"logoFile": "/mcp.png",
"url": "http://mcp.ocean-labs.de/",
"updateUrl": "",
+1 -1
View File
@@ -8,7 +8,7 @@ break-closing-brackets
indent-switches
max-instatement-indent=2
max-instatement-indent=40
pad-oper
pad-header
+2254 -1890
View File
File diff suppressed because it is too large. Load diff
+7100 -2277
View File
File diff suppressed because it is too large. Load diff
+18451 -17922
View File
File diff suppressed because it is too large. Load diff
+12 -6
View File
@@ -38,8 +38,8 @@ DirNatives = %(DirJars)s/bin/natives
Client = %(DirJars)s/bin/minecraft.jar
Server = %(DirJars)s/minecraft_server.jar
LWJGL = %(DirJars)s/bin/jinput.jar,%(DirJars)s/bin/lwjgl.jar,%(DirJars)s/bin/lwjgl_util.jar
MD5Client = 5c1219d869b87d233de3033688ec7567
MD5Server = 9d31b969c3f197a1d40381d5620717ea
MD5Client = 3c56fb4b77b1ca37dde69b5eb896fc4d
MD5Server = ff8f81970a5955737c356b534d3aee96
[RETROGUARD]
Location = %(DirRuntime)s/bin/retroguard.jar
@@ -71,13 +71,15 @@ ClsServerTemp = %(DirTempCls)s/minecraft_server
SrcClientTemp = %(DirTempSrc)s/minecraft
SrcServerTemp = %(DirTempSrc)s/minecraft_server
FFSource = net
FFClientIn = %(DirTemp)s/minecraft_ff_in.jar
FFServerIn = %(DirTemp)s/minecraft_server_ff_in.jar
[OUTPUT]
BinClientTemp = %(DirTempBin)s/minecraft
BinServerTemp = %(DirTempBin)s/minecraft_server
SrcClient = %(DirSrc)s/minecraft
SrcServer = %(DirSrc)s/minecraft_server
TestClient = net/minecraft/client/Minecraft
TestClient = net/minecraft/client/main/Main
TestServer = net/minecraft/server/MinecraftServer
[PATCHES]
@@ -98,7 +100,7 @@ ClassPathClient = %(DirLib)s/,%(DirLib)s/*,%(DirJars)s/bin/minecraft.jar,%(DirJa
ClassPathServer = %(DirLib)s/,%(DirLib)s/*,%(DirJars)s/minecraft_server.jar
ClientFixes = %(DirConf)s/patches
FixStart = Start
IgnorePkg = paulscode,com/jcraft,isom,ibxm,de/matthiasmann/twl,org/xmlpull,javax/xml,com/fasterxml,javax/ws,org/bouncycastle,argo
IgnorePkg = paulscode,com,isom,ibxm,de/matthiasmann/twl,org,javax/xml,javax/ws,argo
[REOBF]
MD5Client = %(DirTemp)s/client.md5
@@ -125,8 +127,8 @@ LogFile = %(DirLogs)s/mcp.log
LogFileErr = %(DirLogs)s/mcperr.log
UpdateUrl =
IgnoreUpdate = %(DirBin)s,%(DirLib)s,%(DirLogs)s,%(DirModSrc)s,%(DirReobf)s,%(DirSrc)s,%(DirTemp)s,%(DirEclipse)s/Client/bin,%(DirEclipse)s/Server/bin,%(DirJars)s/world,%(DirJars)s/saves,%(DirJars)s/resources
RGIndex = 102000
ParamIndex = 22000
RGIndex = 140000
ParamIndex = 40000
[ASTYLE]
AstyleConfig = %(DirConf)s/astyle.cfg
@@ -144,14 +146,18 @@ AStyle_osx = %(DirRuntime)s/bin/astyle-osx
JadRetro = %(DirRuntime)s/bin/jadretro.jar
Fernflower = %(DirRuntime)s/bin/fernflower.jar
Exceptor = %(DirRuntime)s/bin/mcinjector.jar
SpecialSource = %(DirRuntime)s/bin/specialsource.jar
CmdPatch = %s -p1 -u -i {patchfile} -d {srcdir}
CmdJad = %s -b -d {outdir} -dead -o -r -s .java -stat -ff {classes}
CmdAStyle = %s --suffix=none --quiet --options={conffile} {classes}
CmdRG = %s -cp "{classpath}" RetroGuard -searge {conffile}
CmdRGReobf = %s -cp "{classpath}" RetroGuard -notch {conffile}
CmdSS = %s -cp "{classpath}" -jar %s -i {injar} -o {outjar} -m {mapfile} --kill-source
CmdSSReobf = %s -cp "{classpath}" -jar %s -i {injar} -o {outjar} -r -m {mapfile} -d {identifier} -e %s
CmdJadretro = %s -jar %s {targetdir}
CmdFernflower = %s -Xmx512M -jar %s -din=0 -rbr=0 -dgs=1 -asc=1 -log=WARN {indir} {outdir}
CmdExceptor = %s -jar %s {input} {output} {conf} {log}
CmdRecomp = %s -encoding UTF-8 -Xlint:-options -deprecation -g -source 1.6 -target 1.6 -classpath "{classpath}" -sourcepath {sourcepath} -d {outpath} {pkgs}
CmdRecompScala = %s -encoding UTF-8 -deprecation -target:jvm-1.6 -classpath "{classpath}" -sourcepath {sourcepath} -d {outpath} {pkgs}
CmdStartSrv = %s -Xincgc -Xms1024M -Xmx1024M -cp "{classpath}" net.minecraft.server.MinecraftServer
CmdStartClt = %s -Xincgc -Xms1024M -Xmx1024M -cp "{classpath}" -Djava.library.path={natives} Start
+1734 -1480
View File
File diff suppressed because it is too large. Load diff
-8820
View File
File diff suppressed because it is too large. Load diff
+156 -69
View File
@@ -13,12 +13,13 @@ BlockButtonStone,net/minecraft/block
BlockButtonWood,net/minecraft/block
BlockCactus,net/minecraft/block
BlockCake,net/minecraft/block
BlockCarpet,net/minecraft/block
BlockCarrot,net/minecraft/block
BlockCauldron,net/minecraft/block
BlockChest,net/minecraft/block
BlockClay,net/minecraft/block
BlockCloth,net/minecraft/block
BlockCocoa,net/minecraft/block
BlockColored,net/minecraft/block
BlockCommandBlock,net/minecraft/block
BlockComparator,net/minecraft/block
BlockContainer,net/minecraft/block
@@ -51,6 +52,7 @@ BlockGlowStone,net/minecraft/block
BlockGrass,net/minecraft/block
BlockGravel,net/minecraft/block
BlockHalfSlab,net/minecraft/block
BlockHay,net/minecraft/block
BlockHopper,net/minecraft/block
BlockIce,net/minecraft/block
BlockJukeBox,net/minecraft/block
@@ -93,6 +95,7 @@ BlockRedstoneRepeater,net/minecraft/block
BlockRedstoneTorch,net/minecraft/block
BlockRedstoneWire,net/minecraft/block
BlockReed,net/minecraft/block
BlockRotatedPillar,net/minecraft/block
BlockSand,net/minecraft/block
BlockSandStone,net/minecraft/block
BlockSapling,net/minecraft/block
@@ -141,28 +144,23 @@ CallableClientMemoryStats,net/minecraft/client
CallableClientProfiler,net/minecraft/client
CallableGLInfo,net/minecraft/client
CallableLWJGLVersion,net/minecraft/client
CallableLaunchedVersion,net/minecraft/client
CallableModded,net/minecraft/client
CallableParticleScreenName,net/minecraft/client
CallableTexturePack,net/minecraft/client
CallableTickingScreenName,net/minecraft/client
CallableType2,net/minecraft/client
CallableUpdatingScreenName,net/minecraft/client
CanvasCrashReport,net/minecraft/client
CanvasMinecraftApplet,net/minecraft/client
CanvasMojangLogo,net/minecraft/client
EnumOSHelper,net/minecraft/client
GameWindowListener,net/minecraft/client
MinecraftAppletImpl,net/minecraft/client
MinecraftFakeLauncher,net/minecraft/client
PanelCrashReport,net/minecraft/client
Minecraft,net/minecraft/client
StatStringFormatKeyInv,net/minecraft/client
ThreadClientSleep,net/minecraft/client
ThreadShutdown,net/minecraft/client
CodecMus,net/minecraft/client/audio
MusInputStream,net/minecraft/client/audio
ScheduledSound,net/minecraft/client/audio
SoundManager,net/minecraft/client/audio
SoundManagerINNER1,net/minecraft/client/audio
SoundPool,net/minecraft/client/audio
SoundPoolEntry,net/minecraft/client/audio
SoundPoolProtocolHandler,net/minecraft/client/audio
SoundPoolURLConnection,net/minecraft/client/audio
AbstractClientPlayer,net/minecraft/client/entity
EntityClientPlayerMP,net/minecraft/client/entity
EntityOtherPlayerMP,net/minecraft/client/entity
EntityPlayerSP,net/minecraft/client/entity
@@ -201,9 +199,7 @@ GuiMerchant,net/minecraft/client/gui
GuiMultiplayer,net/minecraft/client/gui
GuiNewChat,net/minecraft/client/gui
GuiOptions,net/minecraft/client/gui
GuiParticle,net/minecraft/client/gui
GuiPlayerInfo,net/minecraft/client/gui
GuiProgress,net/minecraft/client/gui
GuiRenameWorld,net/minecraft/client/gui
GuiRepair,net/minecraft/client/gui
GuiScreen,net/minecraft/client/gui
@@ -211,14 +207,13 @@ GuiScreenAddServer,net/minecraft/client/gui
GuiScreenBook,net/minecraft/client/gui
GuiScreenConfigureWorld,net/minecraft/client/gui
GuiScreenConfirmation,net/minecraft/client/gui
GuiScreenCreateOnlineWorld,net/minecraft/client/gui
GuiScreenDemo,net/minecraft/client/gui
GuiScreenDisconnectedOnline,net/minecraft/client/gui
GuiScreenEditOnlineWorld,net/minecraft/client/gui
GuiScreenInvite,net/minecraft/client/gui
GuiScreenLongRunningTask,net/minecraft/client/gui
GuiScreenOnlineServers,net/minecraft/client/gui
GuiScreenResetWorld,net/minecraft/client/gui
GuiScreenOnlineServersSubscreen,net/minecraft/client/gui
GuiScreenSelectLocation,net/minecraft/client/gui
GuiScreenServerList,net/minecraft/client/gui
GuiScreenSubscription,net/minecraft/client/gui
@@ -240,22 +235,17 @@ GuiWorldSlot,net/minecraft/client/gui
GuiYesNo,net/minecraft/client/gui
LoadingScreenRenderer,net/minecraft/client/gui
MapItemRenderer,net/minecraft/client/gui
Particle,net/minecraft/client/gui
RunnableTitleScreen,net/minecraft/client/gui
ScaledResolution,net/minecraft/client/gui
ScreenChatOptions,net/minecraft/client/gui
SelectionListBase,net/minecraft/client/gui
SelectionListInvited,net/minecraft/client/gui
SelectionListLocation,net/minecraft/client/gui
TaskLongRunning,net/minecraft/client/gui
TaskOnlineConnect,net/minecraft/client/gui
TaskResetWorld,net/minecraft/client/gui
TaskWorldCreation,net/minecraft/client/gui
ThreadConnectToOnlineServer,net/minecraft/client/gui
ThreadCreateOnlineWorldScreen,net/minecraft/client/gui
ThreadOnlineConnect,net/minecraft/client/gui
ThreadOnlineScreen,net/minecraft/client/gui
ThreadPollServers,net/minecraft/client/gui
ThreadTitleScreen,net/minecraft/client/gui
GuiAchievement,net/minecraft/client/gui/achievement
GuiAchievements,net/minecraft/client/gui/achievement
GuiSlotStats,net/minecraft/client/gui/achievement
@@ -281,30 +271,52 @@ GuiDispenser,net/minecraft/client/gui/inventory
GuiEditSign,net/minecraft/client/gui/inventory
GuiFurnace,net/minecraft/client/gui/inventory
GuiInventory,net/minecraft/client/gui/inventory
GuiScreenHorseInventory,net/minecraft/client/gui/inventory
SlotCreativeInventory,net/minecraft/client/gui/inventory
GuiScreenBackup,net/minecraft/client/gui/mco
GuiScreenBackupDownloadThread,net/minecraft/client/gui/mco
GuiScreenBackupRestoreTask,net/minecraft/client/gui/mco
GuiScreenBackupSelectionList,net/minecraft/client/gui/mco
GuiScreenCreateOnlineWorld,net/minecraft/client/gui/mco
GuiScreenMcoWorldTemplate,net/minecraft/client/gui/mco
GuiScreenMcoWorldTemplateDownloadThread,net/minecraft/client/gui/mco
GuiScreenMcoWorldTemplateSelectionList,net/minecraft/client/gui/mco
GuiScreenPendingInvitation,net/minecraft/client/gui/mco
GuiScreenPendingInvitationINNER1,net/minecraft/client/gui/mco
GuiScreenPendingInvitationINNER2,net/minecraft/client/gui/mco
GuiScreenPendingInvitationINNER3,net/minecraft/client/gui/mco
GuiScreenPendingInvitationList,net/minecraft/client/gui/mco
GuiScreenResetWorld,net/minecraft/client/gui/mco
ScreenWithCallback,net/minecraft/client/gui/mco
TaskResetWorld,net/minecraft/client/gui/mco
TaskWorldCreation,net/minecraft/client/gui/mco
MainProxyAuthenticator,net/minecraft/client/main
MainShutdownHook,net/minecraft/client/main
Backup,net/minecraft/client/mco
BackupList,net/minecraft/client/mco
ExceptionMcoHttp,net/minecraft/client/mco
ExceptionMcoService,net/minecraft/client/mco
ExceptionRetryCall,net/minecraft/client/mco
Location,net/minecraft/client/mco
Locations,net/minecraft/client/mco
GuiScreenClientOutdated,net/minecraft/client/mco
GuiScreenConfirmationType,net/minecraft/client/mco
McoClient,net/minecraft/client/mco
McoOption,net/minecraft/client/mco
McoOptionNone,net/minecraft/client/mco
McoOptionSome,net/minecraft/client/mco
McoPair,net/minecraft/client/mco
McoServer,net/minecraft/client/mco
McoServerAddress,net/minecraft/client/mco
McoServerList,net/minecraft/client/mco
McoServerListINNER1,net/minecraft/client/mco
McoServerListEmptyAnon,net/minecraft/client/mco
McoServerListUpdateTask,net/minecraft/client/mco
McoServerListUpdateTaskComparator,net/minecraft/client/mco
PendingInvite,net/minecraft/client/mco
PendingInvitesList,net/minecraft/client/mco
Request,net/minecraft/client/mco
RequestDelete,net/minecraft/client/mco
RequestGet,net/minecraft/client/mco
RequestPost,net/minecraft/client/mco
RequestPut,net/minecraft/client/mco
TimerTaskMcoServerListUpdate,net/minecraft/client/mco
TimerTaskMcoServerListUpdateComparator,net/minecraft/client/mco
ValueObjectList,net/minecraft/client/mco
ValueObjectSubscription,net/minecraft/client/mco
WorldTemplate,net/minecraft/client/mco
WorldTemplateList,net/minecraft/client/mco
ModelBase,net/minecraft/client/model
ModelBat,net/minecraft/client/model
ModelBiped,net/minecraft/client/model
@@ -320,8 +332,10 @@ ModelDragon,net/minecraft/client/model
ModelEnderCrystal,net/minecraft/client/model
ModelEnderman,net/minecraft/client/model
ModelGhast,net/minecraft/client/model
ModelHorse,net/minecraft/client/model
ModelIronGolem,net/minecraft/client/model
ModelLargeChest,net/minecraft/client/model
ModelLeashKnot,net/minecraft/client/model
ModelMagmaCube,net/minecraft/client/model
ModelMinecart,net/minecraft/client/model
ModelOcelot,net/minecraft/client/model
@@ -354,7 +368,6 @@ GuiConnecting,net/minecraft/client/multiplayer
LanServer,net/minecraft/client/multiplayer
LanServerList,net/minecraft/client/multiplayer
NetClientHandler,net/minecraft/client/multiplayer
NetClientWebTextures,net/minecraft/client/multiplayer
PlayerControllerMP,net/minecraft/client/multiplayer
ServerAddress,net/minecraft/client/multiplayer
ServerData,net/minecraft/client/multiplayer
@@ -397,7 +410,6 @@ EntitySuspendFX,net/minecraft/client/particle
ActiveRenderInfo,net/minecraft/client/renderer
CallableMouseLocation,net/minecraft/client/renderer
CallableParticlePositionInfo,net/minecraft/client/renderer
CallableParticleScreenName,net/minecraft/client/renderer
CallableScreenName,net/minecraft/client/renderer
CallableScreenSize,net/minecraft/client/renderer
ChestItemRenderHelper,net/minecraft/client/renderer
@@ -413,15 +425,14 @@ ItemRenderer,net/minecraft/client/renderer
OpenGlCapsChecker,net/minecraft/client/renderer
OpenGlHelper,net/minecraft/client/renderer
RenderBlocks,net/minecraft/client/renderer
RenderEngine,net/minecraft/client/renderer
RenderGlobal,net/minecraft/client/renderer
RenderHelper,net/minecraft/client/renderer
RenderList,net/minecraft/client/renderer
RenderSorter,net/minecraft/client/renderer
StitcherException,net/minecraft/client/renderer
Tessellator,net/minecraft/client/renderer
ThreadDownloadImage,net/minecraft/client/renderer
ThreadDownloadImageData,net/minecraft/client/renderer
ThreadDownloadImageDataINNER1,net/minecraft/client/renderer
WorldRenderer,net/minecraft/client/renderer
ClippingHelper,net/minecraft/client/renderer/culling
ClippingHelperImpl,net/minecraft/client/renderer/culling
@@ -433,6 +444,7 @@ RenderBat,net/minecraft/client/renderer/entity
RenderBiped,net/minecraft/client/renderer/entity
RenderBlaze,net/minecraft/client/renderer/entity
RenderBoat,net/minecraft/client/renderer/entity
RenderCaveSpider,net/minecraft/client/renderer/entity
RenderChicken,net/minecraft/client/renderer/entity
RenderCow,net/minecraft/client/renderer/entity
RenderCreeper,net/minecraft/client/renderer/entity
@@ -445,8 +457,10 @@ RenderFireball,net/minecraft/client/renderer/entity
RenderFish,net/minecraft/client/renderer/entity
RenderGhast,net/minecraft/client/renderer/entity
RenderGiantZombie,net/minecraft/client/renderer/entity
RenderHorse,net/minecraft/client/renderer/entity
RenderIronGolem,net/minecraft/client/renderer/entity
RenderItem,net/minecraft/client/renderer/entity
RenderLeashKnot,net/minecraft/client/renderer/entity
RenderLightningBolt,net/minecraft/client/renderer/entity
RenderLiving,net/minecraft/client/renderer/entity
RenderMagmaCube,net/minecraft/client/renderer/entity
@@ -473,17 +487,25 @@ RenderWither,net/minecraft/client/renderer/entity
RenderWolf,net/minecraft/client/renderer/entity
RenderXPOrb,net/minecraft/client/renderer/entity
RenderZombie,net/minecraft/client/renderer/entity
RendererLivingEntity,net/minecraft/client/renderer/entity
AbstractTexture,net/minecraft/client/renderer/texture
DynamicTexture,net/minecraft/client/renderer/texture
IconRegister,net/minecraft/client/renderer/texture
Rect2i,net/minecraft/client/renderer/texture
LayeredTexture,net/minecraft/client/renderer/texture
SimpleTexture,net/minecraft/client/renderer/texture
StitchHolder,net/minecraft/client/renderer/texture
StitchSlot,net/minecraft/client/renderer/texture
Stitcher,net/minecraft/client/renderer/texture
Texture,net/minecraft/client/renderer/texture
TextureAtlasSprite,net/minecraft/client/renderer/texture
TextureClock,net/minecraft/client/renderer/texture
TextureCompass,net/minecraft/client/renderer/texture
TextureManager,net/minecraft/client/renderer/texture
TextureManagerINNER1,net/minecraft/client/renderer/texture
TextureMap,net/minecraft/client/renderer/texture
TextureStitched,net/minecraft/client/renderer/texture
TextureObject,net/minecraft/client/renderer/texture
TextureUtil,net/minecraft/client/renderer/texture
Tickable,net/minecraft/client/renderer/texture
TickableTextureObject,net/minecraft/client/renderer/texture
RenderEndPortal,net/minecraft/client/renderer/tileentity
RenderEnderCrystal,net/minecraft/client/renderer/tileentity
RenderItemFrame,net/minecraft/client/renderer/tileentity
@@ -497,20 +519,54 @@ TileEntityRendererPiston,net/minecraft/client/renderer/tileentity
TileEntitySignRenderer,net/minecraft/client/renderer/tileentity
TileEntitySkullRenderer,net/minecraft/client/renderer/tileentity
TileEntitySpecialRenderer,net/minecraft/client/renderer/tileentity
AbstractResourcePack,net/minecraft/client/resources
DefaultResourcePack,net/minecraft/client/resources
FallbackResourceManager,net/minecraft/client/resources
FileResourcePack,net/minecraft/client/resources
FolderResourcePack,net/minecraft/client/resources
FoliageColorReloadListener,net/minecraft/client/resources
GrassColorReloadListener,net/minecraft/client/resources
GuiScreenTemporaryResourcePackSelect,net/minecraft/client/resources
GuiScreenTemporaryResourcePackSelectSelectionList,net/minecraft/client/resources
I18n,net/minecraft/client/resources
Language,net/minecraft/client/resources
LanguageManager,net/minecraft/client/resources
Locale,net/minecraft/client/resources
ReloadableResourceManager,net/minecraft/client/resources
Resource,net/minecraft/client/resources
ResourceLocation,net/minecraft/client/resources
ResourceManager,net/minecraft/client/resources
ResourceManagerReloadListener,net/minecraft/client/resources
ResourcePack,net/minecraft/client/resources
ResourcePackFileNotFoundException,net/minecraft/client/resources
ResourcePackRepository,net/minecraft/client/resources
ResourcePackRepositoryEntry,net/minecraft/client/resources
ResourcePackRepositoryFilter,net/minecraft/client/resources
SimpleReloadableResourceManager,net/minecraft/client/resources
SimpleReloadableResourceManagerINNER1,net/minecraft/client/resources
SimpleResource,net/minecraft/client/resources
AnimationFrame,net/minecraft/client/resources/data
AnimationMetadataSection,net/minecraft/client/resources/data
AnimationMetadataSectionSerializer,net/minecraft/client/resources/data
BaseMetadataSectionSerializer,net/minecraft/client/resources/data
FontMetadataSection,net/minecraft/client/resources/data
FontMetadataSectionSerializer,net/minecraft/client/resources/data
LanguageMetadataSection,net/minecraft/client/resources/data
LanguageMetadataSectionSerializer,net/minecraft/client/resources/data
MetadataSection,net/minecraft/client/resources/data
MetadataSectionSerializer,net/minecraft/client/resources/data
MetadataSerializer,net/minecraft/client/resources/data
MetadataSerializerEmptyAnon,net/minecraft/client/resources/data
MetadataSerializerRegistration,net/minecraft/client/resources/data
PackMetadataSection,net/minecraft/client/resources/data
PackMetadataSectionSerializer,net/minecraft/client/resources/data
TextureMetadataSection,net/minecraft/client/resources/data
TextureMetadataSectionSerializer,net/minecraft/client/resources/data
EnumOptions,net/minecraft/client/settings
EnumOptionsHelper,net/minecraft/client/settings
GameSettings,net/minecraft/client/settings
KeyBinding,net/minecraft/client/settings
StatPlaceholder,net/minecraft/client/stats
GuiTexturePackSlot,net/minecraft/client/texturepacks
GuiTexturePacks,net/minecraft/client/texturepacks
ITexturePack,net/minecraft/client/texturepacks
TexturePackCustom,net/minecraft/client/texturepacks
TexturePackDefault,net/minecraft/client/texturepacks
TexturePackDownloadSuccess,net/minecraft/client/texturepacks
TexturePackFolder,net/minecraft/client/texturepacks
TexturePackImplementation,net/minecraft/client/texturepacks
TexturePackList,net/minecraft/client/texturepacks
CommandBase,net/minecraft/command
CommandClearInventory,net/minecraft/command
CommandDebug,net/minecraft/command
@@ -526,6 +582,7 @@ CommandHandler,net/minecraft/command
CommandHelp,net/minecraft/command
CommandKill,net/minecraft/command
CommandNotFoundException,net/minecraft/command
CommandPlaySound,net/minecraft/command
CommandServerBan,net/minecraft/command
CommandServerBanIp,net/minecraft/command
CommandServerBanlist,net/minecraft/command
@@ -547,6 +604,8 @@ CommandServerTp,net/minecraft/command
CommandServerWhitelist,net/minecraft/command
CommandSetSpawnpoint,net/minecraft/command
CommandShowSeed,net/minecraft/command
CommandSpreadPlayers,net/minecraft/command
CommandSpreadPlayersPosition,net/minecraft/command
CommandTime,net/minecraft/command
CommandToggleDownfall,net/minecraft/command
CommandWeather,net/minecraft/command
@@ -645,12 +704,6 @@ EnchantmentUntouching,net/minecraft/enchantment
EnchantmentWaterWorker,net/minecraft/enchantment
EnumEnchantmentType,net/minecraft/enchantment
IEnchantmentModifier,net/minecraft/enchantment
CallableEffectAmplifier,net/minecraft/entity
CallableEffectDuration,net/minecraft/entity
CallableEffectID,net/minecraft/entity
CallableEffectIsAmbient,net/minecraft/entity
CallableEffectIsSplash,net/minecraft/entity
CallableEffectName,net/minecraft/entity
CallableEntityName,net/minecraft/entity
CallableEntityTracker,net/minecraft/entity
CallableEntityType,net/minecraft/entity
@@ -662,8 +715,12 @@ EntityCreature,net/minecraft/entity
EntityEggInfo,net/minecraft/entity
EntityFlying,net/minecraft/entity
EntityHanging,net/minecraft/entity
EntityLeashKnot,net/minecraft/entity
EntityList,net/minecraft/entity
EntityLiving,net/minecraft/entity
EntityLivingBase,net/minecraft/entity
EntityLivingData,net/minecraft/entity
EntityOwnable,net/minecraft/entity
EntitySelectorArmoredMob,net/minecraft/entity
EntityTracker,net/minecraft/entity
EntityTrackerEntry,net/minecraft/entity
@@ -677,6 +734,8 @@ INpc,net/minecraft/entity
IProjectile,net/minecraft/entity
IRangedAttackMob,net/minecraft/entity
NpcMerchant,net/minecraft/entity
SharedMonsterAttributes,net/minecraft/entity
SpiderEffectsGroupData,net/minecraft/entity
WatchableObject,net/minecraft/entity
EntityAIArrowAttack,net/minecraft/entity/ai
EntityAIAttackOnCollide,net/minecraft/entity/ai
@@ -705,6 +764,7 @@ EntityAIMoveThroughVillage,net/minecraft/entity/ai
EntityAIMoveTowardsTarget,net/minecraft/entity/ai
EntityAIMoveTwardsRestriction,net/minecraft/entity/ai
EntityAINearestAttackableTarget,net/minecraft/entity/ai
EntityAINearestAttackableTargetSelector,net/minecraft/entity/ai
EntityAINearestAttackableTargetSorter,net/minecraft/entity/ai
EntityAIOcelotAttack,net/minecraft/entity/ai
EntityAIOcelotSit,net/minecraft/entity/ai
@@ -715,6 +775,7 @@ EntityAIPanic,net/minecraft/entity/ai
EntityAIPlay,net/minecraft/entity/ai
EntityAIRestrictOpenDoor,net/minecraft/entity/ai
EntityAIRestrictSun,net/minecraft/entity/ai
EntityAIRunAroundLikeCrazy,net/minecraft/entity/ai
EntityAISit,net/minecraft/entity/ai
EntityAISwimming,net/minecraft/entity/ai
EntityAITarget,net/minecraft/entity/ai
@@ -734,6 +795,16 @@ EntityMinecartMobSpawnerLogic,net/minecraft/entity/ai
EntityMoveHelper,net/minecraft/entity/ai
EntitySenses,net/minecraft/entity/ai
RandomPositionGenerator,net/minecraft/entity/ai
Attribute,net/minecraft/entity/ai/attributes
AttributeInstance,net/minecraft/entity/ai/attributes
AttributeModifier,net/minecraft/entity/ai/attributes
BaseAttribute,net/minecraft/entity/ai/attributes
BaseAttributeMap,net/minecraft/entity/ai/attributes
ClientsideAttributeMap,net/minecraft/entity/ai/attributes
ModifiableAttributeInstance,net/minecraft/entity/ai/attributes
RangedAttribute,net/minecraft/entity/ai/attributes
ReadonlyAttributeInstance,net/minecraft/entity/ai/attributes
ServersideAttributeMap,net/minecraft/entity/ai/attributes
BossStatus,net/minecraft/entity/boss
EntityDragon,net/minecraft/entity/boss
EntityDragonPart,net/minecraft/entity/boss
@@ -788,6 +859,9 @@ EntityAnimal,net/minecraft/entity/passive
EntityBat,net/minecraft/entity/passive
EntityChicken,net/minecraft/entity/passive
EntityCow,net/minecraft/entity/passive
EntityHorse,net/minecraft/entity/passive
EntityHorseBredSelector,net/minecraft/entity/passive
EntityHorseGroupData,net/minecraft/entity/passive
EntityMooshroom,net/minecraft/entity/passive
EntityOcelot,net/minecraft/entity/passive
EntityPig,net/minecraft/entity/passive
@@ -814,6 +888,7 @@ EntitySmallFireball,net/minecraft/entity/projectile
EntitySnowball,net/minecraft/entity/projectile
EntityThrowable,net/minecraft/entity/projectile
EntityWitherSkull,net/minecraft/entity/projectile
AnimalChest,net/minecraft/inventory
Container,net/minecraft/inventory
ContainerBeacon,net/minecraft/inventory
ContainerBrewingStand,net/minecraft/inventory
@@ -822,9 +897,14 @@ ContainerDispenser,net/minecraft/inventory
ContainerEnchantment,net/minecraft/inventory
ContainerFurnace,net/minecraft/inventory
ContainerHopper,net/minecraft/inventory
ContainerHorseInventory,net/minecraft/inventory
ContainerHorseInventorySlotArmor,net/minecraft/inventory
ContainerHorseInventorySlotSaddle,net/minecraft/inventory
ContainerMerchant,net/minecraft/inventory
ContainerPlayer,net/minecraft/inventory
ContainerRepair,net/minecraft/inventory
ContainerRepairINNER1,net/minecraft/inventory
ContainerRepairINNER2,net/minecraft/inventory
ContainerWorkbench,net/minecraft/inventory
ICrafting,net/minecraft/inventory
IInvBasic,net/minecraft/inventory
@@ -836,7 +916,6 @@ InventoryCrafting,net/minecraft/inventory
InventoryEnderChest,net/minecraft/inventory
InventoryLargeChest,net/minecraft/inventory
InventoryMerchant,net/minecraft/inventory
InventoryRepair,net/minecraft/inventory
Slot,net/minecraft/inventory
SlotArmor,net/minecraft/inventory
SlotBeacon,net/minecraft/inventory
@@ -847,7 +926,6 @@ SlotEnchantment,net/minecraft/inventory
SlotEnchantmentTable,net/minecraft/inventory
SlotFurnace,net/minecraft/inventory
SlotMerchantResult,net/minecraft/inventory
SlotRepair,net/minecraft/inventory
BehaviorDispenseArmor,net/minecraft/item
BehaviorDispenseMinecart,net/minecraft/item
EnumAction,net/minecraft/item
@@ -890,6 +968,7 @@ ItemGlassBottle,net/minecraft/item
ItemHangingEntity,net/minecraft/item
ItemHoe,net/minecraft/item
ItemInWorldManager,net/minecraft/item
ItemLeash,net/minecraft/item
ItemLeaves,net/minecraft/item
ItemLilyPad,net/minecraft/item
ItemMap,net/minecraft/item
@@ -897,6 +976,7 @@ ItemMapBase,net/minecraft/item
ItemMinecart,net/minecraft/item
ItemMonsterPlacer,net/minecraft/item
ItemMultiTextureTile,net/minecraft/item
ItemNameTag,net/minecraft/item
ItemPickaxe,net/minecraft/item
ItemPiston,net/minecraft/item
ItemPotion,net/minecraft/item
@@ -938,7 +1018,7 @@ ShapedRecipes,net/minecraft/item/crafting
ShapelessRecipes,net/minecraft/item/crafting
ILogAgent,net/minecraft/logging
LogAgent,net/minecraft/logging
LogAgentINNER1,net/minecraft/logging
LogAgentEmptyAnon,net/minecraft/logging
LogFormatter,net/minecraft/logging
CallableTagCompound1,net/minecraft/nbt
CallableTagCompound2,net/minecraft/nbt
@@ -956,6 +1036,7 @@ NBTTagList,net/minecraft/nbt
NBTTagLong,net/minecraft/nbt
NBTTagShort,net/minecraft/nbt
NBTTagString,net/minecraft/nbt
CallableConnectionName,net/minecraft/network
CallablePacketClass,net/minecraft/network
CallablePacketID,net/minecraft/network
INetworkManager,net/minecraft/network
@@ -1016,6 +1097,7 @@ Packet254ServerPing,net/minecraft/network/packet
Packet255KickDisconnect,net/minecraft/network/packet
Packet25EntityPainting,net/minecraft/network/packet
Packet26EntityExpOrb,net/minecraft/network/packet
Packet27PlayerInput,net/minecraft/network/packet
Packet28EntityVelocity,net/minecraft/network/packet
Packet29DestroyEntity,net/minecraft/network/packet
Packet2ClientProtocol,net/minecraft/network/packet
@@ -1032,6 +1114,7 @@ Packet40EntityMetadata,net/minecraft/network/packet
Packet41EntityEffect,net/minecraft/network/packet
Packet42RemoveEntityEffect,net/minecraft/network/packet
Packet43Experience,net/minecraft/network/packet
Packet44UpdateAttributes,net/minecraft/network/packet
Packet4UpdateTime,net/minecraft/network/packet
Packet51MapChunk,net/minecraft/network/packet
Packet51MapChunkData,net/minecraft/network/packet
@@ -1067,8 +1150,11 @@ PathFinder,net/minecraft/pathfinding
PathNavigate,net/minecraft/pathfinding
PathPoint,net/minecraft/pathfinding
Potion,net/minecraft/potion
PotionAbsoption,net/minecraft/potion
PotionAttackDamage,net/minecraft/potion
PotionEffect,net/minecraft/potion
PotionHealth,net/minecraft/potion
PotionHealthBoost,net/minecraft/potion
PotionHelper,net/minecraft/potion
IPlayerUsage,net/minecraft/profiler
PlayerUsageSnooper,net/minecraft/profiler
@@ -1102,16 +1188,16 @@ DedicatedServerCommandThread,net/minecraft/server/dedicated
DedicatedServerListenThread,net/minecraft/server/dedicated
DedicatedServerSleepThread,net/minecraft/server/dedicated
PropertyManager,net/minecraft/server/dedicated
GuiLogFormatter,net/minecraft/server/gui
GuiLogOutputHandler,net/minecraft/server/gui
GuiStatsComponent,net/minecraft/server/gui
GuiStatsListener,net/minecraft/server/gui
IUpdatePlayerListBox,net/minecraft/server/gui
PlayerListBox,net/minecraft/server/gui
ServerGUI,net/minecraft/server/gui
ServerGuiCommandListener,net/minecraft/server/gui
ServerGuiFocusAdapter,net/minecraft/server/gui
ServerWindowAdapter,net/minecraft/server/gui
MinecraftServerGui,net/minecraft/server/gui
MinecraftServerGuiINNER1,net/minecraft/server/gui
MinecraftServerGuiINNER2,net/minecraft/server/gui
MinecraftServerGuiINNER3,net/minecraft/server/gui
PlayerListComponent,net/minecraft/server/gui
StatsComponent,net/minecraft/server/gui
StatsComponentINNER1,net/minecraft/server/gui
TextAreaLogHandler,net/minecraft/server/gui
TextAreaLogHandlerINNER1,net/minecraft/server/gui
CallableIsModded,net/minecraft/server/integrated
CallableType3,net/minecraft/server/integrated
IntegratedPlayerList,net/minecraft/server/integrated
@@ -1135,6 +1221,7 @@ StatCrafting,net/minecraft/stats
StatFileWriter,net/minecraft/stats
StatList,net/minecraft/stats
StatTypeDistance,net/minecraft/stats
StatTypeFloat,net/minecraft/stats
StatTypeSimple,net/minecraft/stats
StatTypeTime,net/minecraft/stats
StatsSyncher,net/minecraft/stats
@@ -1171,6 +1258,7 @@ AABBLocalPool,net/minecraft/util
AABBPool,net/minecraft/util
AxisAlignedBB,net/minecraft/util
ChatAllowedCharacters,net/minecraft/util
ChatMessageComponent,net/minecraft/util
ChunkCoordinates,net/minecraft/util
CombatEntry,net/minecraft/util
CombatTracker,net/minecraft/util
@@ -1188,8 +1276,6 @@ EnumOS,net/minecraft/util
Facing,net/minecraft/util
FoodStats,net/minecraft/util
HttpUtil,net/minecraft/util
HttpUtilRunnable,net/minecraft/util
IDownloadSuccess,net/minecraft/util
IProgressUpdate,net/minecraft/util
Icon,net/minecraft/util
IntHashMap,net/minecraft/util
@@ -1198,6 +1284,7 @@ LongHashMap,net/minecraft/util
LongHashMapEntry,net/minecraft/util
MD5String,net/minecraft/util
MathHelper,net/minecraft/util
MessageComponentSerializer,net/minecraft/util
MinecraftError,net/minecraft/util
MouseFilter,net/minecraft/util
MouseHelper,net/minecraft/util
@@ -1210,9 +1297,9 @@ Session,net/minecraft/util
StatCollector,net/minecraft/util
StringTranslate,net/minecraft/util
StringUtils,net/minecraft/util
ThreadDownloadResources,net/minecraft/util
Timer,net/minecraft/util
Tuple,net/minecraft/util
Util,net/minecraft/util
ValueObject,net/minecraft/util
Vec3,net/minecraft/util
Vec3Pool,net/minecraft/util
1 class package
13 BlockButtonWood net/minecraft/block
14 BlockCactus net/minecraft/block
15 BlockCake net/minecraft/block
16 BlockCarpet net/minecraft/block
17 BlockCarrot net/minecraft/block
18 BlockCauldron net/minecraft/block
19 BlockChest net/minecraft/block
20 BlockClay net/minecraft/block
BlockCloth net/minecraft/block
21 BlockCocoa net/minecraft/block
22 BlockColored net/minecraft/block
23 BlockCommandBlock net/minecraft/block
24 BlockComparator net/minecraft/block
25 BlockContainer net/minecraft/block
52 BlockGrass net/minecraft/block
53 BlockGravel net/minecraft/block
54 BlockHalfSlab net/minecraft/block
55 BlockHay net/minecraft/block
56 BlockHopper net/minecraft/block
57 BlockIce net/minecraft/block
58 BlockJukeBox net/minecraft/block
95 BlockRedstoneTorch net/minecraft/block
96 BlockRedstoneWire net/minecraft/block
97 BlockReed net/minecraft/block
98 BlockRotatedPillar net/minecraft/block
99 BlockSand net/minecraft/block
100 BlockSandStone net/minecraft/block
101 BlockSapling net/minecraft/block
144 CallableClientProfiler net/minecraft/client
145 CallableGLInfo net/minecraft/client
146 CallableLWJGLVersion net/minecraft/client
147 CallableLaunchedVersion net/minecraft/client
148 CallableModded net/minecraft/client
149 CallableParticleScreenName net/minecraft/client
150 CallableTexturePack net/minecraft/client
CallableTickingScreenName net/minecraft/client
151 CallableType2 net/minecraft/client
152 CallableUpdatingScreenName net/minecraft/client
153 CanvasCrashReport Minecraft net/minecraft/client
CanvasMinecraftApplet net/minecraft/client
CanvasMojangLogo net/minecraft/client
EnumOSHelper net/minecraft/client
GameWindowListener net/minecraft/client
MinecraftAppletImpl net/minecraft/client
MinecraftFakeLauncher net/minecraft/client
PanelCrashReport net/minecraft/client
154 StatStringFormatKeyInv net/minecraft/client
155 ThreadClientSleep net/minecraft/client
ThreadShutdown net/minecraft/client
CodecMus net/minecraft/client/audio
MusInputStream net/minecraft/client/audio
156 ScheduledSound net/minecraft/client/audio
157 SoundManager net/minecraft/client/audio
158 SoundManagerINNER1 net/minecraft/client/audio
159 SoundPool net/minecraft/client/audio
160 SoundPoolEntry net/minecraft/client/audio
161 SoundPoolProtocolHandler net/minecraft/client/audio
162 SoundPoolURLConnection net/minecraft/client/audio
163 AbstractClientPlayer net/minecraft/client/entity
164 EntityClientPlayerMP net/minecraft/client/entity
165 EntityOtherPlayerMP net/minecraft/client/entity
166 EntityPlayerSP net/minecraft/client/entity
199 GuiMultiplayer net/minecraft/client/gui
200 GuiNewChat net/minecraft/client/gui
201 GuiOptions net/minecraft/client/gui
GuiParticle net/minecraft/client/gui
202 GuiPlayerInfo net/minecraft/client/gui
GuiProgress net/minecraft/client/gui
203 GuiRenameWorld net/minecraft/client/gui
204 GuiRepair net/minecraft/client/gui
205 GuiScreen net/minecraft/client/gui
207 GuiScreenBook net/minecraft/client/gui
208 GuiScreenConfigureWorld net/minecraft/client/gui
209 GuiScreenConfirmation net/minecraft/client/gui
GuiScreenCreateOnlineWorld net/minecraft/client/gui
210 GuiScreenDemo net/minecraft/client/gui
211 GuiScreenDisconnectedOnline net/minecraft/client/gui
212 GuiScreenEditOnlineWorld net/minecraft/client/gui
213 GuiScreenInvite net/minecraft/client/gui
214 GuiScreenLongRunningTask net/minecraft/client/gui
215 GuiScreenOnlineServers net/minecraft/client/gui
216 GuiScreenResetWorld GuiScreenOnlineServersSubscreen net/minecraft/client/gui
217 GuiScreenSelectLocation net/minecraft/client/gui
218 GuiScreenServerList net/minecraft/client/gui
219 GuiScreenSubscription net/minecraft/client/gui
235 GuiYesNo net/minecraft/client/gui
236 LoadingScreenRenderer net/minecraft/client/gui
237 MapItemRenderer net/minecraft/client/gui
238 Particle RunnableTitleScreen net/minecraft/client/gui
239 ScaledResolution net/minecraft/client/gui
240 ScreenChatOptions net/minecraft/client/gui
241 SelectionListBase net/minecraft/client/gui
242 SelectionListInvited net/minecraft/client/gui
SelectionListLocation net/minecraft/client/gui
243 TaskLongRunning net/minecraft/client/gui
244 TaskOnlineConnect net/minecraft/client/gui
TaskResetWorld net/minecraft/client/gui
TaskWorldCreation net/minecraft/client/gui
245 ThreadConnectToOnlineServer net/minecraft/client/gui
ThreadCreateOnlineWorldScreen net/minecraft/client/gui
246 ThreadOnlineConnect net/minecraft/client/gui
247 ThreadOnlineScreen net/minecraft/client/gui
248 ThreadPollServers net/minecraft/client/gui
ThreadTitleScreen net/minecraft/client/gui
249 GuiAchievement net/minecraft/client/gui/achievement
250 GuiAchievements net/minecraft/client/gui/achievement
251 GuiSlotStats net/minecraft/client/gui/achievement
271 GuiEditSign net/minecraft/client/gui/inventory
272 GuiFurnace net/minecraft/client/gui/inventory
273 GuiInventory net/minecraft/client/gui/inventory
274 GuiScreenHorseInventory net/minecraft/client/gui/inventory
275 SlotCreativeInventory net/minecraft/client/gui/inventory
276 GuiScreenBackup net/minecraft/client/gui/mco
277 GuiScreenBackupDownloadThread net/minecraft/client/gui/mco
278 GuiScreenBackupRestoreTask net/minecraft/client/gui/mco
279 GuiScreenBackupSelectionList net/minecraft/client/gui/mco
280 GuiScreenCreateOnlineWorld net/minecraft/client/gui/mco
281 GuiScreenMcoWorldTemplate net/minecraft/client/gui/mco
282 GuiScreenMcoWorldTemplateDownloadThread net/minecraft/client/gui/mco
283 GuiScreenMcoWorldTemplateSelectionList net/minecraft/client/gui/mco
284 GuiScreenPendingInvitation net/minecraft/client/gui/mco
285 GuiScreenPendingInvitationINNER1 net/minecraft/client/gui/mco
286 GuiScreenPendingInvitationINNER2 net/minecraft/client/gui/mco
287 GuiScreenPendingInvitationINNER3 net/minecraft/client/gui/mco
288 GuiScreenPendingInvitationList net/minecraft/client/gui/mco
289 GuiScreenResetWorld net/minecraft/client/gui/mco
290 ScreenWithCallback net/minecraft/client/gui/mco
291 TaskResetWorld net/minecraft/client/gui/mco
292 TaskWorldCreation net/minecraft/client/gui/mco
293 MainProxyAuthenticator net/minecraft/client/main
294 MainShutdownHook net/minecraft/client/main
295 Backup net/minecraft/client/mco
296 BackupList net/minecraft/client/mco
297 ExceptionMcoHttp net/minecraft/client/mco
298 ExceptionMcoService net/minecraft/client/mco
299 ExceptionRetryCall net/minecraft/client/mco
300 Location GuiScreenClientOutdated net/minecraft/client/mco
301 Locations GuiScreenConfirmationType net/minecraft/client/mco
302 McoClient net/minecraft/client/mco
McoOption net/minecraft/client/mco
McoOptionNone net/minecraft/client/mco
McoOptionSome net/minecraft/client/mco
McoPair net/minecraft/client/mco
303 McoServer net/minecraft/client/mco
304 McoServerAddress net/minecraft/client/mco
305 McoServerList net/minecraft/client/mco
306 McoServerListINNER1 McoServerListEmptyAnon net/minecraft/client/mco
307 McoServerListUpdateTask net/minecraft/client/mco
308 McoServerListUpdateTaskComparator net/minecraft/client/mco
309 PendingInvite net/minecraft/client/mco
310 PendingInvitesList net/minecraft/client/mco
311 Request net/minecraft/client/mco
312 RequestDelete net/minecraft/client/mco
313 RequestGet net/minecraft/client/mco
314 RequestPost net/minecraft/client/mco
315 RequestPut net/minecraft/client/mco
TimerTaskMcoServerListUpdate net/minecraft/client/mco
TimerTaskMcoServerListUpdateComparator net/minecraft/client/mco
316 ValueObjectList net/minecraft/client/mco
317 ValueObjectSubscription net/minecraft/client/mco
318 WorldTemplate net/minecraft/client/mco
319 WorldTemplateList net/minecraft/client/mco
320 ModelBase net/minecraft/client/model
321 ModelBat net/minecraft/client/model
322 ModelBiped net/minecraft/client/model
332 ModelEnderCrystal net/minecraft/client/model
333 ModelEnderman net/minecraft/client/model
334 ModelGhast net/minecraft/client/model
335 ModelHorse net/minecraft/client/model
336 ModelIronGolem net/minecraft/client/model
337 ModelLargeChest net/minecraft/client/model
338 ModelLeashKnot net/minecraft/client/model
339 ModelMagmaCube net/minecraft/client/model
340 ModelMinecart net/minecraft/client/model
341 ModelOcelot net/minecraft/client/model
368 LanServer net/minecraft/client/multiplayer
369 LanServerList net/minecraft/client/multiplayer
370 NetClientHandler net/minecraft/client/multiplayer
NetClientWebTextures net/minecraft/client/multiplayer
371 PlayerControllerMP net/minecraft/client/multiplayer
372 ServerAddress net/minecraft/client/multiplayer
373 ServerData net/minecraft/client/multiplayer
410 ActiveRenderInfo net/minecraft/client/renderer
411 CallableMouseLocation net/minecraft/client/renderer
412 CallableParticlePositionInfo net/minecraft/client/renderer
CallableParticleScreenName net/minecraft/client/renderer
413 CallableScreenName net/minecraft/client/renderer
414 CallableScreenSize net/minecraft/client/renderer
415 ChestItemRenderHelper net/minecraft/client/renderer
425 OpenGlCapsChecker net/minecraft/client/renderer
426 OpenGlHelper net/minecraft/client/renderer
427 RenderBlocks net/minecraft/client/renderer
RenderEngine net/minecraft/client/renderer
428 RenderGlobal net/minecraft/client/renderer
429 RenderHelper net/minecraft/client/renderer
430 RenderList net/minecraft/client/renderer
431 RenderSorter net/minecraft/client/renderer
432 StitcherException net/minecraft/client/renderer
433 Tessellator net/minecraft/client/renderer
ThreadDownloadImage net/minecraft/client/renderer
434 ThreadDownloadImageData net/minecraft/client/renderer
435 ThreadDownloadImageDataINNER1 net/minecraft/client/renderer
436 WorldRenderer net/minecraft/client/renderer
437 ClippingHelper net/minecraft/client/renderer/culling
438 ClippingHelperImpl net/minecraft/client/renderer/culling
444 RenderBiped net/minecraft/client/renderer/entity
445 RenderBlaze net/minecraft/client/renderer/entity
446 RenderBoat net/minecraft/client/renderer/entity
447 RenderCaveSpider net/minecraft/client/renderer/entity
448 RenderChicken net/minecraft/client/renderer/entity
449 RenderCow net/minecraft/client/renderer/entity
450 RenderCreeper net/minecraft/client/renderer/entity
457 RenderFish net/minecraft/client/renderer/entity
458 RenderGhast net/minecraft/client/renderer/entity
459 RenderGiantZombie net/minecraft/client/renderer/entity
460 RenderHorse net/minecraft/client/renderer/entity
461 RenderIronGolem net/minecraft/client/renderer/entity
462 RenderItem net/minecraft/client/renderer/entity
463 RenderLeashKnot net/minecraft/client/renderer/entity
464 RenderLightningBolt net/minecraft/client/renderer/entity
465 RenderLiving net/minecraft/client/renderer/entity
466 RenderMagmaCube net/minecraft/client/renderer/entity
487 RenderWolf net/minecraft/client/renderer/entity
488 RenderXPOrb net/minecraft/client/renderer/entity
489 RenderZombie net/minecraft/client/renderer/entity
490 RendererLivingEntity net/minecraft/client/renderer/entity
491 AbstractTexture net/minecraft/client/renderer/texture
492 DynamicTexture net/minecraft/client/renderer/texture
493 IconRegister net/minecraft/client/renderer/texture
494 Rect2i LayeredTexture net/minecraft/client/renderer/texture
495 SimpleTexture net/minecraft/client/renderer/texture
496 StitchHolder net/minecraft/client/renderer/texture
497 StitchSlot net/minecraft/client/renderer/texture
498 Stitcher net/minecraft/client/renderer/texture
499 Texture TextureAtlasSprite net/minecraft/client/renderer/texture
500 TextureClock net/minecraft/client/renderer/texture
501 TextureCompass net/minecraft/client/renderer/texture
502 TextureManager net/minecraft/client/renderer/texture
503 TextureManagerINNER1 net/minecraft/client/renderer/texture
504 TextureMap net/minecraft/client/renderer/texture
505 TextureStitched TextureObject net/minecraft/client/renderer/texture
506 TextureUtil net/minecraft/client/renderer/texture
507 Tickable net/minecraft/client/renderer/texture
508 TickableTextureObject net/minecraft/client/renderer/texture
509 RenderEndPortal net/minecraft/client/renderer/tileentity
510 RenderEnderCrystal net/minecraft/client/renderer/tileentity
511 RenderItemFrame net/minecraft/client/renderer/tileentity
519 TileEntitySignRenderer net/minecraft/client/renderer/tileentity
520 TileEntitySkullRenderer net/minecraft/client/renderer/tileentity
521 TileEntitySpecialRenderer net/minecraft/client/renderer/tileentity
522 AbstractResourcePack net/minecraft/client/resources
523 DefaultResourcePack net/minecraft/client/resources
524 FallbackResourceManager net/minecraft/client/resources
525 FileResourcePack net/minecraft/client/resources
526 FolderResourcePack net/minecraft/client/resources
527 FoliageColorReloadListener net/minecraft/client/resources
528 GrassColorReloadListener net/minecraft/client/resources
529 GuiScreenTemporaryResourcePackSelect net/minecraft/client/resources
530 GuiScreenTemporaryResourcePackSelectSelectionList net/minecraft/client/resources
531 I18n net/minecraft/client/resources
532 Language net/minecraft/client/resources
533 LanguageManager net/minecraft/client/resources
534 Locale net/minecraft/client/resources
535 ReloadableResourceManager net/minecraft/client/resources
536 Resource net/minecraft/client/resources
537 ResourceLocation net/minecraft/client/resources
538 ResourceManager net/minecraft/client/resources
539 ResourceManagerReloadListener net/minecraft/client/resources
540 ResourcePack net/minecraft/client/resources
541 ResourcePackFileNotFoundException net/minecraft/client/resources
542 ResourcePackRepository net/minecraft/client/resources
543 ResourcePackRepositoryEntry net/minecraft/client/resources
544 ResourcePackRepositoryFilter net/minecraft/client/resources
545 SimpleReloadableResourceManager net/minecraft/client/resources
546 SimpleReloadableResourceManagerINNER1 net/minecraft/client/resources
547 SimpleResource net/minecraft/client/resources
548 AnimationFrame net/minecraft/client/resources/data
549 AnimationMetadataSection net/minecraft/client/resources/data
550 AnimationMetadataSectionSerializer net/minecraft/client/resources/data
551 BaseMetadataSectionSerializer net/minecraft/client/resources/data
552 FontMetadataSection net/minecraft/client/resources/data
553 FontMetadataSectionSerializer net/minecraft/client/resources/data
554 LanguageMetadataSection net/minecraft/client/resources/data
555 LanguageMetadataSectionSerializer net/minecraft/client/resources/data
556 MetadataSection net/minecraft/client/resources/data
557 MetadataSectionSerializer net/minecraft/client/resources/data
558 MetadataSerializer net/minecraft/client/resources/data
559 MetadataSerializerEmptyAnon net/minecraft/client/resources/data
560 MetadataSerializerRegistration net/minecraft/client/resources/data
561 PackMetadataSection net/minecraft/client/resources/data
562 PackMetadataSectionSerializer net/minecraft/client/resources/data
563 TextureMetadataSection net/minecraft/client/resources/data
564 TextureMetadataSectionSerializer net/minecraft/client/resources/data
565 EnumOptions net/minecraft/client/settings
566 EnumOptionsHelper net/minecraft/client/settings
567 GameSettings net/minecraft/client/settings
568 KeyBinding net/minecraft/client/settings
569 StatPlaceholder net/minecraft/client/stats
GuiTexturePackSlot net/minecraft/client/texturepacks
GuiTexturePacks net/minecraft/client/texturepacks
ITexturePack net/minecraft/client/texturepacks
TexturePackCustom net/minecraft/client/texturepacks
TexturePackDefault net/minecraft/client/texturepacks
TexturePackDownloadSuccess net/minecraft/client/texturepacks
TexturePackFolder net/minecraft/client/texturepacks
TexturePackImplementation net/minecraft/client/texturepacks
TexturePackList net/minecraft/client/texturepacks
570 CommandBase net/minecraft/command
571 CommandClearInventory net/minecraft/command
572 CommandDebug net/minecraft/command
582 CommandHelp net/minecraft/command
583 CommandKill net/minecraft/command
584 CommandNotFoundException net/minecraft/command
585 CommandPlaySound net/minecraft/command
586 CommandServerBan net/minecraft/command
587 CommandServerBanIp net/minecraft/command
588 CommandServerBanlist net/minecraft/command
604 CommandServerWhitelist net/minecraft/command
605 CommandSetSpawnpoint net/minecraft/command
606 CommandShowSeed net/minecraft/command
607 CommandSpreadPlayers net/minecraft/command
608 CommandSpreadPlayersPosition net/minecraft/command
609 CommandTime net/minecraft/command
610 CommandToggleDownfall net/minecraft/command
611 CommandWeather net/minecraft/command
704 EnchantmentWaterWorker net/minecraft/enchantment
705 EnumEnchantmentType net/minecraft/enchantment
706 IEnchantmentModifier net/minecraft/enchantment
CallableEffectAmplifier net/minecraft/entity
CallableEffectDuration net/minecraft/entity
CallableEffectID net/minecraft/entity
CallableEffectIsAmbient net/minecraft/entity
CallableEffectIsSplash net/minecraft/entity
CallableEffectName net/minecraft/entity
707 CallableEntityName net/minecraft/entity
708 CallableEntityTracker net/minecraft/entity
709 CallableEntityType net/minecraft/entity
715 EntityEggInfo net/minecraft/entity
716 EntityFlying net/minecraft/entity
717 EntityHanging net/minecraft/entity
718 EntityLeashKnot net/minecraft/entity
719 EntityList net/minecraft/entity
720 EntityLiving net/minecraft/entity
721 EntityLivingBase net/minecraft/entity
722 EntityLivingData net/minecraft/entity
723 EntityOwnable net/minecraft/entity
724 EntitySelectorArmoredMob net/minecraft/entity
725 EntityTracker net/minecraft/entity
726 EntityTrackerEntry net/minecraft/entity
734 IProjectile net/minecraft/entity
735 IRangedAttackMob net/minecraft/entity
736 NpcMerchant net/minecraft/entity
737 SharedMonsterAttributes net/minecraft/entity
738 SpiderEffectsGroupData net/minecraft/entity
739 WatchableObject net/minecraft/entity
740 EntityAIArrowAttack net/minecraft/entity/ai
741 EntityAIAttackOnCollide net/minecraft/entity/ai
764 EntityAIMoveTowardsTarget net/minecraft/entity/ai
765 EntityAIMoveTwardsRestriction net/minecraft/entity/ai
766 EntityAINearestAttackableTarget net/minecraft/entity/ai
767 EntityAINearestAttackableTargetSelector net/minecraft/entity/ai
768 EntityAINearestAttackableTargetSorter net/minecraft/entity/ai
769 EntityAIOcelotAttack net/minecraft/entity/ai
770 EntityAIOcelotSit net/minecraft/entity/ai
775 EntityAIPlay net/minecraft/entity/ai
776 EntityAIRestrictOpenDoor net/minecraft/entity/ai
777 EntityAIRestrictSun net/minecraft/entity/ai
778 EntityAIRunAroundLikeCrazy net/minecraft/entity/ai
779 EntityAISit net/minecraft/entity/ai
780 EntityAISwimming net/minecraft/entity/ai
781 EntityAITarget net/minecraft/entity/ai
795 EntityMoveHelper net/minecraft/entity/ai
796 EntitySenses net/minecraft/entity/ai
797 RandomPositionGenerator net/minecraft/entity/ai
798 Attribute net/minecraft/entity/ai/attributes
799 AttributeInstance net/minecraft/entity/ai/attributes
800 AttributeModifier net/minecraft/entity/ai/attributes
801 BaseAttribute net/minecraft/entity/ai/attributes
802 BaseAttributeMap net/minecraft/entity/ai/attributes
803 ClientsideAttributeMap net/minecraft/entity/ai/attributes
804 ModifiableAttributeInstance net/minecraft/entity/ai/attributes
805 RangedAttribute net/minecraft/entity/ai/attributes
806 ReadonlyAttributeInstance net/minecraft/entity/ai/attributes
807 ServersideAttributeMap net/minecraft/entity/ai/attributes
808 BossStatus net/minecraft/entity/boss
809 EntityDragon net/minecraft/entity/boss
810 EntityDragonPart net/minecraft/entity/boss
859 EntityBat net/minecraft/entity/passive
860 EntityChicken net/minecraft/entity/passive
861 EntityCow net/minecraft/entity/passive
862 EntityHorse net/minecraft/entity/passive
863 EntityHorseBredSelector net/minecraft/entity/passive
864 EntityHorseGroupData net/minecraft/entity/passive
865 EntityMooshroom net/minecraft/entity/passive
866 EntityOcelot net/minecraft/entity/passive
867 EntityPig net/minecraft/entity/passive
888 EntitySnowball net/minecraft/entity/projectile
889 EntityThrowable net/minecraft/entity/projectile
890 EntityWitherSkull net/minecraft/entity/projectile
891 AnimalChest net/minecraft/inventory
892 Container net/minecraft/inventory
893 ContainerBeacon net/minecraft/inventory
894 ContainerBrewingStand net/minecraft/inventory
897 ContainerEnchantment net/minecraft/inventory
898 ContainerFurnace net/minecraft/inventory
899 ContainerHopper net/minecraft/inventory
900 ContainerHorseInventory net/minecraft/inventory
901 ContainerHorseInventorySlotArmor net/minecraft/inventory
902 ContainerHorseInventorySlotSaddle net/minecraft/inventory
903 ContainerMerchant net/minecraft/inventory
904 ContainerPlayer net/minecraft/inventory
905 ContainerRepair net/minecraft/inventory
906 ContainerRepairINNER1 net/minecraft/inventory
907 ContainerRepairINNER2 net/minecraft/inventory
908 ContainerWorkbench net/minecraft/inventory
909 ICrafting net/minecraft/inventory
910 IInvBasic net/minecraft/inventory
916 InventoryEnderChest net/minecraft/inventory
917 InventoryLargeChest net/minecraft/inventory
918 InventoryMerchant net/minecraft/inventory
InventoryRepair net/minecraft/inventory
919 Slot net/minecraft/inventory
920 SlotArmor net/minecraft/inventory
921 SlotBeacon net/minecraft/inventory
926 SlotEnchantmentTable net/minecraft/inventory
927 SlotFurnace net/minecraft/inventory
928 SlotMerchantResult net/minecraft/inventory
SlotRepair net/minecraft/inventory
929 BehaviorDispenseArmor net/minecraft/item
930 BehaviorDispenseMinecart net/minecraft/item
931 EnumAction net/minecraft/item
968 ItemHangingEntity net/minecraft/item
969 ItemHoe net/minecraft/item
970 ItemInWorldManager net/minecraft/item
971 ItemLeash net/minecraft/item
972 ItemLeaves net/minecraft/item
973 ItemLilyPad net/minecraft/item
974 ItemMap net/minecraft/item
976 ItemMinecart net/minecraft/item
977 ItemMonsterPlacer net/minecraft/item
978 ItemMultiTextureTile net/minecraft/item
979 ItemNameTag net/minecraft/item
980 ItemPickaxe net/minecraft/item
981 ItemPiston net/minecraft/item
982 ItemPotion net/minecraft/item
1018 ShapelessRecipes net/minecraft/item/crafting
1019 ILogAgent net/minecraft/logging
1020 LogAgent net/minecraft/logging
1021 LogAgentINNER1 LogAgentEmptyAnon net/minecraft/logging
1022 LogFormatter net/minecraft/logging
1023 CallableTagCompound1 net/minecraft/nbt
1024 CallableTagCompound2 net/minecraft/nbt
1036 NBTTagLong net/minecraft/nbt
1037 NBTTagShort net/minecraft/nbt
1038 NBTTagString net/minecraft/nbt
1039 CallableConnectionName net/minecraft/network
1040 CallablePacketClass net/minecraft/network
1041 CallablePacketID net/minecraft/network
1042 INetworkManager net/minecraft/network
1097 Packet255KickDisconnect net/minecraft/network/packet
1098 Packet25EntityPainting net/minecraft/network/packet
1099 Packet26EntityExpOrb net/minecraft/network/packet
1100 Packet27PlayerInput net/minecraft/network/packet
1101 Packet28EntityVelocity net/minecraft/network/packet
1102 Packet29DestroyEntity net/minecraft/network/packet
1103 Packet2ClientProtocol net/minecraft/network/packet
1114 Packet41EntityEffect net/minecraft/network/packet
1115 Packet42RemoveEntityEffect net/minecraft/network/packet
1116 Packet43Experience net/minecraft/network/packet
1117 Packet44UpdateAttributes net/minecraft/network/packet
1118 Packet4UpdateTime net/minecraft/network/packet
1119 Packet51MapChunk net/minecraft/network/packet
1120 Packet51MapChunkData net/minecraft/network/packet
1150 PathNavigate net/minecraft/pathfinding
1151 PathPoint net/minecraft/pathfinding
1152 Potion net/minecraft/potion
1153 PotionAbsoption net/minecraft/potion
1154 PotionAttackDamage net/minecraft/potion
1155 PotionEffect net/minecraft/potion
1156 PotionHealth net/minecraft/potion
1157 PotionHealthBoost net/minecraft/potion
1158 PotionHelper net/minecraft/potion
1159 IPlayerUsage net/minecraft/profiler
1160 PlayerUsageSnooper net/minecraft/profiler
1188 DedicatedServerListenThread net/minecraft/server/dedicated
1189 DedicatedServerSleepThread net/minecraft/server/dedicated
1190 PropertyManager net/minecraft/server/dedicated
GuiLogFormatter net/minecraft/server/gui
GuiLogOutputHandler net/minecraft/server/gui
GuiStatsComponent net/minecraft/server/gui
GuiStatsListener net/minecraft/server/gui
1191 IUpdatePlayerListBox net/minecraft/server/gui
1192 PlayerListBox MinecraftServerGui net/minecraft/server/gui
1193 ServerGUI MinecraftServerGuiINNER1 net/minecraft/server/gui
1194 ServerGuiCommandListener MinecraftServerGuiINNER2 net/minecraft/server/gui
1195 ServerGuiFocusAdapter MinecraftServerGuiINNER3 net/minecraft/server/gui
1196 ServerWindowAdapter PlayerListComponent net/minecraft/server/gui
1197 StatsComponent net/minecraft/server/gui
1198 StatsComponentINNER1 net/minecraft/server/gui
1199 TextAreaLogHandler net/minecraft/server/gui
1200 TextAreaLogHandlerINNER1 net/minecraft/server/gui
1201 CallableIsModded net/minecraft/server/integrated
1202 CallableType3 net/minecraft/server/integrated
1203 IntegratedPlayerList net/minecraft/server/integrated
1221 StatFileWriter net/minecraft/stats
1222 StatList net/minecraft/stats
1223 StatTypeDistance net/minecraft/stats
1224 StatTypeFloat net/minecraft/stats
1225 StatTypeSimple net/minecraft/stats
1226 StatTypeTime net/minecraft/stats
1227 StatsSyncher net/minecraft/stats
1258 AABBPool net/minecraft/util
1259 AxisAlignedBB net/minecraft/util
1260 ChatAllowedCharacters net/minecraft/util
1261 ChatMessageComponent net/minecraft/util
1262 ChunkCoordinates net/minecraft/util
1263 CombatEntry net/minecraft/util
1264 CombatTracker net/minecraft/util
1276 Facing net/minecraft/util
1277 FoodStats net/minecraft/util
1278 HttpUtil net/minecraft/util
HttpUtilRunnable net/minecraft/util
IDownloadSuccess net/minecraft/util
1279 IProgressUpdate net/minecraft/util
1280 Icon net/minecraft/util
1281 IntHashMap net/minecraft/util
1284 LongHashMapEntry net/minecraft/util
1285 MD5String net/minecraft/util
1286 MathHelper net/minecraft/util
1287 MessageComponentSerializer net/minecraft/util
1288 MinecraftError net/minecraft/util
1289 MouseFilter net/minecraft/util
1290 MouseHelper net/minecraft/util
1297 StatCollector net/minecraft/util
1298 StringTranslate net/minecraft/util
1299 StringUtils net/minecraft/util
ThreadDownloadResources net/minecraft/util
1300 Timer net/minecraft/util
1301 Tuple net/minecraft/util
1302 Util net/minecraft/util
1303 ValueObject net/minecraft/util
1304 Vec3 net/minecraft/util
1305 Vec3Pool net/minecraft/util
+4180 -3748
View File
File diff suppressed because it is too large. Load diff
+84 -49
View File
@@ -5,75 +5,110 @@ import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Arrays;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import net.minecraft.client.Minecraft;
import net.minecraft.client.main.Main;
public class Start
{
public static void main(String[] args)
public static void main(String[] args) throws Exception
{
int userIndex = -1;
int passIndex = -1;
int sessIndex = -1;
int versIndex = -1;
for( int x = 0; x < args.length; x++)
{
if (args[x].equals("--username")) userIndex = x + 1;
else if (args[x].equals("--password")) passIndex = x + 1;
else if (args[x].equals("--session")) sessIndex = x + 1;
else if (args[x].equals("--version")) versIndex = x + 1;
}
if (userIndex != 0-1 && passIndex != -1 && sessIndex == -1)
{
String[] session = getSession(args[userIndex], args[passIndex]);
if (session != null)
{
args[userIndex] = session[0];
args = concat(args, new String[]{"--session", session[1]});
}
}
//Kill the password if its there so it isn't printed to the console.
if (passIndex != -1)
{
args[passIndex-1] = "no_password_for_joo";
args[passIndex] = "no_password_for_joo";
}
if (versIndex == -1)
{
args = concat(args, new String[]{ "--version", "fml_mcp" });
}
Main.main(args);
}
private static String[] getSession(String username, String password) throws UnsupportedEncodingException
{
String parameters = "http://login.minecraft.net/?user=" + URLEncoder.encode(username, "UTF-8") +
"&password=" + URLEncoder.encode(password, "UTF-8") +
"&version=" + 13;
String result = openUrl(parameters);
if (result == null)
{
System.out.println("Can't connect to minecraft.net");
return null;
}
if (!result.contains(":"))
{
System.out.println("Login Failed: " + result);
return null;
}
String[] values = result.split(":");
return new String[]{ values[2].trim(), values[3].trim() };
}
private static String openUrl(String addr)
{
try
{
Field f = Minecraft.class.getDeclaredField("field_71463_am");
Field.setAccessible(new Field[] { f }, true);
f.set(null, new File("."));
}
catch (Exception e)
{
e.printStackTrace();
return;
}
if (args.length != 2)
{
Minecraft.main(args);
}
else
{
try {
String parameters = "http://login.minecraft.net/?user=" + URLEncoder.encode(args[0], "UTF-8") +
"&password=" + URLEncoder.encode(args[1], "UTF-8") +
"&version=" + 13;
String result = openUrl(parameters);
if (result == null)
{
System.out.println("Can't connect to minecraft.net");
return;
}
if (!result.contains(":"))
{
System.out.println("Login Failed: " + result);
return;
}
//latestVersion, downloadTicket, userName, sessionId
String[] values = result.split(":");
Minecraft.main(new String[]{values[2].trim(), values[3].trim()});
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static String openUrl(String addr)
{
try {
URL url = new URL(addr);
java.io.InputStream is;
is = url.openConnection().getInputStream();
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(is));
String buf = "";
String line = null;
while((line = reader.readLine() ) != null)
while ((line = reader.readLine()) != null)
{
buf += "\n" + line;
buf += "\n" + line;
}
reader.close();
return buf;
} catch (IOException e) {
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
private static <T> T[] concat(T[] first, T[] second)
{
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
}
Loaded 100 of 164 files, more files were not shown because too many files have changed in this diff. Show more