mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7cc50b521 | ||
|
|
1a232cf766 | ||
|
|
853f54bcc2 | ||
|
|
127be2237d | ||
|
|
7e6456d7cd | ||
|
|
664ebda599 | ||
|
|
9b4a225ad2 | ||
|
|
6c59fa2d2c | ||
|
|
5736d850f0 | ||
|
|
127d6ee8ac | ||
|
|
2055543042 | ||
|
|
40e57a26a9 | ||
|
|
d604e44195 | ||
|
|
8b7778ccb6 | ||
|
|
7e30814ecb | ||
|
|
e5b1dfb74c | ||
|
|
27bc77363e | ||
|
|
506b73d0a0 | ||
|
|
20337b6e8a | ||
|
|
33ff87d8d9 | ||
|
|
af06bbd373 | ||
|
|
92a47ace8b | ||
|
|
f285ac369a | ||
|
|
68e76c273a | ||
|
|
e98c311a2c | ||
|
|
293edb316e | ||
|
|
2d4465eaf7 | ||
|
|
9266ff394a | ||
|
|
bbfd85ed1e | ||
|
|
6ecc2303f4 | ||
|
|
d35cfda798 | ||
|
|
cffa2a92a6 | ||
|
|
31695d5ec1 | ||
|
|
bfb3020505 | ||
|
|
22a88ea2e4 | ||
|
|
0423fa5885 | ||
|
|
d17fbb527f | ||
|
|
d40bb0fe32 | ||
|
|
a513060a81 | ||
|
|
8e594a347c | ||
|
|
9af365edcc | ||
|
|
70554d6a2b | ||
|
|
eb84f52493 | ||
|
|
d074830d95 | ||
|
|
f7fe9ebeb2 | ||
|
|
b2c8f37aec | ||
|
|
a5bcccab59 | ||
|
|
a11f368b62 | ||
|
|
59656b004b | ||
|
|
ff8cb67a99 | ||
|
|
fa5256c8a7 | ||
|
|
4b19987ee6 | ||
|
|
9f43303073 | ||
|
|
a20958fb56 | ||
|
|
8c71098081 | ||
|
|
a3a5b44acb | ||
|
|
0473273709 | ||
|
|
bf492f32f9 | ||
|
|
4744677646 | ||
|
|
f0af2e4ef5 | ||
|
|
c7f763d6f0 | ||
|
|
563b8d1215 | ||
|
|
221493453f | ||
|
|
86c928430a | ||
|
|
cd0a0e51d5 | ||
|
|
66ff95f9d7 | ||
|
|
8ad172295f | ||
|
|
26a2ef5995 | ||
|
|
b4e3490fa1 | ||
|
|
828341f987 | ||
|
|
bc03fbb3be | ||
|
|
7a8dae5e35 | ||
|
|
d3c0e1f589 | ||
|
|
9c77d3f25b | ||
|
|
6371e9b71e | ||
|
|
578ef5cfeb | ||
|
|
516954e6f9 | ||
|
|
1151d5c3e3 | ||
|
|
25f1ddac30 | ||
|
|
39a146f8e6 | ||
|
|
037dcaefea | ||
|
|
01d6da3a90 | ||
|
|
8b2665980d | ||
|
|
42b3e6ad56 | ||
|
|
e709ab8a70 | ||
|
|
501409d1fb | ||
|
|
0fb3a34235 | ||
|
|
e4ba1f863e | ||
|
|
1f5c58b723 | ||
|
|
61e4db2c3b | ||
|
|
5efc1eb34c | ||
|
|
96c6f91201 | ||
|
|
62e69a2804 | ||
|
|
e9352d2675 | ||
|
|
ee6abdf28d | ||
|
|
968ee7ab09 | ||
|
|
3b3600d44f | ||
|
|
edcc5ca554 | ||
|
|
ca79dfe298 | ||
|
|
5945279b8b | ||
|
|
57bf64318b | ||
|
|
d9d0a46809 | ||
|
|
2fac644914 | ||
|
|
570592b24b | ||
|
|
fde94144ec | ||
|
|
f348496c10 | ||
|
|
a5c31b5365 | ||
|
|
2dc3f0ddef | ||
|
|
fa567014a5 | ||
|
|
96935bb122 | ||
|
|
43d3042dff | ||
|
|
fec221f8a6 | ||
|
|
b0f0635eb3 | ||
|
|
23a25131b0 | ||
|
|
a6eaa2bebc | ||
|
|
c6a0741379 | ||
|
|
5a1930e2d6 | ||
|
|
418deba5bf | ||
|
|
4ff2cff3c0 | ||
|
|
bd2123cf9d | ||
|
|
c2a603c910 | ||
|
|
db12af48fa | ||
|
|
a0f574a0ac | ||
|
|
8356fe9a7b | ||
|
|
6edce8b5f4 | ||
|
|
ca2bbe0b5f | ||
|
|
c8941a7faa | ||
|
|
5e20c03736 | ||
|
|
b19e882aab | ||
|
|
9d7d32a1b5 | ||
|
|
d512539554 | ||
|
|
a3a93f3387 | ||
|
|
a7eb5dc773 | ||
|
|
b23081df78 | ||
|
|
66db4ec46e | ||
|
|
8bd98c3a2d | ||
|
|
34cc42d3cb | ||
|
|
09eade4623 | ||
|
|
9bfe7df373 | ||
|
|
8006b774bf | ||
|
|
7cc91cfb0c | ||
|
|
24d72852e7 | ||
|
|
cedf3d55d5 | ||
|
|
d915f39996 | ||
|
|
346691c298 | ||
|
|
6dadc1d889 | ||
|
|
8a55f68a18 | ||
|
|
5645fa5847 | ||
|
|
ff0f00f64f | ||
|
|
7a34246dc9 | ||
|
|
62a6b52487 | ||
|
|
b845cde73d | ||
|
|
2c36dfbb34 | ||
|
|
acd880dd2a | ||
|
|
e6f57e5d94 | ||
|
|
b1de0fc17c | ||
|
|
ad4461932f | ||
|
|
3a94211377 | ||
|
|
9386e23b1f | ||
|
|
10b318c71d | ||
|
|
995d5b7b3a | ||
|
|
bbb12c84fd | ||
|
|
b50058ee47 | ||
|
|
4a0bfa937a | ||
|
|
4d1ec666dd | ||
|
|
b52e3d0e7d | ||
|
|
a1011c99a9 | ||
|
|
0ebd4f3d94 | ||
|
|
89c68c46a2 | ||
|
|
e4702cb09d | ||
|
|
6e64fd7a11 | ||
|
|
014b3f4ad5 | ||
|
|
7628c67883 | ||
|
|
54a322c09f | ||
|
|
aadf396244 | ||
|
|
81e18552e3 | ||
|
|
5686fd40a4 | ||
|
|
989ab3e96b | ||
|
|
88f1dc97b6 | ||
|
|
470a18522c | ||
|
|
002951804a | ||
|
|
fe7a832fad | ||
|
|
a2bc30b356 | ||
|
|
bae1f74681 | ||
|
|
887aa277a4 | ||
|
|
e17f2677c7 | ||
|
|
3b9972af39 | ||
|
|
5c96afec70 | ||
|
|
1bca393ecb | ||
|
|
27cf731552 | ||
|
|
94c84cd994 | ||
|
|
c2d3195e76 | ||
|
|
d0e7c9e2ea | ||
|
|
f3e1cac5a1 | ||
|
|
51fb513213 | ||
|
|
65c9fdd8d7 | ||
|
|
c1d4458acc | ||
|
|
ca1ca4f944 | ||
|
|
15ee8bf5a1 | ||
|
|
a08b5b19d5 | ||
|
|
8dac58ffc1 | ||
|
|
f0837070d6 | ||
|
|
dd7502a051 | ||
|
|
b36d4471e6 | ||
|
|
efb1066a88 | ||
|
|
dd39ae540b | ||
|
|
b39f808618 | ||
|
|
a2c059e562 | ||
|
|
19316a0d38 | ||
|
|
fbc7a5c063 | ||
|
|
e9cfd10e39 | ||
|
|
1424883773 | ||
|
|
6c746ec6d9 | ||
|
|
aacbfeb66e | ||
|
|
1513b369d3 | ||
|
|
35852a69fb | ||
|
|
96537dc091 | ||
|
|
e88ddc56ca | ||
|
|
f24ff07b30 | ||
|
|
3420ea7a2d | ||
|
|
87104f0e2d | ||
|
|
640446b868 | ||
|
|
2cf4917ded | ||
|
|
6394ee8714 | ||
|
|
7299e05fe1 | ||
|
|
c4bd0405fd | ||
|
|
89b8236a9c | ||
|
|
70f55c59c0 | ||
|
|
1c1716d833 | ||
|
|
d567f79652 | ||
|
|
ecd4e46a45 | ||
|
|
16fe495d18 | ||
|
|
4f70d23d0e | ||
|
|
290a3c94b7 | ||
|
|
9485dc5a96 | ||
|
|
e6abb69b0e | ||
|
|
e862052bb4 | ||
|
|
4071ad1278 | ||
|
|
60619643e6 | ||
|
|
b818769c1f | ||
|
|
12bc4bab0c | ||
|
|
8fccfa21df | ||
|
|
a697d043fc | ||
|
|
9d812f12cc | ||
|
|
869cf78e98 | ||
|
|
186680cd8c | ||
|
|
5aed6d995d | ||
|
|
3d7a665987 | ||
|
|
10a716969b | ||
|
|
0eb7180fc1 | ||
|
|
b1b4c61b80 | ||
|
|
359cfb5c98 | ||
|
|
8656fd50ce | ||
|
|
25a4dcb653 | ||
|
|
c90a853377 | ||
|
|
18069d8fd2 | ||
|
|
a40f4a75a9 | ||
|
|
5b6460b68c | ||
|
|
c0d1348e65 | ||
|
|
482c163344 | ||
|
|
221d1131b4 | ||
|
|
f19f426449 | ||
|
|
9dd9b6eb71 | ||
|
|
acb0b21d6d | ||
|
|
b17dd3c695 | ||
|
|
fa66ffaf3f | ||
|
|
b106420774 | ||
|
|
c971adb59b | ||
|
|
d6326deeb0 | ||
|
|
483667c919 | ||
|
|
8bef512803 | ||
|
|
501009c11f | ||
|
|
d3d430827f | ||
|
|
2d9b88bd52 | ||
|
|
93d5934ea7 | ||
|
|
180a279558 | ||
|
|
cf38461911 | ||
|
|
2c85539517 | ||
|
|
d651189581 | ||
|
|
f6a8cd556e | ||
|
|
3bde961dc7 | ||
|
|
6396beaef7 | ||
|
|
6bc6defb07 | ||
|
|
732861092f | ||
|
|
9fcc452ed3 | ||
|
|
26302a6ff2 | ||
|
|
62dbfb3837 | ||
|
|
b91cbe9794 | ||
|
|
93b8ba9576 | ||
|
|
23fdbbd03d | ||
|
|
d7a74d84ea | ||
|
|
58e6dd9794 | ||
|
|
907cf2d925 | ||
|
|
ee48a3673d | ||
|
|
c6f362b77f | ||
|
|
6e01c59635 | ||
|
|
d411f66903 | ||
|
|
0768dc1610 | ||
|
|
4c3db16842 | ||
|
|
805fd1dd90 | ||
|
|
c59996b24b | ||
|
|
e0a1e8293b | ||
|
|
e8af9c0233 | ||
|
|
a955d30d64 | ||
|
|
dbab3bb259 | ||
|
|
bd9c4ee99a | ||
|
|
a0cbd3755d | ||
|
|
12323e233f | ||
|
|
8a308db3d4 | ||
|
|
0583dc8b74 | ||
|
|
789a4a3659 | ||
|
|
a87d0451c8 | ||
|
|
82e9309d27 | ||
|
|
8deaa378c9 | ||
|
|
b5363e3552 | ||
|
|
28a10ac340 | ||
|
|
c349d51923 | ||
|
|
ef01745e09 | ||
|
|
c97d6a65d0 | ||
|
|
2062273504 | ||
|
|
6e6436ee41 | ||
|
|
38f4a22bc4 | ||
|
|
3a8b047e3c | ||
|
|
52483ee6bd | ||
|
|
dce1cbc096 | ||
|
|
46c563a9a8 | ||
|
|
1380c2ecce | ||
|
|
71a3818bdd | ||
|
|
e3a343c797 | ||
|
|
195b1a043e | ||
|
|
69e66c327f | ||
|
|
885637cc7d | ||
|
|
90a7c8f787 | ||
|
|
2171c0caa4 | ||
|
|
924a6f9254 | ||
|
|
ad4cffb0c6 | ||
|
|
cf77ffb89d | ||
|
|
b2fdcd7f1c | ||
|
|
094ce2ae18 | ||
|
|
e8cb2c1bfe | ||
|
|
9c6c56c49d | ||
|
|
0d5affede3 | ||
|
|
13f210f403 | ||
|
|
c61ad51883 | ||
|
|
c0842b0797 | ||
|
|
2851079ff0 | ||
|
|
5197524d1c | ||
|
|
78efd1acc6 | ||
|
|
eee0a99b88 | ||
|
|
10c96c394d | ||
|
|
07cc3fb2d9 | ||
|
|
e31f1433bf | ||
|
|
af06c97efd | ||
|
|
400de1d66e | ||
|
|
2a9285eee8 | ||
|
|
785bdde6bd | ||
|
|
071e2dc524 | ||
|
|
fc08d072a4 | ||
|
|
0019485aba | ||
|
|
e76f145b65 | ||
|
|
27d5937f4c | ||
|
|
868c4c5977 | ||
|
|
5a37929ceb | ||
|
|
b1dc2dbf8a | ||
|
|
ecfbef95c7 | ||
|
|
bfd8fbefee | ||
|
|
f8c36104ad | ||
|
|
e26230fb2d | ||
|
|
6417ad0a3c | ||
|
|
0f988d087c | ||
|
|
7c01b64aed | ||
|
|
03130c78a7 | ||
|
|
30ab326d2b | ||
|
|
8d1cba57f8 | ||
|
|
cbfd6c1a66 | ||
|
|
81cb3c82f4 | ||
|
|
e64296e109 | ||
|
|
5872b31781 | ||
|
|
51b801b1c6 | ||
|
|
9ef153c0b6 | ||
|
|
2e236faec7 | ||
|
|
129c356ecf | ||
|
|
d8316b0bdc | ||
|
|
1d3a92f3f1 | ||
|
|
81c858c719 | ||
|
|
341041aedb | ||
|
|
25256b2295 | ||
|
|
13874ba547 | ||
|
|
bde58add62 | ||
|
|
9112c63347 | ||
|
|
78fa2b8d78 | ||
|
|
6922c369f3 | ||
|
|
b0fd438a1d | ||
|
|
99f4f0c7d3 | ||
|
|
b09c1cd242 | ||
|
|
5ca3bf9362 | ||
|
|
c6a9884bde | ||
|
|
43825ca78e | ||
|
|
44eeadb211 | ||
|
|
7011da5fa9 | ||
|
|
c61ddfa9d1 | ||
|
|
e64b6dcb13 | ||
|
|
183dc236e4 | ||
|
|
ef5349dec2 | ||
|
|
b39afc0711 | ||
|
|
a8579b43ac | ||
|
|
fa92eca328 | ||
|
|
42165df29f | ||
|
|
9860569536 | ||
|
|
7aa48a167f | ||
|
|
6e3764da48 | ||
|
|
4d503d6925 | ||
|
|
8e04d40034 | ||
|
|
cb57cd02e0 | ||
|
|
22fe48e477 | ||
|
|
204f73cb05 | ||
|
|
28096abea5 | ||
|
|
2d7eb5cb7f | ||
|
|
e6d6932e21 | ||
|
|
406e5d64c0 | ||
|
|
13756aad9f | ||
|
|
c1a8b16f30 | ||
|
|
e3671285c3 |
No files matched your search
+10
-1
@@ -1 +1,10 @@
|
||||
* text=auto
|
||||
* text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.patch text eol=lf
|
||||
*.png binary
|
||||
*.exe binary
|
||||
*.dll binary
|
||||
*.zip binary
|
||||
*.pyd binary
|
||||
*.cfg text eol=lf
|
||||
*.py text eol=lf
|
||||
+3
-2
@@ -4,9 +4,10 @@
|
||||
/fmlbuild.properties
|
||||
/fmlversion.properties
|
||||
/difflist.txt
|
||||
/.metadata/
|
||||
/eclipse/.metadata/
|
||||
/target
|
||||
fmlbranding.properties
|
||||
/fernflower.zip
|
||||
/commands.py.bck
|
||||
/mcp*.zip
|
||||
/mcp
|
||||
/eclipse
|
||||
@@ -9,20 +9,6 @@
|
||||
====================================================================== -->
|
||||
<project name="FML" default="jenkinsbuild">
|
||||
<description>The Forge Mod Loader</description>
|
||||
<macrodef name="side">
|
||||
<attribute name="prop" />
|
||||
<attribute name="src" />
|
||||
<attribute name="side" />
|
||||
<sequential>
|
||||
<property name="@{prop}" value="${@{side}.@{src}}" />
|
||||
<condition property="is.client">
|
||||
<equals arg1="@{side}" arg2="client" />
|
||||
</condition>
|
||||
<condition property="is.server">
|
||||
<equals arg1="@{side}" arg2="server" />
|
||||
</condition>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<target name="writeversion" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${basedir}" failonerror="true">
|
||||
<arg value="${basedir}/getversion.py" />
|
||||
@@ -38,36 +24,36 @@
|
||||
<format pattern="yyMMddHHmmss" property="timestamp" />
|
||||
</tstamp>
|
||||
<property environment="env" />
|
||||
<property file="fmlbuild.properties" />
|
||||
<property name="modname" value="fml" />
|
||||
<condition property="dev.home" value="${env.WORKSPACE}" else="${default.dev.home}">
|
||||
<condition property="mcp.home" value="${env.WORKSPACE}/mcp" else="${basedir}/mcp">
|
||||
<isset property="env.WORKSPACE" />
|
||||
</condition>
|
||||
<condition property="mcp.home" value="${env.WORKSPACE}/mcpworkspace" else="${default.mcp.home}">
|
||||
<isset property="env.WORKSPACE" />
|
||||
</condition>
|
||||
<condition property="python.exe" value="${mcp.home}/runtime/bin/python/python_mcp" else="python">
|
||||
<property name="fml.python.dir" location="${basedir}/python" />
|
||||
<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>
|
||||
<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="server.mcp.obfoutput" location="${mcp.obfoutput}/minecraft_server" />
|
||||
<property name="mcp.srcdir" location="${mcp.home}/src" />
|
||||
<property name="common.mcp.srcdir" location="${mcp.srcdir}/common" />
|
||||
<property name="client.mcp.srcdir" location="${mcp.srcdir}/minecraft" />
|
||||
<property name="server.mcp.srcdir" location="${mcp.srcdir}/minecraft_server" />
|
||||
<property name="clean.mcp.srcdir" location="${mcp.home}/src-base" />
|
||||
<property name="patch.mcp.srcdir" location="${mcp.home}/src-work" />
|
||||
<property name="tmp.mcp.srcdir" location="${mcp.home}/src-tmp" />
|
||||
<property name="renamed.mcp.srcdir" location="${mcp.home}/src-renamed" />
|
||||
<property name="common.src.dir" location="${basedir}/common" />
|
||||
<property name="client.src.dir" location="${basedir}/client" />
|
||||
<property name="server.src.dir" location="${basedir}/server" />
|
||||
<property name="patch.src.dir" location="${basedir}/patches" />
|
||||
<property name="fml.conf.dir" location="${basedir}/conf" />
|
||||
<condition property="version.build" value="${env.BUILD_NUMBER}" else="1">
|
||||
<isset property="env.BUILD_NUMBER" />
|
||||
</condition>
|
||||
<available file="eclipse" property="eclipse.exists"/>
|
||||
</target>
|
||||
|
||||
<target name="makeversion" depends="buildenvsetup">
|
||||
@@ -77,58 +63,58 @@
|
||||
<property name="version.major" value="${fmlbuild.major.number}" />
|
||||
<property name="version.minor" value="${fmlbuild.minor.number}" />
|
||||
<property name="version.rev" value="${fmlbuild.revision.number}" />
|
||||
<property name="version.minecraft" value="${fmlbuild.mcversion}" />
|
||||
<property name="version.branch" value="${fmlbuild.branch}" />
|
||||
<property name="version" value="${version.major}.${version.minor}.${version.rev}.${version.build}" />
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="buildenvsetup">
|
||||
<target name="makeclean" depends="buildenvsetup" if="mcp.exists">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
<arg value="-f" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="buildenvsetup,makeclean" if="mcp.exists">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/decompile.py" />
|
||||
<arg value="-d" />
|
||||
<arg value="-n" />
|
||||
<arg value="${basedir}/decompile.py" />
|
||||
<arg value="${mcp.home}" />
|
||||
<arg value="${basedir}" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="buildandreobfmcp" depends="buildenvsetup,recompile">
|
||||
<target name="reobfuscate" depends="buildenvsetup,recompile">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
|
||||
<arg value="${mcp.home}/runtime/reobfuscate.py" />
|
||||
</exec>
|
||||
<fail message="Reobfuscation failed">
|
||||
<condition>
|
||||
<not>
|
||||
<and>
|
||||
<available file="${mcp.home}/temp/server.md5"/>
|
||||
<available file="${mcp.home}/temp/server_reobf.md5"/>
|
||||
<available file="${mcp.home}/temp/client.md5"/>
|
||||
<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>
|
||||
</fail>
|
||||
</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"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="recompile" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
|
||||
<arg value="${mcp.home}/runtime/recompile.py" />
|
||||
</exec>
|
||||
<fail message="Compilation failed">
|
||||
<condition>
|
||||
<not>
|
||||
<and>
|
||||
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
|
||||
<available file="${mcp.home}/bin/minecraft_server/net/minecraft/server/MinecraftServer.class"/>
|
||||
</and>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<fail message="Compilation failed">
|
||||
<condition>
|
||||
<not>
|
||||
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
</target>
|
||||
|
||||
<target name="merge-client" depends="buildenvsetup">
|
||||
@@ -137,40 +123,34 @@
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-server" depends="buildenvsetup">
|
||||
<copy todir="${server.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<fileset dir="${server.src.dir}" includes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-common">
|
||||
<copy todir="${common.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<copy todir="${client.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<fileset dir="${common.src.dir}" includes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-source" depends="buildenvsetup,merge-client,merge-server,merge-common" />
|
||||
|
||||
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,buildandreobfmcp,makeversion">
|
||||
<antcall target="extract-built-jar">
|
||||
<param name="side" value="client" />
|
||||
</antcall>
|
||||
</target>
|
||||
<target name="merge-source" depends="buildenvsetup,merge-client,merge-common" />
|
||||
|
||||
<target name="build-server" depends="buildenvsetup,merge-server,merge-common,buildandreobfmcp,makeversion">
|
||||
<antcall target="extract-built-jar">
|
||||
<param name="side" value="server" />
|
||||
</antcall>
|
||||
</target>
|
||||
<target name="build-universal" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion">
|
||||
<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>
|
||||
|
||||
<target name="extract-built-jar">
|
||||
<side prop="output" src="mcp.obfoutput" side="${side}" />
|
||||
<property name="jarname" value="${modname}-${side}-${version}" />
|
||||
<mkdir dir="${basedir}/target" />
|
||||
<zip destfile="${basedir}/target/${jarname}.zip">
|
||||
<fileset dir="${output}" includes="**/*.class" />
|
||||
<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"/>
|
||||
</manifest>
|
||||
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" excludes="*.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"/>
|
||||
<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="*.cfg" />
|
||||
<mappedresources>
|
||||
@@ -191,48 +171,19 @@
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build-universal">
|
||||
<property name="universal.jarname" value="${modname}-universal-${version}" />
|
||||
<mkdir dir="${basedir}/target" />
|
||||
<jar destfile="${basedir}/target/${universal.jarname}.zip">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
|
||||
</manifest>
|
||||
<fileset dir="${server.mcp.obfoutput}" includes="**/*.class" />
|
||||
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
|
||||
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
|
||||
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
|
||||
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
|
||||
<mappedresources>
|
||||
<concat>
|
||||
<fileset dir="${basedir}/install" includes="README.txt" />
|
||||
<filterchain>
|
||||
<replacetokens>
|
||||
<token key="MAJOR" value="${version.major}" />
|
||||
<token key="MINOR" value="${version.minor}" />
|
||||
<token key="REV" value="${version.rev}" />
|
||||
<token key="BUILD" value="${version.build}" />
|
||||
<token key="MCVERSION" value="${version.minecraft}" />
|
||||
</replacetokens>
|
||||
</filterchain>
|
||||
</concat>
|
||||
<mergemapper to="README-fml.txt" />
|
||||
</mappedresources>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="build-source-pack" depends="makeversion">
|
||||
<property name="srcpack.jarname" value="${modname}-src-${version}" />
|
||||
<property name="srcpack.jarname" value="${modname}-src-${version.minecraft}-${version}-${version.branch}" />
|
||||
<zip destfile="${basedir}/target/${srcpack.jarname}.zip">
|
||||
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt,commands.patch,mcp_merge.cfg" prefix="fml" />
|
||||
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt,commands.patch,mcp_merge.cfg,mc_versions.cfg" prefix="fml" />
|
||||
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/common" />
|
||||
<zipfileset dir="${client.src.dir}" includes="**/*.java" prefix="fml/client" />
|
||||
<zipfileset dir="${server.src.dir}" includes="**/*.java" prefix="fml/server" />
|
||||
<zipfileset dir="${client.src.dir}" includes="mcp.png" prefix="fml/client" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/common" />
|
||||
<zipfileset dir="${common.src.dir}" includes="*.cfg" prefix="fml/common" />
|
||||
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" prefix="fml/common" />
|
||||
<zipfileset dir="${patch.src.dir}" includes="**/*.patch" prefix="fml/patches" />
|
||||
<zipfileset dir="${fml.conf.dir}" prefix="fml/conf" />
|
||||
<zipfileset dir="${fml.python.dir}" prefix="fml/python" />
|
||||
<mappedresources>
|
||||
<concat>
|
||||
<fileset dir="${basedir}/install" includes="README.txt" />
|
||||
@@ -252,7 +203,7 @@
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="buildenvsetup,merge-server,merge-client,merge-common,build-server,build-client,build-universal,build-source-pack" />
|
||||
<target name="build" depends="buildenvsetup,merge-client,merge-common,build-universal,build-source-pack" />
|
||||
|
||||
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build"/>
|
||||
|
||||
@@ -273,11 +224,7 @@
|
||||
</condition>
|
||||
<fail if="do.not.continue">You have decided not to continue. This script will stop now.</fail>
|
||||
<echo>Preparing the MCP environment at ${mcp.home}</echo>
|
||||
<!--<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/download_fernflower.py" />
|
||||
<arg value="${mcp.home}"/>
|
||||
</exec>-->
|
||||
<antcall target="fmldecompile"/>
|
||||
<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}"/>
|
||||
@@ -295,26 +242,19 @@
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
<antcall target="writeversion"/>
|
||||
<echo>Setup complete! You should now be able to open ${basedir}/eclipse as a workspace in eclipse and import/refresh the FML-Server and FML-Client projects</echo>
|
||||
<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">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
<arg value="-f" />
|
||||
</exec>
|
||||
|
||||
<target name="fmldecompile" depends="buildenvsetup,makeclean">
|
||||
<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/decompile.py" />
|
||||
<arg value="${mcp.home}" />
|
||||
<arg value="${basedir}" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="jenkinsfmldecompile" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
<arg value="-f" />
|
||||
</exec>
|
||||
|
||||
<target name="jenkinsfmldecompile" depends="buildenvsetup,makeclean">
|
||||
<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/decompile.py" />
|
||||
<arg value="${mcp.home}" />
|
||||
@@ -340,7 +280,7 @@
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="repatchclean" depends="buildenvsetup">
|
||||
<delete dir="${mcp.srcdir}"/>
|
||||
<copy todir="${mcp.srcdir}">
|
||||
@@ -354,20 +294,21 @@
|
||||
|
||||
<target name="cleanargo" depends="buildenvsetup">
|
||||
<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"/>
|
||||
</present>
|
||||
<present targetdir="${patch.src.dir}">
|
||||
<globmapper from="*.java" to="*.java.patch"/>
|
||||
</present>
|
||||
</srcfiles>
|
||||
<globmapper from="*.java" to="${patch.src.dir}/*.java.patch"/>
|
||||
</uptodate>
|
||||
<fail unless="checkUptodate.uptodate">
|
||||
A patch is out of date. Update your patches!
|
||||
</fail>
|
||||
<fail unless="checkUptodate.uptodate">
|
||||
A patch is out of date. Update your patches!
|
||||
</fail>
|
||||
</target>
|
||||
|
||||
<target name="updatepatches" depends="buildenvsetup">
|
||||
@@ -378,7 +319,14 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-server,buildandreobfmcp">
|
||||
<target name="makeeclipse" depends="buildenvsetup" unless="eclipse.exists">
|
||||
<echo>
|
||||
Extracting fresh eclipse workspace to ${basedir}/eclipse
|
||||
</echo>
|
||||
<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}"/>
|
||||
</copy>
|
||||
@@ -393,4 +341,12 @@
|
||||
<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"/>
|
||||
</target>
|
||||
</project>
|
||||
@@ -0,0 +1,43 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.GuiErrorScreen;
|
||||
import cpw.mods.fml.common.IFMLHandledException;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/**
|
||||
* If a mod throws this exception during loading, it will be called back to render
|
||||
* the error screen through the methods below. This error will not be cleared, and will
|
||||
* not allow the game to carry on, but might be useful if your mod wishes to report
|
||||
* a fatal configuration error in a pretty way.
|
||||
*
|
||||
* Throw this through a proxy. It won't work on the dedicated server environment.
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public abstract class CustomModLoadingErrorDisplayException extends RuntimeException implements IFMLHandledException
|
||||
{
|
||||
/**
|
||||
* Called after the GUI is inited by the parent code. You can do extra stuff here, maybe?
|
||||
*
|
||||
* @param errorScreen The error screen we're painting
|
||||
* @param fontRenderer A font renderer for you
|
||||
*/
|
||||
public abstract void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer);
|
||||
|
||||
/**
|
||||
* Draw your error to the screen.
|
||||
*
|
||||
* <br/><em>Warning: Minecraft is in a deep error state.</em> <strong>All</strong> it can do is stop.
|
||||
* Do not try and do anything involving complex user interaction here.
|
||||
*
|
||||
* @param errorScreen The error screen to draw to
|
||||
* @param fontRenderer A font renderer for you
|
||||
* @param mouseRelX Mouse X
|
||||
* @param mouseRelY Mouse Y
|
||||
* @param tickTime tick time
|
||||
*/
|
||||
public abstract void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime);
|
||||
}
|
||||
@@ -12,114 +12,73 @@
|
||||
*/
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.Dimension;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.multiplayer.GuiConnecting;
|
||||
import net.minecraft.client.multiplayer.NetClientHandler;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet131MapData;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.MapDifference.ValueDifference;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.CrashReport;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.GameSettings;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.Item;
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.MLProp;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
import net.minecraft.src.NetClientHandler;
|
||||
import net.minecraft.src.NetworkManager;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet1Login;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Packet3Chat;
|
||||
import net.minecraft.src.Profiler;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.RenderManager;
|
||||
import net.minecraft.src.RenderPlayer;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.WorldClient;
|
||||
import net.minecraft.src.WorldType;
|
||||
import argo.jdom.JdomParser;
|
||||
import argo.jdom.JsonNode;
|
||||
import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
|
||||
import cpw.mods.fml.client.registry.ClientRegistry;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.DummyModContainer;
|
||||
import cpw.mods.fml.common.DuplicateModsFoundException;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLDummyContainer;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.IFMLSidedHandler;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.ProxyInjector;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.SidedProxy;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.modloader.ModProperty;
|
||||
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
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.relauncher.Side;
|
||||
|
||||
|
||||
/**
|
||||
* Handles primary communication from hooked code into the system
|
||||
*
|
||||
* The FML entry point is {@link #beginMinecraftLoading(MinecraftServer)} called from
|
||||
* {@link MinecraftServer}
|
||||
* The FML entry point is {@link #beginMinecraftLoading(Minecraft)} called from
|
||||
* {@link Minecraft}
|
||||
*
|
||||
* Obfuscated code should focus on this class and other members of the "server"
|
||||
* (or "client") code
|
||||
@@ -146,21 +105,29 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
*/
|
||||
private Minecraft client;
|
||||
|
||||
|
||||
private boolean firstTick;
|
||||
/**
|
||||
* Called to start the whole game off from
|
||||
* {@link MinecraftServer#startServer}
|
||||
*
|
||||
* @param minecraftServer
|
||||
*/
|
||||
|
||||
private DummyModContainer optifineContainer;
|
||||
|
||||
private boolean guiLoaded;
|
||||
|
||||
private boolean serverIsRunning;
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
private boolean loading;
|
||||
|
||||
private WrongMinecraftVersionException wrongMC;
|
||||
|
||||
private CustomModLoadingErrorDisplayException customError;
|
||||
|
||||
private DuplicateModsFoundException dupesFound;
|
||||
|
||||
private boolean serverShouldBeKilledQuietly;
|
||||
|
||||
/**
|
||||
* Called to start the whole game off
|
||||
*
|
||||
* @param minecraft The minecraft instance being launched
|
||||
*/
|
||||
public void beginMinecraftLoading(Minecraft minecraft)
|
||||
{
|
||||
if (minecraft.func_71355_q())
|
||||
@@ -170,6 +137,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
return;
|
||||
}
|
||||
|
||||
loading = true;
|
||||
client = minecraft;
|
||||
ObfuscationReflectionHelper.detectObfuscation(World.class);
|
||||
TextureFXManager.instance().setClient(client);
|
||||
@@ -180,7 +148,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
Class<?> optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader());
|
||||
String optifineVersion = (String) optifineConfig.getField("VERSION").get(null);
|
||||
Map<String,Object> dummyOptifineMeta = ImmutableMap.<String,Object>builder().put("name", "Optifine").put("version", optifineVersion).build();
|
||||
ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info")).getMetadataForId("optifine", dummyOptifineMeta);
|
||||
ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info"),"optifine").getMetadataForId("optifine", dummyOptifineMeta);
|
||||
optifineContainer = new DummyModContainer(optifineMetadata);
|
||||
FMLLog.info("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion());
|
||||
}
|
||||
@@ -192,6 +160,23 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
{
|
||||
Loader.instance().loadMods();
|
||||
}
|
||||
catch (WrongMinecraftVersionException wrong)
|
||||
{
|
||||
wrongMC = wrong;
|
||||
}
|
||||
catch (DuplicateModsFoundException dupes)
|
||||
{
|
||||
dupesFound = dupes;
|
||||
}
|
||||
catch (MissingModsException missing)
|
||||
{
|
||||
modsMissing = missing;
|
||||
}
|
||||
catch (CustomModLoadingErrorDisplayException custom)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, custom, "A custom exception was thrown by a mod, the game will now halt");
|
||||
customError = custom;
|
||||
}
|
||||
catch (LoaderException le)
|
||||
{
|
||||
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
|
||||
@@ -210,28 +195,60 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
* Also initializes key bindings
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void finishMinecraftLoading()
|
||||
{
|
||||
if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
Loader.instance().initializeMods();
|
||||
}
|
||||
catch (CustomModLoadingErrorDisplayException custom)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, custom, "A custom exception was thrown by a mod, the game will now halt");
|
||||
customError = custom;
|
||||
return;
|
||||
}
|
||||
catch (LoaderException le)
|
||||
{
|
||||
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
|
||||
return;
|
||||
}
|
||||
LanguageRegistry.reloadLanguageTable();
|
||||
RenderingRegistry.instance().loadEntityRenderers((Map<Class<? extends Entity>, Render>)RenderManager.field_78727_a.field_78729_o);
|
||||
|
||||
KeyBindingRegistry.uploadKeyBindingsToGame(client.field_71474_y);
|
||||
loading = false;
|
||||
KeyBindingRegistry.instance().uploadKeyBindingsToGame(client.field_71474_y);
|
||||
}
|
||||
|
||||
// Mark this as a "first tick"
|
||||
firstTick = true;
|
||||
public void onInitializationComplete()
|
||||
{
|
||||
if (wrongMC != null)
|
||||
{
|
||||
client.func_71373_a(new GuiWrongMinecraft(wrongMC));
|
||||
}
|
||||
else if (modsMissing != null)
|
||||
{
|
||||
client.func_71373_a(new GuiModsMissing(modsMissing));
|
||||
}
|
||||
else if (dupesFound != null)
|
||||
{
|
||||
client.func_71373_a(new GuiDupesFound(dupesFound));
|
||||
}
|
||||
else if (customError != null)
|
||||
{
|
||||
client.func_71373_a(new GuiCustomModLoadingErrorScreen(customError));
|
||||
}
|
||||
else
|
||||
{
|
||||
TextureFXManager.instance().loadTextures(client.field_71418_C.func_77292_e());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the server instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Minecraft getClient()
|
||||
{
|
||||
@@ -266,16 +283,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void profileStart(String profileLabel) {
|
||||
client.field_71424_I.func_76320_a(profileLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void profileEnd() {
|
||||
client.field_71424_I.func_76319_b();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mods
|
||||
*/
|
||||
@@ -293,7 +300,7 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
{
|
||||
return Arrays.asList(String.format("Optifine %s",optifineContainer.getVersion()));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
return ImmutableList.<String>of();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,23 +323,42 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket packet)
|
||||
public Entity spawnEntityIntoClientWorld(EntityRegistration er, EntitySpawnPacket packet)
|
||||
{
|
||||
WorldClient wc = client.field_71441_e;
|
||||
|
||||
Class<? extends Entity> cls = er.getEntityClass();
|
||||
|
||||
try
|
||||
{
|
||||
Entity entity = (Entity)(cls.getConstructor(World.class).newInstance(wc));
|
||||
if (entity instanceof IThrowableEntity)
|
||||
Entity entity;
|
||||
if (er.hasCustomSpawning())
|
||||
{
|
||||
Entity thrower = client.field_71439_g.field_70157_k == packet.throwerId ? client.field_71439_g : wc.func_73024_a(packet.throwerId);
|
||||
((IThrowableEntity)entity).setThrower(thrower);
|
||||
entity = er.doCustomSpawning(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
entity = (Entity)(cls.getConstructor(World.class).newInstance(wc));
|
||||
entity.field_70157_k = packet.entityId;
|
||||
entity.func_70012_b(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch);
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
entity.field_70118_ct = packet.rawX;
|
||||
entity.field_70117_cu = packet.rawY;
|
||||
entity.field_70116_cv = packet.rawZ;
|
||||
|
||||
if (entity instanceof IThrowableEntity)
|
||||
{
|
||||
Entity thrower = client.field_71439_g.field_70157_k == packet.throwerId ? client.field_71439_g : wc.func_73045_a(packet.throwerId);
|
||||
((IThrowableEntity)entity).setThrower(thrower);
|
||||
}
|
||||
|
||||
|
||||
Entity parts[] = entity.func_70021_al();
|
||||
if (parts != null)
|
||||
{
|
||||
@@ -343,13 +369,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
}
|
||||
}
|
||||
|
||||
entity.field_70157_k = packet.entityId;
|
||||
entity.func_70056_a(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch, 1);
|
||||
|
||||
if (entity instanceof EntityLiving)
|
||||
{
|
||||
((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw;
|
||||
}
|
||||
|
||||
if (packet.metadata != null)
|
||||
{
|
||||
@@ -379,15 +398,23 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
@Override
|
||||
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket packet)
|
||||
{
|
||||
Entity ent = client.field_71441_e.func_73024_a(packet.entityId);
|
||||
ent.field_70118_ct = packet.serverX;
|
||||
ent.field_70117_cu = packet.serverY;
|
||||
ent.field_70116_cv = packet.serverZ;
|
||||
Entity ent = client.field_71441_e.func_73045_a(packet.entityId);
|
||||
if (ent != null)
|
||||
{
|
||||
ent.field_70118_ct = packet.serverX;
|
||||
ent.field_70117_cu = packet.serverY;
|
||||
ent.field_70116_cv = packet.serverZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Attempted to adjust the position of entity %d which is not present on the client", packet.entityId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginServerLoading(MinecraftServer server)
|
||||
{
|
||||
serverShouldBeKilledQuietly = false;
|
||||
// NOOP
|
||||
}
|
||||
|
||||
@@ -402,4 +429,105 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
{
|
||||
return client.func_71401_C();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Packet packet)
|
||||
{
|
||||
if(client.field_71439_g != null)
|
||||
{
|
||||
client.field_71439_g.field_71174_a.func_72552_c(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayMissingMods(ModMissingPacket modMissingPacket)
|
||||
{
|
||||
client.func_71373_a(new GuiModsMissingForServer(modMissingPacket));
|
||||
}
|
||||
|
||||
/**
|
||||
* If the client is in the midst of loading, we disable saving so that custom settings aren't wiped out
|
||||
*/
|
||||
public boolean isLoading()
|
||||
{
|
||||
return loading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
((NetClientHandler)handler).fmlPacket131Callback(mapData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientCompatibilityLevel(byte compatibilityLevel)
|
||||
{
|
||||
NetClientHandler.setConnectionCompatibilityLevel(compatibilityLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getClientCompatibilityLevel()
|
||||
{
|
||||
return NetClientHandler.getConnectionCompatibilityLevel();
|
||||
}
|
||||
|
||||
public void warnIDMismatch(MapDifference<Integer, ItemData> idDifferences, boolean mayContinue)
|
||||
{
|
||||
GuiIdMismatchScreen mismatch = new GuiIdMismatchScreen(idDifferences, mayContinue);
|
||||
client.func_71373_a(mismatch);
|
||||
}
|
||||
|
||||
public void callbackIdDifferenceResponse(boolean response)
|
||||
{
|
||||
if (response)
|
||||
{
|
||||
serverShouldBeKilledQuietly = false;
|
||||
GameData.releaseGate(true);
|
||||
client.continueWorldLoading();
|
||||
}
|
||||
else
|
||||
{
|
||||
serverShouldBeKilledQuietly = true;
|
||||
GameData.releaseGate(false);
|
||||
// Reset and clear the client state
|
||||
client.func_71403_a((WorldClient)null);
|
||||
client.func_71373_a(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldServerShouldBeKilledQuietly()
|
||||
{
|
||||
return serverShouldBeKilledQuietly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnectIDMismatch(MapDifference<Integer, ItemData> s, NetHandler toKill, INetworkManager mgr)
|
||||
{
|
||||
boolean criticalMismatch = !s.entriesOnlyOnLeft().isEmpty();
|
||||
for (Entry<Integer, ValueDifference<ItemData>> mismatch : s.entriesDiffering().entrySet())
|
||||
{
|
||||
ValueDifference<ItemData> vd = mismatch.getValue();
|
||||
if (!vd.leftValue().mayDifferByOrdinal(vd.rightValue()))
|
||||
{
|
||||
criticalMismatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!criticalMismatch)
|
||||
{
|
||||
// We'll carry on with this connection, and just log a message instead
|
||||
return;
|
||||
}
|
||||
// Nuke the connection
|
||||
((NetClientHandler)toKill).func_72553_e();
|
||||
// Stop GuiConnecting
|
||||
GuiConnecting.forceTermination((GuiConnecting)client.field_71462_r);
|
||||
// pulse the network manager queue to clear cruft
|
||||
mgr.func_74428_b();
|
||||
// Nuke the world client
|
||||
client.func_71403_a((WorldClient)null);
|
||||
// Show error screen
|
||||
warnIDMismatch(s, false);
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,12 @@ import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
import net.minecraft.client.renderer.texturefx.TextureFX;
|
||||
import net.minecraft.client.texturepacks.ITexturePack;
|
||||
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
{
|
||||
@@ -31,7 +32,7 @@ public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
public int tileSizeMask = 15;
|
||||
public int tileSizeSquareMask = 255;
|
||||
public boolean errored = false;
|
||||
protected Logger log = FMLCommonHandler.instance().getFMLLogger();
|
||||
protected Logger log = FMLLog.getLogger();
|
||||
|
||||
public FMLTextureFX(int icon)
|
||||
{
|
||||
@@ -41,7 +42,7 @@ public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
@Override public void setErrored(boolean err){ errored = err; }
|
||||
@Override public boolean getErrored(){ return errored; }
|
||||
@Override
|
||||
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions)
|
||||
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions)
|
||||
{
|
||||
onTextureDimensionsUpdate(dimensions.width, dimensions.height);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.client.gui.GuiErrorScreen;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||
|
||||
public class GuiCustomModLoadingErrorScreen extends GuiErrorScreen
|
||||
{
|
||||
private CustomModLoadingErrorDisplayException customException;
|
||||
public GuiCustomModLoadingErrorScreen(CustomModLoadingErrorDisplayException customException)
|
||||
{
|
||||
this.customException = customException;
|
||||
}
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
super.func_73866_w_();
|
||||
this.customException.initGui(this, field_73886_k);
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
this.customException.drawScreen(this, field_73886_k, p_73863_1_, p_73863_2_, p_73863_3_);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.client.gui.GuiErrorScreen;
|
||||
|
||||
import cpw.mods.fml.common.DuplicateModsFoundException;
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiDupesFound extends GuiErrorScreen
|
||||
{
|
||||
|
||||
private DuplicateModsFoundException dupes;
|
||||
|
||||
public GuiDupesFound(DuplicateModsFoundException dupes)
|
||||
{
|
||||
this.dupes = dupes;
|
||||
}
|
||||
|
||||
@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 - dupes.dupes.size() * 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, "You have mod sources that are duplicate within your system", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, "Mod Id : File name", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=5;
|
||||
for (Entry<ModContainer, File> mc : dupes.dupes.entries())
|
||||
{
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s : %s", mc.getKey().getModId(), mc.getValue().getName()), this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiYesNo;
|
||||
import net.minecraft.util.StringTranslate;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.MapDifference.ValueDifference;
|
||||
|
||||
import cpw.mods.fml.common.registry.ItemData;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiIdMismatchScreen extends GuiYesNo {
|
||||
private List<String> missingIds = Lists.newArrayList();
|
||||
private List<String> mismatchedIds = Lists.newArrayList();
|
||||
private boolean allowContinue;
|
||||
|
||||
public GuiIdMismatchScreen(MapDifference<Integer, ItemData> idDifferences, boolean allowContinue)
|
||||
{
|
||||
super(null,"ID mismatch", "Should I continue?", 1);
|
||||
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()));
|
||||
}
|
||||
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()));
|
||||
}
|
||||
this.allowContinue = allowContinue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73878_a(boolean choice, int p_73878_2_)
|
||||
{
|
||||
FMLClientHandler.instance().callbackIdDifferenceResponse(choice);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
if (!allowContinue && field_73887_h.size() == 2)
|
||||
{
|
||||
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;
|
||||
for (String s: missingIds) {
|
||||
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
offset += 10;
|
||||
}
|
||||
for (String s: mismatchedIds) {
|
||||
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
offset += 10;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.func_73732_a(this.field_73886_k, "You cannot connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 10;
|
||||
}
|
||||
// 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);
|
||||
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.func_73737_a(this.field_73882_e, p_73863_1_, p_73863_2_);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,22 +16,21 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
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.util.StringTranslate;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.common.FMLModContainer;
|
||||
import cpw.mods.fml.common.FMLDummyContainer;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.FontRenderer;
|
||||
import net.minecraft.src.GuiButton;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.GuiSmallButton;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.Tessellator;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -47,7 +46,7 @@ public class GuiModList extends GuiScreen
|
||||
private ArrayList<ModContainer> mods;
|
||||
|
||||
/**
|
||||
* @param guiMainMenu
|
||||
* @param mainMenu
|
||||
*/
|
||||
public GuiModList(GuiScreen mainMenu)
|
||||
{
|
||||
@@ -55,8 +54,19 @@ public class GuiModList extends GuiScreen
|
||||
this.mods=new ArrayList<ModContainer>();
|
||||
FMLClientHandler.instance().addSpecialModEntries(mods);
|
||||
for (ModContainer mod : Loader.instance().getModList()) {
|
||||
if (mod.getMetadata()!=null && mod.getMetadata().parentMod != null) {
|
||||
continue;
|
||||
if (mod.getMetadata()!=null && mod.getMetadata().parentMod==null && !Strings.isNullOrEmpty(mod.getMetadata().parent)) {
|
||||
String parentMod = mod.getMetadata().parent;
|
||||
ModContainer parentContainer = Loader.instance().getIndexedModList().get(parentMod);
|
||||
if (parentContainer != null)
|
||||
{
|
||||
mod.getMetadata().parentMod = parentContainer;
|
||||
parentContainer.getMetadata().childMods.add(mod);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (mod.getMetadata()!=null && mod.getMetadata().parentMod!=null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
mods.add(mod);
|
||||
}
|
||||
@@ -103,6 +113,7 @@ public class GuiModList extends GuiScreen
|
||||
this.func_73732_a(this.field_73886_k, "Mod List", this.field_73880_f / 2, 16, 0xFFFFFF);
|
||||
int offset = this.listWidth + 20;
|
||||
if (selectedMod != null) {
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
if (!selectedMod.getMetadata().autogenerated) {
|
||||
int shifty = 35;
|
||||
if (!selectedMod.getMetadata().logoFile.isEmpty())
|
||||
@@ -125,8 +136,8 @@ public class GuiModList extends GuiScreen
|
||||
this.field_73886_k.func_78261_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
|
||||
shifty += 12;
|
||||
|
||||
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getMetadata().version, selectedMod.getVersion()), offset, shifty);
|
||||
shifty = drawLine(String.format("Mod State: %s", Loader.instance().getModState(selectedMod)), offset, shifty);
|
||||
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getDisplayVersion(), selectedMod.getVersion()), offset, shifty);
|
||||
shifty = drawLine(String.format("Mod ID: '%s' Mod State: %s", selectedMod.getModId(), Loader.instance().getModState(selectedMod)), offset, shifty);
|
||||
if (!selectedMod.getMetadata().credits.isEmpty()) {
|
||||
shifty = drawLine(String.format("Credits: %s", selectedMod.getMetadata().credits), offset, shifty);
|
||||
}
|
||||
@@ -142,6 +153,7 @@ public class GuiModList extends GuiScreen
|
||||
this.func_73732_a(this.field_73886_k, "No mod information found", offset, 65, 0xDDDDDD);
|
||||
this.func_73732_a(this.field_73886_k, "Ask your mod author to provide a mod mcmod.info file", offset, 75, 0xDDDDDD);
|
||||
}
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
super.func_73863_a(p_571_1_, p_571_2_, p_571_3_);
|
||||
}
|
||||
@@ -167,10 +179,6 @@ public class GuiModList extends GuiScreen
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param var1
|
||||
* @return
|
||||
*/
|
||||
public boolean modIndexSelected(int var1)
|
||||
{
|
||||
return var1==selected;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.client.gui.GuiErrorScreen;
|
||||
import cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiModsMissing extends GuiErrorScreen
|
||||
{
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
public GuiModsMissing(MissingModsException modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
super.func_73866_w_();
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = Math.max(85 - modsMissing.missingMods.size() * 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, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=5;
|
||||
for (ArtifactVersion v : modsMissing.missingMods)
|
||||
{
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
}
|
||||
offset+=20;
|
||||
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiSmallButton;
|
||||
import net.minecraft.util.StringTranslate;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiModsMissingForServer extends GuiScreen
|
||||
{
|
||||
private ModMissingPacket modsMissing;
|
||||
|
||||
public GuiModsMissingForServer(ModMissingPacket modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
StringTranslate translations = StringTranslate.func_74808_a();
|
||||
this.field_73887_h.add(new GuiSmallButton(1, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void func_73875_a(GuiButton p_73875_1_)
|
||||
{
|
||||
if (p_73875_1_.field_73742_g && p_73875_1_.field_73741_f == 1)
|
||||
{
|
||||
FMLClientHandler.instance().getClient().func_71373_a(null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = Math.max(85 - modsMissing.getModList().size() * 10, 10);
|
||||
this.func_73732_a(this.field_73886_k, "Forge Mod Loader could not connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 10;
|
||||
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 10;
|
||||
this.func_73732_a(this.field_73886_k, "They are required to play on this server", this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset += 5;
|
||||
for (ArtifactVersion v : modsMissing.getModList())
|
||||
{
|
||||
offset += 10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
|
||||
}
|
||||
super.func_73863_a(p_73863_1_, p_73863_2_, p_73863_3_);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.GuiButton;
|
||||
import net.minecraft.src.Tessellator;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -81,9 +82,10 @@ public abstract class GuiScrollingList
|
||||
protected void func_27257_b(int p_27257_1_, int p_27257_2_) {}
|
||||
|
||||
public int func_27256_c(int p_27256_1_, int p_27256_2_)
|
||||
|
||||
{
|
||||
int var3 = this.listWidth / 2 - 110;
|
||||
int var4 = this.listWidth / 2 + 110;
|
||||
int var3 = this.left + 1;
|
||||
int var4 = this.left + this.listWidth - 7;
|
||||
int var5 = p_27256_2_ - this.top - this.field_27261_r + (int)this.scrollDistance - 4;
|
||||
int var6 = var5 / this.slotHeight;
|
||||
return p_27256_1_ >= var3 && p_27256_1_ <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1;
|
||||
|
||||
@@ -16,15 +16,11 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.GuiLanguage;
|
||||
import net.minecraft.src.GuiSlot;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.Tessellator;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -78,15 +74,15 @@ public class GuiSlotModList extends GuiScrollingList
|
||||
ModContainer mc=mods.get(listIndex);
|
||||
if (Loader.instance().getModState(mc)==ModState.DISABLED)
|
||||
{
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 11), this.left + 3 , var3 + 22, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xFF2222);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 10), this.left + 3 , var3 + 22, 0xFF2222);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFFFFFF);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 9), this.left + 3 , var3 + 22, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFFFFFF);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 10), this.left + 3 , var3 + 22, 0xCCCCCC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.client.gui.GuiErrorScreen;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiWrongMinecraft extends GuiErrorScreen
|
||||
{
|
||||
private WrongMinecraftVersionException wrongMC;
|
||||
public GuiWrongMinecraft(WrongMinecraftVersionException wrongMC)
|
||||
{
|
||||
this.wrongMC = wrongMC;
|
||||
}
|
||||
@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 = 75;
|
||||
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, String.format("The mod listed below does not want to run in Minecraft version %s", Loader.instance().getMinecraftModContainer().getVersion()), this.field_73880_f / 2, offset, 0xFFFFFF);
|
||||
offset+=5;
|
||||
offset+=10;
|
||||
this.func_73732_a(this.field_73886_k, String.format("%s (%s) wants Minecraft %s", wrongMC.mod.getName(), wrongMC.mod.getModId(), wrongMC.mod.acceptableMinecraftVersionRange()), 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);
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,12 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import net.minecraft.src.*;
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
import net.minecraft.client.texturepacks.ITexturePack;
|
||||
|
||||
public interface ITextureFX
|
||||
{
|
||||
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions);
|
||||
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions);
|
||||
|
||||
public void onTextureDimensionsUpdate(int width, int height);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.client.renderer.texturefx.TextureFX;
|
||||
|
||||
class OverrideInfo
|
||||
{
|
||||
|
||||
@@ -18,10 +18,8 @@ import java.util.BitSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.ModLoader;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -35,6 +33,9 @@ public class SpriteHelper
|
||||
BitSet slots =
|
||||
SpriteHelper.toBitSet(
|
||||
"0000000000000000" +
|
||||
"0000000000110000" +
|
||||
"0000000000100000" +
|
||||
"0000000001100000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
@@ -42,13 +43,10 @@ public class SpriteHelper
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000011111" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000011111100" +
|
||||
"0000000011111111" +
|
||||
"0000000011111000" +
|
||||
"0000000111111100" +
|
||||
"0000000111111000" +
|
||||
"0000000001111100" +
|
||||
"0000000001111000" +
|
||||
"0000000000000000");
|
||||
spriteInfo.put("/terrain.png", slots);
|
||||
|
||||
@@ -59,15 +57,15 @@ public class SpriteHelper
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000001000000000" +
|
||||
"0000001110000000" +
|
||||
"0000001000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0111110000000000" +
|
||||
"1111111010000000" +
|
||||
"1111111010100000" +
|
||||
"1111111111111100" +
|
||||
"1111111111111111" +
|
||||
"1111111111111111" +
|
||||
"0111111110000000" +
|
||||
"0111111111111001" +
|
||||
"1111111111111111" +
|
||||
"0000011111111111" +
|
||||
"0000000000000000");
|
||||
spriteInfo.put("/gui/items.png", slots);
|
||||
}
|
||||
@@ -132,10 +130,6 @@ public class SpriteHelper
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param textureToOverride
|
||||
* @return
|
||||
*/
|
||||
public static int freeSlotCount(String textureToOverride)
|
||||
{
|
||||
return spriteInfo.get(textureToOverride).cardinality();
|
||||
|
||||
@@ -18,22 +18,20 @@ import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
import net.minecraft.client.renderer.texturefx.TextureFX;
|
||||
import net.minecraft.client.texturepacks.ITexturePack;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
import net.minecraft.src.Profiler;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
public class TextureFXManager
|
||||
@@ -53,12 +51,12 @@ public class TextureFXManager
|
||||
private List<TextureFX> addedTextureFX = new ArrayList<TextureFX>();
|
||||
|
||||
private Minecraft client;
|
||||
|
||||
|
||||
void setClient(Minecraft client)
|
||||
{
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
||||
public boolean onUpdateTextureEffect(TextureFX effect)
|
||||
{
|
||||
ITextureFX ifx = (effect instanceof ITextureFX ? ((ITextureFX)effect) : null);
|
||||
@@ -69,8 +67,7 @@ public class TextureFXManager
|
||||
}
|
||||
|
||||
String name = effect.getClass().getSimpleName();
|
||||
FMLClientHandler.instance().profileStart(name);
|
||||
|
||||
client.field_71424_I.func_76320_a(name);
|
||||
try
|
||||
{
|
||||
if (!FMLClientHandler.instance().hasOptifine())
|
||||
@@ -85,10 +82,10 @@ public class TextureFXManager
|
||||
{
|
||||
ifx.setErrored(true);
|
||||
}
|
||||
FMLClientHandler.instance().profileEnd();
|
||||
client.field_71424_I.func_76319_b();
|
||||
return false;
|
||||
}
|
||||
FMLClientHandler.instance().profileEnd();
|
||||
client.field_71424_I.func_76319_b();
|
||||
|
||||
if (ifx != null)
|
||||
{
|
||||
@@ -162,19 +159,15 @@ public class TextureFXManager
|
||||
}
|
||||
|
||||
int old = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
||||
|
||||
effect.func_76845_a(client.field_71446_o);
|
||||
|
||||
id = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
||||
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, old);
|
||||
|
||||
effectTextures.put(effect, id);
|
||||
|
||||
effect.field_76848_d = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
public void onTexturePackChange(RenderEngine engine, TexturePackBase texturepack, List<TextureFX> effects)
|
||||
public void onTexturePackChange(RenderEngine engine, ITexturePack texturepack, List<TextureFX> effects)
|
||||
{
|
||||
pruneOldTextureFX(texturepack, effects);
|
||||
|
||||
@@ -191,7 +184,7 @@ public class TextureFXManager
|
||||
|
||||
private HashMap<Integer, Dimension> textureDims = new HashMap<Integer, Dimension>();
|
||||
private IdentityHashMap<TextureFX, Integer> effectTextures = new IdentityHashMap<TextureFX, Integer>();
|
||||
private TexturePackBase earlyTexturePack;
|
||||
private ITexturePack earlyTexturePack;
|
||||
public void setTextureDimensions(int id, int width, int height, List<TextureFX> effects)
|
||||
{
|
||||
Dimension dim = new Dimension(width, height);
|
||||
@@ -216,9 +209,6 @@ public class TextureFXManager
|
||||
return textureDims.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param anim
|
||||
*/
|
||||
public void addAnimation(TextureFX anim)
|
||||
{
|
||||
OverrideInfo info=new OverrideInfo();
|
||||
@@ -232,20 +222,13 @@ public class TextureFXManager
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param p_6531_1_
|
||||
*/
|
||||
public void loadTextures(TexturePackBase texturePack)
|
||||
public void loadTextures(ITexturePack texturePack)
|
||||
{
|
||||
registerTextureOverrides(client.field_71446_o);
|
||||
}
|
||||
|
||||
|
||||
public void registerTextureOverrides(RenderEngine renderer) {
|
||||
for (ModContainer mod : Loader.instance().getActiveModList()) {
|
||||
registerAnimatedTexturesFor(mod);
|
||||
}
|
||||
|
||||
for (OverrideInfo animationOverride : animationSet) {
|
||||
renderer.func_78355_a(animationOverride.textureFX);
|
||||
addedTextureFX.add(animationOverride.textureFX);
|
||||
@@ -270,17 +253,11 @@ public class TextureFXManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
*/
|
||||
private void registerAnimatedTexturesFor(ModContainer mod)
|
||||
protected void registerAnimatedTexturesFor(ModContainer mod)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param field_6539_c
|
||||
*/
|
||||
public void onEarlyTexturePackLoad(TexturePackBase fallback)
|
||||
public void onEarlyTexturePackLoad(ITexturePack fallback)
|
||||
{
|
||||
if (client==null) {
|
||||
// We're far too early- let's wait
|
||||
@@ -291,7 +268,7 @@ public class TextureFXManager
|
||||
}
|
||||
|
||||
|
||||
public void pruneOldTextureFX(TexturePackBase var1, List<TextureFX> effects)
|
||||
public void pruneOldTextureFX(ITexturePack var1, List<TextureFX> effects)
|
||||
{
|
||||
ListIterator<TextureFX> li = addedTextureFX.listIterator();
|
||||
while (li.hasNext())
|
||||
@@ -320,11 +297,6 @@ public class TextureFXManager
|
||||
FMLLog.fine("Overriding %s @ %d with %s. %d slots remaining",textureToOverride, location, overridingTexturePath, SpriteHelper.freeSlotCount(textureToOverride));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param renderEngine
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
|
||||
{
|
||||
InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
|
||||
|
||||
@@ -14,13 +14,11 @@
|
||||
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
|
||||
@@ -1,63 +1,178 @@
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.client.*;
|
||||
import net.minecraft.client.entity.EntityClientPlayerMP;
|
||||
import net.minecraft.client.multiplayer.NetClientHandler;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import com.google.common.base.Equivalences;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.MapDifference.ValueDifference;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
|
||||
public class ModLoaderClientHelper implements IModLoaderSidedHelper
|
||||
{
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
* @param inventoryRenderer
|
||||
* @return
|
||||
*/
|
||||
public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
|
||||
{
|
||||
int renderId=RenderingRegistry.instance().getNextAvailableRenderId();
|
||||
int renderId=RenderingRegistry.getNextAvailableRenderId();
|
||||
ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
|
||||
RenderingRegistry.instance().registerBlockHandler(bri);
|
||||
RenderingRegistry.registerBlockHandler(bri);
|
||||
return renderId;
|
||||
}
|
||||
|
||||
|
||||
public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
|
||||
{
|
||||
FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId());
|
||||
BaseMod mod = (BaseMod) mc.getMod();
|
||||
|
||||
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap();
|
||||
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.field_78727_a.field_78729_o);
|
||||
|
||||
mod.addRenderer(renderers);
|
||||
|
||||
for (Entry<Class<? extends Entity>, Render> e : renderers.entrySet())
|
||||
try
|
||||
{
|
||||
RenderingRegistry.instance().registerEntityRenderingHandler(e.getKey(), e.getValue());
|
||||
FMLLog.finest("Requesting renderers from basemod %s", mc.getModId());
|
||||
mod.addRenderer(renderers);
|
||||
FMLLog.finest("Received %d renderers from basemod %s", renderers.size(), mc.getModId());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the addRenderer call. Continuing, but expect odd results", mc.getModId());
|
||||
}
|
||||
|
||||
mod.registerAnimation(game);
|
||||
MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.field_78727_a.field_78729_o, renderers, Equivalences.identity());
|
||||
|
||||
for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
|
||||
{
|
||||
FMLLog.warning("The mod %s attempted to remove an entity renderer %s from the entity map. This will be ignored.", mc.getModId(), e.getKey().getName());
|
||||
}
|
||||
|
||||
for (Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnRight().entrySet())
|
||||
{
|
||||
FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName());
|
||||
RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
for (Entry<Class<? extends Entity>, ValueDifference<Render>> e : difference.entriesDiffering().entrySet())
|
||||
{
|
||||
FMLLog.finest("Registering ModLoader entity rendering override for %s as instance of %s", e.getKey().getName(), e.getValue().rightValue().getClass().getName());
|
||||
RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue().rightValue());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
mod.registerAnimation(game);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the registerAnimation call. Continuing, but expect odd results", mc.getModId());
|
||||
}
|
||||
}
|
||||
|
||||
public ModLoaderClientHelper(Minecraft client)
|
||||
{
|
||||
this.client = client;
|
||||
ModLoaderHelper.sidedHelper = this;
|
||||
keyBindingContainers = Multimaps.newMultimap(Maps.<ModLoaderModContainer, Collection<ModLoaderKeyBindingHandler>>newHashMap(), new Supplier<Collection<ModLoaderKeyBindingHandler>>()
|
||||
{
|
||||
@Override
|
||||
public Collection<ModLoaderKeyBindingHandler> get()
|
||||
{
|
||||
return Collections.singleton(new ModLoaderKeyBindingHandler());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Minecraft client;
|
||||
private static Multimap<ModLoaderModContainer, ModLoaderKeyBindingHandler> keyBindingContainers;
|
||||
|
||||
@Override
|
||||
public void finishModLoading(ModLoaderModContainer mc)
|
||||
{
|
||||
handleFinishLoadingFor(mc, client);
|
||||
}
|
||||
|
||||
|
||||
public static void registerKeyBinding(BaseModProxy mod, KeyBinding keyHandler, boolean allowRepeat)
|
||||
{
|
||||
ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
|
||||
ModLoaderKeyBindingHandler handler = Iterables.getOnlyElement(keyBindingContainers.get(mlmc));
|
||||
handler.setModContainer(mlmc);
|
||||
handler.addKeyBinding(keyHandler, allowRepeat);
|
||||
KeyBindingRegistry.registerKeyBinding(handler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getClientGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
|
||||
{
|
||||
return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er)
|
||||
{
|
||||
return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.field_71441_e, input.scaledX, input.scaledY, input.scaledZ);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)mod).clientCustomPayload(client.field_71439_g.field_71174_a, packet);
|
||||
}
|
||||
|
||||
private Map<INetworkManager,NetHandler> managerLookups = new MapMaker().weakKeys().weakValues().makeMap();
|
||||
@Override
|
||||
public void clientConnectionOpened(NetHandler netClientHandler, INetworkManager manager, BaseModProxy mod)
|
||||
{
|
||||
managerLookups.put(manager, netClientHandler);
|
||||
((BaseMod)mod).clientConnect((NetClientHandler)netClientHandler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean clientConnectionClosed(INetworkManager manager, BaseModProxy mod)
|
||||
{
|
||||
if (managerLookups.containsKey(manager))
|
||||
{
|
||||
((BaseMod)mod).clientDisconnect((NetClientHandler) managerLookups.get(manager));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,19 @@
|
||||
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.src.KeyBinding;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import com.google.common.primitives.Booleans;
|
||||
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -33,61 +35,55 @@ import cpw.mods.fml.common.registry.TickRegistry;
|
||||
public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
|
||||
{
|
||||
private ModLoaderModContainer modContainer;
|
||||
private boolean downArmed;
|
||||
private boolean upArmed;
|
||||
private List<KeyBinding> helper;
|
||||
private boolean[] active = new boolean[0];
|
||||
private boolean[] mlRepeats = new boolean[0];
|
||||
private boolean[] armed = new boolean[0];
|
||||
|
||||
/**
|
||||
* @param keyHandler
|
||||
* @param allowRepeat
|
||||
* @param modContainer
|
||||
*/
|
||||
public ModLoaderKeyBindingHandler(KeyBinding keyBinding, boolean allowRepeat, ModLoaderModContainer modContainer)
|
||||
public ModLoaderKeyBindingHandler()
|
||||
{
|
||||
super(keyBinding, allowRepeat);
|
||||
this.modContainer=modContainer;
|
||||
super(new KeyBinding[0], new boolean[0]);
|
||||
}
|
||||
|
||||
public void onRenderEndTick()
|
||||
void setModContainer(ModLoaderModContainer modContainer)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(keyBinding);
|
||||
this.modContainer = modContainer;
|
||||
}
|
||||
|
||||
public void fireKeyEvent(KeyBinding kb)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(kb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyDown(EnumSet<TickType> type, boolean end, boolean repeats)
|
||||
public void keyDown(EnumSet<TickType> type, KeyBinding kb, boolean end, boolean repeats)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
upArmed = false;
|
||||
int idx = helper.indexOf(kb);
|
||||
if (type.contains(TickType.CLIENT))
|
||||
{
|
||||
downArmed = true;
|
||||
armed[idx] = true;
|
||||
}
|
||||
if (type.contains(TickType.RENDER) && downArmed)
|
||||
if (armed[idx] && type.contains(TickType.RENDER) && (!active[idx] || mlRepeats[idx]))
|
||||
{
|
||||
onRenderEndTick();
|
||||
downArmed = false;
|
||||
fireKeyEvent(kb);
|
||||
active[idx] = true;
|
||||
armed[idx] = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyUp(EnumSet<TickType> type, boolean end)
|
||||
public void keyUp(EnumSet<TickType> type, KeyBinding kb, boolean end)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
downArmed = false;
|
||||
if (type.contains(TickType.CLIENT))
|
||||
{
|
||||
upArmed = true;
|
||||
}
|
||||
if (type.contains(TickType.RENDER) && upArmed)
|
||||
{
|
||||
onRenderEndTick();
|
||||
upArmed = false;
|
||||
}
|
||||
int idx = helper.indexOf(kb);
|
||||
active[idx] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,6 +95,18 @@ public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return modContainer.getModId() +" KB "+keyBinding.field_74512_d;
|
||||
return modContainer.getModId() +" KB "+keyBindings[0].field_74512_d;
|
||||
}
|
||||
|
||||
void addKeyBinding(KeyBinding binding, boolean repeats)
|
||||
{
|
||||
this.keyBindings = ObjectArrays.concat(this.keyBindings, binding);
|
||||
this.repeatings = new boolean[this.keyBindings.length];
|
||||
Arrays.fill(this.repeatings, true);
|
||||
this.active = new boolean[this.keyBindings.length];
|
||||
this.armed = new boolean[this.keyBindings.length];
|
||||
this.mlRepeats = Booleans.concat(this.mlRepeats, new boolean[] { repeats });
|
||||
this.keyDown = new boolean[this.keyBindings.length];
|
||||
this.helper = Arrays.asList(this.keyBindings);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,9 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.TileEntity;
|
||||
import net.minecraft.src.TileEntityRenderer;
|
||||
import net.minecraft.src.TileEntitySpecialRenderer;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public class ClientRegistry
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
public interface ISimpleBlockRenderingHandler
|
||||
{
|
||||
|
||||
@@ -2,46 +2,97 @@ package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.src.GameSettings;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.ITickHandler;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public class KeyBindingRegistry
|
||||
{
|
||||
/**
|
||||
* Register a KeyHandler to the game. This handler will be called on certain tick events
|
||||
* if any of its key is inactive or has recently changed state
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public static void registerKeyBinding(KeyHandler handler) {
|
||||
instance().keyHandlers.add(handler);
|
||||
if (!handler.isDummy)
|
||||
{
|
||||
TickRegistry.registerTickHandler(handler, Side.CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extend this class to register a KeyBinding and recieve callback
|
||||
* when the key binding is triggered
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static abstract class KeyHandler implements ITickHandler
|
||||
{
|
||||
protected KeyBinding keyBinding;
|
||||
protected boolean keyDown;
|
||||
protected boolean repeating;
|
||||
protected KeyBinding[] keyBindings;
|
||||
protected boolean[] keyDown;
|
||||
protected boolean[] repeatings;
|
||||
private boolean isDummy;
|
||||
|
||||
public KeyHandler(KeyBinding keyBinding, boolean repeating)
|
||||
/**
|
||||
* Pass an array of keybindings and a repeat flag for each one
|
||||
*
|
||||
* @param keyBindings
|
||||
* @param repeatings
|
||||
*/
|
||||
public KeyHandler(KeyBinding[] keyBindings, boolean[] repeatings)
|
||||
{
|
||||
this.keyBinding = keyBinding;
|
||||
this.repeating = repeating;
|
||||
assert keyBindings.length == repeatings.length : "You need to pass two arrays of identical length";
|
||||
this.keyBindings = keyBindings;
|
||||
this.repeatings = repeatings;
|
||||
this.keyDown = new boolean[keyBindings.length];
|
||||
}
|
||||
|
||||
public KeyBinding getKeyBinding()
|
||||
|
||||
/**
|
||||
* Register the keys into the system. You will do your own keyboard management elsewhere. No events will fire
|
||||
* if you use this method
|
||||
*
|
||||
* @param keyBindings
|
||||
*/
|
||||
public KeyHandler(KeyBinding[] keyBindings)
|
||||
{
|
||||
return this.keyBinding;
|
||||
this.keyBindings = keyBindings;
|
||||
this.isDummy = true;
|
||||
}
|
||||
|
||||
public KeyBinding[] getKeyBindings()
|
||||
{
|
||||
return this.keyBindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not to be overridden - KeyBindings are tickhandlers under the covers
|
||||
*/
|
||||
@Override
|
||||
public final void tickStart(EnumSet<TickType> type, Object... tickData)
|
||||
{
|
||||
keyTick(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not to be overridden - KeyBindings are tickhandlers under the covers
|
||||
*/
|
||||
@Override
|
||||
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
|
||||
{
|
||||
@@ -50,39 +101,81 @@ public class KeyBindingRegistry
|
||||
|
||||
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
|
||||
{
|
||||
int keyCode = keyBinding.field_74512_d;
|
||||
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
|
||||
if (state != keyDown || (state && repeating))
|
||||
for (int i = 0; i < keyBindings.length; i++)
|
||||
{
|
||||
if (state)
|
||||
KeyBinding keyBinding = keyBindings[i];
|
||||
int keyCode = keyBinding.field_74512_d;
|
||||
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
|
||||
if (state != keyDown[i] || (state && repeatings[i]))
|
||||
{
|
||||
keyDown(type, tickEnd, state!=keyDown);
|
||||
if (state)
|
||||
{
|
||||
keyDown(type, keyBinding, tickEnd, state!=keyDown[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUp(type, keyBinding, tickEnd);
|
||||
}
|
||||
if (tickEnd)
|
||||
{
|
||||
keyDown[i] = state;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUp(type, tickEnd);
|
||||
}
|
||||
keyDown = state;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void keyDown(EnumSet<TickType> types, boolean tickEnd, boolean isRepeat);
|
||||
public abstract void keyUp(EnumSet<TickType> types, boolean tickEnd);
|
||||
/**
|
||||
* Called when the key is first in the down position on any tick from the {@link #ticks()}
|
||||
* set. Will be called subsequently with isRepeat set to true
|
||||
*
|
||||
* @see #keyUp(EnumSet, KeyBinding, boolean)
|
||||
*
|
||||
* @param types the type(s) of tick that fired when this key was first down
|
||||
* @param tickEnd was it an end or start tick which fired the key
|
||||
* @param isRepeat is it a repeat key event
|
||||
*/
|
||||
public abstract void keyDown(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd, boolean isRepeat);
|
||||
/**
|
||||
* Fired once when the key changes state from down to up
|
||||
*
|
||||
* @see #keyDown(EnumSet, KeyBinding, boolean, boolean)
|
||||
*
|
||||
* @param types the type(s) of tick that fired when this key was first down
|
||||
* @param tickEnd was it an end or start tick which fired the key
|
||||
*/
|
||||
public abstract void keyUp(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd);
|
||||
|
||||
|
||||
/**
|
||||
* This is the list of ticks for which the key binding should trigger. The only
|
||||
* valid ticks are client side ticks, obviously.
|
||||
*
|
||||
* @see cpw.mods.fml.common.ITickHandler#ticks()
|
||||
*/
|
||||
public abstract EnumSet<TickType> ticks();
|
||||
}
|
||||
|
||||
private static List<KeyHandler> keyHandlers = Lists.newArrayList();
|
||||
private static final KeyBindingRegistry INSTANCE = new KeyBindingRegistry();
|
||||
|
||||
public static void registerKeyBinding(KeyHandler handler) {
|
||||
keyHandlers.add(handler);
|
||||
TickRegistry.registerTickHandler(handler, Side.CLIENT);
|
||||
private Set<KeyHandler> keyHandlers = Sets.newLinkedHashSet();
|
||||
|
||||
@Deprecated
|
||||
public static KeyBindingRegistry instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static void uploadKeyBindingsToGame(GameSettings settings)
|
||||
|
||||
public void uploadKeyBindingsToGame(GameSettings settings)
|
||||
{
|
||||
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
|
||||
for (KeyHandler key : keyHandlers)
|
||||
{
|
||||
harvestedBindings.add(key.keyBinding);
|
||||
for (KeyBinding kb : key.keyBindings)
|
||||
{
|
||||
harvestedBindings.add(kb);
|
||||
}
|
||||
}
|
||||
KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]);
|
||||
KeyBinding[] allKeys = new KeyBinding[settings.field_74324_K.length + modKeyBindings.length];
|
||||
|
||||
@@ -1,44 +1,130 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.entity.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.RenderPlayer;
|
||||
import cpw.mods.fml.client.modloader.ModLoaderBlockRendererHandler;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.client.SpriteHelper;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class RenderingRegistry
|
||||
{
|
||||
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
|
||||
|
||||
private int nextRenderId = 30;
|
||||
private int nextRenderId = 36;
|
||||
|
||||
private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
|
||||
|
||||
private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
|
||||
|
||||
public int addNewArmourRendererPrefix(String armor)
|
||||
/**
|
||||
* Add a new armour prefix to the RenderPlayer
|
||||
*
|
||||
* @param armor
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
public static RenderingRegistry instance()
|
||||
/**
|
||||
* Register an entity rendering handler. This will, after mod initialization, be inserted into the main
|
||||
* render map for entities
|
||||
*
|
||||
* @param entityClass
|
||||
* @param renderer
|
||||
*/
|
||||
public static void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
|
||||
{
|
||||
instance().entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a simple block rendering handler
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public static void registerBlockHandler(ISimpleBlockRenderingHandler handler)
|
||||
{
|
||||
instance().blockRenderers.put(handler.getRenderId(), handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the simple block rendering handler
|
||||
* This version will not call getRenderId on the passed in handler, instead using the supplied ID, so you
|
||||
* can easily re-use the same rendering handler for multiple IDs
|
||||
*
|
||||
* @param renderId
|
||||
* @param handler
|
||||
*/
|
||||
public static void registerBlockHandler(int renderId, ISimpleBlockRenderingHandler handler)
|
||||
{
|
||||
instance().blockRenderers.put(renderId, handler);
|
||||
}
|
||||
/**
|
||||
* Get the next available renderId from the block render ID list
|
||||
*/
|
||||
public static int getNextAvailableRenderId()
|
||||
{
|
||||
return instance().nextRenderId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a texture override for the given path and return the used index
|
||||
*
|
||||
* @param fileToOverride
|
||||
* @param fileToAdd
|
||||
*/
|
||||
public static int addTextureOverride(String fileToOverride, String fileToAdd)
|
||||
{
|
||||
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
|
||||
addTextureOverride(fileToOverride, fileToAdd, idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a texture override for the given path and index
|
||||
*
|
||||
* @param path
|
||||
* @param overlayPath
|
||||
* @param index
|
||||
*/
|
||||
public static void addTextureOverride(String path, String overlayPath, int index)
|
||||
{
|
||||
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and reserve a unique texture index for the supplied path
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public static int getUniqueTextureIndex(String path)
|
||||
{
|
||||
return SpriteHelper.getUniqueSpriteIndex(path);
|
||||
}
|
||||
|
||||
@Deprecated public static RenderingRegistry instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private class EntityRendererInfo
|
||||
private static class EntityRendererInfo
|
||||
{
|
||||
public EntityRendererInfo(Class<? extends Entity> target, Render renderer)
|
||||
{
|
||||
@@ -49,30 +135,6 @@ public class RenderingRegistry
|
||||
private Render renderer;
|
||||
}
|
||||
|
||||
public void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
|
||||
{
|
||||
entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
|
||||
}
|
||||
|
||||
public void registerBlockHandler(ISimpleBlockRenderingHandler handler)
|
||||
{
|
||||
blockRenderers.put(handler.getRenderId(), handler);
|
||||
}
|
||||
|
||||
public int getNextAvailableRenderId()
|
||||
{
|
||||
return nextRenderId++;
|
||||
}
|
||||
/**
|
||||
* @param renderer
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param block
|
||||
* @param modelId
|
||||
* @return
|
||||
*/
|
||||
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
|
||||
{
|
||||
if (!blockRenderers.containsKey(modelId)) { return false; }
|
||||
@@ -80,12 +142,6 @@ public class RenderingRegistry
|
||||
return bri.renderWorldBlock(world, x, y, z, block, modelId, renderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param renderer
|
||||
* @param block
|
||||
* @param metadata
|
||||
* @param modelID
|
||||
*/
|
||||
public void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
if (!blockRenderers.containsKey(modelID)) { return; }
|
||||
@@ -93,10 +149,6 @@ public class RenderingRegistry
|
||||
bri.renderInventoryBlock(block, metadata, modelID, renderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p_1219_0_
|
||||
* @return
|
||||
*/
|
||||
public boolean renderItemAsFull3DBlock(int modelId)
|
||||
{
|
||||
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
|
||||
@@ -108,6 +160,7 @@ public class RenderingRegistry
|
||||
for (EntityRendererInfo info : entityRenderers)
|
||||
{
|
||||
rendererMap.put(info.target, info.renderer);
|
||||
info.renderer.func_76976_a(RenderManager.field_78727_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
@@ -12,19 +12,35 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static cpw.mods.fml.relauncher.Side.CLIENT;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.*;
|
||||
import net.minecraft.client.entity.EntityClientPlayerMP;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.multiplayer.NetClientHandler;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.NetServerHandler;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.IConsoleHandler;
|
||||
import cpw.mods.fml.common.ICraftingHandler;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.INetworkHandler;
|
||||
import cpw.mods.fml.common.IPickupNotifier;
|
||||
import cpw.mods.fml.common.IPlayerTracker;
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModProxy
|
||||
{
|
||||
@@ -33,7 +49,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object... data)
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
boolean hasWorld = true;
|
||||
boolean hasWorld = mc.field_71441_e != null;
|
||||
// World and render ticks
|
||||
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT ) && hasWorld) {
|
||||
return onTickInGame((Float) data[0], mc);
|
||||
@@ -44,29 +60,21 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
public final boolean doTickInGUI(TickType tick, boolean tickEnd, Object... data)
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT)) {
|
||||
|
||||
boolean hasWorld = mc.field_71441_e != null;
|
||||
|
||||
if (tickEnd && ( tick==TickType.RENDER || ( tick==TickType.CLIENT && hasWorld))) {
|
||||
return onTickInGUI((Float) data[0], mc, mc.field_71462_r);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param minecraftInstance
|
||||
* @return
|
||||
*//*
|
||||
|
||||
*//**
|
||||
* @param renderers
|
||||
*//*
|
||||
/*
|
||||
public final void onRenderHarvest(Map renderers)
|
||||
{
|
||||
addRenderer((Map<Class<? extends Entity>,Render>)renderers);
|
||||
|
||||
}
|
||||
|
||||
*//**
|
||||
*
|
||||
*//*
|
||||
public final void onRegisterAnimations()
|
||||
{
|
||||
registerAnimation(FMLClientHandler.instance().getClient());
|
||||
@@ -155,48 +163,28 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
}
|
||||
}
|
||||
|
||||
*//**
|
||||
* NO-OP on client side
|
||||
*//*
|
||||
@Override
|
||||
public final boolean handleCommand(String command, Object... data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*/ // BASEMOD API
|
||||
*/
|
||||
// BASEMOD API
|
||||
/**
|
||||
* Override if you wish to provide a fuel item for the furnace and return the fuel value of the item
|
||||
*
|
||||
* @param id
|
||||
* @param metadata
|
||||
* @return
|
||||
*/
|
||||
public int addFuel(int id, int metadata)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void addRenderer(Map<Class<? extends Entity>, Render> renderers)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Override if you wish to perform some action other than just dispensing the item from the dispenser
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVel
|
||||
* @param zVel
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,10 +211,22 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to return a gui screen to display
|
||||
* @param player
|
||||
* @param containerID
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public GuiContainer getContainerGUI(EntityClientPlayerMP player, int containerID, int x, int y, int z)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of your mod. Defaults to the class name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
@@ -235,8 +235,6 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
/**
|
||||
* Get your mod priorities
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPriorities()
|
||||
{
|
||||
@@ -245,11 +243,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
/**
|
||||
* Return the version of your mod
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void keyboardEvent(KeyBinding event)
|
||||
{
|
||||
|
||||
@@ -284,11 +281,18 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
* @param minecraftInstance the client
|
||||
* @return true to continue receiving ticks
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public boolean onTickInGame(float time, Minecraft minecraftInstance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onTickInGame(MinecraftServer minecraftServer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public boolean onTickInGUI(float tick, Minecraft game, GuiScreen gui)
|
||||
{
|
||||
return false;
|
||||
@@ -296,38 +300,57 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
/**
|
||||
* Only implemented on the client side
|
||||
* {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)}
|
||||
* {@link #serverChat(NetServerHandler, String)}
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
@Override
|
||||
public void receiveChatPacket(String text)
|
||||
public void clientChat(String text)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called on the client side
|
||||
* {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)}
|
||||
* Called when a client connects
|
||||
* @param handler
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public void clientConnect(NetClientHandler handler)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the client disconnects
|
||||
* @param handler
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public void clientDisconnect(NetClientHandler handler)
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* Called client side to receive a custom payload for this mod
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
@Override
|
||||
public void receiveCustomPacket(Packet250CustomPayload packet)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void registerAnimation(Minecraft game)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
|
||||
{
|
||||
return false;
|
||||
@@ -339,6 +362,12 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverCustomPayload(NetServerHandler handler, Packet250CustomPayload packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverDisconnect() {
|
||||
|
||||
@@ -374,37 +403,12 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a 250 packet is received on a channel registered to this mod
|
||||
*
|
||||
* @param source
|
||||
* @param payload
|
||||
* Called when a chat message is received. Return true to stop further processing
|
||||
*/
|
||||
@Override
|
||||
public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload)
|
||||
public void serverChat(NetServerHandler source, String message)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a chat message is received. Return true to stop further processing
|
||||
*
|
||||
* @param source
|
||||
* @param chat
|
||||
* @return true if you want to consume the message so it is not available for further processing
|
||||
*/
|
||||
public boolean onChatMessageReceived(EntityPlayer source, Packet3Chat chat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Called when a server command is received
|
||||
* @param command
|
||||
* @return true if you want to consume the message so it is not available for further processing
|
||||
*/
|
||||
public boolean onServerCommand(String command, String sender, Object listener)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new client logs in.
|
||||
*
|
||||
@@ -417,22 +421,23 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
|
||||
|
||||
/**
|
||||
* Called when a client logs out of the server.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
@Override
|
||||
public void onClientLogout(NetworkManager mgr)
|
||||
public void onClientLogout(INetworkManager mgr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Called when a client changes dimensions on the server.
|
||||
*
|
||||
* @param player
|
||||
* Spawn the entity of the supplied type, if it is your mod's
|
||||
*/
|
||||
public void onClientDimensionChanged(EntityPlayer player)
|
||||
@SideOnly(CLIENT)
|
||||
public Entity spawnEntity(int entityId, World world, double scaledX, double scaledY, double scaledZ)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clientCustomPayload(NetClientHandler handler, Packet250CustomPayload packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
|
||||
public class EntityRendererProxy extends EntityRenderer
|
||||
{
|
||||
|
||||
@@ -19,10 +19,15 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.renderer.RenderBlocks;
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
import net.minecraft.client.renderer.texturefx.TextureFX;
|
||||
import net.minecraft.client.texturepacks.ITexturePack;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
/**
|
||||
@@ -69,21 +74,24 @@ public class FMLRenderAccessLibrary
|
||||
return TextureFXManager.instance().getTextureDimensions(textureFX);
|
||||
}
|
||||
|
||||
public static void onTexturePackChange(RenderEngine engine, TexturePackBase texturePack, List<TextureFX> textureFXList)
|
||||
public static void onTexturePackChange(RenderEngine engine, ITexturePack texturePack, List<TextureFX> textureFXList)
|
||||
{
|
||||
TextureFXManager.instance().onTexturePackChange(engine, texturePack, textureFXList);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
|
||||
{
|
||||
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean renderItemAsFull3DBlock(int modelId)
|
||||
{
|
||||
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelId);
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import static java.lang.annotation.RetentionPolicy.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
|
||||
@@ -12,17 +12,49 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static cpw.mods.fml.relauncher.Side.CLIENT;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockDispenser;
|
||||
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.texturefx.TextureFX;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.dispenser.IBehaviorDispenseItem;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.NetServerHandler;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet1Login;
|
||||
import net.minecraft.network.packet.Packet250CustomPayload;
|
||||
import net.minecraft.server.*;
|
||||
import net.minecraft.stats.Achievement;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldType;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.SpriteHelper;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
@@ -34,14 +66,17 @@ import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.network.PacketDispatcher;
|
||||
import cpw.mods.fml.common.network.Player;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.registry.LanguageRegistry;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import cpw.mods.fml.server.FMLServerHandler;
|
||||
|
||||
public class ModLoader
|
||||
{
|
||||
@@ -49,12 +84,13 @@ public class ModLoader
|
||||
// TODO dirty workaround for millinaire
|
||||
@Deprecated
|
||||
public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap();
|
||||
|
||||
/**
|
||||
* Not used on the server.
|
||||
* Adds localization info for an achievement, Not used on the server.
|
||||
*
|
||||
* @param achievement
|
||||
* @param name
|
||||
* @param description
|
||||
* @param achievement The achievement to name
|
||||
* @param name The name
|
||||
* @param description The description
|
||||
*/
|
||||
public static void addAchievementDesc(Achievement achievement, String name, String description)
|
||||
{
|
||||
@@ -66,11 +102,11 @@ public class ModLoader
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
*
|
||||
* {@link FMLCommonHandler#fuelLookup(int, int)}
|
||||
* {@link GameRegistry#getFuelValue(ItemStack)}
|
||||
*
|
||||
* @param id
|
||||
* @param metadata
|
||||
* @return
|
||||
* @param id The Item ID
|
||||
* @param metadata The Item Metadata
|
||||
* @return The fuel strength, in ticks, 0 if unhandled
|
||||
*/
|
||||
@Deprecated
|
||||
public static int addAllFuel(int id, int metadata)
|
||||
@@ -79,41 +115,66 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers)
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void addAnimation(TextureFX anim)
|
||||
{
|
||||
TextureFXManager.instance().addAnimation(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is unimplemented in server versions to date.
|
||||
* Adds a new prefix to the armor texture list
|
||||
*
|
||||
* @param armor
|
||||
* @return
|
||||
* {@link RenderingRegistry#addNewArmourRendererPrefix(String)}
|
||||
*
|
||||
* @param armor The new armor prefix
|
||||
* @return The new armor index
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int addArmor(String armor)
|
||||
{
|
||||
return RenderingRegistry.instance().addNewArmourRendererPrefix(armor);
|
||||
return RenderingRegistry.addNewArmourRendererPrefix(armor);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds the supplied biome to the set of candidate biomes for the default world generator type.
|
||||
*
|
||||
* @param biome
|
||||
* @param biome The biome to add
|
||||
*/
|
||||
public static void addBiome(BiomeGenBase biome)
|
||||
{
|
||||
GameRegistry.addBiome(biome);
|
||||
}
|
||||
|
||||
public static void addEntityTracker(BaseMod mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval, boolean sendVelocityInfo)
|
||||
{
|
||||
ModLoaderHelper.buildEntityTracker(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
|
||||
}
|
||||
|
||||
public static void addCommand(ICommand command)
|
||||
{
|
||||
ModLoaderHelper.addCommand(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a behaviour to the dispenser
|
||||
*
|
||||
* @param item
|
||||
* @param behavior
|
||||
*/
|
||||
public static void addDispenserBehavior(Item item, IBehaviorDispenseItem behavior)
|
||||
{
|
||||
BlockDispenser.field_82527_a.func_82595_a(item, behavior);
|
||||
}
|
||||
/**
|
||||
* Add localization for the specified string
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param key Key
|
||||
* @param value Value
|
||||
*/
|
||||
public static void addLocalization(String key, String value)
|
||||
{
|
||||
@@ -123,9 +184,9 @@ public class ModLoader
|
||||
/**
|
||||
* Add localization for the specified string
|
||||
*
|
||||
* @param key
|
||||
* @param lang
|
||||
* @param value
|
||||
* @param key Key
|
||||
* @param lang Language identifier
|
||||
* @param value Value
|
||||
*/
|
||||
public static void addLocalization(String key, String lang, String value)
|
||||
{
|
||||
@@ -135,8 +196,8 @@ public class ModLoader
|
||||
/**
|
||||
* Name the specified minecraft object with the supplied name
|
||||
*
|
||||
* @param instance
|
||||
* @param name
|
||||
* @param instance Item to name
|
||||
* @param name The name to give it
|
||||
*/
|
||||
public static void addName(Object instance, String name)
|
||||
{
|
||||
@@ -146,9 +207,9 @@ public class ModLoader
|
||||
/**
|
||||
* Unimplemented on the server as it does not generate names
|
||||
*
|
||||
* @param instance
|
||||
* @param lang
|
||||
* @param name
|
||||
* @param instance Item to name
|
||||
* @param lang Languge identifier
|
||||
* @param name Name to give it
|
||||
*/
|
||||
public static void addName(Object instance, String lang, String name)
|
||||
{
|
||||
@@ -156,36 +217,48 @@ public class ModLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to register a small image to be applied to a larger texture image,
|
||||
* typically how old ModLoader mods add custom Item/Block textures.
|
||||
*
|
||||
* Forge mods should use setTextureFile in Item/Block
|
||||
*
|
||||
* Will return the icon index it was applied to.
|
||||
*
|
||||
* Unimplemented on the server as it does not render textures
|
||||
*
|
||||
* @param fileToOverride
|
||||
* @param fileToAdd
|
||||
* @return
|
||||
* @param fileToOverride The texture to apply the new image to
|
||||
* @param fileToAdd The new image
|
||||
* @return The 'icon index' in the main image that the new image will be applied to
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int addOverride(String fileToOverride, String fileToAdd)
|
||||
{
|
||||
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
|
||||
addOverride(fileToOverride, fileToAdd, idx);
|
||||
return idx;
|
||||
return RenderingRegistry.addTextureOverride(fileToOverride, fileToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to register a small image to be applied to a larger texture image,
|
||||
* typically how old ModLoader mods add custom Item/Block textures.
|
||||
*
|
||||
* Forge mods should use setTextureFile in Item/Block
|
||||
*
|
||||
* Unimplemented on the server as it does not render textures
|
||||
*
|
||||
* @param path
|
||||
* @param overlayPath
|
||||
* @param index
|
||||
* @param path The texture to apply the new image to
|
||||
* @param overlayPath The new image
|
||||
* @param index Where on the texture to apply it
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static void addOverride(String path, String overlayPath, int index)
|
||||
{
|
||||
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
|
||||
RenderingRegistry.addTextureOverride(path, overlayPath, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Shaped Recipe
|
||||
*
|
||||
* @param output
|
||||
* @param params
|
||||
* @param output The result
|
||||
* @param params The input
|
||||
*/
|
||||
public static void addRecipe(ItemStack output, Object... params)
|
||||
{
|
||||
@@ -195,8 +268,8 @@ public class ModLoader
|
||||
/**
|
||||
* Add a shapeless recipe
|
||||
*
|
||||
* @param output
|
||||
* @param params
|
||||
* @param output The result
|
||||
* @param params The input
|
||||
*/
|
||||
public static void addShapelessRecipe(ItemStack output, Object... params)
|
||||
{
|
||||
@@ -214,6 +287,16 @@ public class ModLoader
|
||||
GameRegistry.addSmelting(input, output, 1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new product to be smelted
|
||||
*
|
||||
* @param input
|
||||
* @param output
|
||||
*/
|
||||
public static void addSmelting(int input, ItemStack output, float experience)
|
||||
{
|
||||
GameRegistry.addSmelting(input, output, experience);
|
||||
}
|
||||
/**
|
||||
* Add a mob to the spawn list
|
||||
*
|
||||
@@ -272,9 +355,21 @@ public class ModLoader
|
||||
EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
|
||||
}
|
||||
|
||||
public static void addTrade(int profession, TradeEntry entry)
|
||||
{
|
||||
ModLoaderHelper.registerTrade(profession, entry);
|
||||
}
|
||||
/**
|
||||
* Send a packet from the client
|
||||
* @param packet
|
||||
*/
|
||||
public static void clientSendPacket(Packet packet)
|
||||
{
|
||||
PacketDispatcher.sendPacketToServer(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#tryDispensingEntity(World, double, double, double, byte, byte, ItemStack)}
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
@@ -283,7 +378,7 @@ public class ModLoader
|
||||
* @param xVel
|
||||
* @param zVel
|
||||
* @param item
|
||||
* @return
|
||||
* @return Always false, not implemented here
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
|
||||
@@ -353,7 +448,7 @@ public class ModLoader
|
||||
* Get a list of all BaseMod loaded into the system
|
||||
* {@link ModLoaderModContainer#findAll}
|
||||
*
|
||||
* @return
|
||||
* @return A list containing all loaded ModLoader mods
|
||||
*/
|
||||
public static List<BaseMod> getLoadedMods()
|
||||
{
|
||||
@@ -363,24 +458,19 @@ public class ModLoader
|
||||
/**
|
||||
* Get a logger instance {@link FMLCommonHandler#getFMLLogger()}
|
||||
*
|
||||
* @return
|
||||
* @return The current logger
|
||||
*/
|
||||
public static Logger getLogger()
|
||||
{
|
||||
return FMLLog.getLogger();
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static Minecraft getMinecraftInstance()
|
||||
{
|
||||
return FMLClientHandler.instance().getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not the server
|
||||
* {@link FMLClientHandler#getServer()}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static MinecraftServer getMinecraftServerInstance()
|
||||
{
|
||||
return FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
@@ -393,7 +483,7 @@ public class ModLoader
|
||||
* @param instanceclass
|
||||
* @param instance
|
||||
* @param fieldindex
|
||||
* @return
|
||||
* @return The value in the specified field.
|
||||
*/
|
||||
public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, int fieldindex)
|
||||
{
|
||||
@@ -402,12 +492,12 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* Get a value from a field using reflection
|
||||
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, String)}
|
||||
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, String[])}
|
||||
*
|
||||
* @param instanceclass
|
||||
* @param instance
|
||||
* @param field
|
||||
* @return
|
||||
* @return The value in the specified field.
|
||||
*/
|
||||
public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, String field)
|
||||
{
|
||||
@@ -418,6 +508,7 @@ public class ModLoader
|
||||
* Stubbed method on the server to return a unique model id
|
||||
*
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
|
||||
{
|
||||
return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
|
||||
@@ -425,15 +516,16 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* Get a new unique entity id
|
||||
* {@link Entity#getNextId()}
|
||||
* {@link EntityRegistry#findGlobalUniqueEntityId()}
|
||||
*
|
||||
* @return
|
||||
* @return A unique entity ID
|
||||
*/
|
||||
public static int getUniqueEntityId()
|
||||
{
|
||||
return EntityRegistry.findGlobalUniqueEntityId();
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static int getUniqueSpriteIndex(String path)
|
||||
{
|
||||
return SpriteHelper.getUniqueSpriteIndex(path);
|
||||
@@ -445,13 +537,14 @@ public class ModLoader
|
||||
*
|
||||
* @param player
|
||||
* @param channel
|
||||
* @return
|
||||
* @return If the channel is registered to the current connection.
|
||||
*/
|
||||
public static boolean isChannelActive(EntityPlayer player, String channel)
|
||||
{
|
||||
return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean isGUIOpen(Class<? extends GuiScreen> gui)
|
||||
{
|
||||
return FMLClientHandler.instance().getClient().field_71462_r != null && FMLClientHandler.instance().getClient().field_71462_r.equals(gui);
|
||||
@@ -462,7 +555,7 @@ public class ModLoader
|
||||
* {@link Loader#isModLoaded(String)}
|
||||
*
|
||||
* @param modname
|
||||
* @return
|
||||
* @return If the specified mod is loaded
|
||||
*/
|
||||
public static boolean isModLoaded(String modname)
|
||||
{
|
||||
@@ -477,6 +570,7 @@ public class ModLoader
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
|
||||
{
|
||||
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
|
||||
@@ -495,10 +589,12 @@ public class ModLoader
|
||||
* Call in from elsewhere. Unimplemented here.
|
||||
*/
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void onTick(float tick, Minecraft game)
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void openGUI(EntityPlayer player, GuiScreen gui)
|
||||
{
|
||||
FMLClientHandler.instance().displayGuiScreen(player, gui);
|
||||
@@ -511,7 +607,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLServerHandler#handlePacket250(Packet250CustomPayload, EntityPlayer)}
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
@@ -521,12 +616,14 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
|
||||
{
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerAllTextureOverrides(RenderEngine cache)
|
||||
{
|
||||
}
|
||||
@@ -552,6 +649,10 @@ public class ModLoader
|
||||
GameRegistry.registerBlock(block, itemclass);
|
||||
}
|
||||
|
||||
public static void registerContainerID(BaseMod mod, int id)
|
||||
{
|
||||
ModLoaderHelper.buildGuiHelper(mod, id);
|
||||
}
|
||||
/**
|
||||
* Register a new entity ID
|
||||
*
|
||||
@@ -578,15 +679,15 @@ public class ModLoader
|
||||
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
|
||||
{
|
||||
ModLoaderModContainer mlmc=ModLoaderHelper.registerKeyHelper(mod);
|
||||
KeyBindingRegistry.registerKeyBinding(new ModLoaderKeyBindingHandler(keyHandler, allowRepeat, mlmc));
|
||||
ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the mod for packets on this channel.
|
||||
* {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)}
|
||||
* {@link NetworkRegistry#registerChannel(IPacketHandler, String)}
|
||||
*
|
||||
* @param mod
|
||||
* @param channel
|
||||
@@ -607,6 +708,7 @@ public class ModLoader
|
||||
GameRegistry.registerTileEntity(tileEntityClass, id);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
|
||||
{
|
||||
ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
|
||||
@@ -669,18 +771,21 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean renderBlockIsItemFull3D(int modelID)
|
||||
{
|
||||
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
|
||||
{
|
||||
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
|
||||
@@ -695,13 +800,16 @@ public class ModLoader
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet from client to server
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
public static void sendPacket(Packet packet) {
|
||||
// TODO
|
||||
// FMLClientHandler.instance().sendPacket(packet);
|
||||
PacketDispatcher.sendPacketToServer(packet);
|
||||
}
|
||||
/**
|
||||
* Send a chat message to the server
|
||||
* {@link FMLClientHandler#handleChatPacket(Packet3Chat, EntityPlayer)}
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
@@ -712,11 +820,24 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
public static void serverSendPacket(NetServerHandler handler, Packet packet)
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
PacketDispatcher.sendPacketToPlayer(packet, (Player)handler.getPlayer());
|
||||
}
|
||||
}
|
||||
public static void serverOpenWindow(EntityPlayerMP player, Container container, int ID, int x, int y, int z)
|
||||
{
|
||||
ModLoaderHelper.openGui(ID, player, container, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate that you want to receive ticks
|
||||
*
|
||||
@@ -765,7 +886,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#onItemCrafted(EntityPlayer, ItemStack, IInventory)}
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
@@ -778,7 +898,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#onItemSmelted(EntityPlayer, ItemStack)}
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
@@ -790,7 +909,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* Throw the offered exception. Likely will stop the game.
|
||||
* {@link FMLClientHandler#raiseException(Throwable, String, boolean)}
|
||||
*
|
||||
* @param message
|
||||
* @param e
|
||||
|
||||
@@ -18,15 +18,15 @@ import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
/**
|
||||
* A texture override for animations, it takes a vertical image of
|
||||
* A texture override for animations, it takes a vertical image of
|
||||
* texture frames and constantly rotates them in the texture.
|
||||
*/
|
||||
public class ModTextureAnimation extends FMLTextureFX
|
||||
@@ -35,45 +35,45 @@ public class ModTextureAnimation extends FMLTextureFX
|
||||
private byte[][] images;
|
||||
private int index = 0;
|
||||
private int ticks = 0;
|
||||
|
||||
|
||||
private String targetTex = null;
|
||||
private BufferedImage imgData = null;
|
||||
|
||||
|
||||
public ModTextureAnimation(int icon, int target, BufferedImage image, int tickCount)
|
||||
{
|
||||
this(icon, 1, target, image, tickCount);
|
||||
}
|
||||
|
||||
public ModTextureAnimation(int icon, int size, int target, BufferedImage image, int tickCount)
|
||||
public ModTextureAnimation(int icon, int size, int target, BufferedImage image, int tickCount)
|
||||
{
|
||||
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image, tickCount);
|
||||
}
|
||||
|
||||
|
||||
public ModTextureAnimation(int icon, int size, String target, BufferedImage image, int tickCount)
|
||||
{
|
||||
super(icon);
|
||||
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
|
||||
|
||||
|
||||
targetTex = target;
|
||||
field_76849_e = size;
|
||||
field_76847_f = re.func_78341_b(target);
|
||||
|
||||
|
||||
tickRate = tickCount;
|
||||
ticks = tickCount;
|
||||
imgData = image;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
super.setup();
|
||||
|
||||
|
||||
int sWidth = imgData.getWidth();
|
||||
int sHeight = imgData.getHeight();
|
||||
int tWidth = tileSizeBase;
|
||||
int tHeight = tileSizeBase;
|
||||
|
||||
|
||||
|
||||
|
||||
int frames = (int)Math.floor((double)(sHeight / sWidth));
|
||||
|
||||
if (frames < 1)
|
||||
@@ -84,7 +84,7 @@ public class ModTextureAnimation extends FMLTextureFX
|
||||
{
|
||||
images = new byte[frames][];
|
||||
BufferedImage image = imgData;
|
||||
|
||||
|
||||
if (sWidth != tWidth)
|
||||
{
|
||||
BufferedImage b = new BufferedImage(tWidth, tHeight * frames, 6);
|
||||
@@ -111,8 +111,8 @@ public class ModTextureAnimation extends FMLTextureFX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void func_783_a()
|
||||
|
||||
public void func_76846_a()
|
||||
{
|
||||
if (++ticks >= tickRate)
|
||||
{
|
||||
@@ -125,4 +125,17 @@ public class ModTextureAnimation extends FMLTextureFX
|
||||
ticks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void func_76845_a(RenderEngine renderEngine)
|
||||
{
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, field_76847_f);
|
||||
}
|
||||
|
||||
// TODO: REMOVE THIS - just for you dan200
|
||||
@Deprecated
|
||||
public void func_783_a()
|
||||
{
|
||||
func_76846_a();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,16 +14,18 @@
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
|
||||
import net.minecraft.client.renderer.RenderEngine;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class ModTextureStatic extends FMLTextureFX
|
||||
{
|
||||
@@ -32,31 +34,31 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
private String targetTex = null;
|
||||
private int storedSize;
|
||||
private BufferedImage overrideData = null;
|
||||
private int needApply = 2;
|
||||
|
||||
|
||||
private int needApply = 10;
|
||||
|
||||
|
||||
public ModTextureStatic(int icon, int target, BufferedImage image)
|
||||
{
|
||||
this(icon, 1, target, image);
|
||||
}
|
||||
|
||||
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
|
||||
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
|
||||
{
|
||||
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image);
|
||||
}
|
||||
|
||||
|
||||
public ModTextureStatic(int icon, int size, String target, BufferedImage image)
|
||||
{
|
||||
super(icon);
|
||||
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
|
||||
|
||||
|
||||
targetTex = target;
|
||||
storedSize = size;
|
||||
field_76849_e = size;
|
||||
field_76847_f = re.func_78341_b(target);
|
||||
overrideData = image;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
@@ -80,16 +82,17 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
public void func_783_a()
|
||||
|
||||
@Override
|
||||
public void func_76846_a()
|
||||
{
|
||||
if (oldanaglyph != field_76851_c)
|
||||
{
|
||||
update();
|
||||
}
|
||||
// This makes it so we only apply the texture to the target texture when we need to,
|
||||
//due to the fact that update is called when the Effect is first registered, we actually
|
||||
//need to wait for the next one.
|
||||
// This makes it so we only apply the texture to the target texture when we need to,
|
||||
//due to the fact that update is called when the Effect is first registered, we actually
|
||||
//need to wait for the next one.
|
||||
field_76849_e = (needApply == 0 ? 0 : storedSize);
|
||||
if (needApply > 0)
|
||||
{
|
||||
@@ -97,14 +100,15 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
}
|
||||
}
|
||||
|
||||
public void func_782_a(RenderEngine p_782_1_)
|
||||
@Override
|
||||
public void func_76845_a(RenderEngine p_76845_1_)
|
||||
{
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, p_782_1_.func_78341_b(targetTex));
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, p_76845_1_.func_78341_b(targetTex));
|
||||
}
|
||||
|
||||
|
||||
public void update()
|
||||
{
|
||||
needApply = 2;
|
||||
needApply = 10;
|
||||
for (int idx = 0; idx < pixels.length; idx++)
|
||||
{
|
||||
int i = idx * 4;
|
||||
@@ -126,7 +130,7 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
|
||||
oldanaglyph = field_76851_c;
|
||||
}
|
||||
|
||||
|
||||
//Implementation of http://scale2x.sourceforge.net/algorithm.html
|
||||
public static BufferedImage scale2x(BufferedImage image)
|
||||
{
|
||||
@@ -170,9 +174,9 @@ public class ModTextureStatic extends FMLTextureFX
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ModTextureStatic %s @ %d", targetTex, field_76850_b);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
/**
|
||||
* Compatibility class for ModLoader -- do not use
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class TradeEntry
|
||||
{
|
||||
public final int id;
|
||||
public float chance;
|
||||
public boolean buying;
|
||||
public int min = 0;
|
||||
public int max = 0;
|
||||
|
||||
public TradeEntry(int id, float chance, boolean buying, int min, int max)
|
||||
{
|
||||
this.id = id;
|
||||
this.chance = chance;
|
||||
this.buying = buying;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public TradeEntry(int id, float chance, boolean buying)
|
||||
{
|
||||
this(id, chance, buying, 0, 0);
|
||||
}
|
||||
}
|
||||
+91
-87
@@ -9,53 +9,45 @@
|
||||
if not sys.platform.startswith('win'):
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
@@ -582,6 +584,9 @@
|
||||
self.has_astyle_cfg = False
|
||||
if os.path.isfile(self.astyleconf):
|
||||
self.has_astyle_cfg = True
|
||||
+
|
||||
+ #FML Entries
|
||||
+ self.srcshared = os.path.normpath(os.path.join(self.dirsrc, 'common'))
|
||||
|
||||
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
|
||||
"""Create the files necessary for RetroGuard"""
|
||||
@@ -779,7 +784,8 @@
|
||||
@@ -788,6 +790,8 @@
|
||||
binlk = {CLIENT: self.binclient, SERVER: self.binserver}
|
||||
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
|
||||
|
||||
if not os.path.exists(os.path.join(srclk[side], os.path.normpath(testlk[side] + '.java'))):
|
||||
- return False
|
||||
+ if not os.path.exists(os.path.join(self.srcshared, os.path.normpath(testlk[side] + '.java'))):
|
||||
+ return False
|
||||
+ if side == SERVER:
|
||||
+ return self.checkbins(CLIENT)
|
||||
if not os.path.exists(os.path.join(binlk[side], os.path.normpath(testlk[side] + '.class'))):
|
||||
return False
|
||||
return True
|
||||
@@ -1029,6 +1033,10 @@
|
||||
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
pathlog = {CLIENT: self.clientrecomplog, SERVER: self.serverrecomplog}
|
||||
|
||||
def checkbins(self, side):
|
||||
@@ -1039,6 +1045,7 @@
|
||||
all_files = True
|
||||
append_pattern = False
|
||||
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
|
||||
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=append_pattern, all_files=all_files) #FML, Add Common folder
|
||||
dirs = ' '.join(pkglist)
|
||||
classpath = os.pathsep.join(cplk[side])
|
||||
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
|
||||
@@ -1060,7 +1067,7 @@
|
||||
+ if side == SERVER: #Disable server because FML recombines it into client
|
||||
+ self.logger.info('Server side recompiling skipped, this is normal')
|
||||
+ return
|
||||
+
|
||||
if not os.path.exists(pathbinlk[side]):
|
||||
os.makedirs(pathbinlk[side])
|
||||
|
||||
@@ -1062,7 +1070,7 @@
|
||||
raise
|
||||
|
||||
def startserver(self):
|
||||
- classpath = [self.binserver] + self.cpathserver
|
||||
+ classpath = [self.binserver, self.srcshared] + self.cpathserver
|
||||
+ classpath = [self.binclient, self.srcclient] + self.cpathserver
|
||||
classpath = [os.path.join('..', p) for p in classpath]
|
||||
classpath = os.pathsep.join(classpath)
|
||||
os.chdir(self.dirjars)
|
||||
@@ -1068,7 +1075,7 @@
|
||||
@@ -1070,7 +1078,7 @@
|
||||
self.runmc(forkcmd)
|
||||
|
||||
def startclient(self):
|
||||
- classpath = [self.binclient] + self.cpathclient
|
||||
+ classpath = [self.binclient, self.srcshared] + self.cpathclient
|
||||
+ classpath = [self.binclient, self.srcclient] + self.cpathclient
|
||||
classpath = [os.path.join('..', p) for p in classpath]
|
||||
classpath = os.pathsep.join(classpath)
|
||||
natives = os.path.join('..', self.dirnatives)
|
||||
@@ -1195,20 +1202,20 @@
|
||||
@@ -1197,20 +1205,20 @@
|
||||
with open(self.csvmethods, 'rb') as fh:
|
||||
methodsreader = csv.DictReader(fh)
|
||||
for row in methodsreader:
|
||||
@@ -79,56 +71,7 @@
|
||||
names['params'][row['param']] = row['name']
|
||||
|
||||
regexps = {
|
||||
@@ -1238,6 +1245,11 @@
|
||||
|
||||
# HINT: We pathwalk the sources
|
||||
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
|
||||
+ for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
+ updatefile(os.path.normpath(os.path.join(path, cur_file)))
|
||||
+
|
||||
+ # FML, copy of the above, for the common folder
|
||||
+ for path, _, filelist in os.walk(self.srcshared, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
updatefile(os.path.normpath(os.path.join(path, cur_file)))
|
||||
return True
|
||||
@@ -1320,12 +1332,14 @@
|
||||
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
|
||||
strip_comments(pathsrclk[side])
|
||||
+ strip_comments(self.srcshared)
|
||||
|
||||
def process_cleanup(self, side):
|
||||
"""Do lots of random cleanups including stripping comments, trailing whitespace and extra blank lines"""
|
||||
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
|
||||
src_cleanup(pathsrclk[side], fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
|
||||
+ src_cleanup(self.srcshared, fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
|
||||
|
||||
def process_javadoc(self, side):
|
||||
"""Add CSV descriptions to methods and fields as javadoc"""
|
||||
@@ -1334,6 +1348,21 @@
|
||||
if not self.has_doc_csv:
|
||||
self.logger.warning('!! javadoc disabled due to no csvs !!')
|
||||
return False
|
||||
+
|
||||
+ #FML Recall this function on the common folder
|
||||
+ #Potential bug: If this is called without a subsiquent rename call, will cause double comments
|
||||
+ if pathsrclk[side] != self.srcshared:
|
||||
+ if side == CLIENT:
|
||||
+ tmp = self.srcclient
|
||||
+ self.srcclient = self.srcshared
|
||||
+ self.process_javadoc(side)
|
||||
+ self.srcclient = tmp
|
||||
+ else:
|
||||
+ tmp = self.srcserver
|
||||
+ self.srcserver = self.srcshared
|
||||
+ self.process_javadoc(side)
|
||||
+ self.srcserver = tmp
|
||||
+
|
||||
|
||||
#HINT: We read the relevant CSVs
|
||||
methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
|
||||
@@ -1342,13 +1371,13 @@
|
||||
@@ -1344,13 +1352,13 @@
|
||||
methods = {}
|
||||
for row in methodsreader:
|
||||
#HINT: Only include methods that have a non-empty description
|
||||
@@ -144,15 +87,59 @@
|
||||
fields[row['searge']] = row['desc'].replace('*/', '* /')
|
||||
|
||||
regexps = {
|
||||
@@ -1420,6 +1449,7 @@
|
||||
|
||||
# HINT: We create the list of source directories based on the list of packages
|
||||
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
|
||||
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=True) #FML, Add Common folder
|
||||
dirs = ' '.join(pkglist)
|
||||
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
|
||||
@@ -1427,7 +1435,7 @@
|
||||
self.runcmd(forkcmd)
|
||||
@@ -1592,6 +1622,9 @@
|
||||
return True
|
||||
|
||||
- def gathermd5s(self, side, reobf=False):
|
||||
+ def gathermd5s(self, side, reobf=False, skip_fml=False):
|
||||
if not reobf:
|
||||
md5lk = {CLIENT: self.md5client, SERVER: self.md5server}
|
||||
else:
|
||||
@@ -1442,6 +1450,9 @@
|
||||
class_path = ''
|
||||
else:
|
||||
class_path += '/'
|
||||
+ if skip_fml:
|
||||
+ if class_path.startswith('cpw/'):
|
||||
+ continue
|
||||
for class_file in fnmatch.filter(filelist, '*.class'):
|
||||
class_name = class_path + os.path.splitext(class_file)[0]
|
||||
bin_file = os.path.normpath(os.path.join(path, class_file))
|
||||
@@ -1535,6 +1546,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:
|
||||
@@ -1548,6 +1561,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)
|
||||
@@ -1594,6 +1624,9 @@
|
||||
sys.exit(1)
|
||||
|
||||
for entry in newfiles:
|
||||
@@ -162,3 +149,20 @@
|
||||
if entry[3] == 'U':
|
||||
self.logger.info('Retrieving file from server : %s', entry[0])
|
||||
cur_file = os.path.normpath(entry[0])
|
||||
@@ -1614,6 +1647,9 @@
|
||||
md5reoblk = {CLIENT: self.md5reobfclient, SERVER: self.md5reobfserver}
|
||||
outpathlk = {CLIENT: self.srcmodclient, SERVER: self.srcmodserver}
|
||||
src = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
+
|
||||
+ if side == SERVER: #Noop out server side stuff
|
||||
+ return
|
||||
|
||||
# HINT: We need a table for the old md5 and the new ones
|
||||
md5table = {}
|
||||
@@ -1656,3 +1692,6 @@
|
||||
except IOError:
|
||||
self.logger.error('* File %s copy failed', in_class)
|
||||
|
||||
+def commands_sanity_check():
|
||||
+ print 'Commands patch applied successfully'
|
||||
+
|
||||
@@ -0,0 +1,29 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Declare a variable to be populated by a Bukkit Plugin proxy instance if the bukkit coremod
|
||||
* is available. It can only be applied to field typed as {@link BukkitProxy}
|
||||
* Generally it should be used in conjunction with {@link Mod#bukkitPlugin()} specifying the
|
||||
* plugin to load.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface BukkitPluginRef
|
||||
{
|
||||
/**
|
||||
* A reference (possibly version specific) to a Bukkit Plugin by name, using the name@versionbound
|
||||
* specification. If this is a bukkit enabled environment the field annotated by this
|
||||
* will be populated with a {@link BukkitProxy} instance if possible. This proxy will be gotten by
|
||||
* reflectively calling the "getModProxy" method on the bukkit plugin instance.
|
||||
* @return The name of the plugin which we will inject into this field
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
/**
|
||||
* A marker interface for retrieving a proxy to a bukkit plugin.
|
||||
* Fields associated with {@link BukkitPluginRef} annotations should be should probably
|
||||
* declare this type and cast down if the target is available (not null)
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface BukkitProxy
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.cert.Certificate;
|
||||
|
||||
public class CertificateHelper {
|
||||
|
||||
private static final String HEXES = "0123456789abcdef";
|
||||
|
||||
public static String getFingerprint(Certificate certificate)
|
||||
{
|
||||
if (certificate == null)
|
||||
{
|
||||
return "NO VALID CERTIFICATE FOUND";
|
||||
}
|
||||
try
|
||||
{
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
byte[] der = certificate.getEncoded();
|
||||
md.update(der);
|
||||
byte[] digest = md.digest();
|
||||
return hexify(digest);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFingerprint(ByteBuffer buffer)
|
||||
{
|
||||
try
|
||||
{
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||
digest.update(buffer);
|
||||
byte[] chksum = digest.digest();
|
||||
return hexify(chksum);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String hexify(byte[] chksum)
|
||||
{
|
||||
final StringBuilder hex = new StringBuilder( 2 * chksum.length );
|
||||
for ( final byte b : chksum ) {
|
||||
hex.append(HEXES.charAt((b & 0xF0) >> 4))
|
||||
.append(HEXES.charAt((b & 0x0F)));
|
||||
}
|
||||
return hex.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
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;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class DummyModContainer implements ModContainer
|
||||
{
|
||||
private ModMetadata md;
|
||||
private ArtifactVersion processedVersion;
|
||||
|
||||
public DummyModContainer(ModMetadata md)
|
||||
{
|
||||
@@ -42,9 +44,9 @@ public class DummyModContainer implements ModContainer
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +110,11 @@ public class DummyModContainer implements ModContainer
|
||||
@Override
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
return null;
|
||||
if (processedVersion == null)
|
||||
{
|
||||
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
|
||||
}
|
||||
return processedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,4 +128,21 @@ public class DummyModContainer implements ModContainer
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return md.version;
|
||||
}
|
||||
@Override
|
||||
public VersionRange acceptableMinecraftVersionRange()
|
||||
{
|
||||
return Loader.instance().getMinecraftModContainer().getStaticVersionRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Certificate getSigningCertificate()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
public class DuplicateModsFoundException extends LoaderException {
|
||||
|
||||
public SetMultimap<ModContainer,File> dupes;
|
||||
|
||||
public DuplicateModsFoundException(SetMultimap<ModContainer, File> dupes) {
|
||||
this.dupes = dupes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,45 +13,46 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.DedicatedServer;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet131MapData;
|
||||
import net.minecraft.server.*;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.ItemData;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.server.FMLServerHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -80,20 +81,26 @@ public class FMLCommonHandler
|
||||
|
||||
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
|
||||
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
|
||||
private Class<?> forge;
|
||||
private boolean noForge;
|
||||
private List<String> brandings;
|
||||
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
|
||||
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
|
||||
|
||||
|
||||
|
||||
public void beginLoading(IFMLSidedHandler handler)
|
||||
{
|
||||
sidedDelegate = handler;
|
||||
FMLLog.info("Attempting early MinecraftForge initialization");
|
||||
callForgeMethod("initialize");
|
||||
callForgeMethod("registerCrashCallable");
|
||||
FMLLog.info("Completed early MinecraftForge initialization");
|
||||
}
|
||||
|
||||
public void rescheduleTicks(Side side)
|
||||
{
|
||||
sidedDelegate.profileStart("modTickScheduling");
|
||||
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
|
||||
{
|
||||
@@ -103,19 +110,15 @@ public class FMLCommonHandler
|
||||
{
|
||||
return;
|
||||
}
|
||||
sidedDelegate.profileStart("modTickStart$"+ticks);
|
||||
for (IScheduledTickHandler ticker : scheduledTicks)
|
||||
{
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
|
||||
ticksToRun.removeAll(EnumSet.complementOf(ticks));
|
||||
if (!ticksToRun.isEmpty())
|
||||
{
|
||||
sidedDelegate.profileStart(ticker.getLabel());
|
||||
ticker.tickStart(ticksToRun, data);
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
}
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
|
||||
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
|
||||
@@ -126,19 +129,15 @@ public class FMLCommonHandler
|
||||
{
|
||||
return;
|
||||
}
|
||||
sidedDelegate.profileStart("modTickEnd$"+ticks);
|
||||
for (IScheduledTickHandler ticker : scheduledTicks)
|
||||
{
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
|
||||
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
|
||||
ticksToRun.removeAll(EnumSet.complementOf(ticks));
|
||||
if (!ticksToRun.isEmpty())
|
||||
{
|
||||
sidedDelegate.profileStart(ticker.getLabel());
|
||||
ticker.tickEnd(ticksToRun, data);
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
}
|
||||
sidedDelegate.profileEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +150,6 @@ public class FMLCommonHandler
|
||||
/**
|
||||
* Find the container that associates with the supplied mod object
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
public ModContainer findContainerFor(Object mod)
|
||||
{
|
||||
@@ -159,34 +157,35 @@ public class FMLCommonHandler
|
||||
}
|
||||
/**
|
||||
* Get the forge mod loader logging instance (goes to the forgemodloader log file)
|
||||
* @return
|
||||
* @return The log instance for the FML log file
|
||||
*/
|
||||
public Logger getFMLLogger()
|
||||
{
|
||||
return FMLLog.getLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param lang
|
||||
* @param value
|
||||
*/
|
||||
/**
|
||||
* @param languagePack
|
||||
* @param lang
|
||||
*/
|
||||
|
||||
public Side getSide()
|
||||
{
|
||||
return sidedDelegate.getSide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the effective side for the context in the game. This is dependent
|
||||
* on thread analysis to try and determine whether the code is running in the
|
||||
* server or not. Use at your own risk
|
||||
*/
|
||||
public Side getEffectiveSide()
|
||||
{
|
||||
Thread thr = Thread.currentThread();
|
||||
if ((thr instanceof ThreadMinecraftServer) || (thr instanceof ServerListenThread))
|
||||
{
|
||||
return Side.SERVER;
|
||||
}
|
||||
|
||||
return Side.CLIENT;
|
||||
}
|
||||
/**
|
||||
* Raise an exception
|
||||
*
|
||||
* @param exception
|
||||
* @param message
|
||||
* @param stopGame
|
||||
*/
|
||||
public void raiseException(Throwable exception, String message, boolean stopGame)
|
||||
{
|
||||
@@ -198,9 +197,6 @@ public class FMLCommonHandler
|
||||
}
|
||||
|
||||
|
||||
private Class<?> forge;
|
||||
private boolean noForge;
|
||||
private List<String> brandings;
|
||||
private Class<?> findMinecraftForge()
|
||||
{
|
||||
if (forge==null && !noForge)
|
||||
@@ -228,18 +224,24 @@ public class FMLCommonHandler
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string
|
||||
* @return
|
||||
*/
|
||||
|
||||
public void computeBranding()
|
||||
{
|
||||
if (brandings == null)
|
||||
{
|
||||
Builder brd = ImmutableList.<String>builder();
|
||||
brd.add(Loader.instance().getMCVersionString());
|
||||
brd.add(Loader.instance().getFMLVersionString());
|
||||
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
|
||||
brd.add(Loader.instance().getMCPVersionString());
|
||||
brd.add("FML v"+Loader.instance().getFMLVersionString());
|
||||
String forgeBranding = (String) callForgeMethod("getBrandingVersion");
|
||||
if (!Strings.isNullOrEmpty(forgeBranding))
|
||||
{
|
||||
brd.add(forgeBranding);
|
||||
}
|
||||
if (sidedDelegate!=null)
|
||||
{
|
||||
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
|
||||
}
|
||||
try {
|
||||
Properties props=new Properties();
|
||||
props.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
|
||||
@@ -262,9 +264,6 @@ public class FMLCommonHandler
|
||||
return ImmutableList.copyOf(brandings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public IFMLSidedHandler getSidedDelegate()
|
||||
{
|
||||
return sidedDelegate;
|
||||
@@ -330,9 +329,9 @@ public class FMLCommonHandler
|
||||
sidedDelegate.showGuiScreen(clientGuiElement);
|
||||
}
|
||||
|
||||
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket entitySpawnPacket)
|
||||
public Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket entitySpawnPacket)
|
||||
{
|
||||
return sidedDelegate.spawnEntityIntoClientWorld(cls, entitySpawnPacket);
|
||||
return sidedDelegate.spawnEntityIntoClientWorld(registration, entitySpawnPacket);
|
||||
}
|
||||
|
||||
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
|
||||
@@ -342,16 +341,7 @@ public class FMLCommonHandler
|
||||
|
||||
public void onServerStart(DedicatedServer dedicatedServer)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Done this way so that the client doesn't depend on server side handler
|
||||
Class<?> cls = Class.forName("cpw.mods.fml.server.FMLServerHandler", true, getClass().getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to load the FML server handler");
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
FMLServerHandler.instance();
|
||||
sidedDelegate.beginServerLoading(dedicatedServer);
|
||||
}
|
||||
|
||||
@@ -384,11 +374,83 @@ public class FMLCommonHandler
|
||||
|
||||
public void onPlayerPreTick(EntityPlayer player)
|
||||
{
|
||||
tickStart(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
|
||||
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
|
||||
tickStart(EnumSet.of(TickType.PLAYER), side, player);
|
||||
}
|
||||
|
||||
public void onPlayerPostTick(EntityPlayer player)
|
||||
{
|
||||
tickEnd(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
|
||||
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
|
||||
tickEnd(EnumSet.of(TickType.PLAYER), side, player);
|
||||
}
|
||||
|
||||
public void registerCrashCallable(ICrashCallable callable)
|
||||
{
|
||||
crashCallables.add(callable);
|
||||
}
|
||||
|
||||
public void enhanceCrashReport(CrashReport crashReport, CrashReportCategory category)
|
||||
{
|
||||
for (ICrashCallable call: crashCallables)
|
||||
{
|
||||
category.func_71500_a(call.getLabel(), call);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
sidedDelegate.handleTinyPacket(handler, mapData);
|
||||
}
|
||||
|
||||
public void handleWorldDataSave(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
|
||||
{
|
||||
for (ModContainer mc : Loader.instance().getModList())
|
||||
{
|
||||
if (mc instanceof InjectedModContainer)
|
||||
{
|
||||
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
|
||||
if (wac != null)
|
||||
{
|
||||
NBTTagCompound dataForWriting = wac.getDataForWriting(handler, worldInfo);
|
||||
tagCompound.func_74766_a(mc.getModId(), dataForWriting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleWorldDataLoad(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
|
||||
{
|
||||
if (getEffectiveSide()!=Side.SERVER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (handlerSet.contains(handler))
|
||||
{
|
||||
return;
|
||||
}
|
||||
handlerSet.add(handler);
|
||||
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
|
||||
worldInfo.setAdditionalProperties(additionalProperties);
|
||||
for (ModContainer mc : Loader.instance().getModList())
|
||||
{
|
||||
if (mc instanceof InjectedModContainer)
|
||||
{
|
||||
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
|
||||
if (wac != null)
|
||||
{
|
||||
wac.readData(handler, worldInfo, additionalProperties, tagCompound.func_74775_l(mc.getModId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldServerBeKilledQuietly()
|
||||
{
|
||||
return sidedDelegate.shouldServerShouldBeKilledQuietly();
|
||||
}
|
||||
|
||||
public void disconnectIDMismatch(MapDifference<Integer, ItemData> serverDifference, NetHandler toKill, INetworkManager network)
|
||||
{
|
||||
sidedDelegate.disconnectIDMismatch(serverDifference, toKill, network);
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,28 @@
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.registry.ItemData;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class FMLDummyContainer extends DummyModContainer
|
||||
public class FMLDummyContainer extends DummyModContainer implements WorldAccessContainer
|
||||
{
|
||||
public FMLDummyContainer()
|
||||
{
|
||||
@@ -49,4 +62,66 @@ public class FMLDummyContainer extends DummyModContainer
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
|
||||
{
|
||||
NBTTagCompound fmlData = new NBTTagCompound();
|
||||
NBTTagList list = new NBTTagList();
|
||||
for (ModContainer mc : Loader.instance().getActiveModList())
|
||||
{
|
||||
NBTTagCompound mod = new NBTTagCompound();
|
||||
mod.func_74778_a("ModId", mc.getModId());
|
||||
mod.func_74778_a("ModVersion", mc.getVersion());
|
||||
list.func_74742_a(mod);
|
||||
}
|
||||
fmlData.func_74782_a("ModList", list);
|
||||
NBTTagList itemList = new NBTTagList();
|
||||
GameData.writeItemData(itemList);
|
||||
fmlData.func_74782_a("ModItemData", itemList);
|
||||
return fmlData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
|
||||
{
|
||||
if (tag.func_74764_b("ModList"))
|
||||
{
|
||||
NBTTagList modList = tag.func_74761_m("ModList");
|
||||
for (int i = 0; i < modList.func_74745_c(); i++)
|
||||
{
|
||||
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
|
||||
String modId = mod.func_74779_i("ModId");
|
||||
String modVersion = mod.func_74779_i("ModVersion");
|
||||
ModContainer container = Loader.instance().getIndexedModList().get(modId);
|
||||
if (container == null)
|
||||
{
|
||||
FMLLog.severe("This world was saved with mod %s which appears to be missing, things may not work well", modId);
|
||||
continue;
|
||||
}
|
||||
if (!modVersion.equals(container.getVersion()))
|
||||
{
|
||||
FMLLog.info("This world was saved with mod %s version %s and it is now at version %s, things may not work well", modId, modVersion, container.getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tag.func_74764_b("ModItemData"))
|
||||
{
|
||||
NBTTagList modList = tag.func_74761_m("ModItemData");
|
||||
Set<ItemData> worldSaveItems = GameData.buildWorldItemData(modList);
|
||||
GameData.validateWorldSave(worldSaveItems);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameData.validateWorldSave(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Certificate getSigningCertificate()
|
||||
{
|
||||
Certificate[] certificates = getClass().getProtectionDomain().getCodeSource().getCertificates();
|
||||
return certificates != null ? certificates[0] : null;
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,12 @@ public class FMLLog
|
||||
|
||||
public static void log(Level level, String format, Object... data)
|
||||
{
|
||||
coreLog.log(level, String.format(format, data));
|
||||
coreLog.log(level, format, data);
|
||||
}
|
||||
|
||||
public static void log(Level level, Throwable ex, String format, Object... data)
|
||||
{
|
||||
coreLog.log(level, String.format(format, data), ex);
|
||||
coreLog.log(level, ex, format, data);
|
||||
}
|
||||
|
||||
public static void severe(String format, Object... data)
|
||||
|
||||
@@ -13,37 +13,49 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.Mod.Block;
|
||||
import cpw.mods.fml.common.Mod.Instance;
|
||||
import cpw.mods.fml.common.Mod.Metadata;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent;
|
||||
import cpw.mods.fml.common.event.FMLFingerprintViolationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartedEvent;
|
||||
@@ -51,9 +63,10 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class FMLModContainer implements ModContainer
|
||||
{
|
||||
@@ -64,9 +77,7 @@ public class FMLModContainer implements ModContainer
|
||||
private String className;
|
||||
private Map<String, Object> descriptor;
|
||||
private boolean enabled = true;
|
||||
private List<ArtifactVersion> requirements;
|
||||
private List<ArtifactVersion> dependencies;
|
||||
private List<ArtifactVersion> dependants;
|
||||
private String internalVersion;
|
||||
private boolean overridesMetadata;
|
||||
private EventBus eventBus;
|
||||
private LoadController controller;
|
||||
@@ -74,15 +85,22 @@ public class FMLModContainer implements ModContainer
|
||||
private DefaultArtifactVersion processedVersion;
|
||||
private boolean isNetworkMod;
|
||||
|
||||
private static final BiMap<Class<? extends FMLStateEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLStateEvent>, Class<? extends Annotation>>builder()
|
||||
private static final BiMap<Class<? extends FMLEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLEvent>, Class<? extends Annotation>>builder()
|
||||
.put(FMLPreInitializationEvent.class, Mod.PreInit.class)
|
||||
.put(FMLInitializationEvent.class, Mod.Init.class)
|
||||
.put(FMLPostInitializationEvent.class, Mod.PostInit.class)
|
||||
.put(FMLServerStartingEvent.class, Mod.ServerStarting.class)
|
||||
.put(FMLServerStartedEvent.class, Mod.ServerStarted.class)
|
||||
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
|
||||
.put(IMCEvent.class,Mod.IMCCallback.class)
|
||||
.put(FMLFingerprintViolationEvent.class, Mod.FingerprintWarning.class)
|
||||
.build();
|
||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||
private String annotationDependencies;
|
||||
private VersionRange minecraftAccepted;
|
||||
private boolean fingerprintNotPresent;
|
||||
private Set<String> sourceFingerprints;
|
||||
private Certificate certificate;
|
||||
|
||||
|
||||
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
||||
@@ -107,7 +125,7 @@ public class FMLModContainer implements ModContainer
|
||||
@Override
|
||||
public String getVersion()
|
||||
{
|
||||
return modMetadata.version;
|
||||
return internalVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,20 +145,100 @@ public class FMLModContainer implements ModContainer
|
||||
{
|
||||
modMetadata = mc.getMetadataForId(getModId(), descriptor);
|
||||
|
||||
if (descriptor.containsKey("usesMetadata"))
|
||||
if (descriptor.containsKey("useMetadata"))
|
||||
{
|
||||
overridesMetadata = !((Boolean)descriptor.get("usesMetadata")).booleanValue();
|
||||
overridesMetadata = !((Boolean)descriptor.get("useMetadata")).booleanValue();
|
||||
}
|
||||
|
||||
if (overridesMetadata || !modMetadata.useDependencyInformation)
|
||||
{
|
||||
List<ArtifactVersion> requirements = Lists.newArrayList();
|
||||
Set<ArtifactVersion> requirements = Sets.newHashSet();
|
||||
List<ArtifactVersion> dependencies = Lists.newArrayList();
|
||||
List<ArtifactVersion> dependants = Lists.newArrayList();
|
||||
Loader.instance().computeDependencies((String) descriptor.get("dependencies"), requirements, dependencies, dependants);
|
||||
annotationDependencies = (String) descriptor.get("dependencies");
|
||||
Loader.instance().computeDependencies(annotationDependencies, requirements, dependencies, dependants);
|
||||
modMetadata.requiredMods = requirements;
|
||||
modMetadata.dependencies = dependencies;
|
||||
modMetadata.dependants = dependants;
|
||||
FMLLog.finest("Parsed dependency info : %s %s %s", requirements, dependencies, dependants);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.finest("Using mcmod dependency info : %s %s %s", modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants);
|
||||
}
|
||||
if (Strings.isNullOrEmpty(modMetadata.name))
|
||||
{
|
||||
FMLLog.info("Mod %s is missing the required element 'name'. Substituting %s", getModId(), getModId());
|
||||
modMetadata.name = getModId();
|
||||
}
|
||||
internalVersion = (String) descriptor.get("version");
|
||||
if (Strings.isNullOrEmpty(internalVersion))
|
||||
{
|
||||
Properties versionProps = searchForVersionProperties();
|
||||
if (versionProps != null)
|
||||
{
|
||||
internalVersion = versionProps.getProperty(getModId()+".version");
|
||||
FMLLog.fine("Found version %s for mod %s in version.properties, using", internalVersion, getModId());
|
||||
}
|
||||
|
||||
}
|
||||
if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version))
|
||||
{
|
||||
FMLLog.warning("Mod %s is missing the required element 'version' and a version.properties file could not be found. Falling back to metadata version %s", getModId(), modMetadata.version);
|
||||
internalVersion = modMetadata.version;
|
||||
}
|
||||
if (Strings.isNullOrEmpty(internalVersion))
|
||||
{
|
||||
FMLLog.warning("Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
|
||||
modMetadata.version = internalVersion = "1.0";
|
||||
}
|
||||
|
||||
String mcVersionString = (String) descriptor.get("acceptedMinecraftVersions");
|
||||
if (!Strings.isNullOrEmpty(mcVersionString))
|
||||
{
|
||||
minecraftAccepted = VersionParser.parseRange(mcVersionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
minecraftAccepted = Loader.instance().getMinecraftModContainer().getStaticVersionRange();
|
||||
}
|
||||
}
|
||||
|
||||
public Properties searchForVersionProperties()
|
||||
{
|
||||
try
|
||||
{
|
||||
FMLLog.fine("Attempting to load the file version.properties from %s to locate a version number for %s", getSource().getName(), getModId());
|
||||
Properties version = null;
|
||||
if (getSource().isFile())
|
||||
{
|
||||
ZipFile source = new ZipFile(getSource());
|
||||
ZipEntry versionFile = source.getEntry("version.properties");
|
||||
if (versionFile!=null)
|
||||
{
|
||||
version = new Properties();
|
||||
version.load(source.getInputStream(versionFile));
|
||||
}
|
||||
source.close();
|
||||
}
|
||||
else if (getSource().isDirectory())
|
||||
{
|
||||
File propsFile = new File(getSource(),"version.properties");
|
||||
if (propsFile.exists() && propsFile.isFile())
|
||||
{
|
||||
version = new Properties();
|
||||
FileInputStream fis = new FileInputStream(propsFile);
|
||||
version.load(fis);
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
FMLLog.fine("Failed to find a usable version.properties file");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +249,7 @@ public class FMLModContainer implements ModContainer
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return modMetadata.requiredMods;
|
||||
}
|
||||
@@ -171,7 +269,7 @@ public class FMLModContainer implements ModContainer
|
||||
@Override
|
||||
public String getSortingRules()
|
||||
{
|
||||
return modMetadata.printableSortingRules();
|
||||
return ((overridesMetadata || !modMetadata.useDependencyInformation) ? Strings.nullToEmpty(annotationDependencies) : modMetadata.printableSortingRules());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,55 +305,103 @@ public class FMLModContainer implements ModContainer
|
||||
{
|
||||
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
|
||||
|
||||
for (Field f : clazz.getDeclaredFields())
|
||||
{
|
||||
for (Annotation a : f.getAnnotations())
|
||||
{
|
||||
f.setAccessible(true);
|
||||
anns.put(a.annotationType(), f);
|
||||
}
|
||||
}
|
||||
|
||||
for (Method m : clazz.getDeclaredMethods())
|
||||
{
|
||||
for (Annotation a : m.getAnnotations())
|
||||
{
|
||||
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
|
||||
if (modTypeAnnotations.containsKey(a.annotationType()))
|
||||
{
|
||||
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
|
||||
|
||||
if (Arrays.equals(m.getParameterTypes(), paramTypes))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
anns.put(a.annotationType(), m);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
|
||||
if (Arrays.equals(m.getParameterTypes(), paramTypes))
|
||||
{
|
||||
m.setAccessible(true);
|
||||
anns.put(a.annotationType(), m);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return anns;
|
||||
}
|
||||
|
||||
private void processFieldAnnotations() throws Exception
|
||||
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
|
||||
{
|
||||
// Instance annotation
|
||||
for (Object o : annotations.get(Instance.class))
|
||||
{
|
||||
Field f = (Field) o;
|
||||
f.set(modInstance, modInstance);
|
||||
}
|
||||
SetMultimap<String, ASMData> annotations = asmDataTable.getAnnotationsFor(this);
|
||||
|
||||
for (Object o : annotations.get(Metadata.class))
|
||||
parseSimpleFieldAnnotation(annotations, Instance.class.getName(), new Function<ModContainer, Object>()
|
||||
{
|
||||
Field f = (Field) o;
|
||||
f.set(modInstance, modMetadata);
|
||||
public Object apply(ModContainer mc)
|
||||
{
|
||||
return mc.getMod();
|
||||
}
|
||||
});
|
||||
parseSimpleFieldAnnotation(annotations, Metadata.class.getName(), new Function<ModContainer, Object>()
|
||||
{
|
||||
public Object apply(ModContainer mc)
|
||||
{
|
||||
return mc.getMetadata();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
|
||||
{
|
||||
String[] annName = annotationClassName.split("\\.");
|
||||
String annotationName = annName[annName.length - 1];
|
||||
for (ASMData targets : annotations.get(annotationClassName))
|
||||
{
|
||||
String targetMod = (String) targets.getAnnotationInfo().get("value");
|
||||
Field f = null;
|
||||
Object injectedMod = null;
|
||||
ModContainer mc = this;
|
||||
boolean isStatic = false;
|
||||
Class<?> clz = modInstance.getClass();
|
||||
if (!Strings.isNullOrEmpty(targetMod))
|
||||
{
|
||||
if (Loader.isModLoaded(targetMod))
|
||||
{
|
||||
mc = Loader.instance().getIndexedModList().get(targetMod);
|
||||
}
|
||||
else
|
||||
{
|
||||
mc = null;
|
||||
}
|
||||
}
|
||||
if (mc != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader());
|
||||
f = clz.getDeclaredField(targets.getObjectName());
|
||||
f.setAccessible(true);
|
||||
isStatic = Modifier.isStatic(f.getModifiers());
|
||||
injectedMod = retreiver.apply(mc);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
FMLLog.log(Level.WARNING, e, "Attempting to load @%s in class %s for %s and failing", annotationName, targets.getClassName(), mc.getModId());
|
||||
}
|
||||
}
|
||||
if (f != null)
|
||||
{
|
||||
Object target = null;
|
||||
if (!isStatic)
|
||||
{
|
||||
target = modInstance;
|
||||
if (!modInstance.getClass().equals(clz))
|
||||
{
|
||||
FMLLog.warning("Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f.set(target, injectedMod);
|
||||
}
|
||||
}
|
||||
//TODO
|
||||
// for (Object o : annotations.get(Block.class))
|
||||
// {
|
||||
// Field f = (Field) o;
|
||||
// f.set(modInstance, GameRegistry.buildBlock(this, f.getType(), f.getAnnotation(Block.class)));
|
||||
// }
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -266,14 +412,53 @@ public class FMLModContainer implements ModContainer
|
||||
ModClassLoader modClassLoader = event.getModClassLoader();
|
||||
modClassLoader.addFile(source);
|
||||
Class<?> clazz = Class.forName(className, true, modClassLoader);
|
||||
ASMDataTable asmHarvestedAnnotations = event.getASMHarvestedData();
|
||||
// TODO
|
||||
asmHarvestedAnnotations.getAnnotationsFor(this);
|
||||
|
||||
Certificate[] certificates = clazz.getProtectionDomain().getCodeSource().getCertificates();
|
||||
int len = 0;
|
||||
if (certificates != null)
|
||||
{
|
||||
len = certificates.length;
|
||||
}
|
||||
Builder<String> certBuilder = ImmutableList.<String>builder();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
certBuilder.add(CertificateHelper.getFingerprint(certificates[i]));
|
||||
}
|
||||
|
||||
ImmutableList<String> certList = certBuilder.build();
|
||||
sourceFingerprints = ImmutableSet.copyOf(certList);
|
||||
|
||||
String expectedFingerprint = (String) descriptor.get("certificateFingerprint");
|
||||
|
||||
fingerprintNotPresent = true;
|
||||
|
||||
if (expectedFingerprint != null && !expectedFingerprint.isEmpty())
|
||||
{
|
||||
if (!sourceFingerprints.contains(expectedFingerprint))
|
||||
{
|
||||
Level warnLevel = Level.SEVERE;
|
||||
if (source.isDirectory())
|
||||
{
|
||||
warnLevel = Level.FINER;
|
||||
}
|
||||
FMLLog.log(warnLevel, "The mod %s is expecting signature %s for source %s, however there is no signature matching that description", getModId(), expectedFingerprint, source.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
certificate = certificates[certList.indexOf(expectedFingerprint)];
|
||||
fingerprintNotPresent = false;
|
||||
}
|
||||
}
|
||||
|
||||
annotations = gatherAnnotations(clazz);
|
||||
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
|
||||
modInstance = clazz.newInstance();
|
||||
if (fingerprintNotPresent)
|
||||
{
|
||||
eventBus.post(new FMLFingerprintViolationEvent(source.isDirectory(), source, ImmutableSet.copyOf(this.sourceFingerprints), expectedFingerprint));
|
||||
}
|
||||
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
||||
processFieldAnnotations();
|
||||
processFieldAnnotations(event.getASMHarvestedData());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
@@ -283,7 +468,7 @@ public class FMLModContainer implements ModContainer
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleModStateEvent(FMLStateEvent event)
|
||||
public void handleModStateEvent(FMLEvent event)
|
||||
{
|
||||
Class<? extends Annotation> annotation = modAnnotationTypes.get(event.getClass());
|
||||
if (annotation == null)
|
||||
@@ -325,4 +510,22 @@ public class FMLModContainer implements ModContainer
|
||||
{
|
||||
return isNetworkMod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return modMetadata.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionRange acceptableMinecraftVersionRange()
|
||||
{
|
||||
return minecraftAccepted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Certificate getSigningCertificate()
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,9 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Return a crafting handler for the mod container to call
|
||||
@@ -29,15 +29,15 @@ public interface ICraftingHandler
|
||||
* The object array contains these three arguments
|
||||
*
|
||||
* @param player
|
||||
* @param craftedItem
|
||||
* @param craftingGrid
|
||||
* @param item
|
||||
* @param craftMatrix
|
||||
*/
|
||||
void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix);
|
||||
|
||||
/**
|
||||
* The object array contains these two arguments
|
||||
* @param player
|
||||
* @param smeltedItem
|
||||
* @param item
|
||||
*/
|
||||
void onSmelting(EntityPlayer player, ItemStack item);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface ICrashCallable extends Callable<String>
|
||||
{
|
||||
String getLabel();
|
||||
}
|
||||
@@ -12,22 +12,37 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.World;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
||||
/**
|
||||
* Deprecated without replacement, use vanilla DispenserRegistry code
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IDispenseHandler
|
||||
{
|
||||
/**
|
||||
* Return -1 if you don't want to dispense anything. the other values seem to have specific meanings
|
||||
* to blockdispenser.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVelocity
|
||||
* @param zVelocity
|
||||
* @param data
|
||||
* @return
|
||||
* @param world
|
||||
* @param item
|
||||
* @param random
|
||||
* @param entX
|
||||
* @param entY
|
||||
* @param entZ
|
||||
*/
|
||||
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item);
|
||||
@Deprecated
|
||||
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
*
|
||||
* Deprecated without replacement. Use vanilla DispenserRegistry code.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public interface IDispenserHandler
|
||||
{
|
||||
/**
|
||||
* Called to dispense an entity
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVelocity
|
||||
* @param zVelocity
|
||||
* @param world
|
||||
* @param item
|
||||
* @param random
|
||||
* @param entX
|
||||
* @param entY
|
||||
* @param entZ
|
||||
*/
|
||||
int dispense(int x, int y, int z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
public interface IFMLHandledException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,27 +1,24 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.collect.MapDifference;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.INetworkManager;
|
||||
import net.minecraft.network.packet.NetHandler;
|
||||
import net.minecraft.network.packet.Packet;
|
||||
import net.minecraft.network.packet.Packet131MapData;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.DedicatedServer;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
import cpw.mods.fml.common.modloader.ModProperty;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.registry.ItemData;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public interface IFMLSidedHandler
|
||||
{
|
||||
void profileStart(String profileLabel);
|
||||
|
||||
void profileEnd();
|
||||
|
||||
List<String> getAdditionalBrandingInformation();
|
||||
|
||||
Side getSide();
|
||||
@@ -30,7 +27,7 @@ public interface IFMLSidedHandler
|
||||
|
||||
void showGuiScreen(Object clientGuiElement);
|
||||
|
||||
Entity spawnEntityIntoClientWorld(Class<? extends Entity> entityClass, EntitySpawnPacket packet);
|
||||
Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket packet);
|
||||
|
||||
void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket);
|
||||
|
||||
@@ -39,4 +36,18 @@ public interface IFMLSidedHandler
|
||||
void finishServerLoading();
|
||||
|
||||
MinecraftServer getServer();
|
||||
|
||||
void sendPacket(Packet packet);
|
||||
|
||||
void displayMissingMods(ModMissingPacket modMissingPacket);
|
||||
|
||||
void handleTinyPacket(NetHandler handler, Packet131MapData mapData);
|
||||
|
||||
void setClientCompatibilityLevel(byte compatibilityLevel);
|
||||
|
||||
byte getClientCompatibilityLevel();
|
||||
|
||||
boolean shouldServerShouldBeKilledQuietly();
|
||||
|
||||
void disconnectIDMismatch(MapDifference<Integer, ItemData> s, NetHandler toKill, INetworkManager mgr);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IFuelHandler
|
||||
{
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public interface IPickupNotifier
|
||||
{
|
||||
void notifyPickup(Object... pickupData);
|
||||
void notifyPickup(EntityItem item, EntityPlayer player);
|
||||
}
|
||||
@@ -14,13 +14,19 @@
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IPlayerTracker
|
||||
{
|
||||
void onPlayerLogin(Object player);
|
||||
void onPlayerLogout(Object player);
|
||||
void onPlayerChangedDimension(Object player);
|
||||
void onPlayerLogin(EntityPlayer player);
|
||||
|
||||
void onPlayerLogout(EntityPlayer player);
|
||||
|
||||
void onPlayerChangedDimension(EntityPlayer player);
|
||||
|
||||
void onPlayerRespawn(EntityPlayer player);
|
||||
}
|
||||
@@ -6,8 +6,7 @@ public interface IScheduledTickHandler extends ITickHandler
|
||||
* Return the number of actual ticks that will pass
|
||||
* before your next tick will fire. This will be called
|
||||
* just after your last tick fired to compute the next delay.
|
||||
* @param tick
|
||||
* @return
|
||||
* @return Time until next tick
|
||||
*/
|
||||
public int nextTickSpacing();
|
||||
}
|
||||
@@ -51,14 +51,11 @@ public interface ITickHandler
|
||||
|
||||
/**
|
||||
* Returns the list of ticks this tick handler is interested in receiving at the minute
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public EnumSet<TickType> ticks();
|
||||
|
||||
/**
|
||||
* A profiling label for this tick handler
|
||||
* @return
|
||||
*/
|
||||
public String getLabel();
|
||||
}
|
||||
@@ -15,12 +15,12 @@ package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
|
||||
|
||||
/**
|
||||
* This is called back during world generation. The {@link #generate(Random, int, int, Object...)} method passes in some additional data that
|
||||
* can be cast into minecraft objects.
|
||||
* This is called back during world generation.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
@@ -31,10 +31,10 @@ public interface IWorldGenerator
|
||||
* Generate some world
|
||||
*
|
||||
* @param random the chunk specific {@link Random}.
|
||||
* @param chunkX the block X coordinate of this chunk.
|
||||
* @param chunkZ the block Z coordinate of this chunk.
|
||||
* @param chunkX the chunk X coordinate of this chunk.
|
||||
* @param chunkZ the chunk Z coordinate of this chunk.
|
||||
* @param world : additionalData[0] The minecraft {@link World} we're generating for.
|
||||
* @param generator : additionalData[1] The {@link IChunkProvider} that is generating.
|
||||
* @param chunkGenerator : additionalData[1] The {@link IChunkProvider} that is generating.
|
||||
* @param chunkProvider : additionalData[2] {@link IChunkProvider} that is requesting the world generation.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class InjectedModContainer implements ModContainer
|
||||
{
|
||||
@@ -53,7 +56,7 @@ public class InjectedModContainer implements ModContainer
|
||||
wrappedContainer.setEnabledState(enabled);
|
||||
}
|
||||
|
||||
public List<ArtifactVersion> getRequirements()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return wrappedContainer.getRequirements();
|
||||
}
|
||||
@@ -103,4 +106,34 @@ public class InjectedModContainer implements ModContainer
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return wrappedContainer.getDisplayVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionRange acceptableMinecraftVersionRange()
|
||||
{
|
||||
return wrappedContainer.acceptableMinecraftVersionRange();
|
||||
}
|
||||
|
||||
public WorldAccessContainer getWrappedWorldAccessContainer()
|
||||
{
|
||||
if (wrappedContainer instanceof WorldAccessContainer)
|
||||
{
|
||||
return (WorldAccessContainer) wrappedContainer;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Certificate getSigningCertificate()
|
||||
{
|
||||
return wrappedContainer.getSigningCertificate();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -8,23 +9,20 @@ import java.util.logging.Level;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.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.network.FMLNetworkHandler;
|
||||
|
||||
public class LoadController
|
||||
{
|
||||
@@ -36,7 +34,7 @@ public class LoadController
|
||||
private Multimap<String, Throwable> errors = ArrayListMultimap.create();
|
||||
private Map<String, ModContainer> modList;
|
||||
private List<ModContainer> activeModList = Lists.newArrayList();
|
||||
private String activeContainer;
|
||||
private ModContainer activeContainer;
|
||||
private BiMap<ModContainer, Object> modObjectList;
|
||||
|
||||
public LoadController(Loader loader)
|
||||
@@ -92,74 +90,109 @@ public class LoadController
|
||||
state = state.transition(!errors.isEmpty());
|
||||
if (state != desiredState)
|
||||
{
|
||||
Throwable toThrow = null;
|
||||
FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
printModStates(sb);
|
||||
FMLLog.severe(sb.toString());
|
||||
FMLLog.getLogger().severe(sb.toString());
|
||||
FMLLog.severe("The following problems were captured during this phase");
|
||||
for (Entry<String, Throwable> error : errors.entries())
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, error.getValue(), "Caught exception from %s", error.getKey());
|
||||
if (error.getValue() instanceof IFMLHandledException)
|
||||
{
|
||||
toThrow = error.getValue();
|
||||
}
|
||||
else if (toThrow == null)
|
||||
{
|
||||
toThrow = error.getValue();
|
||||
}
|
||||
}
|
||||
if (toThrow != null && toThrow instanceof RuntimeException)
|
||||
{
|
||||
throw (RuntimeException)toThrow;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new LoaderException(toThrow);
|
||||
}
|
||||
|
||||
// Throw embedding the first error (usually the only one)
|
||||
throw new LoaderException(errors.values().iterator().next());
|
||||
}
|
||||
}
|
||||
|
||||
public ModContainer activeContainer()
|
||||
{
|
||||
return activeContainer!=null ? modList.get(activeContainer) : null;
|
||||
return activeContainer;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void propogateStateMessage(FMLStateEvent stateEvent)
|
||||
public void propogateStateMessage(FMLEvent stateEvent)
|
||||
{
|
||||
for (Map.Entry<String,EventBus> entry : eventChannels.entrySet())
|
||||
if (stateEvent instanceof FMLPreInitializationEvent)
|
||||
{
|
||||
activeContainer = entry.getKey();
|
||||
stateEvent.applyModContainer(activeContainer());
|
||||
FMLLog.finer("Posting state event %s to mod %s", stateEvent, entry.getKey());
|
||||
entry.getValue().post(stateEvent);
|
||||
FMLLog.finer("State event %s delivered to mod %s", stateEvent, entry.getKey());
|
||||
activeContainer = null;
|
||||
if (!errors.containsKey(entry.getKey()))
|
||||
{
|
||||
modStates.put(entry.getKey(), stateEvent.getModState());
|
||||
}
|
||||
else
|
||||
{
|
||||
modStates.put(entry.getKey(), ModState.ERRORED);
|
||||
}
|
||||
modObjectList = buildModObjectList();
|
||||
}
|
||||
if (stateEvent instanceof FMLConstructionEvent)
|
||||
for (ModContainer mc : activeModList)
|
||||
{
|
||||
buildModObjectList();
|
||||
activeContainer = mc;
|
||||
String modId = mc.getModId();
|
||||
stateEvent.applyModContainer(activeContainer());
|
||||
FMLLog.finer("Sending event %s to mod %s", stateEvent.getEventType(), modId);
|
||||
eventChannels.get(modId).post(stateEvent);
|
||||
FMLLog.finer("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void buildModObjectList()
|
||||
public ImmutableBiMap<ModContainer, Object> buildModObjectList()
|
||||
{
|
||||
ImmutableBiMap.Builder<ModContainer, Object> builder = ImmutableBiMap.<ModContainer, Object>builder();
|
||||
for (ModContainer mc : activeModList)
|
||||
{
|
||||
builder.put(mc, mc.getMod());
|
||||
if (!mc.isImmutable() && mc.getMod()!=null)
|
||||
{
|
||||
builder.put(mc, mc.getMod());
|
||||
}
|
||||
if (mc.getMod()==null && !mc.isImmutable() && state!=LoaderState.CONSTRUCTING)
|
||||
{
|
||||
FMLLog.severe("There is a severe problem with %s - it appears not to have constructed correctly", mc.getModId());
|
||||
if (state != LoaderState.CONSTRUCTING)
|
||||
{
|
||||
this.errorOccurred(mc, new RuntimeException());
|
||||
}
|
||||
}
|
||||
}
|
||||
modObjectList = builder.build();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public void errorOccurred(ModContainer modContainer, Throwable exception)
|
||||
{
|
||||
errors.put(modContainer.getModId(), exception);
|
||||
if (exception instanceof InvocationTargetException)
|
||||
{
|
||||
errors.put(modContainer.getModId(), ((InvocationTargetException)exception).getCause());
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.put(modContainer.getModId(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void printModStates(StringBuilder ret)
|
||||
{
|
||||
for (String modId : modStates.keySet())
|
||||
for (ModContainer mc : loader.getModList())
|
||||
{
|
||||
ModContainer mod = modList.get(modId);
|
||||
ret.append("\n\t").append(mod.getName()).append(" (").append(mod.getSource().getName()).append(") ");
|
||||
Joiner.on("->"). appendTo(ret, modStates.get(modId));
|
||||
ret.append("\n\t").append(mc.getModId()).append(" [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
|
||||
Joiner.on("->"). appendTo(ret, modStates.get(mc.getModId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,6 +221,20 @@ public class LoadController
|
||||
|
||||
public BiMap<ModContainer, Object> getModObjectList()
|
||||
{
|
||||
if (modObjectList == null)
|
||||
{
|
||||
FMLLog.severe("Detected an attempt by a mod %s to perform game activity during mod construction. This is a serious programming error.", activeContainer);
|
||||
return buildModObjectList();
|
||||
}
|
||||
return ImmutableBiMap.copyOf(modObjectList);
|
||||
}
|
||||
|
||||
public boolean isInState(LoaderState state)
|
||||
{
|
||||
return this.state == state;
|
||||
}
|
||||
|
||||
boolean hasReachedState(LoaderState state) {
|
||||
return this.state.ordinal()>=state.ordinal() && this.state!=LoaderState.ERRORED;
|
||||
}
|
||||
}
|
||||
@@ -14,42 +14,48 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.crash.CallableMinecraftVersion;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Splitter.MapSplitter;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Multiset.Entry;
|
||||
import com.google.common.collect.Multisets;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
import com.google.common.collect.TreeMultimap;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ContainerType;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
import cpw.mods.fml.common.event.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.functions.ModIdFunction;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.common.toposort.ModSorter;
|
||||
import cpw.mods.fml.common.toposort.ModSortingException;
|
||||
import cpw.mods.fml.common.toposort.TopologicalSort;
|
||||
@@ -103,7 +109,7 @@ public class Loader
|
||||
private static String rev;
|
||||
private static String build;
|
||||
private static String mccversion;
|
||||
private static String mcsversion;
|
||||
private static String mcpversion;
|
||||
|
||||
/**
|
||||
* The class loader we load the mods into.
|
||||
@@ -131,6 +137,8 @@ public class Loader
|
||||
private Exception capturedError;
|
||||
private File canonicalModsDir;
|
||||
private LoadController modController;
|
||||
private MinecraftDummyContainer minecraft;
|
||||
private MCPDummyContainer mcp;
|
||||
|
||||
private static File minecraftDir;
|
||||
private static List<String> injectedContainers;
|
||||
@@ -152,7 +160,7 @@ public class Loader
|
||||
rev = (String) data[2];
|
||||
build = (String) data[3];
|
||||
mccversion = (String) data[4];
|
||||
mcsversion = (String) data[5];
|
||||
mcpversion = (String) data[5];
|
||||
minecraftDir = (File) data[6];
|
||||
injectedContainers = (List<String>)data[7];
|
||||
}
|
||||
@@ -160,6 +168,15 @@ public class Loader
|
||||
private Loader()
|
||||
{
|
||||
modClassLoader = new ModClassLoader(getClass().getClassLoader());
|
||||
String actualMCVersion = new CallableMinecraftVersion(null).func_71493_a();
|
||||
if (!mccversion.equals(actualMCVersion))
|
||||
{
|
||||
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, actualMCVersion);
|
||||
throw new LoaderException();
|
||||
}
|
||||
|
||||
minecraft = new MinecraftDummyContainer(actualMCVersion);
|
||||
mcp = new MCPDummyContainer(MetadataCollection.from(getClass().getResourceAsStream("/mcpmod.info"), "MCP").getMetadataForId("mcp", null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,14 +189,37 @@ public class Loader
|
||||
FMLLog.fine("Verifying mod requirements are satisfied");
|
||||
try
|
||||
{
|
||||
Map<String, ArtifactVersion> modVersions = Maps.newHashMap();
|
||||
for (ModContainer mod : mods)
|
||||
BiMap<String, ArtifactVersion> modVersions = HashBiMap.create();
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
modVersions.put(mod.getModId(), mod.getProcessedVersion());
|
||||
}
|
||||
|
||||
for (ModContainer mod : mods)
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
if (!mod.acceptableMinecraftVersionRange().containsVersion(minecraft.getProcessedVersion()))
|
||||
{
|
||||
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();
|
||||
}
|
||||
});
|
||||
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
|
||||
Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
|
||||
if (!missingMods.isEmpty())
|
||||
{
|
||||
FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
|
||||
for (String modid : missingMods)
|
||||
{
|
||||
versionMissingMods.add(names.get(modid));
|
||||
}
|
||||
throw new MissingModsException(versionMissingMods);
|
||||
}
|
||||
ImmutableList<ArtifactVersion> allDeps = ImmutableList.<ArtifactVersion>builder().addAll(mod.getDependants()).addAll(mod.getDependencies()).build();
|
||||
for (ArtifactVersion v : allDeps)
|
||||
{
|
||||
@@ -187,21 +227,32 @@ public class Loader
|
||||
{
|
||||
if (!v.containsVersion(modVersions.get(v.getLabel())))
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "The mod %s (%s) requires mods %s to be available, one or more are not", mod.getModId(), mod.getName(), allDeps);
|
||||
throw new LoaderException();
|
||||
versionMissingMods.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!versionMissingMods.isEmpty())
|
||||
{
|
||||
FMLLog.severe("The mod %s (%s) requires mod versions %s to be available", mod.getModId(), mod.getName(), versionMissingMods);
|
||||
throw new MissingModsException(versionMissingMods);
|
||||
}
|
||||
}
|
||||
|
||||
FMLLog.fine("All mod requirements are satisfied");
|
||||
|
||||
ModSorter sorter = new ModSorter(mods, namedMods);
|
||||
ModSorter sorter = new ModSorter(getActiveModList(), namedMods);
|
||||
|
||||
try
|
||||
{
|
||||
FMLLog.fine("Sorting mods into an ordered list");
|
||||
mods = sorter.sort();
|
||||
List<ModContainer> sortedMods = sorter.sort();
|
||||
// Reset active list to the sorted list
|
||||
modController.getActiveModList().clear();
|
||||
modController.getActiveModList().addAll(sortedMods);
|
||||
// And inject the sorted list into the overall list
|
||||
mods.removeAll(sortedMods);
|
||||
sortedMods.addAll(mods);
|
||||
mods = sortedMods;
|
||||
FMLLog.fine("Mod sorting completed successfully");
|
||||
}
|
||||
catch (ModSortingException sortException)
|
||||
@@ -216,11 +267,11 @@ public class Loader
|
||||
finally
|
||||
{
|
||||
FMLLog.fine("Mod sorting data:");
|
||||
for (ModContainer mod : mods)
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
if (!mod.isImmutable())
|
||||
{
|
||||
FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules());
|
||||
FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), mod.getSortingRules());
|
||||
}
|
||||
}
|
||||
if (mods.size()==0)
|
||||
@@ -255,6 +306,8 @@ public class Loader
|
||||
private ModDiscoverer identifyMods()
|
||||
{
|
||||
FMLLog.fine("Building injected Mod Containers %s", injectedContainers);
|
||||
// Add in the MCP mod container
|
||||
mods.add(new InjectedModContainer(mcp,new File("minecraft.jar")));
|
||||
File coremod = new File(minecraftDir,"coremods");
|
||||
for (String cont : injectedContainers)
|
||||
{
|
||||
@@ -279,11 +332,49 @@ public class Loader
|
||||
discoverer.findModDirMods(canonicalModsDir);
|
||||
|
||||
mods.addAll(discoverer.identifyMods());
|
||||
identifyDuplicates(mods);
|
||||
namedMods = Maps.uniqueIndex(mods, new ModIdFunction());
|
||||
FMLLog.info("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 1 ? "s" : "");
|
||||
return discoverer;
|
||||
}
|
||||
|
||||
private class ModIdComparator implements Comparator<ModContainer>
|
||||
{
|
||||
@Override
|
||||
public int compare(ModContainer o1, ModContainer o2)
|
||||
{
|
||||
return o1.getModId().compareTo(o2.getModId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void identifyDuplicates(List<ModContainer> mods)
|
||||
{
|
||||
TreeMultimap<ModContainer, File> dupsearch = TreeMultimap.create(new ModIdComparator(), Ordering.arbitrary());
|
||||
for (ModContainer mc : mods)
|
||||
{
|
||||
if (mc.getSource() != null)
|
||||
{
|
||||
dupsearch.put(mc, mc.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableMultiset<ModContainer> duplist = Multisets.copyHighestCountFirst(dupsearch.keys());
|
||||
SetMultimap<ModContainer, File> dupes = LinkedHashMultimap.create();
|
||||
for (Entry<ModContainer> e : duplist.entrySet())
|
||||
{
|
||||
if (e.getCount() > 1)
|
||||
{
|
||||
FMLLog.severe("Found a duplicate mod %s at %s", e.getElement().getModId(), dupsearch.get(e.getElement()));
|
||||
dupes.putAll(e.getElement(),dupsearch.get(e.getElement()));
|
||||
}
|
||||
}
|
||||
if (!dupes.isEmpty())
|
||||
{
|
||||
throw new DuplicateModsFoundException(dupes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@@ -348,12 +439,12 @@ public class Loader
|
||||
|
||||
public List<ModContainer> getModList()
|
||||
{
|
||||
return ImmutableList.copyOf(instance().mods);
|
||||
return instance().mods != null ? ImmutableList.copyOf(instance().mods) : ImmutableList.<ModContainer>of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the hook to start mod loading. We trigger the
|
||||
* {@link #identifyMods()} and {@link #preModInit()} phases here. Finally,
|
||||
* {@link #identifyMods()} and Constructing, Preinitalization, and Initalization phases here. Finally,
|
||||
* the mod list is frozen completely and is consider immutable from then on.
|
||||
*/
|
||||
public void loadMods()
|
||||
@@ -365,11 +456,31 @@ public class Loader
|
||||
modController.transition(LoaderState.LOADING);
|
||||
ModDiscoverer disc = identifyMods();
|
||||
disableRequestedMods();
|
||||
modController.distributeStateMessage(FMLLoadEvent.class);
|
||||
sortModList();
|
||||
mods = ImmutableList.copyOf(mods);
|
||||
modController.distributeStateMessage(FMLLoadEvent.class);
|
||||
for (File nonMod : disc.getNonModLibs())
|
||||
{
|
||||
if (nonMod.isFile())
|
||||
{
|
||||
FMLLog.info("FML has found a non-mod file %s in your mods directory. It will now be injected into your classpath. This could severe stability issues, it should be removed if possible.", nonMod.getName());
|
||||
try
|
||||
{
|
||||
modClassLoader.addFile(nonMod);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Encountered a weird problem with non-mod file injection : %s", nonMod.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
modController.transition(LoaderState.CONSTRUCTING);
|
||||
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, disc.getASMTable());
|
||||
FMLLog.fine("Mod signature data:");
|
||||
for (ModContainer mod : getActiveModList())
|
||||
{
|
||||
FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), CertificateHelper.getFingerprint(mod.getSigningCertificate()));
|
||||
}
|
||||
modController.transition(LoaderState.PREINITIALIZATION);
|
||||
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, disc.getASMTable(), canonicalConfigDir);
|
||||
modController.transition(LoaderState.INITIALIZATION);
|
||||
@@ -377,30 +488,30 @@ public class Loader
|
||||
|
||||
private void disableRequestedMods()
|
||||
{
|
||||
String disabledModList = System.getProperty("fml.modStates", "");
|
||||
FMLLog.fine("Received a system property request \'%s\'",disabledModList);
|
||||
String forcedModList = System.getProperty("fml.modStates", "");
|
||||
FMLLog.fine("Received a system property request \'%s\'",forcedModList);
|
||||
Map<String, String> sysPropertyStateList = Splitter.on(CharMatcher.anyOf(";:"))
|
||||
.omitEmptyStrings().trimResults().withKeyValueSeparator("=")
|
||||
.split(disabledModList);
|
||||
.split(forcedModList);
|
||||
FMLLog.fine("System property request managing the state of %d mods", sysPropertyStateList.size());
|
||||
Map<String, String> modStates = Maps.newHashMap();
|
||||
|
||||
File disabledModFile = new File(canonicalConfigDir, "fmlModState.properties");
|
||||
Properties disabledModListProperties = new Properties();
|
||||
if (disabledModFile.exists() && disabledModFile.isFile())
|
||||
File forcedModFile = new File(canonicalConfigDir, "fmlModState.properties");
|
||||
Properties forcedModListProperties = new Properties();
|
||||
if (forcedModFile.exists() && forcedModFile.isFile())
|
||||
{
|
||||
FMLLog.fine("Found a mod state file %s", disabledModFile.getName());
|
||||
FMLLog.fine("Found a mod state file %s", forcedModFile.getName());
|
||||
try
|
||||
{
|
||||
disabledModListProperties.load(new FileReader(disabledModFile));
|
||||
FMLLog.fine("Loaded states for %d mods from file", disabledModListProperties.size());
|
||||
forcedModListProperties.load(new FileReader(forcedModFile));
|
||||
FMLLog.fine("Loaded states for %d mods from file", forcedModListProperties.size());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.INFO, e, "An error occurred reading the fmlModState.properties file");
|
||||
}
|
||||
}
|
||||
modStates.putAll(Maps.fromProperties(disabledModListProperties));
|
||||
modStates.putAll(Maps.fromProperties(forcedModListProperties));
|
||||
modStates.putAll(sysPropertyStateList);
|
||||
FMLLog.fine("After merging, found state information for %d mods", modStates.size());
|
||||
|
||||
@@ -408,7 +519,7 @@ public class Loader
|
||||
{
|
||||
public Boolean apply(String input)
|
||||
{
|
||||
return !Boolean.parseBoolean(input);
|
||||
return Boolean.parseBoolean(input);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -426,16 +537,13 @@ public class Loader
|
||||
* Query if we know of a mod named modname
|
||||
*
|
||||
* @param modname
|
||||
* @return
|
||||
* @return If the mod is loaded
|
||||
*/
|
||||
public static boolean isModLoaded(String modname)
|
||||
{
|
||||
return instance().namedMods.containsKey(modname);
|
||||
return instance().namedMods.containsKey(modname) && instance().modController.getModState(instance.namedMods.get(modname))!=ModState.DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public File getConfigDir()
|
||||
{
|
||||
return canonicalConfigDir;
|
||||
@@ -454,23 +562,17 @@ public class Loader
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getFMLVersionString()
|
||||
{
|
||||
return String.format("FML v%s.%s.%s.%s", major, minor, rev, build);
|
||||
return String.format("%s.%s.%s.%s", major, minor, rev, build);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public ClassLoader getModClassLoader()
|
||||
{
|
||||
return modClassLoader;
|
||||
}
|
||||
|
||||
public void computeDependencies(String dependencyString, List<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
|
||||
public void computeDependencies(String dependencyString, Set<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
|
||||
{
|
||||
if (dependencyString == null || dependencyString.length() == 0)
|
||||
{
|
||||
@@ -553,26 +655,33 @@ public class Loader
|
||||
// Mod controller should be in the initialization state here
|
||||
modController.distributeStateMessage(LoaderState.INITIALIZATION);
|
||||
modController.transition(LoaderState.POSTINITIALIZATION);
|
||||
modController.distributeStateMessage(FMLInterModComms.IMCEvent.class);
|
||||
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
|
||||
modController.transition(LoaderState.AVAILABLE);
|
||||
modController.distributeStateMessage(LoaderState.AVAILABLE);
|
||||
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size()==1 ? "" : "s");
|
||||
}
|
||||
|
||||
public Callable getCallableCrashInformation()
|
||||
public ICrashCallable getCallableCrashInformation()
|
||||
{
|
||||
return new Callable<String>() {
|
||||
return new ICrashCallable() {
|
||||
@Override
|
||||
public String call() throws Exception
|
||||
{
|
||||
return getCrashInformation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
return "FML";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public List<ModContainer> getActiveModList()
|
||||
{
|
||||
return modController.getActiveModList();
|
||||
return modController != null ? modController.getActiveModList() : ImmutableList.<ModContainer>of();
|
||||
}
|
||||
|
||||
public ModState getModState(ModContainer selectedMod)
|
||||
@@ -614,4 +723,27 @@ public class Loader
|
||||
{
|
||||
return getModObjectList().inverse();
|
||||
}
|
||||
|
||||
public ModContainer activeModContainer()
|
||||
{
|
||||
return modController != null ? modController.activeContainer() : null;
|
||||
}
|
||||
|
||||
public boolean isInState(LoaderState state)
|
||||
{
|
||||
return modController.isInState(state);
|
||||
}
|
||||
|
||||
public MinecraftDummyContainer getMinecraftModContainer()
|
||||
{
|
||||
return minecraft;
|
||||
}
|
||||
|
||||
public boolean hasReachedState(LoaderState state) {
|
||||
return modController != null ? modController.hasReachedState(state) : false;
|
||||
}
|
||||
|
||||
public String getMCPVersionString() {
|
||||
return String.format("MCP v%s", mcpversion);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package cpw.mods.fml.common;
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
@@ -59,7 +60,7 @@ public enum LoaderState
|
||||
{
|
||||
return eventClass != null;
|
||||
}
|
||||
|
||||
|
||||
public FMLStateEvent getEvent(Object... eventData)
|
||||
{
|
||||
try
|
||||
@@ -87,7 +88,7 @@ public enum LoaderState
|
||||
AVAILABLE("Available"),
|
||||
DISABLED("Disabled"),
|
||||
ERRORED("Errored");
|
||||
|
||||
|
||||
private String label;
|
||||
|
||||
private ModState(String label)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
public class MCPDummyContainer extends DummyModContainer {
|
||||
public MCPDummyContainer(ModMetadata metadata) {
|
||||
super(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import argo.jdom.JdomParser;
|
||||
import argo.jdom.JsonNode;
|
||||
@@ -14,7 +11,6 @@ import argo.jdom.JsonRootNode;
|
||||
import argo.saj.InvalidSyntaxException;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class MetadataCollection
|
||||
@@ -23,13 +19,13 @@ public class MetadataCollection
|
||||
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
|
||||
private int metadataVersion = 1;
|
||||
|
||||
public static MetadataCollection from(InputStream inputStream)
|
||||
public static MetadataCollection from(InputStream inputStream, String sourceName)
|
||||
{
|
||||
if (inputStream == null)
|
||||
{
|
||||
return new MetadataCollection();
|
||||
}
|
||||
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(inputStream);
|
||||
try
|
||||
{
|
||||
@@ -43,6 +39,11 @@ public class MetadataCollection
|
||||
return parseModInfo(root);
|
||||
}
|
||||
}
|
||||
catch (InvalidSyntaxException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "The mcmod.info file in %s cannot be parsed as valid JSON. It will be ignored", sourceName);
|
||||
return new MetadataCollection();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw Throwables.propagate(e);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class MinecraftDummyContainer extends DummyModContainer
|
||||
{
|
||||
|
||||
private VersionRange staticRange;
|
||||
public MinecraftDummyContainer(String actualMCVersion)
|
||||
{
|
||||
super(new ModMetadata());
|
||||
getMetadata().modId = "Minecraft";
|
||||
getMetadata().name = "Minecraft";
|
||||
getMetadata().version = actualMCVersion;
|
||||
staticRange = VersionParser.parseRange("["+actualMCVersion+"]");
|
||||
}
|
||||
|
||||
|
||||
public VersionRange getStaticVersionRange()
|
||||
{
|
||||
return staticRange;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class MissingModsException extends RuntimeException
|
||||
{
|
||||
|
||||
public Set<ArtifactVersion> missingMods;
|
||||
|
||||
public MissingModsException(Set<ArtifactVersion> missingMods)
|
||||
{
|
||||
this.missingMods = missingMods;
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,10 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartedEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
|
||||
import net.minecraft.src.ItemBlock;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage;
|
||||
|
||||
/**
|
||||
* The new mod style in FML 1.3
|
||||
@@ -39,31 +35,91 @@ public @interface Mod
|
||||
{
|
||||
/**
|
||||
* The unique mod identifier for this mod
|
||||
* @return
|
||||
*/
|
||||
String modid();
|
||||
/**
|
||||
* A user friendly name for the mod
|
||||
* @return
|
||||
*/
|
||||
String name() default "";
|
||||
/**
|
||||
* A version string for this mod
|
||||
* @return
|
||||
*/
|
||||
String version() default "";
|
||||
/**
|
||||
* A simple dependency string for this mod (see modloader's "priorities" string specification)
|
||||
* @return
|
||||
*/
|
||||
String dependencies() default "";
|
||||
/**
|
||||
* Whether to use the mcmod.info metadata by default for this mod.
|
||||
* If true, settings in the mcmod.info file will override settings in these annotations.
|
||||
* @return
|
||||
*/
|
||||
boolean useMetadata() default false;
|
||||
|
||||
/**
|
||||
* The acceptable range of minecraft versions that this mod will load and run in
|
||||
* The default ("empty string") indicates that only the current minecraft version is acceptable.
|
||||
* FML will refuse to run with an error if the minecraft version is not in this range across all mods.
|
||||
* @return A version range as specified by the maven version range specification or the empty string
|
||||
*/
|
||||
String acceptedMinecraftVersions() default "";
|
||||
/**
|
||||
* 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.
|
||||
* @return The name of the plugin to load for this mod
|
||||
*/
|
||||
String bukkitPlugin() default "";
|
||||
/**
|
||||
* 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.
|
||||
* Entries can be prefixed with a + for a positive exclusion assertion, or - for a negative exclusion
|
||||
* assertion. Asterisk is the wildcard and represents <strong>all</strong> mods.
|
||||
*
|
||||
* The <strong>only</strong> mods that cannot be excluded are FML and MCP, trivially.
|
||||
* Other special values:
|
||||
* <ul>
|
||||
* <li>+f indicates that the mod will accept a minecraft forge environment.</li>
|
||||
* <li>-* indicates that the mod will not accept any other mods.</li>
|
||||
* </ul>
|
||||
*
|
||||
* Some examples:
|
||||
* <ul>
|
||||
* <li><em>-*,+f,+IronChest</em>: Will run only in a minecraft forge environment with the mod IronChests.
|
||||
* The -* forces all mods to be excluded, then the +f and +IronChest add into the "allowed list".</li>
|
||||
* <li><em>+f,-IC2</em>: Will run in a minecraft forge environment but will <strong>not</strong> run if
|
||||
* IndustrialCraft 2 (IC2) is loaded alongside.</li>
|
||||
* <li><em>-*</em>: Will not run if <strong>any</strong> othe mod is loaded except MCP/FML itself.</li>
|
||||
* </ul>
|
||||
*
|
||||
* If a mod is present on the excluded list, the game will stop and show an error screen. If the
|
||||
* class containing the {@link Mod} annotation has a "getCustomErrorException" method, it will be
|
||||
* called to retrieve a custom error message for display in this case. If two mods have a declared
|
||||
* exclusion which is matched, the screen that is shown is indeterminate.
|
||||
*
|
||||
* @return A string listing modids to exclude from loading with this mod.
|
||||
*/
|
||||
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>.
|
||||
*
|
||||
* @return A certificate fingerprint that is expected for this mod.
|
||||
*/
|
||||
String certificateFingerprint() default "";
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface FingerprintWarning {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "pre-initialization" phase
|
||||
* @author cpw
|
||||
@@ -97,7 +153,7 @@ public @interface Mod
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStarting {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* Mark the designated method as being called at the "server-started" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@@ -105,13 +161,22 @@ public @interface Mod
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStarted {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* Mark the designated method as being called at the "server-stopping" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStopping {}
|
||||
/**
|
||||
* Mark the designated method as the receiver for {@link FMLInterModComms} messages
|
||||
* Called between {@link Init} and {@link PostInit}
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface IMCCallback {}
|
||||
/**
|
||||
* Populate the annotated field with the mod instance.
|
||||
* @author cpw
|
||||
@@ -122,7 +187,6 @@ public @interface Mod
|
||||
public @interface Instance {
|
||||
/**
|
||||
* The mod object to inject into this field
|
||||
* @return
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
@@ -136,7 +200,6 @@ public @interface Mod
|
||||
public @interface Metadata {
|
||||
/**
|
||||
* The mod id specifying the metadata to load here
|
||||
* @return
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
@@ -150,12 +213,10 @@ public @interface Mod
|
||||
public @interface Block {
|
||||
/**
|
||||
* The block's name
|
||||
* @return
|
||||
*/
|
||||
String name();
|
||||
/**
|
||||
* The associated ItemBlock subtype for the item (can be null for an ItemBlock)
|
||||
* @return
|
||||
*/
|
||||
Class<?> itemTypeClass() default ItemBlock.class;
|
||||
}
|
||||
@@ -169,12 +230,10 @@ public @interface Mod
|
||||
public @interface Item {
|
||||
/**
|
||||
* The name of the item
|
||||
* @return
|
||||
*/
|
||||
String name();
|
||||
/**
|
||||
* The type of the item
|
||||
* @return
|
||||
*/
|
||||
String typeClass();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
@@ -24,8 +23,9 @@ import java.util.logging.Level;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ModCandidate;
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.common.asm.ASMTransformer;
|
||||
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
/**
|
||||
@@ -79,4 +79,11 @@ public class ModClassLoader extends URLClassLoader
|
||||
{
|
||||
return STANDARD_LIBRARIES;
|
||||
}
|
||||
|
||||
public Class<? extends BaseModProxy> loadBaseModClass(String modClazzName) throws Exception
|
||||
{
|
||||
AccessTransformer transformer = (AccessTransformer)mainClassLoader.getTransformers().get(0);
|
||||
transformer.ensurePublicAccessFor(modClazzName);
|
||||
return (Class<? extends BaseModProxy>) Class.forName(modClazzName, true, this);
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,14 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
/**
|
||||
* The container that wraps around mods in the system.
|
||||
@@ -38,66 +40,48 @@ public interface ModContainer
|
||||
{
|
||||
/**
|
||||
* The globally unique modid for this mod
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getModId();
|
||||
|
||||
/**
|
||||
* A human readable name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* A human readable version identifier
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* The location on the file system which this mod came from
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
File getSource();
|
||||
|
||||
/**
|
||||
* The metadata for this mod
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
ModMetadata getMetadata();
|
||||
|
||||
/**
|
||||
* Attach this mod to it's metadata from the supplied metadata collection
|
||||
*
|
||||
* @param mc
|
||||
*/
|
||||
void bindMetadata(MetadataCollection mc);
|
||||
|
||||
/**
|
||||
* Set the enabled/disabled state of this mod
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
void setEnabledState(boolean enabled);
|
||||
|
||||
/**
|
||||
* A list of the modids that this mod requires loaded prior to loading
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ArtifactVersion> getRequirements();
|
||||
Set<ArtifactVersion> getRequirements();
|
||||
|
||||
/**
|
||||
* A list of modids that should be loaded prior to this one. The special
|
||||
* value <strong>*</strong> indicates to load <em>before</em> any other mod.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ArtifactVersion> getDependencies();
|
||||
|
||||
@@ -105,16 +89,12 @@ public interface ModContainer
|
||||
* A list of modids that should be loaded <em>after</em> this one. The
|
||||
* special value <strong>*</strong> indicates to load <em>after</em> any
|
||||
* other mod.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<ArtifactVersion> getDependants();
|
||||
|
||||
/**
|
||||
* A representative string encapsulating the sorting preferences for this
|
||||
* mod
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getSortingRules();
|
||||
|
||||
@@ -126,7 +106,6 @@ public interface ModContainer
|
||||
*
|
||||
* @param bus
|
||||
* @param controller
|
||||
* @return
|
||||
*/
|
||||
boolean registerBus(EventBus bus, LoadController controller);
|
||||
|
||||
@@ -134,14 +113,11 @@ public interface ModContainer
|
||||
* Does this mod match the supplied mod
|
||||
*
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
boolean matches(Object mod);
|
||||
|
||||
/**
|
||||
* Get the actual mod object
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object getMod();
|
||||
|
||||
@@ -150,4 +126,10 @@ public interface ModContainer
|
||||
boolean isImmutable();
|
||||
|
||||
boolean isNetworkMod();
|
||||
|
||||
String getDisplayVersion();
|
||||
|
||||
VersionRange acceptableMinecraftVersionRange();
|
||||
|
||||
Certificate getSigningCertificate();
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ModCandidate;
|
||||
import cpw.mods.fml.common.discovery.asm.ASMModParser;
|
||||
import cpw.mods.fml.common.discovery.asm.ModAnnotation;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
@@ -16,20 +17,38 @@ public class ModContainerFactory
|
||||
public static ModContainerFactory instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
public ModContainer build(ASMModParser modParser, File modSource)
|
||||
public ModContainer build(ASMModParser modParser, File modSource, ModCandidate container)
|
||||
{
|
||||
String className = modParser.getASMType().getClassName();
|
||||
if (modParser.isBaseMod() && modClass.matcher(className).find())
|
||||
if (modParser.isBaseMod(container.getRememberedBaseMods()) && modClass.matcher(className).find())
|
||||
{
|
||||
FMLLog.fine("Identified a BaseMod type mod %s", className);
|
||||
return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties());
|
||||
}
|
||||
else if (modClass.matcher(className).find())
|
||||
{
|
||||
FMLLog.fine("Identified a class %s following modloader naming convention but not directly a BaseMod or currently seen subclass", className);
|
||||
container.rememberModCandidateType(modParser);
|
||||
}
|
||||
else if (modParser.isBaseMod(container.getRememberedBaseMods()))
|
||||
{
|
||||
FMLLog.fine("Found a basemod %s of non-standard naming format", className);
|
||||
container.rememberBaseModType(className);
|
||||
}
|
||||
|
||||
// We warn if it's not a basemod instance -- compatibility requires it to be in net.minecraft.src *sigh*
|
||||
if (className.startsWith("net.minecraft.src.") && container.isClasspath() && !container.isMinecraftJar())
|
||||
{
|
||||
FMLLog.severe("FML has detected a mod that is using a package name based on 'net.minecraft.src' : %s. This is generally a severe programming error. "
|
||||
+ " There should be no mod code in the minecraft namespace. MOVE YOUR MOD! If you're in eclipse, select your source code and 'refactor' it into "
|
||||
+ "a new package. Go on. DO IT NOW!",className);
|
||||
}
|
||||
|
||||
for (ModAnnotation ann : modParser.getAnnotations())
|
||||
{
|
||||
if (ann.getASMType().equals(Type.getType(Mod.class)))
|
||||
{
|
||||
FMLLog.fine("Identified a FMLMod type mod %s", className);
|
||||
FMLLog.fine("Identified an FMLMod type mod %s", className);
|
||||
return new FMLModContainer(className, modSource, ann.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import static argo.jdom.JsonNodeBuilders.aStringBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import argo.jdom.JsonNode;
|
||||
import argo.jdom.JsonStringNode;
|
||||
@@ -35,12 +36,9 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.functions.ModNameFunction;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
|
||||
import static argo.jdom.JsonNodeBuilders.*;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
@@ -88,19 +86,20 @@ public class ModMetadata
|
||||
public List<ModContainer> childMods = Lists.newArrayList();
|
||||
|
||||
public boolean useDependencyInformation;
|
||||
public List<ArtifactVersion> requiredMods;
|
||||
public Set<ArtifactVersion> requiredMods;
|
||||
public List<ArtifactVersion> dependencies;
|
||||
public List<ArtifactVersion> dependants;
|
||||
public boolean autogenerated;
|
||||
|
||||
/**
|
||||
* @param mod2
|
||||
* @param type2
|
||||
*/
|
||||
public ModMetadata(JsonNode node)
|
||||
{
|
||||
Map<JsonStringNode, Object> processedFields = Maps.transformValues(node.getFields(), new JsonStringConverter());
|
||||
modId = (String)processedFields.get(aStringBuilder("modid"));
|
||||
if (Strings.isNullOrEmpty(modId))
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "Found an invalid mod metadata file - missing modid");
|
||||
throw new LoaderException();
|
||||
}
|
||||
name = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("name")));
|
||||
description = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("description")));
|
||||
url = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("url")));
|
||||
@@ -109,10 +108,10 @@ public class ModMetadata
|
||||
version = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("version")));
|
||||
credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
|
||||
parent = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
|
||||
authorList = Optional.fromNullable((List<String>)processedFields.get(aStringBuilder("authorList"))).or(authorList);
|
||||
requiredMods = processReferences((List<String>)processedFields.get(aStringBuilder("requiredMods")));
|
||||
dependencies = processReferences((List<String>)processedFields.get(aStringBuilder("dependencies")));
|
||||
dependants = processReferences((List<String>)processedFields.get(aStringBuilder("dependants")));
|
||||
authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
|
||||
requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), HashSet.class);
|
||||
dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), ArrayList.class);
|
||||
dependants = processReferences(processedFields.get(aStringBuilder("dependants")), ArrayList.class);
|
||||
useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
|
||||
}
|
||||
|
||||
@@ -120,22 +119,29 @@ public class ModMetadata
|
||||
{
|
||||
}
|
||||
|
||||
private List<ArtifactVersion> processReferences(List<String> refs)
|
||||
private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
|
||||
{
|
||||
List<ArtifactVersion> res = Lists.newArrayList();
|
||||
T res = null;
|
||||
try
|
||||
{
|
||||
res = retType.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// unpossible
|
||||
}
|
||||
|
||||
if (refs == null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
for (String ref : refs)
|
||||
for (String ref : ((List<String>)refs))
|
||||
{
|
||||
res.add(VersionParser.parseVersionReference(ref));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
||||
public String getChildModCountString()
|
||||
{
|
||||
return String.format("%d child mod%s", childMods.size(), childMods.size() != 1 ? "s" : "");
|
||||
@@ -146,9 +152,6 @@ public class ModMetadata
|
||||
return Joiner.on(", ").join(authorList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getChildModList()
|
||||
{
|
||||
return Joiner.on(", ").join(Lists.transform(childMods, new ModNameFunction()));
|
||||
@@ -156,6 +159,6 @@ public class ModMetadata
|
||||
|
||||
public String printableSortingRules()
|
||||
{
|
||||
return null;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,9 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
|
||||
@@ -29,13 +29,11 @@ public @interface SidedProxy
|
||||
{
|
||||
/**
|
||||
* The name of the client side class to load and populate
|
||||
* @return
|
||||
*/
|
||||
String clientSide() default "";
|
||||
|
||||
/**
|
||||
* The name of the server side class to load and populate
|
||||
* @return
|
||||
*/
|
||||
String serverSide() default "";
|
||||
|
||||
|
||||
@@ -69,8 +69,6 @@ public enum TickType {
|
||||
|
||||
/**
|
||||
* Partner ticks that are also cancelled by returning false from onTickInGame
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public EnumSet<TickType> partnerTicks()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.world.storage.*;
|
||||
|
||||
|
||||
public interface WorldAccessContainer
|
||||
{
|
||||
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info);
|
||||
public void readData(SaveHandler handler, WorldInfo info, Map<String,NBTBase> propertyMap, NBTTagCompound tag);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
public class WrongMinecraftVersionException extends RuntimeException
|
||||
{
|
||||
|
||||
public ModContainer mod;
|
||||
|
||||
public WrongMinecraftVersionException(ModContainer mod)
|
||||
{
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,22 @@
|
||||
package cpw.mods.fml.common.asm;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.ObjectInputStream.GetField;
|
||||
import java.io.StringReader;
|
||||
import java.net.JarURLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.CodeSource;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathValidator;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.PKIXCertPathValidatorResult;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
@@ -9,12 +26,15 @@ import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.common.CertificateHelper;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
public class FMLSanityChecker implements IFMLCallHook
|
||||
{
|
||||
private static final String FMLFINGERPRINT = "AE:F6:54:79:96:E9:1B:D1:59:70:6C:B4:6B:F5:4A:89:C5:CE:08:1D".toLowerCase().replace(":","");
|
||||
private static final String FORGEFINGERPRINT = "DE:4C:F8:A3:F3:BC:15:63:58:10:04:4C:39:24:0B:F9:68:04:EA:7D".toLowerCase().replace(":", "");
|
||||
static class MLDetectorClassVisitor extends ClassVisitor
|
||||
{
|
||||
private boolean foundMarker = false;
|
||||
@@ -39,6 +59,42 @@ public class FMLSanityChecker implements IFMLCallHook
|
||||
@Override
|
||||
public Void call() throws Exception
|
||||
{
|
||||
CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
|
||||
boolean goodFML = false;
|
||||
if (codeSource.getLocation().getProtocol().equals("jar"))
|
||||
{
|
||||
Certificate[] certificates = codeSource.getCertificates();
|
||||
if (certificates!=null)
|
||||
{
|
||||
|
||||
for (Certificate cert : certificates)
|
||||
{
|
||||
String fingerprint = CertificateHelper.getFingerprint(cert);
|
||||
if (fingerprint.equals(FMLFINGERPRINT))
|
||||
{
|
||||
FMLLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint);
|
||||
goodFML = true;
|
||||
}
|
||||
else if (fingerprint.equals(FORGEFINGERPRINT))
|
||||
{
|
||||
FMLLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint);
|
||||
goodFML = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("Found invalid fingerprint for FML: %s", fingerprint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goodFML = true;
|
||||
}
|
||||
if (!goodFML)
|
||||
{
|
||||
FMLLog.severe("FML appears to be missing any signature data. This is not a good thing");
|
||||
}
|
||||
byte[] mlClass = cl.getClassBytes("ModLoader");
|
||||
// Only care in obfuscated env
|
||||
if (mlClass == null)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package cpw.mods.fml.common.asm;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Used to force certain classes to reobfuscate
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface ReobfuscationMarker {
|
||||
|
||||
}
|
||||
@@ -1,27 +1,20 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
@@ -29,15 +22,12 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -49,6 +39,7 @@ import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
private static final boolean DEBUG = false;
|
||||
private class Modifier
|
||||
{
|
||||
public String name = "";
|
||||
@@ -58,13 +49,14 @@ public class AccessTransformer implements IClassTransformer
|
||||
public int targetAccess = 0;
|
||||
public boolean changeFinal = false;
|
||||
public boolean markFinal = false;
|
||||
protected boolean modifyClassVisibility;
|
||||
|
||||
private void setTargetAccess(String name)
|
||||
{
|
||||
if (name.startsWith("public")) targetAccess = ACC_PUBLIC;
|
||||
else if (name.startsWith("private")) targetAccess = ACC_PRIVATE;
|
||||
else if (name.startsWith("protected")) targetAccess = ACC_PROTECTED;
|
||||
|
||||
|
||||
if (name.endsWith("-f"))
|
||||
{
|
||||
changeFinal = true;
|
||||
@@ -118,25 +110,32 @@ public class AccessTransformer implements IClassTransformer
|
||||
return true;
|
||||
}
|
||||
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
|
||||
if (parts.size()>2 || parts.get(1).indexOf('.') == -1)
|
||||
if (parts.size()>2)
|
||||
{
|
||||
throw new RuntimeException("Invalid config file line "+ input);
|
||||
}
|
||||
Modifier m = new Modifier();
|
||||
m.setTargetAccess(parts.get(0));
|
||||
List<String> descriptor = Lists.newArrayList(Splitter.on(".").trimResults().split(parts.get(1)));
|
||||
String nameReference = descriptor.get(1);
|
||||
int parenIdx = nameReference.indexOf('(');
|
||||
if (parenIdx>0)
|
||||
if (descriptor.size() == 1)
|
||||
{
|
||||
m.desc = nameReference.substring(parenIdx);
|
||||
m.name = nameReference.substring(0,parenIdx);
|
||||
m.modifyClassVisibility = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.name = nameReference;
|
||||
String nameReference = descriptor.get(1);
|
||||
int parenIdx = nameReference.indexOf('(');
|
||||
if (parenIdx>0)
|
||||
{
|
||||
m.desc = nameReference.substring(parenIdx);
|
||||
m.name = nameReference.substring(0,parenIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.name = nameReference;
|
||||
}
|
||||
}
|
||||
modifiers.put(descriptor.get(0), m);
|
||||
modifiers.put(descriptor.get(0).replace('/', '.'), m);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -146,6 +145,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
if (!modifiers.containsKey(name)) { return bytes; }
|
||||
|
||||
ClassNode classNode = new ClassNode();
|
||||
@@ -155,16 +155,31 @@ public class AccessTransformer implements IClassTransformer
|
||||
Collection<Modifier> mods = modifiers.get(name);
|
||||
for (Modifier m : mods)
|
||||
{
|
||||
if (m.modifyClassVisibility)
|
||||
{
|
||||
classNode.access = getFixedAccess(classNode.access, m);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (m.desc.isEmpty())
|
||||
{
|
||||
for (FieldNode n : (List<FieldNode>) classNode.fields)
|
||||
{
|
||||
if (n.name.equals(m.name))
|
||||
if (n.name.equals(m.name) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
System.out.println(String.format("Field: %s.%s %s -> %s", name, m.name, Integer.toBinaryString(m.oldAccess),
|
||||
Integer.toBinaryString(m.newAccess)));
|
||||
break;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Field: %s.%s %s -> %s", name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
}
|
||||
|
||||
if (!m.name.equals("*"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,11 +187,18 @@ public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
for (MethodNode n : (List<MethodNode>) classNode.methods)
|
||||
{
|
||||
if (n.name.equals(m.name) && n.desc.equals(m.desc))
|
||||
if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, m.name, m.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
break;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
|
||||
}
|
||||
|
||||
if (!m.name.equals("*"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +237,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
default:
|
||||
throw new RuntimeException("The fuck?");
|
||||
}
|
||||
|
||||
|
||||
// Clear the "final" marker on fields only if specified in control field
|
||||
if (target.changeFinal && target.desc == "")
|
||||
{
|
||||
@@ -237,7 +259,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
if (args.length < 2)
|
||||
{
|
||||
System.out.println("Usage: AccessTransformer <JarPath> <MapFile> [MapFile2]... ");
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
boolean hasTransformer = false;
|
||||
@@ -259,7 +281,7 @@ public class AccessTransformer implements IClassTransformer
|
||||
if (!hasTransformer)
|
||||
{
|
||||
System.out.println("Culd not find a valid transformer to perform");
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File orig = new File(args[0]);
|
||||
@@ -267,13 +289,13 @@ public class AccessTransformer implements IClassTransformer
|
||||
if (!orig.exists() && !temp.exists())
|
||||
{
|
||||
System.out.println("Could not find target jar: " + orig);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!orig.renameTo(temp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + orig + " -> " + temp);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -283,8 +305,9 @@ public class AccessTransformer implements IClassTransformer
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (!temp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + temp);
|
||||
@@ -386,4 +409,11 @@ public class AccessTransformer implements IClassTransformer
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ensurePublicAccessFor(String modClazzName)
|
||||
{
|
||||
Modifier m = new Modifier();
|
||||
m.setTargetAccess("public");
|
||||
m.modifyClassVisibility = true;
|
||||
modifiers.put(modClazzName, m);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,42 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class MCPMerger
|
||||
{
|
||||
@@ -25,13 +45,15 @@ public class MCPMerger
|
||||
private static Hashtable<String, ClassInfo> servers = new Hashtable<String, ClassInfo>();
|
||||
private static HashSet<String> copyToServer = new HashSet<String>();
|
||||
private static HashSet<String> copyToClient = new HashSet<String>();
|
||||
private static HashSet<String> dontAnnotate = new HashSet<String>();
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length != 3)
|
||||
{
|
||||
System.out.println("Usage: AccessTransformer <MapFile> <minecraft.jar> <minecraft_server.jar>");
|
||||
return;
|
||||
System.out.println("Usage: MCPMerger <MapFile> <minecraft.jar> <minecraft_server.jar>");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File map_file = new File(args[0]);
|
||||
@@ -54,31 +76,31 @@ public class MCPMerger
|
||||
if (!client_jar.exists())
|
||||
{
|
||||
System.out.println("Could not find minecraft.jar: " + client_jar);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!server_jar.exists())
|
||||
{
|
||||
System.out.println("Could not find minecraft_server.jar: " + server_jar);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!client_jar.renameTo(client_jar_tmp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!server_jar.renameTo(server_jar_tmp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!readMapFile(map_file))
|
||||
{
|
||||
System.out.println("Could not read map file: " + map_file);
|
||||
return;
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -88,6 +110,7 @@ public class MCPMerger
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!client_jar_tmp.delete())
|
||||
@@ -112,10 +135,16 @@ public class MCPMerger
|
||||
String line;
|
||||
while ((line = br.readLine()) != null)
|
||||
{
|
||||
boolean toClient = line.charAt(0) == '<';
|
||||
line = line.substring(1);
|
||||
if (toClient) copyToClient.add(line);
|
||||
else copyToServer.add(line);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
in.close();
|
||||
@@ -157,6 +186,8 @@ public class MCPMerger
|
||||
}
|
||||
Hashtable<String, ZipEntry> cClasses = getClassEntries(cInJar, cOutJar);
|
||||
Hashtable<String, ZipEntry> sClasses = getClassEntries(sInJar, sOutJar);
|
||||
HashSet<String> cAdded = new HashSet<String>();
|
||||
HashSet<String> sAdded = new HashSet<String>();
|
||||
|
||||
for (Entry<String, ZipEntry> entry : cClasses.entrySet())
|
||||
{
|
||||
@@ -168,12 +199,18 @@ public class MCPMerger
|
||||
{
|
||||
if (!copyToServer.contains(name))
|
||||
{
|
||||
copyEntry(cInJar, cEntry, cOutJar);
|
||||
copyClass(cInJar, cEntry, cOutJar, null, true);
|
||||
cAdded.add(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Copy class c->s : " + name);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println("Copy class c->s : " + name);
|
||||
}
|
||||
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
|
||||
cAdded.add(name);
|
||||
sAdded.add(name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -191,28 +228,34 @@ public class MCPMerger
|
||||
cOutJar.write(data);
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
cAdded.add(name);
|
||||
sAdded.add(name);
|
||||
}
|
||||
|
||||
for (Entry<String, ZipEntry> entry : sClasses.entrySet())
|
||||
{
|
||||
if (!copyToClient.contains(entry.getKey()))
|
||||
{
|
||||
copyEntry(sInJar, entry.getValue(), sOutJar);
|
||||
}
|
||||
else
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println("Copy class s->c : " + entry.getKey());
|
||||
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
|
||||
}
|
||||
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
|
||||
}
|
||||
|
||||
for (String name : new String[]{SideOnly.class.getName(), Side.class.getName()})
|
||||
{
|
||||
String eName = name.replace(".", "/");
|
||||
byte[] data = getClassBytes(name);
|
||||
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
|
||||
cOutJar.putNextEntry(newEntry);
|
||||
cOutJar.write(data);
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
if (!cAdded.contains(eName))
|
||||
{
|
||||
cOutJar.putNextEntry(newEntry);
|
||||
cOutJar.write(data);
|
||||
}
|
||||
if (!sAdded.contains(eName))
|
||||
{
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -245,18 +288,28 @@ public class MCPMerger
|
||||
ClassNode classNode = new ClassNode();
|
||||
|
||||
reader.accept(classNode, 0);
|
||||
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
|
||||
|
||||
if (!dontAnnotate.contains(classNode.name))
|
||||
{
|
||||
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
byte[] data = writer.toByteArray();
|
||||
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(data);
|
||||
outJar2.putNextEntry(newEntry);
|
||||
outJar2.write(data);
|
||||
if (outJar != null)
|
||||
{
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(data);
|
||||
}
|
||||
if (outJar2 != null)
|
||||
{
|
||||
outJar2.putNextEntry(newEntry);
|
||||
outJar2.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
private static AnnotationNode getSideAnn(boolean isClientOnly)
|
||||
@@ -282,7 +335,9 @@ public class MCPMerger
|
||||
String entryName = entry.getName();
|
||||
if (!entryName.endsWith(".class") || entryName.startsWith("."))
|
||||
{
|
||||
copyEntry(inFile, entry, outFile);
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outFile.putNextEntry(newEntry);
|
||||
outFile.write(readEntry(inFile, entry));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -291,12 +346,6 @@ public class MCPMerger
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private static void copyEntry(ZipFile inFile, ZipEntry entry, ZipOutputStream outFile) throws IOException
|
||||
{
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outFile.putNextEntry(newEntry);
|
||||
outFile.write(readEntry(inFile, entry));
|
||||
}
|
||||
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
|
||||
{
|
||||
return readFully(inFile.getInputStream(entry));
|
||||
@@ -444,7 +493,10 @@ public class MCPMerger
|
||||
mw.server = this.server | mw.server;
|
||||
this.client = this.client | mw.client;
|
||||
this.server = this.server | mw.server;
|
||||
System.out.printf(" eq: %s %s\n", this, mw);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf(" eq: %s %s\n", this, mw);
|
||||
}
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
@@ -486,13 +538,19 @@ public class MCPMerger
|
||||
serverName = sM.name;
|
||||
if (!serverName.equals(lastName) && cPos != cLen)
|
||||
{
|
||||
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
MethodWrapper mw = new MethodWrapper(sM);
|
||||
mw.server = true;
|
||||
allMethods.add(mw);
|
||||
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
sPos++;
|
||||
}
|
||||
while (sPos < sLen);
|
||||
@@ -507,13 +565,19 @@ public class MCPMerger
|
||||
clientName = cM.name;
|
||||
if (!clientName.equals(lastName) && sPos != sLen)
|
||||
{
|
||||
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
MethodWrapper mw = new MethodWrapper(cM);
|
||||
mw.client = true;
|
||||
allMethods.add(mw);
|
||||
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
|
||||
}
|
||||
cPos++;
|
||||
}
|
||||
while (cPos < cLen);
|
||||
@@ -524,7 +588,10 @@ public class MCPMerger
|
||||
|
||||
for (MethodWrapper mw : allMethods)
|
||||
{
|
||||
System.out.println(mw);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(mw);
|
||||
}
|
||||
cMethods.add(mw.node);
|
||||
sMethods.add(mw.node);
|
||||
if (mw.server && mw.client)
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
@@ -29,20 +16,14 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.LineProcessor;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
@@ -108,6 +89,7 @@ public class MarkerTransformer implements IClassTransformer
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
if (!markers.containsKey(name)) { return bytes; }
|
||||
|
||||
ClassNode classNode = new ClassNode();
|
||||
|
||||
@@ -11,29 +11,43 @@ import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class SideTransformer implements IClassTransformer
|
||||
{
|
||||
private static String SIDE = FMLRelauncher.side();
|
||||
private static final boolean DEBUG = false;
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
if (remove((List<AnnotationNode>)classNode.visibleAnnotations, SIDE))
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
|
||||
}
|
||||
throw new RuntimeException(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
|
||||
}
|
||||
|
||||
Iterator<FieldNode> fields = classNode.fields.iterator();
|
||||
while(fields.hasNext())
|
||||
{
|
||||
FieldNode field = fields.next();
|
||||
if (remove((List<AnnotationNode>)field.visibleAnnotations, SIDE))
|
||||
{
|
||||
System.out.println("Removing Field: " + field.name);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
|
||||
}
|
||||
fields.remove();
|
||||
}
|
||||
}
|
||||
@@ -43,7 +57,10 @@ public class SideTransformer implements IClassTransformer
|
||||
MethodNode method = methods.next();
|
||||
if (remove((List<AnnotationNode>)method.visibleAnnotations, SIDE))
|
||||
{
|
||||
System.out.println("Removing Method: " + method.name + " " + method.desc);
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
|
||||
}
|
||||
methods.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -10,12 +8,10 @@ import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.ImmutableBiMap.Builder;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
|
||||
@@ -3,17 +3,16 @@ package cpw.mods.fml.common.discovery;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModContainerFactory;
|
||||
@@ -54,12 +53,14 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
|
||||
try
|
||||
{
|
||||
FileInputStream fis = new FileInputStream(metadata);
|
||||
mc = MetadataCollection.from(fis);
|
||||
mc = MetadataCollection.from(fis,modDir.getName());
|
||||
fis.close();
|
||||
FMLLog.fine("Found an mcmod.info file in directory %s", modDir.getName());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
mc = MetadataCollection.from(null);
|
||||
mc = MetadataCollection.from(null,"");
|
||||
FMLLog.fine("No mcmod.info file found in directory %s", modDir.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +87,11 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
|
||||
modParser = new ASMModParser(fis);
|
||||
fis.close();
|
||||
}
|
||||
catch (LoaderException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "There was a problem reading the file %s - probably this is a corrupt file", file.getPath());
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagate(e);
|
||||
@@ -93,7 +99,7 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
|
||||
|
||||
modParser.validate();
|
||||
modParser.sendToTable(table, candidate);
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
|
||||
if (container!=null)
|
||||
{
|
||||
harvestedMods.add(container);
|
||||
|
||||
@@ -2,7 +2,7 @@ package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
@@ -10,6 +10,7 @@ import java.util.zip.ZipFile;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.MetadataCollection;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModContainerFactory;
|
||||
@@ -32,17 +33,36 @@ public class JarDiscoverer implements ITypeDiscoverer
|
||||
if (modInfo != null)
|
||||
{
|
||||
FMLLog.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName());
|
||||
mc = MetadataCollection.from(jar.getInputStream(modInfo));
|
||||
mc = MetadataCollection.from(jar.getInputStream(modInfo), candidate.getModContainer().getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.fine("The mod container %s appears to be missing an mcmod.info file", candidate.getModContainer().getName());
|
||||
mc = MetadataCollection.from(null, "");
|
||||
}
|
||||
for (ZipEntry ze : Collections.list(jar.entries()))
|
||||
{
|
||||
if (ze.getName()!=null && ze.getName().startsWith("__MACOSX"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Matcher match = classFile.matcher(ze.getName());
|
||||
if (match.matches())
|
||||
{
|
||||
ASMModParser modParser = new ASMModParser(jar.getInputStream(ze));
|
||||
ASMModParser modParser;
|
||||
try
|
||||
{
|
||||
modParser = new ASMModParser(jar.getInputStream(ze));
|
||||
}
|
||||
catch (LoaderException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "There was a problem reading the entry %s in the jar %s - probably a corrupt zip", ze.getName(), candidate.getModContainer().getPath());
|
||||
jar.close();
|
||||
throw e;
|
||||
}
|
||||
modParser.validate();
|
||||
modParser.sendToTable(table, candidate);
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
|
||||
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
|
||||
if (container!=null)
|
||||
{
|
||||
table.addContainer(container);
|
||||
@@ -54,7 +74,7 @@ public class JarDiscoverer implements ITypeDiscoverer
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.warning("Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
|
||||
FMLLog.log(Level.WARNING, e, "Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -3,7 +3,11 @@ package cpw.mods.fml.common.discovery;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.asm.ASMModParser;
|
||||
|
||||
|
||||
public class ModCandidate
|
||||
@@ -12,16 +16,20 @@ public class ModCandidate
|
||||
private File modContainer;
|
||||
private ContainerType sourceType;
|
||||
private boolean classpath;
|
||||
private List<String> baseModTypes = Lists.newArrayList();
|
||||
private boolean isMinecraft;
|
||||
private List<ASMModParser> baseModCandidateTypes = Lists.newArrayListWithCapacity(1);
|
||||
|
||||
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType)
|
||||
{
|
||||
this(classPathRoot, modContainer, sourceType, false);
|
||||
this(classPathRoot, modContainer, sourceType, false, false);
|
||||
}
|
||||
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean classpath)
|
||||
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean isMinecraft, boolean classpath)
|
||||
{
|
||||
this.classPathRoot = classPathRoot;
|
||||
this.modContainer = modContainer;
|
||||
this.sourceType = sourceType;
|
||||
this.isMinecraft = isMinecraft;
|
||||
this.classpath = classpath;
|
||||
}
|
||||
|
||||
@@ -41,6 +49,36 @@ public class ModCandidate
|
||||
}
|
||||
public List<ModContainer> explore(ASMDataTable table)
|
||||
{
|
||||
return sourceType.findMods(this, table);
|
||||
List<ModContainer> mods = sourceType.findMods(this, table);
|
||||
if (!baseModCandidateTypes.isEmpty())
|
||||
{
|
||||
FMLLog.info("Attempting to reparse the mod container %s", getModContainer().getName());
|
||||
return sourceType.findMods(this, table);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mods;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isClasspath()
|
||||
{
|
||||
return classpath;
|
||||
}
|
||||
public void rememberBaseModType(String className)
|
||||
{
|
||||
baseModTypes.add(className);
|
||||
}
|
||||
public List<String> getRememberedBaseMods()
|
||||
{
|
||||
return baseModTypes;
|
||||
}
|
||||
public boolean isMinecraftJar()
|
||||
{
|
||||
return isMinecraft;
|
||||
}
|
||||
public void rememberModCandidateType(ASMModParser modParser)
|
||||
{
|
||||
baseModCandidateTypes.add(modParser);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,15 @@
|
||||
package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.common.collect.Tables;
|
||||
import com.google.common.collect.ImmutableTable.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.Table.Cell;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
@@ -54,6 +25,8 @@ public class ModDiscoverer
|
||||
|
||||
private ASMDataTable dataTable = new ASMDataTable();
|
||||
|
||||
private List<File> nonModLibs = Lists.newArrayList();
|
||||
|
||||
public void findClasspathMods(ModClassLoader modClassLoader)
|
||||
{
|
||||
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries()).addAll(RelaunchLibraryManager.getLibraries()).build();
|
||||
@@ -61,7 +34,7 @@ public class ModDiscoverer
|
||||
if (minecraftSources.length == 1 && minecraftSources[0].isFile())
|
||||
{
|
||||
FMLLog.fine("Minecraft is a file at %s, loading", minecraftSources[0].getAbsolutePath());
|
||||
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR));
|
||||
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR, true, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -76,13 +49,13 @@ public class ModDiscoverer
|
||||
else
|
||||
{
|
||||
FMLLog.fine("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, true));
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, i==0, true));
|
||||
}
|
||||
}
|
||||
else if (minecraftSources[i].isDirectory())
|
||||
{
|
||||
FMLLog.fine("Found a minecraft related directory at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, true));
|
||||
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, i==0, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,7 +101,14 @@ public class ModDiscoverer
|
||||
try
|
||||
{
|
||||
List<ModContainer> mods = candidate.explore(dataTable);
|
||||
modList.addAll(mods);
|
||||
if (mods.isEmpty() && !candidate.isClasspath())
|
||||
{
|
||||
nonModLibs.add(candidate.getModContainer());
|
||||
}
|
||||
else
|
||||
{
|
||||
modList.addAll(mods);
|
||||
}
|
||||
}
|
||||
catch (LoaderException le)
|
||||
{
|
||||
@@ -148,4 +128,9 @@ public class ModDiscoverer
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
public List<File> getNonModLibs()
|
||||
{
|
||||
return nonModLibs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package cpw.mods.fml.common.discovery.asm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.src.BaseMod;
|
||||
|
||||
@@ -13,10 +15,10 @@ import org.objectweb.asm.Type;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ModCandidate;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
|
||||
public class ASMModParser
|
||||
{
|
||||
@@ -34,8 +36,16 @@ public class ASMModParser
|
||||
|
||||
public ASMModParser(InputStream stream) throws IOException
|
||||
{
|
||||
ClassReader reader = new ClassReader(stream);
|
||||
reader.accept(new ModClassVisitor(this), 0);
|
||||
try
|
||||
{
|
||||
ClassReader reader = new ClassReader(stream);
|
||||
reader.accept(new ModClassVisitor(this), 0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, ex, "Unable to read a class file correctly");
|
||||
throw new LoaderException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void beginNewTypeName(String typeQName, int classVersion, String superClassQName)
|
||||
@@ -70,7 +80,7 @@ public class ASMModParser
|
||||
.add("classVersion", classVersion)
|
||||
.add("superName", asmSuperType.getClassName())
|
||||
.add("annotations", annotations)
|
||||
.add("isBaseMod", isBaseMod())
|
||||
.add("isBaseMod", isBaseMod(Collections.<String>emptyList()))
|
||||
.add("baseModProperties", baseModProperties)
|
||||
.toString();
|
||||
}
|
||||
@@ -104,9 +114,9 @@ public class ASMModParser
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean isBaseMod()
|
||||
public boolean isBaseMod(List<String> rememberedTypes)
|
||||
{
|
||||
return getASMSuperType().equals(Type.getType(BaseMod.class));
|
||||
return getASMSuperType().equals(Type.getType(BaseMod.class)) || rememberedTypes.contains(getASMSuperType().getClassName());
|
||||
}
|
||||
|
||||
public void setBaseModProperties(String foundProperties)
|
||||
@@ -135,13 +145,13 @@ public class ASMModParser
|
||||
public void addAnnotationEnumProperty(String name, String desc, String value)
|
||||
{
|
||||
annotations.getFirst().addEnumProperty(name, desc, value);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void endArray()
|
||||
{
|
||||
annotations.getFirst().endArray();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addSubAnnotation(String name, String desc)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package cpw.mods.fml.common.discovery.asm;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
@@ -16,32 +18,32 @@ public class ModClassVisitor extends ClassVisitor
|
||||
super(Opcodes.ASM4);
|
||||
this.discoverer = discoverer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
discoverer.beginNewTypeName(name, version, superName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
|
||||
{
|
||||
discoverer.startClassAnnotation(annotationName);
|
||||
return new ModAnnotationVisitor(discoverer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
|
||||
{
|
||||
return new ModFieldVisitor(name, discoverer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
if (discoverer.isBaseMod() && name.equals("getPriorities") && desc.equals(Type.getMethodDescriptor(Type.getType(String.class))))
|
||||
if (discoverer.isBaseMod(Collections.<String>emptyList()) && name.equals("getPriorities") && desc.equals(Type.getMethodDescriptor(Type.getType(String.class))))
|
||||
{
|
||||
return new ModMethodVisitor(name, discoverer);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.LinkedList;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Table;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModClassLoader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
|
||||
public class FMLConstructionEvent extends FMLStateEvent
|
||||
{
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
public class FMLEvent
|
||||
{
|
||||
public final String getEventType()
|
||||
{
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public void applyModContainer(ModContainer activeContainer) {
|
||||
// NO OP
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
||||
public class FMLFingerprintViolationEvent extends FMLEvent {
|
||||
|
||||
public final boolean isDirectory;
|
||||
public final Set<String> fingerprints;
|
||||
public final File source;
|
||||
public final String expectedFingerprint;
|
||||
|
||||
public FMLFingerprintViolationEvent(boolean isDirectory, File source, ImmutableSet<String> fingerprints, String expectedFingerprint)
|
||||
{
|
||||
super();
|
||||
this.isDirectory = isDirectory;
|
||||
this.source = source;
|
||||
this.fingerprints = fingerprints;
|
||||
this.expectedFingerprint = expectedFingerprint;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.Mod.Instance;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Mod.Init;
|
||||
import cpw.mods.fml.common.Mod.PostInit;
|
||||
|
||||
/**
|
||||
* Simple intermod communications to receive simple messages directed at you
|
||||
* from other mods
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class FMLInterModComms {
|
||||
private static final ImmutableList<IMCMessage> emptyIMCList = ImmutableList.<IMCMessage>of();
|
||||
private static ArrayListMultimap<String, IMCMessage> modMessages = ArrayListMultimap.create();
|
||||
|
||||
/**
|
||||
* Subscribe to this event to receive your messages (they are sent between
|
||||
* {@link Init} and {@link PostInit})
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static class IMCEvent extends FMLEvent {
|
||||
@Override
|
||||
public void applyModContainer(ModContainer activeContainer)
|
||||
{
|
||||
currentList = ImmutableList.copyOf(modMessages.removeAll(activeContainer.getModId()));
|
||||
FMLLog.finest("Attempting to deliver %d IMC messages to mod %s", currentList.size(), activeContainer.getModId());
|
||||
}
|
||||
|
||||
private ImmutableList<IMCMessage> currentList;
|
||||
|
||||
public ImmutableList<IMCMessage> getMessages()
|
||||
{
|
||||
return currentList;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* You will receive an instance of this for each message sent
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static final class IMCMessage {
|
||||
/**
|
||||
* This is the modid of the mod that sent you the message
|
||||
*/
|
||||
private String sender;
|
||||
/**
|
||||
* This field, and {@link #value} are both at the mod's discretion
|
||||
*/
|
||||
public final String key;
|
||||
/**
|
||||
* This field, and {@link #key} are both at the mod's discretion
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
private IMCMessage(String key, Object value)
|
||||
{
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return sender;
|
||||
}
|
||||
|
||||
public String getSender()
|
||||
{
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
void setSender(ModContainer activeModContainer)
|
||||
{
|
||||
this.sender = activeModContainer.getModId();
|
||||
}
|
||||
|
||||
public String getStringValue()
|
||||
{
|
||||
return (String) value;
|
||||
}
|
||||
|
||||
public NBTTagCompound getNBTValue()
|
||||
{
|
||||
return (NBTTagCompound) value;
|
||||
}
|
||||
|
||||
public ItemStack getItemStackValue()
|
||||
{
|
||||
return (ItemStack) value;
|
||||
}
|
||||
|
||||
public Class<?> getMessageType()
|
||||
{
|
||||
return value.getClass();
|
||||
}
|
||||
|
||||
public boolean isStringMessage()
|
||||
{
|
||||
return String.class.isAssignableFrom(getMessageType());
|
||||
}
|
||||
|
||||
public boolean isItemStackMessage()
|
||||
{
|
||||
return ItemStack.class.isAssignableFrom(getMessageType());
|
||||
}
|
||||
|
||||
public boolean isNBTMessage()
|
||||
{
|
||||
return NBTTagCompound.class.isAssignableFrom(getMessageType());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sendMessage(String modId, String key, NBTTagCompound value)
|
||||
{
|
||||
return enqueueStartupMessage(modId, new IMCMessage(key, value));
|
||||
}
|
||||
public static boolean sendMessage(String modId, String key, ItemStack value)
|
||||
{
|
||||
return enqueueStartupMessage(modId, new IMCMessage(key, value));
|
||||
}
|
||||
public static boolean sendMessage(String modId, String key, String value)
|
||||
{
|
||||
return enqueueStartupMessage(modId, new IMCMessage(key, value));
|
||||
}
|
||||
|
||||
public static void sendRuntimeMessage(Object sourceMod, String modId, String key, NBTTagCompound value)
|
||||
{
|
||||
enqueueMessage(sourceMod, modId, new IMCMessage(key, value));
|
||||
}
|
||||
|
||||
public static void sendRuntimeMessage(Object sourceMod, String modId, String key, ItemStack value)
|
||||
{
|
||||
enqueueMessage(sourceMod, modId, new IMCMessage(key, value));
|
||||
}
|
||||
|
||||
public static void sendRuntimeMessage(Object sourceMod, String modId, String key, String value)
|
||||
{
|
||||
enqueueMessage(sourceMod, modId, new IMCMessage(key, value));
|
||||
}
|
||||
|
||||
private static boolean enqueueStartupMessage(String modTarget, IMCMessage message)
|
||||
{
|
||||
if (Loader.instance().activeModContainer() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
enqueueMessage(Loader.instance().activeModContainer(), modTarget, message);
|
||||
return Loader.isModLoaded(modTarget) && !Loader.instance().hasReachedState(LoaderState.POSTINITIALIZATION);
|
||||
|
||||
}
|
||||
private static void enqueueMessage(Object sourceMod, String modTarget, IMCMessage message)
|
||||
{
|
||||
ModContainer mc;
|
||||
if (sourceMod instanceof ModContainer) {
|
||||
mc = (ModContainer) sourceMod;
|
||||
}
|
||||
else
|
||||
{
|
||||
mc = FMLCommonHandler.instance().findContainerFor(sourceMod);
|
||||
}
|
||||
if (mc != null && Loader.isModLoaded(modTarget))
|
||||
{
|
||||
message.setSender(mc);
|
||||
modMessages.put(modTarget, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve any pending runtime messages for the mod
|
||||
* @param forMod The {@link Instance} of the Mod to fetch messages for
|
||||
* @return any messages - the collection will never be null
|
||||
*/
|
||||
public static ImmutableList<IMCMessage> fetchRuntimeMessages(Object forMod)
|
||||
{
|
||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(forMod);
|
||||
if (mc != null)
|
||||
{
|
||||
return ImmutableList.copyOf(modMessages.removeAll(mc));
|
||||
}
|
||||
else
|
||||
{
|
||||
return emptyIMCList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLLoadCompleteEvent extends FMLStateEvent
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLPostInitializationEvent extends FMLStateEvent
|
||||
@@ -15,4 +18,21 @@ public class FMLPostInitializationEvent extends FMLStateEvent
|
||||
return ModState.POSTINITIALIZED;
|
||||
}
|
||||
|
||||
public Object buildSoftDependProxy(String modId, String className)
|
||||
{
|
||||
if (Loader.isModLoaded(modId))
|
||||
{
|
||||
try
|
||||
{
|
||||
Class<?> clz = Class.forName(className,true,Loader.instance().getModClassLoader());
|
||||
return clz.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.CodeSource;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.FMLModContainer;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
|
||||
public class FMLPreInitializationEvent extends FMLStateEvent
|
||||
{
|
||||
@@ -16,6 +20,7 @@ public class FMLPreInitializationEvent extends FMLStateEvent
|
||||
private File configurationDir;
|
||||
private File suggestedConfigFile;
|
||||
private ASMDataTable asmData;
|
||||
private ModContainer modContainer;
|
||||
|
||||
public FMLPreInitializationEvent(Object... data)
|
||||
{
|
||||
@@ -33,6 +38,7 @@ public class FMLPreInitializationEvent extends FMLStateEvent
|
||||
@Override
|
||||
public void applyModContainer(ModContainer activeContainer)
|
||||
{
|
||||
this.modContainer = activeContainer;
|
||||
this.modMetadata = activeContainer.getMetadata();
|
||||
this.sourceFile = activeContainer.getSource();
|
||||
this.suggestedConfigFile = new File(configurationDir, activeContainer.getModId()+".cfg");
|
||||
@@ -62,4 +68,51 @@ public class FMLPreInitializationEvent extends FMLStateEvent
|
||||
{
|
||||
return asmData;
|
||||
}
|
||||
|
||||
public Properties getVersionProperties()
|
||||
{
|
||||
if (this.modContainer instanceof FMLModContainer)
|
||||
{
|
||||
return ((FMLModContainer)this.modContainer).searchForVersionProperties();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a logger instance configured to write to the FML Log as a parent, identified by modid. Handy for mod logging!
|
||||
*
|
||||
* @return A logger
|
||||
*/
|
||||
public Logger getModLog()
|
||||
{
|
||||
Logger log = Logger.getLogger(modContainer.getModId());
|
||||
log.setParent(FMLLog.getLogger());
|
||||
return log;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the FML signing certificates, if any. Validate these against the
|
||||
* published FML certificates in your mod, if you wish.
|
||||
*
|
||||
* Deprecated because mods should <b>NOT</b> trust this code. Rather
|
||||
* they should copy this, or something like this, into their own mods.
|
||||
*
|
||||
* @return Certificates used to sign FML and Forge
|
||||
*/
|
||||
@Deprecated
|
||||
public Certificate[] getFMLSigningCertificates()
|
||||
{
|
||||
CodeSource codeSource = getClass().getClassLoader().getParent().getClass().getProtectionDomain().getCodeSource();
|
||||
Certificate[] certs = codeSource.getCertificates();
|
||||
if (certs == null)
|
||||
{
|
||||
return new Certificate[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return certs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLServerStartedEvent extends FMLStateEvent
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import net.minecraft.command.CommandHandler;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLServerStartingEvent extends FMLStateEvent
|
||||
{
|
||||
|
||||
private Object server;
|
||||
|
||||
private MinecraftServer server;
|
||||
|
||||
public FMLServerStartingEvent(Object... data)
|
||||
{
|
||||
super(data);
|
||||
this.server = data[0];
|
||||
this.server = (MinecraftServer) data[0];
|
||||
}
|
||||
@Override
|
||||
public ModState getModState()
|
||||
@@ -19,4 +21,14 @@ public class FMLServerStartingEvent extends FMLStateEvent
|
||||
return ModState.AVAILABLE;
|
||||
}
|
||||
|
||||
public MinecraftServer getServer()
|
||||
{
|
||||
return server;
|
||||
}
|
||||
|
||||
public void registerServerCommand(ICommand command)
|
||||
{
|
||||
CommandHandler ch = (CommandHandler) getServer().func_71187_D();
|
||||
ch.func_71560_a(command);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
|
||||
public class FMLServerStoppingEvent extends FMLStateEvent
|
||||
|
||||
@@ -2,8 +2,7 @@ package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public abstract class FMLStateEvent extends FMLEvent
|
||||
{
|
||||
@@ -14,11 +13,6 @@ public abstract class FMLStateEvent extends FMLEvent
|
||||
|
||||
public abstract ModState getModState();
|
||||
|
||||
public void applyModContainer(ModContainer activeContainer)
|
||||
{
|
||||
// NO OP
|
||||
}
|
||||
|
||||
public Side getSide()
|
||||
{
|
||||
return FMLCommonHandler.instance().getSide();
|
||||
|
||||
Loaded 100 of 352 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user