mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 09:05:17 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
b33cff3613 | ||
|
|
afc2a4a75c | ||
|
|
7c4583c87a | ||
|
|
f563815961 | ||
|
|
0ce38f747c | ||
|
|
efce8e916b | ||
|
|
44728c9f93 | ||
|
|
d96a81e4f2 | ||
|
|
f11844374e | ||
|
|
8c63203bb4 | ||
|
|
751299d5f1 | ||
|
|
7d479bf854 | ||
|
|
c812a4ede5 | ||
|
|
a826283111 | ||
|
|
f61f30c1e6 | ||
|
|
8f76e8ba8b | ||
|
|
537d89b9e0 | ||
|
|
0927aaa0f1 | ||
|
|
d17aad797d | ||
|
|
53e611a03a | ||
|
|
7ac1be8a9a | ||
|
|
dd7d70d619 | ||
|
|
b9d1d1e2f4 | ||
|
|
2dc00adec8 | ||
|
|
b97e937f28 | ||
|
|
c54c4e73e6 | ||
|
|
93528597f4 | ||
|
|
a85bb7bfdb | ||
|
|
0f2d00abf3 | ||
|
|
0e4c716177 | ||
|
|
85b77c3d12 | ||
|
|
03884b1aaa | ||
|
|
dbdc76e6ea | ||
|
|
b8aaed368b | ||
|
|
6ec3379153 | ||
|
|
b177aad1ee | ||
|
|
e050c7807d | ||
|
|
f3f7398a8b | ||
|
|
da4311dc74 | ||
|
|
59471f6cac | ||
|
|
d8b92064d7 | ||
|
|
8e96e60179 | ||
|
|
54877176a6 | ||
|
|
a3ad32a3e5 | ||
|
|
602a4f219c | ||
|
|
f24977dc3d | ||
|
|
4607f9ebb0 | ||
|
|
672f4a03f2 | ||
|
|
f0736ade3d | ||
|
|
4da48cea7a | ||
|
|
1b02ea0677 | ||
|
|
0d1bd4c5d0 | ||
|
|
3f08f1a94c | ||
|
|
1069366219 | ||
|
|
0002bd2875 | ||
|
|
823077dd7d | ||
|
|
34971ff3e0 | ||
|
|
965069ba3a | ||
|
|
43766751a4 | ||
|
|
a92da71c6b | ||
|
|
da47985361 | ||
|
|
68ae32c48c | ||
|
|
3373e33d4b | ||
|
|
2839e79ab0 | ||
|
|
5bffbfbe0d | ||
|
|
4080338c1b | ||
|
|
e06e9393c1 | ||
|
|
4bb9fd7226 | ||
|
|
7edc7d74d4 | ||
|
|
9a5dac605c | ||
|
|
c0a781c0bd | ||
|
|
719bea515e | ||
|
|
153eafdcb0 | ||
|
|
2f588cf6ef | ||
|
|
3ad3c474b5 | ||
|
|
73ba4b68be | ||
|
|
b786d8909a | ||
|
|
ab45ec9fa4 | ||
|
|
fcbe56b504 | ||
|
|
693ec7ddf6 | ||
|
|
61b83ab992 | ||
|
|
6ce9b1ab05 | ||
|
|
a5d58d79fc | ||
|
|
dac3249dc4 | ||
|
|
99eddbfa13 | ||
|
|
ea1fc8f358 | ||
|
|
bbb5a0e891 | ||
|
|
3f491fa7cb | ||
|
|
ae007fcebc | ||
|
|
8580a99728 | ||
|
|
3257d2595d | ||
|
|
5434b3ca24 | ||
|
|
1ea6ba273b | ||
|
|
039d9252c6 | ||
|
|
ca67d6eb6d | ||
|
|
7179edfba7 | ||
|
|
baec9785a2 | ||
|
|
ae2039c65d | ||
|
|
3f803653c4 | ||
|
|
6ff67693b9 | ||
|
|
5501d644b9 | ||
|
|
276fccb170 | ||
|
|
e2fac06f64 | ||
|
|
25def1ceaf | ||
|
|
c0f70309dd | ||
|
|
899c1f519c | ||
|
|
5c1363150e | ||
|
|
4153584392 | ||
|
|
2858731063 | ||
|
|
874a0c32e0 | ||
|
|
4f845befaa | ||
|
|
95194f1c5b | ||
|
|
df6bbaa7c5 | ||
|
|
b1ca21a161 | ||
|
|
bc42a54a51 | ||
|
|
1555bd8c53 | ||
|
|
649e3e7bc5 | ||
|
|
ead4e5255e | ||
|
|
5eafb71083 | ||
|
|
8ed36f583d | ||
|
|
3e311fd4c1 | ||
|
|
a4ce90a918 | ||
|
|
ba46389a87 | ||
|
|
f7e07ca7d8 | ||
|
|
3e80a9ee7d | ||
|
|
dfc6f7b1c1 | ||
|
|
753f5f7bc8 | ||
|
|
982271e8ec | ||
|
|
802ec3d86a | ||
|
|
f1b0e33694 | ||
|
|
1d64fb01bd | ||
|
|
086f575a41 | ||
|
|
3cda115cd5 | ||
|
|
d491502750 | ||
|
|
1d4c33d161 | ||
|
|
47a879a961 | ||
|
|
b59184424b | ||
|
|
a7803d1785 | ||
|
|
5415bf87ce | ||
|
|
a33f2dde77 | ||
|
|
bb7ef791de | ||
|
|
d00e229198 |
No files matched your search
-10
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="common"/>
|
||||
<classpathentry kind="src" path="server"/>
|
||||
<classpathentry kind="src" path="minecraft_server"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,7 @@
|
||||
* text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.patch text
|
||||
*.png binary
|
||||
*.exe binary
|
||||
*.dll binary
|
||||
*.zip binary
|
||||
+10
-10
@@ -1,10 +1,10 @@
|
||||
/bin
|
||||
/minecraft_server
|
||||
/mods
|
||||
/fmlbuild.properties
|
||||
/fmlversion.properties
|
||||
/difflist.txt
|
||||
/.metadata/
|
||||
/eclipse/.metadata/
|
||||
/target
|
||||
fmlbranding.properties
|
||||
/bin
|
||||
/minecraft_server
|
||||
/mods
|
||||
/fmlbuild.properties
|
||||
/fmlversion.properties
|
||||
/difflist.txt
|
||||
/target
|
||||
fmlbranding.properties
|
||||
/fernflower.zip
|
||||
/commands.py.bck
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>fml</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>minecraft_server</name>
|
||||
<type>2</type>
|
||||
<location>/home/cpw/projects/mcworkspace/vanilla125/src-work/minecraft_server</location>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
@@ -1,11 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
@@ -1,3 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.ui.javadoc=true
|
||||
org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*\n * The FML Forge Mod Loader suite.\n * Copyright (C) 2012 cpw\n * \n * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free\n * Software Foundation; either version 2.1 of the License, or any later version.\n * \n * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR\n * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.\n * \n * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51\n * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method sLine truncated
|
||||
@@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
||||
@@ -1,4 +0,0 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
@@ -3,6 +3,12 @@ under the GNU LGPL v2.1 or later.
|
||||
|
||||
Homepage: https://github.com/cpw/FML
|
||||
|
||||
This software includes portions from the Apache Maven project at
|
||||
http://maven.apache.org/ specifically the ComparableVersion.java code. It is
|
||||
included based on guidelines at
|
||||
http://www.softwarefreedom.org/resources/2007/gpl-non-gpl-collaboration.html
|
||||
with notices intact. The only change is a non-functional change of package name.
|
||||
|
||||
========
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
+7
-59
@@ -1,66 +1,14 @@
|
||||
import sys
|
||||
import os, os.path, shutil
|
||||
import commands
|
||||
import fnmatch
|
||||
import re
|
||||
import subprocess, shlex
|
||||
|
||||
def cmdsplit(args):
|
||||
if os.sep == '\\':
|
||||
args = args.replace('\\', '\\\\')
|
||||
return shlex.split(args)
|
||||
import os, sys
|
||||
|
||||
def main():
|
||||
print("Applying patches")
|
||||
sys.stdout.flush()
|
||||
patches = os.path.abspath(sys.argv[1])
|
||||
work = os.path.normpath(sys.argv[2])
|
||||
mcp = os.path.normpath(sys.argv[3])
|
||||
temp = os.path.abspath('temp.patch')
|
||||
fml_dir = os.path.abspath(sys.argv[1])
|
||||
work_dir = os.path.normpath(sys.argv[2])
|
||||
mcp_dir = os.path.normpath(sys.argv[3])
|
||||
|
||||
cmd = cmdsplit('patch -p2 -i "%s" ' % temp)
|
||||
display = True
|
||||
sys.path.append(os.path.join(fml_dir, 'install'))
|
||||
from fml import apply_fml_patches
|
||||
|
||||
if os.name == 'nt':
|
||||
mcp = os.path.abspath(os.path.join(mcp, 'runtime', 'bin', 'applydiff.exe'))
|
||||
cmd = cmdsplit('"%s" -uf -p2 -i "%s"' % (mcp, temp))
|
||||
display = False
|
||||
|
||||
for path, _, filelist in os.walk(patches, followlinks=True):
|
||||
for cur_file in fnmatch.filter(filelist, '*.patch'):
|
||||
patch_file = os.path.normpath(os.path.join(patches, path[len(patches)+1:], cur_file))
|
||||
if display:
|
||||
print 'patching file %s' % os.path.join(path[len(patches)+1:], cur_file)
|
||||
normaliselines(patch_file, temp)
|
||||
process = subprocess.Popen(cmd, cwd=work, bufsize=-1)
|
||||
process.communicate()
|
||||
|
||||
if os.path.isfile(temp):
|
||||
os.remove(temp)
|
||||
|
||||
#Taken from MCP
|
||||
def normaliselines(in_filename, out_filename=None):
|
||||
in_filename = os.path.normpath(in_filename)
|
||||
if out_filename is None:
|
||||
tmp_filename = in_filename + '.tmp'
|
||||
else:
|
||||
out_filename = os.path.normpath(out_filename)
|
||||
tmp_filename = out_filename
|
||||
dir_name = os.path.dirname(out_filename)
|
||||
if dir_name:
|
||||
if not os.path.exists(dir_name):
|
||||
os.makedirs(dir_name)
|
||||
regex_ending = re.compile(r'\r?\n')
|
||||
with open(in_filename, 'rb') as in_file:
|
||||
with open(tmp_filename, 'wb') as out_file:
|
||||
buf = in_file.read()
|
||||
if os.linesep == '\r\n':
|
||||
buf = regex_ending.sub(r'\r\n', buf)
|
||||
else:
|
||||
buf = buf.replace('\r\n', '\n')
|
||||
out_file.write(buf)
|
||||
if out_filename is None:
|
||||
shutil.move(tmp_filename, in_filename)
|
||||
apply_fml_patches(fml_dir, mcp_dir, work_dir, False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- ======================================================================
|
||||
30 Mar 2012 13:35:40
|
||||
<!-- ======================================================================
|
||||
30 Mar 2012 13:35:40
|
||||
|
||||
FML
|
||||
FML
|
||||
The Forge Mod Loader
|
||||
|
||||
cpw
|
||||
|
||||
cpw
|
||||
====================================================================== -->
|
||||
<project name="FML" default="build">
|
||||
<project name="FML" default="jenkinsbuild">
|
||||
<description>The Forge Mod Loader</description>
|
||||
<macrodef name="side">
|
||||
<attribute name="prop" />
|
||||
@@ -26,6 +26,7 @@
|
||||
<target name="writeversion" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${basedir}" failonerror="true">
|
||||
<arg value="${basedir}/getversion.py" />
|
||||
<arg value="${mcp.home}" />
|
||||
</exec>
|
||||
<propertyfile file="fmlversion.properties">
|
||||
<entry key="fmlbuild.build.number" type="int" value="${version.build}"/>
|
||||
@@ -50,31 +51,33 @@
|
||||
</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>
|
||||
</target>
|
||||
|
||||
<target name="init" depends="buildenvsetup">
|
||||
<target name="makeversion" depends="buildenvsetup">
|
||||
<antcall target="writeversion" />
|
||||
<property file="fmlversion.properties" />
|
||||
<property name="build.number" value="${fmlbuild.major.number}.${fmlbuild.minor.number}.${fmlbuild.revision.number}" />
|
||||
<property name="version.minecraft" value="${fmlbuild.mcversion}" />
|
||||
<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" value="${version.major}.${version.minor}.${version.rev}.${version.build}" />
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<target name="clean" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
<arg value="-f" />
|
||||
@@ -86,23 +89,20 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="buildandreobfmcp" depends="init">
|
||||
<target name="reobfuscate" depends="buildenvsetup,recompile">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
|
||||
<arg value="${mcp.home}/runtime/recompile.py" />
|
||||
<arg value="${mcp.home}/runtime/reobfuscate.py" />
|
||||
</exec>
|
||||
<fail message="Compilation failed">
|
||||
<fail message="Reobfuscation 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"/>
|
||||
<available file="${mcp.home}/temp/client.md5"/>
|
||||
<available file="${mcp.home}/temp/client_reobf.md5"/>
|
||||
</and>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/reobfuscate.py" />
|
||||
</exec>
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${basedir}/generatechangedfilelist.py"/>
|
||||
<arg value="${mcp.home}"/>
|
||||
@@ -110,39 +110,34 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="merge-client" depends="init,clean">
|
||||
<antcall target="merge-source">
|
||||
<param name="side" value="client" />
|
||||
</antcall>
|
||||
<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>
|
||||
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
</target>
|
||||
|
||||
<target name="merge-server" depends="init,clean">
|
||||
<antcall target="merge-source">
|
||||
<param name="side" value="server" />
|
||||
</antcall>
|
||||
<target name="merge-client" depends="buildenvsetup">
|
||||
<copy todir="${client.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<fileset dir="${client.src.dir}" includes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="merge-source">
|
||||
<side prop="merge-to" src="mcp.srcdir" side="${side}" />
|
||||
<side prop="side-from" src="src.dir" side="${side}" />
|
||||
|
||||
<copy todir="${merge-to}" overwrite="true" verbose="true">
|
||||
<fileset dir="${side-from}" includes="**/*.java" />
|
||||
<target name="merge-common">
|
||||
<copy todir="${common.mcp.srcdir}" overwrite="true" verbose="true">
|
||||
<fileset dir="${common.src.dir}" includes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build-client" depends="init,merge-client,buildandreobfmcp">
|
||||
<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="init,clean,merge-server,buildandreobfmcp">
|
||||
<antcall target="extract-built-jar">
|
||||
<param name="side" value="server" />
|
||||
</antcall>
|
||||
</target>
|
||||
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion"/>
|
||||
|
||||
<target name="extract-built-jar">
|
||||
<side prop="output" src="mcp.obfoutput" side="${side}" />
|
||||
@@ -153,6 +148,7 @@
|
||||
<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" />
|
||||
@@ -171,17 +167,47 @@
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build-source-pack">
|
||||
<property name="jarname" value="${modname}-src-${version}" />
|
||||
<zip destfile="${basedir}/target/${jarname}.zip">
|
||||
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt" prefix="fml" />
|
||||
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/src/minecraft_server" />
|
||||
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/src/minecraft" />
|
||||
<zipfileset dir="${client.src.dir}" includes="**/*.java" prefix="fml/src/minecraft" />
|
||||
<zipfileset dir="${server.src.dir}" includes="**/*.java" prefix="fml/src/minecraft_server" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/src/minecraft" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/src/minecraft_server" />
|
||||
<target name="build-universal" depends="build-client">
|
||||
<property name="universal.jarname" value="${modname}-universal-${version}" />
|
||||
<mkdir dir="${basedir}/target" />
|
||||
<jar destfile="${basedir}/target/${universal.jarname}.zip" 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" />
|
||||
<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}" />
|
||||
<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="${common.src.dir}" includes="**/*.java" prefix="fml/common" />
|
||||
<zipfileset dir="${client.src.dir}" includes="**/*.java" prefix="fml/client" />
|
||||
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/common" />
|
||||
<zipfileset dir="${common.src.dir}" includes="*.cfg" prefix="fml/common" />
|
||||
<zipfileset dir="${patch.src.dir}" includes="**/*.patch" prefix="fml/patches" />
|
||||
<zipfileset dir="${fml.conf.dir}" prefix="fml/conf" />
|
||||
<mappedresources>
|
||||
<concat>
|
||||
<fileset dir="${basedir}/install" includes="README.txt" />
|
||||
@@ -197,20 +223,145 @@
|
||||
</concat>
|
||||
<mergemapper to="fml/README-fml.txt" />
|
||||
</mappedresources>
|
||||
<zipfileset dir="${basedir}/install" excludes="README.txt" prefix="fml" />
|
||||
<zipfileset dir="${basedir}/install" excludes="README.txt,fml.pyc" prefix="fml" />
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="init,clean,merge-server,merge-client,patch,build-server,build-client,build-source-pack" />
|
||||
<target name="build" depends="buildenvsetup,merge-client,merge-common,build-client,build-universal,build-source-pack" />
|
||||
|
||||
<target name="patch" depends="init">
|
||||
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build"/>
|
||||
|
||||
<target name="patch" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/applypatches.py" />
|
||||
<arg value="${patch.src.dir}" />
|
||||
<arg value="${basedir}" />
|
||||
<arg value="${mcp.srcdir}" />
|
||||
<arg value="${mcp.home}" />
|
||||
</exec>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="setupenvironment" depends="buildenvsetup">
|
||||
<input message="This will clean the mcp environment at ${mcp.home} and backup any src-work folder there (src-base will be erased). Continue?" validargs="y,n" addproperty="do.continue" />
|
||||
<condition property="do.not.continue">
|
||||
<equals arg1="n" arg2="${do.continue}" />
|
||||
</condition>
|
||||
<fail if="do.not.continue">You have decided not to continue. This script will stop now.</fail>
|
||||
<echo>Preparing the MCP environment at ${mcp.home}</echo>
|
||||
<antcall target="fmldecompile"/>
|
||||
<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}"/>
|
||||
</move>
|
||||
<echo>Deleting old patch references at ${clean.mcp.srcdir}</echo>
|
||||
<delete dir="${clean.mcp.srcdir}" failonerror="false"/>
|
||||
<echo>Creating new patch references at ${clean.mcp.srcdir}</echo>
|
||||
<copy todir="${clean.mcp.srcdir}">
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
<antcall target="cleanargo"/>
|
||||
<antcall target="patch"/>
|
||||
<echo>Creating clean patched references at ${patch.mcp.srcdir}</echo>
|
||||
<copy todir="${patch.mcp.srcdir}">
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</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>
|
||||
</target>
|
||||
|
||||
<target name="fmldecompile" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/cleanup.py" />
|
||||
<arg value="-f" />
|
||||
</exec>
|
||||
<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>
|
||||
<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/decompile.py" />
|
||||
<arg value="${mcp.home}" />
|
||||
<arg value="${basedir}" />
|
||||
<arg value="-no_gen_conf" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="repatch" depends="buildenvsetup,checkpatches">
|
||||
<echo>Moving old patched sources at ${mcp.home}/src-work out of the way</echo>
|
||||
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
|
||||
<fileset dir="${patch.mcp.srcdir}"/>
|
||||
</move>
|
||||
<delete dir="${mcp.srcdir}"/>
|
||||
<copy todir="${mcp.srcdir}">
|
||||
<fileset dir="${clean.mcp.srcdir}"/>
|
||||
</copy>
|
||||
|
||||
<antcall target="cleanargo"/>
|
||||
|
||||
<antcall target="patch"/>
|
||||
<copy todir="${patch.mcp.srcdir}">
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="repatchclean" depends="buildenvsetup">
|
||||
<delete dir="${mcp.srcdir}"/>
|
||||
<copy todir="${mcp.srcdir}">
|
||||
<fileset dir="${clean.mcp.srcdir}"/>
|
||||
</copy>
|
||||
|
||||
<antcall target="cleanargo"/>
|
||||
|
||||
<antcall target="patch"/>
|
||||
</target>
|
||||
|
||||
<target name="cleanargo" depends="buildenvsetup">
|
||||
<delete dir="${client.mcp.srcdir}/argo"/>
|
||||
</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>
|
||||
</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>
|
||||
</target>
|
||||
|
||||
<target name="updatepatches" depends="buildenvsetup">
|
||||
<exec executable="${python.exe}" dir="${basedir}">
|
||||
<arg value="${basedir}/update_patches.py" />
|
||||
<arg value="${mcp.home}"/>
|
||||
<arg value="${basedir}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-common,reobfuscate">
|
||||
<copy todir="${tmp.mcp.srcdir}">
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
<exec executable="${python.exe}" dir="${mcp.home}">
|
||||
<arg value="${mcp.home}/runtime/updatenames.py" />
|
||||
<arg value="-f" />
|
||||
</exec>
|
||||
<copy todir="${renamed.mcp.srcdir}">
|
||||
<fileset dir="${mcp.srcdir}"/>
|
||||
</copy>
|
||||
<move todir="${mcp.srcdir}">
|
||||
<fileset dir="${tmp.mcp.srcdir}"/>
|
||||
</move>
|
||||
</target>
|
||||
</project>
|
||||
+43
-43
@@ -1,43 +1,43 @@
|
||||
import sys
|
||||
import os, os.path, shutil
|
||||
import fnmatch
|
||||
import re
|
||||
|
||||
def main():
|
||||
sys.stdout.flush()
|
||||
for x in range(1, len(sys.argv)):
|
||||
cleanup_source(sys.argv[x])
|
||||
|
||||
count = 0
|
||||
def cleanup_source(path):
|
||||
path = os.path.normpath(path)
|
||||
regex_cases_before = re.compile(r'((case|default).+\r?\n)\r?\n', re.MULTILINE) #Fixes newline after case before case body
|
||||
regex_cases_after = re.compile(r'\r?\n(\r?\n[ \t]+(case|default))', re.MULTILINE) #Fixes newline after case body before new case
|
||||
|
||||
def updatefile(src_file):
|
||||
global count
|
||||
tmp_file = src_file + '.tmp'
|
||||
count = 0
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
def fix_cases(match):
|
||||
global count
|
||||
count += 1
|
||||
return match.group(1)
|
||||
|
||||
buf = regex_cases_before.sub(fix_cases, buf)
|
||||
buf = regex_cases_after.sub(fix_cases, buf)
|
||||
if count > 0:
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
for path, _, filelist in os.walk(path, followlinks=True):
|
||||
sub_dir = os.path.relpath(path, path)
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
updatefile(src_file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
import sys
|
||||
import os, os.path, shutil
|
||||
import fnmatch
|
||||
import re
|
||||
|
||||
def main():
|
||||
sys.stdout.flush()
|
||||
for x in range(1, len(sys.argv)):
|
||||
cleanup_source(sys.argv[x])
|
||||
|
||||
count = 0
|
||||
def cleanup_source(path):
|
||||
path = os.path.normpath(path)
|
||||
regex_cases_before = re.compile(r'((case|default).+\r?\n)\r?\n', re.MULTILINE) #Fixes newline after case before case body
|
||||
regex_cases_after = re.compile(r'\r?\n(\r?\n[ \t]+(case|default))', re.MULTILINE) #Fixes newline after case body before new case
|
||||
|
||||
def updatefile(src_file):
|
||||
global count
|
||||
tmp_file = src_file + '.tmp'
|
||||
count = 0
|
||||
with open(src_file, 'r') as fh:
|
||||
buf = fh.read()
|
||||
|
||||
def fix_cases(match):
|
||||
global count
|
||||
count += 1
|
||||
return match.group(1)
|
||||
|
||||
buf = regex_cases_before.sub(fix_cases, buf)
|
||||
buf = regex_cases_after.sub(fix_cases, buf)
|
||||
if count > 0:
|
||||
with open(tmp_file, 'w') as fh:
|
||||
fh.write(buf)
|
||||
shutil.move(tmp_file, src_file)
|
||||
|
||||
for path, _, filelist in os.walk(path, followlinks=True):
|
||||
sub_dir = os.path.relpath(path, path)
|
||||
for cur_file in fnmatch.filter(filelist, '*.java'):
|
||||
src_file = os.path.normpath(os.path.join(path, cur_file))
|
||||
updatefile(src_file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,43 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import cpw.mods.fml.common.IFMLHandledException;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
import net.minecraft.src.FontRenderer;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,69 +1,69 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TexturePackBase;
|
||||
|
||||
public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
{
|
||||
public int tileSizeBase = 16;
|
||||
public int tileSizeSquare = 256;
|
||||
public int tileSizeMask = 15;
|
||||
public int tileSizeSquareMask = 255;
|
||||
public boolean errored = false;
|
||||
protected Logger log = FMLCommonHandler.instance().getFMLLogger();
|
||||
|
||||
public FMLTextureFX(int icon)
|
||||
{
|
||||
super(icon);
|
||||
}
|
||||
|
||||
@Override public void setErrored(boolean err){ errored = err; }
|
||||
@Override public boolean getErrored(){ return errored; }
|
||||
@Override
|
||||
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions)
|
||||
{
|
||||
onTextureDimensionsUpdate(dimensions.width, dimensions.height);
|
||||
}
|
||||
@Override
|
||||
public void onTextureDimensionsUpdate(int width, int height)
|
||||
{
|
||||
tileSizeBase = width >> 4;
|
||||
tileSizeSquare = tileSizeBase * tileSizeBase;
|
||||
tileSizeMask = tileSizeBase - 1;
|
||||
tileSizeSquareMask = tileSizeSquare - 1;
|
||||
setErrored(false);
|
||||
setup();
|
||||
}
|
||||
|
||||
protected void setup()
|
||||
{
|
||||
field_1127_a = new byte[tileSizeSquare << 2];
|
||||
}
|
||||
|
||||
public boolean unregister(RenderEngine engine, List<TextureFX> effects)
|
||||
{
|
||||
effects.remove(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.ITexturePack;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
public class FMLTextureFX extends TextureFX implements ITextureFX
|
||||
{
|
||||
public int tileSizeBase = 16;
|
||||
public int tileSizeSquare = 256;
|
||||
public int tileSizeMask = 15;
|
||||
public int tileSizeSquareMask = 255;
|
||||
public boolean errored = false;
|
||||
protected Logger log = FMLLog.getLogger();
|
||||
|
||||
public FMLTextureFX(int icon)
|
||||
{
|
||||
super(icon);
|
||||
}
|
||||
|
||||
@Override public void setErrored(boolean err){ errored = err; }
|
||||
@Override public boolean getErrored(){ return errored; }
|
||||
@Override
|
||||
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions)
|
||||
{
|
||||
onTextureDimensionsUpdate(dimensions.width, dimensions.height);
|
||||
}
|
||||
@Override
|
||||
public void onTextureDimensionsUpdate(int width, int height)
|
||||
{
|
||||
tileSizeBase = width >> 4;
|
||||
tileSizeSquare = tileSizeBase * tileSizeBase;
|
||||
tileSizeMask = tileSizeBase - 1;
|
||||
tileSizeSquareMask = tileSizeSquare - 1;
|
||||
setErrored(false);
|
||||
setup();
|
||||
}
|
||||
|
||||
protected void setup()
|
||||
{
|
||||
field_76852_a = new byte[tileSizeSquare << 2];
|
||||
}
|
||||
|
||||
public boolean unregister(RenderEngine engine, List<TextureFX> effects)
|
||||
{
|
||||
effects.remove(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
|
||||
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,44 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
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;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,7 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.common.FMLModContainer;
|
||||
import cpw.mods.fml.common.FMLModLoaderContainer;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.FontRenderer;
|
||||
import net.minecraft.src.GuiButton;
|
||||
@@ -33,13 +25,19 @@ import net.minecraft.src.GuiSmallButton;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import net.minecraft.src.Tessellator;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class GuiModList extends GuiScreen
|
||||
{
|
||||
|
||||
private GuiScreen mainMenu;
|
||||
private GuiSlotModList modList;
|
||||
private int selected = -1;
|
||||
@@ -48,105 +46,120 @@ public class GuiModList extends GuiScreen
|
||||
private ArrayList<ModContainer> mods;
|
||||
|
||||
/**
|
||||
* @param guiMainMenu
|
||||
* @param mainMenu
|
||||
*/
|
||||
public GuiModList(GuiScreen mainMenu)
|
||||
{
|
||||
this.mainMenu=mainMenu;
|
||||
this.mods=new ArrayList<ModContainer>();
|
||||
FMLClientHandler.instance().addSpecialModEntries(mods);
|
||||
for (ModContainer mod : Loader.getModList()) {
|
||||
if (mod.getMetadata()!=null && mod.getMetadata().parentMod != null) {
|
||||
continue;
|
||||
for (ModContainer mod : Loader.instance().getModList()) {
|
||||
if (mod.getMetadata()!=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;
|
||||
}
|
||||
}
|
||||
mods.add(mod);
|
||||
}
|
||||
}
|
||||
|
||||
public void func_6448_a()
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
for (ModContainer mod : mods) {
|
||||
listWidth=Math.max(listWidth,getFontRenderer().func_871_a(mod.getName()) + 10);
|
||||
listWidth=Math.max(listWidth,getFontRenderer().func_871_a(mod.getVersion()) + 10);
|
||||
listWidth=Math.max(listWidth,getFontRenderer().func_78256_a(mod.getName()) + 10);
|
||||
listWidth=Math.max(listWidth,getFontRenderer().func_78256_a(mod.getVersion()) + 10);
|
||||
}
|
||||
listWidth=Math.min(listWidth, 150);
|
||||
StringTranslate translations = StringTranslate.func_20162_a();
|
||||
this.field_949_e.add(new GuiSmallButton(6, this.field_951_c / 2 - 75, this.field_950_d - 38, translations.func_20163_a("gui.done")));
|
||||
StringTranslate translations = StringTranslate.func_74808_a();
|
||||
this.field_73887_h.add(new GuiSmallButton(6, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
|
||||
this.modList=new GuiSlotModList(this, mods, listWidth);
|
||||
this.modList.registerScrollButtons(this.field_949_e, 7, 8);
|
||||
this.modList.registerScrollButtons(this.field_73887_h, 7, 8);
|
||||
}
|
||||
|
||||
protected void func_572_a(GuiButton button) {
|
||||
if (button.field_937_g)
|
||||
@Override
|
||||
protected void func_73875_a(GuiButton button) {
|
||||
if (button.field_73742_g)
|
||||
{
|
||||
switch (button.field_938_f)
|
||||
switch (button.field_73741_f)
|
||||
{
|
||||
case 6:
|
||||
this.field_945_b.func_6272_a(this.mainMenu);
|
||||
this.field_73882_e.func_71373_a(this.mainMenu);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.func_572_a(button);
|
||||
super.func_73875_a(button);
|
||||
}
|
||||
|
||||
public int drawLine(String line, int offset, int shifty)
|
||||
{
|
||||
this.field_6451_g.func_873_b(line, offset, shifty, 0xd7edea);
|
||||
this.field_73886_k.func_78276_b(line, offset, shifty, 0xd7edea);
|
||||
return shifty + 10;
|
||||
}
|
||||
public void func_571_a(int p_571_1_, int p_571_2_, float p_571_3_)
|
||||
|
||||
@Override
|
||||
public void func_73863_a(int p_571_1_, int p_571_2_, float p_571_3_)
|
||||
{
|
||||
this.modList.drawScreen(p_571_1_, p_571_2_, p_571_3_);
|
||||
this.func_548_a(this.field_6451_g, "Mod List", this.field_951_c / 2, 16, 0xFFFFFF);
|
||||
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) {
|
||||
if (selectedMod.getMetadata() != null) {
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
if (!selectedMod.getMetadata().autogenerated) {
|
||||
int shifty = 35;
|
||||
if (!selectedMod.getMetadata().logoFile.isEmpty())
|
||||
{
|
||||
int texture = this.field_945_b.field_6315_n.func_1070_a(selectedMod.getMetadata().logoFile);
|
||||
int texture = this.field_73882_e.field_71446_o.func_78341_b(selectedMod.getMetadata().logoFile);
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
this.field_945_b.field_6315_n.func_1076_b(texture);
|
||||
Dimension dim = FMLClientHandler.instance().getTextureDimensions(texture);
|
||||
this.field_73882_e.field_71446_o.func_78342_b(texture);
|
||||
Dimension dim = TextureFXManager.instance().getTextureDimensions(texture);
|
||||
int top = 32;
|
||||
Tessellator tess = Tessellator.field_1512_a;
|
||||
tess.func_977_b();
|
||||
tess.func_983_a(offset, top + dim.height, field_923_k, 0, 1);
|
||||
tess.func_983_a(offset + dim.width, top + dim.height, field_923_k, 1, 1);
|
||||
tess.func_983_a(offset + dim.width, top, field_923_k, 1, 0);
|
||||
tess.func_983_a(offset, top, field_923_k, 0, 0);
|
||||
tess.func_982_a();
|
||||
|
||||
Tessellator tess = Tessellator.field_78398_a;
|
||||
tess.func_78382_b();
|
||||
tess.func_78374_a(offset, top + dim.height, field_73735_i, 0, 1);
|
||||
tess.func_78374_a(offset + dim.width, top + dim.height, field_73735_i, 1, 1);
|
||||
tess.func_78374_a(offset + dim.width, top, field_73735_i, 1, 0);
|
||||
tess.func_78374_a(offset, top, field_73735_i, 0, 0);
|
||||
tess.func_78381_a();
|
||||
|
||||
shifty += 65;
|
||||
}
|
||||
this.field_6451_g.func_50103_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
|
||||
this.field_73886_k.func_78261_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
|
||||
shifty += 12;
|
||||
|
||||
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getMetadata().version, selectedMod.getVersion()), offset, shifty);
|
||||
|
||||
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getDisplayVersion(), selectedMod.getVersion()), offset, shifty);
|
||||
shifty = drawLine(String.format("Mod State: %s", Loader.instance().getModState(selectedMod)), offset, shifty);
|
||||
if (!selectedMod.getMetadata().credits.isEmpty()) {
|
||||
shifty = drawLine(String.format("Credits: %s", selectedMod.getMetadata().credits), offset, shifty);
|
||||
}
|
||||
shifty = drawLine(String.format("Authors: %s", selectedMod.getMetadata().getAuthorList()), offset, shifty);
|
||||
shifty = drawLine(String.format("URL: %s", selectedMod.getMetadata().url), offset, shifty);
|
||||
shifty = drawLine(selectedMod.getMetadata().childMods.isEmpty() ? "No child mods for this mod" : String.format("Child mods: %s", selectedMod.getMetadata().getChildModList()), offset, shifty);
|
||||
this.getFontRenderer().func_27278_a(selectedMod.getMetadata().description, offset, shifty + 10, this.field_951_c - offset - 20, 0xDDDDDD);
|
||||
this.getFontRenderer().func_78279_b(selectedMod.getMetadata().description, offset, shifty + 10, this.field_73880_f - offset - 20, 0xDDDDDD);
|
||||
} else {
|
||||
offset = ( this.listWidth + this.field_951_c ) / 2;
|
||||
this.func_548_a(this.field_6451_g, selectedMod.getName(), offset, 35, 0xFFFFFF);
|
||||
this.func_548_a(this.field_6451_g, String.format("Version: %s",selectedMod.getVersion()), offset, 45, 0xFFFFFF);
|
||||
this.func_548_a(this.field_6451_g, "No mod information found", offset, 55, 0xDDDDDD);
|
||||
this.func_548_a(this.field_6451_g, "Ask your mod author to provide a mod .info file", offset, 65, 0xDDDDDD);
|
||||
offset = ( this.listWidth + this.field_73880_f ) / 2;
|
||||
this.func_73732_a(this.field_73886_k, selectedMod.getName(), offset, 35, 0xFFFFFF);
|
||||
this.func_73732_a(this.field_73886_k, String.format("Version: %s",selectedMod.getVersion()), offset, 45, 0xFFFFFF);
|
||||
this.func_73732_a(this.field_73886_k, String.format("Mod State: %s",Loader.instance().getModState(selectedMod)), offset, 55, 0xFFFFFF);
|
||||
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_571_a(p_571_1_, p_571_2_, p_571_3_);
|
||||
super.func_73863_a(p_571_1_, p_571_2_, p_571_3_);
|
||||
}
|
||||
|
||||
Minecraft getMinecraftInstance() {
|
||||
return field_945_b;
|
||||
return field_73882_e;
|
||||
}
|
||||
|
||||
|
||||
FontRenderer getFontRenderer() {
|
||||
return field_6451_g;
|
||||
return field_73886_k;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,10 +175,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 cpw.mods.fml.common.MissingModsException;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
|
||||
public class GuiModsMissing extends GuiErrorScreen
|
||||
{
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
||||
public GuiModsMissing(MissingModsException modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
super.func_73866_w_();
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = 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.src.GuiButton;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.GuiSmallButton;
|
||||
import net.minecraft.src.StringTranslate;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
|
||||
public class GuiModsMissingForServer extends GuiScreen
|
||||
{
|
||||
private ModMissingPacket modsMissing;
|
||||
|
||||
public GuiModsMissingForServer(ModMissingPacket modsMissing)
|
||||
{
|
||||
this.modsMissing = modsMissing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_73866_w_()
|
||||
{
|
||||
StringTranslate translations = StringTranslate.func_74808_a();
|
||||
this.field_73887_h.add(new GuiSmallButton(1, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void func_73875_a(GuiButton p_73875_1_)
|
||||
{
|
||||
if (p_73875_1_.field_73742_g && p_73875_1_.field_73741_f == 1)
|
||||
{
|
||||
FMLClientHandler.instance().getClient().func_71373_a(null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||
{
|
||||
this.func_73873_v_();
|
||||
int offset = 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,6 +1,7 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.GuiButton;
|
||||
import net.minecraft.src.Tessellator;
|
||||
@@ -81,9 +82,10 @@ public abstract class GuiScrollingList
|
||||
protected void func_27257_b(int p_27257_1_, int p_27257_2_) {}
|
||||
|
||||
public int func_27256_c(int p_27256_1_, int p_27256_2_)
|
||||
|
||||
{
|
||||
int var3 = this.listWidth / 2 - 110;
|
||||
int var4 = this.listWidth / 2 + 110;
|
||||
int var3 = this.left + 1;
|
||||
int var4 = this.left + this.listWidth - 7;
|
||||
int var5 = p_27256_2_ - this.top - this.field_27261_r + (int)this.scrollDistance - 4;
|
||||
int var6 = var5 / this.slotHeight;
|
||||
return p_27256_1_ >= var3 && p_27256_1_ <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1;
|
||||
@@ -117,15 +119,15 @@ public abstract class GuiScrollingList
|
||||
|
||||
public void actionPerformed(GuiButton button)
|
||||
{
|
||||
if (button.field_937_g)
|
||||
if (button.field_73742_g)
|
||||
{
|
||||
if (button.field_938_f == this.scrollUpActionId)
|
||||
if (button.field_73741_f == this.scrollUpActionId)
|
||||
{
|
||||
this.scrollDistance -= (float)(this.slotHeight * 2 / 3);
|
||||
this.initialMouseClickY = -2.0F;
|
||||
this.applyScrollLimits();
|
||||
}
|
||||
else if (button.field_938_f == this.scrollDownActionId)
|
||||
else if (button.field_73741_f == this.scrollDownActionId)
|
||||
{
|
||||
this.scrollDistance += (float)(this.slotHeight * 2 / 3);
|
||||
this.initialMouseClickY = -2.0F;
|
||||
@@ -249,17 +251,17 @@ public abstract class GuiScrollingList
|
||||
this.applyScrollLimits();
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_FOG);
|
||||
Tessellator var18 = Tessellator.field_1512_a;
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_6315_n.func_1070_a("/gui/background.png"));
|
||||
Tessellator var18 = Tessellator.field_78398_a;
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_71446_o.func_78341_b("/gui/background.png"));
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
float var17 = 32.0F;
|
||||
var18.func_977_b();
|
||||
var18.func_990_b(2105376);
|
||||
var18.func_983_a((double)this.left, (double)this.bottom, 0.0D, (double)((float)this.left / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
|
||||
var18.func_983_a((double)this.right, (double)this.bottom, 0.0D, (double)((float)this.right / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
|
||||
var18.func_983_a((double)this.right, (double)this.top, 0.0D, (double)((float)this.right / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
|
||||
var18.func_983_a((double)this.left, (double)this.top, 0.0D, (double)((float)this.left / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
|
||||
var18.func_982_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78378_d(2105376);
|
||||
var18.func_78374_a((double)this.left, (double)this.bottom, 0.0D, (double)((float)this.left / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
|
||||
var18.func_78374_a((double)this.right, (double)this.bottom, 0.0D, (double)((float)this.right / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
|
||||
var18.func_78374_a((double)this.right, (double)this.top, 0.0D, (double)((float)this.right / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
|
||||
var18.func_78374_a((double)this.left, (double)this.top, 0.0D, (double)((float)this.left / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
|
||||
var18.func_78381_a();
|
||||
// boxRight = this.listWidth / 2 - 92 - 16;
|
||||
var10 = this.top + 4 - (int)this.scrollDistance;
|
||||
|
||||
@@ -283,18 +285,18 @@ public abstract class GuiScrollingList
|
||||
int var15 = boxRight;
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
var18.func_977_b();
|
||||
var18.func_990_b(8421504);
|
||||
var18.func_983_a((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_983_a((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D);
|
||||
var18.func_990_b(0);
|
||||
var18.func_983_a((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_983_a((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D);
|
||||
var18.func_982_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78378_d(8421504);
|
||||
var18.func_78374_a((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78374_a((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78378_d(0);
|
||||
var18.func_78374_a((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78374_a((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78381_a();
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
@@ -311,22 +313,22 @@ public abstract class GuiScrollingList
|
||||
GL11.glDisable(GL11.GL_ALPHA_TEST);
|
||||
GL11.glShadeModel(GL11.GL_SMOOTH);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
var18.func_977_b();
|
||||
var18.func_6513_a(0, 0);
|
||||
var18.func_983_a((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_6513_a(0, 255);
|
||||
var18.func_983_a((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_982_a();
|
||||
var18.func_977_b();
|
||||
var18.func_6513_a(0, 255);
|
||||
var18.func_983_a((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D);
|
||||
var18.func_6513_a(0, 0);
|
||||
var18.func_983_a((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D);
|
||||
var18.func_982_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78384_a(0, 0);
|
||||
var18.func_78374_a((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78384_a(0, 255);
|
||||
var18.func_78374_a((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78381_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78384_a(0, 255);
|
||||
var18.func_78374_a((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78384_a(0, 0);
|
||||
var18.func_78374_a((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78381_a();
|
||||
var19 = this.getContentHeight() - (this.bottom - this.top - 4);
|
||||
|
||||
if (var19 > 0)
|
||||
@@ -350,27 +352,27 @@ public abstract class GuiScrollingList
|
||||
var14 = this.top;
|
||||
}
|
||||
|
||||
var18.func_977_b();
|
||||
var18.func_6513_a(0, 255);
|
||||
var18.func_983_a((double)scrollBarXStart, (double)this.bottom, 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)scrollBarXEnd, (double)this.bottom, 0.0D, 1.0D, 1.0D);
|
||||
var18.func_983_a((double)scrollBarXEnd, (double)this.top, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)scrollBarXStart, (double)this.top, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_982_a();
|
||||
var18.func_977_b();
|
||||
var18.func_6513_a(8421504, 255);
|
||||
var18.func_983_a((double)scrollBarXStart, (double)(var14 + var13), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)scrollBarXEnd, (double)(var14 + var13), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_983_a((double)scrollBarXEnd, (double)var14, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_982_a();
|
||||
var18.func_977_b();
|
||||
var18.func_6513_a(12632256, 255);
|
||||
var18.func_983_a((double)scrollBarXStart, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_983_a((double)(scrollBarXEnd - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_983_a((double)(scrollBarXEnd - 1), (double)var14, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_983_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_982_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78384_a(0, 255);
|
||||
var18.func_78374_a((double)scrollBarXStart, (double)this.bottom, 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)scrollBarXEnd, (double)this.bottom, 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78374_a((double)scrollBarXEnd, (double)this.top, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)scrollBarXStart, (double)this.top, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78381_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78384_a(8421504, 255);
|
||||
var18.func_78374_a((double)scrollBarXStart, (double)(var14 + var13), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)scrollBarXEnd, (double)(var14 + var13), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78374_a((double)scrollBarXEnd, (double)var14, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78381_a();
|
||||
var18.func_78382_b();
|
||||
var18.func_78384_a(12632256, 255);
|
||||
var18.func_78374_a((double)scrollBarXStart, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D);
|
||||
var18.func_78374_a((double)(scrollBarXEnd - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D);
|
||||
var18.func_78374_a((double)(scrollBarXEnd - 1), (double)var14, 0.0D, 1.0D, 0.0D);
|
||||
var18.func_78374_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
|
||||
var18.func_78381_a();
|
||||
}
|
||||
|
||||
this.func_27257_b(mouseX, mouseY);
|
||||
@@ -382,17 +384,17 @@ public abstract class GuiScrollingList
|
||||
|
||||
private void overlayBackground(int p_22239_1_, int p_22239_2_, int p_22239_3_, int p_22239_4_)
|
||||
{
|
||||
Tessellator var5 = Tessellator.field_1512_a;
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_6315_n.func_1070_a("/gui/background.png"));
|
||||
Tessellator var5 = Tessellator.field_78398_a;
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_71446_o.func_78341_b("/gui/background.png"));
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
float var6 = 32.0F;
|
||||
var5.func_977_b();
|
||||
var5.func_6513_a(4210752, p_22239_4_);
|
||||
var5.func_983_a(0.0D, (double)p_22239_2_, 0.0D, 0.0D, (double)((float)p_22239_2_ / var6));
|
||||
var5.func_983_a((double)this.listWidth + 30, (double)p_22239_2_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_2_ / var6));
|
||||
var5.func_6513_a(4210752, p_22239_3_);
|
||||
var5.func_983_a((double)this.listWidth + 30, (double)p_22239_1_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_1_ / var6));
|
||||
var5.func_983_a(0.0D, (double)p_22239_1_, 0.0D, 0.0D, (double)((float)p_22239_1_ / var6));
|
||||
var5.func_982_a();
|
||||
var5.func_78382_b();
|
||||
var5.func_78384_a(4210752, p_22239_4_);
|
||||
var5.func_78374_a(0.0D, (double)p_22239_2_, 0.0D, 0.0D, (double)((float)p_22239_2_ / var6));
|
||||
var5.func_78374_a((double)this.listWidth + 30, (double)p_22239_2_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_2_ / var6));
|
||||
var5.func_78384_a(4210752, p_22239_3_);
|
||||
var5.func_78374_a((double)this.listWidth + 30, (double)p_22239_1_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_1_ / var6));
|
||||
var5.func_78374_a(0.0D, (double)p_22239_1_, 0.0D, 0.0D, (double)((float)p_22239_1_ / var6));
|
||||
var5.func_78381_a();
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,10 @@ package cpw.mods.fml.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
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;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -36,7 +32,7 @@ public class GuiSlotModList extends GuiScrollingList
|
||||
|
||||
public GuiSlotModList(GuiModList parent, ArrayList<ModContainer> mods, int listWidth)
|
||||
{
|
||||
super(parent.getMinecraftInstance(), listWidth, parent.field_950_d, 32, parent.field_950_d - 65 + 4, 10, 35);
|
||||
super(parent.getMinecraftInstance(), listWidth, parent.field_73881_g, 32, parent.field_73881_g - 65 + 4, 10, 35);
|
||||
this.parent=parent;
|
||||
this.mods=mods;
|
||||
}
|
||||
@@ -62,7 +58,7 @@ public class GuiSlotModList extends GuiScrollingList
|
||||
@Override
|
||||
protected void drawBackground()
|
||||
{
|
||||
this.parent.func_578_i();
|
||||
this.parent.func_73873_v_();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,14 +66,23 @@ public class GuiSlotModList extends GuiScrollingList
|
||||
{
|
||||
return (this.getSize()) * 35 + 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void drawSlot(int listIndex, int var2, int var3, int var4, Tessellator var5)
|
||||
{
|
||||
ModContainer mc=mods.get(listIndex);
|
||||
this.parent.getFontRenderer().func_873_b(this.parent.getFontRenderer().func_50107_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFFFFFF);
|
||||
this.parent.getFontRenderer().func_873_b(this.parent.getFontRenderer().func_50107_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xCCCCCC);
|
||||
this.parent.getFontRenderer().func_873_b(this.parent.getFontRenderer().func_50107_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 9), this.left + 3 , var3 + 22, 0xCCCCCC);
|
||||
if (Loader.instance().getModState(mc)==ModState.DISABLED)
|
||||
{
|
||||
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 - 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,35 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import net.minecraft.src.GuiErrorScreen;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,31 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import net.minecraft.src.*;
|
||||
|
||||
public interface ITextureFX
|
||||
{
|
||||
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions);
|
||||
|
||||
public void onTextureDimensionsUpdate(int width, int height);
|
||||
|
||||
public void setErrored(boolean errored);
|
||||
|
||||
public boolean getErrored();
|
||||
}
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.ITexturePack;
|
||||
|
||||
public interface ITextureFX
|
||||
{
|
||||
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions);
|
||||
|
||||
public void onTextureDimensionsUpdate(int width, int height);
|
||||
|
||||
public void setErrored(boolean errored);
|
||||
|
||||
public boolean getErrored();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import cpw.mods.fml.common.IKeyHandler;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class KeyBindingHandler implements IKeyHandler
|
||||
{
|
||||
|
||||
private boolean shouldRepeat;
|
||||
private KeyBinding keyBinding;
|
||||
private ModContainer modContainer;
|
||||
private boolean lastState = false;
|
||||
|
||||
/**
|
||||
* @param keyHandler
|
||||
* @param allowRepeat
|
||||
* @param modContainer
|
||||
*/
|
||||
public KeyBindingHandler(KeyBinding keyHandler, boolean allowRepeat, ModContainer modContainer)
|
||||
{
|
||||
this.keyBinding=keyHandler;
|
||||
this.shouldRepeat=allowRepeat;
|
||||
this.modContainer=modContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getKeyBinding()
|
||||
{
|
||||
return this.keyBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the modContainer
|
||||
*/
|
||||
public ModContainer getOwningContainer()
|
||||
{
|
||||
return modContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndTick()
|
||||
{
|
||||
int keyCode = keyBinding.field_1370_b;
|
||||
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
|
||||
if (state && (!lastState || (lastState && shouldRepeat)))
|
||||
{
|
||||
modContainer.keyBindEvent(keyBinding);
|
||||
}
|
||||
lastState = state;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import cpw.mods.fml.common.FMLModContainer;
|
||||
import cpw.mods.fml.common.IConsoleHandler;
|
||||
import cpw.mods.fml.common.ICraftingHandler;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.IKeyHandler;
|
||||
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.ModContainer;
|
||||
import cpw.mods.fml.common.ModMetadata;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class OptifineModContainer extends FMLModContainer
|
||||
{
|
||||
private String optifineVersion;
|
||||
private ModMetadata metadata;
|
||||
/**
|
||||
* @param optifineConfig
|
||||
*/
|
||||
public OptifineModContainer(Class<?> optifineConfig)
|
||||
{
|
||||
super("Optifine");
|
||||
try
|
||||
{
|
||||
optifineVersion = (String) optifineConfig.getField("VERSION").get(null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "Optifine";
|
||||
}
|
||||
@Override
|
||||
public String getVersion()
|
||||
{
|
||||
return optifineVersion;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,11 +16,10 @@ package cpw.mods.fml.client;
|
||||
|
||||
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.Loader;
|
||||
import cpw.mods.fml.common.LoaderException;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -31,9 +30,12 @@ public class SpriteHelper
|
||||
private static HashMap<String, BitSet> spriteInfo = new HashMap<String, BitSet>();
|
||||
|
||||
private static void initMCSpriteMaps() {
|
||||
BitSet slots =
|
||||
BitSet slots =
|
||||
SpriteHelper.toBitSet(
|
||||
"0000000000000000" +
|
||||
"0000000000110000" +
|
||||
"0000000000100000" +
|
||||
"0000000001100000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
@@ -41,16 +43,13 @@ public class SpriteHelper
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000011111" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000011111100" +
|
||||
"0000000011111111" +
|
||||
"0000000011111000" +
|
||||
"0000000111111100" +
|
||||
"0000000111111000" +
|
||||
"0000000001111100" +
|
||||
"0000000001111000" +
|
||||
"0000000000000000");
|
||||
spriteInfo.put("/terrain.png", slots);
|
||||
|
||||
|
||||
slots = SpriteHelper.toBitSet(
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
@@ -58,23 +57,23 @@ public class SpriteHelper
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000001000000000" +
|
||||
"0000001110000000" +
|
||||
"0000001000000000" +
|
||||
"1111111010000000" +
|
||||
"1111111010100000" +
|
||||
"1111111111111100" +
|
||||
"1111111111111111" +
|
||||
"1111111111111111" +
|
||||
"1111111111111111" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0000000000000000" +
|
||||
"0111100000000000" +
|
||||
"1111100010000000" +
|
||||
"0000101110000000" +
|
||||
"0111000000000000" +
|
||||
"1100001100001111" +
|
||||
"0000000000001111" +
|
||||
"0000000000000000");
|
||||
spriteInfo.put("/gui/items.png", slots);
|
||||
}
|
||||
/**
|
||||
* Register a sprite map for ModTextureStatic, to allow for other mods to override
|
||||
* your sprite page.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static void registerSpriteMapForFile(String file, String spriteMap) {
|
||||
if (spriteInfo.size() == 0) {
|
||||
@@ -86,20 +85,20 @@ public class SpriteHelper
|
||||
}
|
||||
spriteInfo.put(file, toBitSet(spriteMap));
|
||||
}
|
||||
|
||||
|
||||
public static int getUniqueSpriteIndex(String path)
|
||||
{
|
||||
if (!spriteInfo.containsKey("/terrain.png"))
|
||||
{
|
||||
initMCSpriteMaps();
|
||||
}
|
||||
|
||||
|
||||
BitSet slots = spriteInfo.get(path);
|
||||
|
||||
|
||||
if (slots == null)
|
||||
{
|
||||
Exception ex = new Exception(String.format("Invalid getUniqueSpriteIndex call for texture: %s", path));
|
||||
Loader.log.throwing("ModLoader", "getUniqueSpriteIndex", ex);
|
||||
FMLLog.log(Level.SEVERE, ex, "A critical error has been detected with sprite overrides");
|
||||
FMLCommonHandler.instance().raiseException(ex,"Invalid request to getUniqueSpriteIndex",true);
|
||||
}
|
||||
|
||||
@@ -108,7 +107,7 @@ public class SpriteHelper
|
||||
if (ret == -1)
|
||||
{
|
||||
Exception ex = new Exception(String.format("No more sprite indicies left for: %s", path));
|
||||
Loader.log.throwing("ModLoader", "getUniqueSpriteIndex", ex);
|
||||
FMLLog.log(Level.SEVERE, ex, "There are no sprite indicies left for %s", path);
|
||||
FMLCommonHandler.instance().raiseException(ex,"No more sprite indicies left", true);
|
||||
}
|
||||
return ret;
|
||||
@@ -131,10 +130,6 @@ public class SpriteHelper
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param textureToOverride
|
||||
* @return
|
||||
*/
|
||||
public static int freeSlotCount(String textureToOverride)
|
||||
{
|
||||
return spriteInfo.get(textureToOverride).cardinality();
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
package cpw.mods.fml.client;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_BINDING_2D;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.ModTextureStatic;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.ITexturePack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
public class TextureFXManager
|
||||
{
|
||||
private static final TextureFXManager INSTANCE = new TextureFXManager();
|
||||
|
||||
private class TextureProperties
|
||||
{
|
||||
private int textureId;
|
||||
private Dimension dim;
|
||||
}
|
||||
|
||||
private Map<Integer,TextureProperties> textureProperties = Maps.newHashMap();
|
||||
private Multimap<String, OverrideInfo> overrideInfo = ArrayListMultimap.create();
|
||||
private HashSet<OverrideInfo> animationSet = new HashSet<OverrideInfo>();
|
||||
|
||||
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);
|
||||
|
||||
if (ifx != null && ifx.getErrored())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = effect.getClass().getSimpleName();
|
||||
client.field_71424_I.func_76320_a(name);
|
||||
try
|
||||
{
|
||||
if (!FMLClientHandler.instance().hasOptifine())
|
||||
{
|
||||
effect.func_76846_a();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.warning("Texture FX %s has failed to animate. Likely caused by a texture pack change that they did not respond correctly to", name);
|
||||
if (ifx != null)
|
||||
{
|
||||
ifx.setErrored(true);
|
||||
}
|
||||
client.field_71424_I.func_76319_b();
|
||||
return false;
|
||||
}
|
||||
client.field_71424_I.func_76319_b();
|
||||
|
||||
if (ifx != null)
|
||||
{
|
||||
Dimension dim = getTextureDimensions(effect);
|
||||
int target = ((dim.width >> 4) * (dim.height >> 4)) << 2;
|
||||
if (effect.field_76852_a.length != target)
|
||||
{
|
||||
FMLLog.warning("Detected a texture FX sizing discrepancy in %s (%d, %d)", name, effect.field_76852_a.length, target);
|
||||
ifx.setErrored(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//Quick and dirty image scaling, no smoothing or fanciness, meant for speed as it will be called every tick.
|
||||
public void scaleTextureFXData(byte[] data, ByteBuffer buf, int target, int length)
|
||||
{
|
||||
int sWidth = (int)Math.sqrt(data.length / 4);
|
||||
int factor = target / sWidth;
|
||||
byte[] tmp = new byte[4];
|
||||
|
||||
buf.clear();
|
||||
|
||||
if (factor > 1)
|
||||
{
|
||||
for (int y = 0; y < sWidth; y++)
|
||||
{
|
||||
int sRowOff = sWidth * y;
|
||||
int tRowOff = target * y * factor;
|
||||
for (int x = 0; x < sWidth; x++)
|
||||
{
|
||||
int sPos = (x + sRowOff) * 4;
|
||||
tmp[0] = data[sPos + 0];
|
||||
tmp[1] = data[sPos + 1];
|
||||
tmp[2] = data[sPos + 2];
|
||||
tmp[3] = data[sPos + 3];
|
||||
|
||||
int tPosTop = (x * factor) + tRowOff;
|
||||
for (int y2 = 0; y2 < factor; y2++)
|
||||
{
|
||||
buf.position((tPosTop + (y2 * target)) * 4);
|
||||
for (int x2 = 0; x2 < factor; x2++)
|
||||
{
|
||||
buf.put(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf.position(0).limit(length);
|
||||
}
|
||||
|
||||
public void onPreRegisterEffect(TextureFX effect)
|
||||
{
|
||||
Dimension dim = getTextureDimensions(effect);
|
||||
if (effect instanceof ITextureFX)
|
||||
{
|
||||
((ITextureFX)effect).onTextureDimensionsUpdate(dim.width, dim.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getEffectTexture(TextureFX effect)
|
||||
{
|
||||
Integer id = effectTextures.get(effect);
|
||||
if (id != null)
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public void onTexturePackChange(RenderEngine engine, ITexturePack texturepack, List<TextureFX> effects)
|
||||
{
|
||||
pruneOldTextureFX(texturepack, effects);
|
||||
|
||||
for (TextureFX tex : effects)
|
||||
{
|
||||
if (tex instanceof ITextureFX)
|
||||
{
|
||||
((ITextureFX)tex).onTexturePackChanged(engine, texturepack, getTextureDimensions(tex));
|
||||
}
|
||||
}
|
||||
|
||||
loadTextures(texturepack);
|
||||
}
|
||||
|
||||
private HashMap<Integer, Dimension> textureDims = new HashMap<Integer, Dimension>();
|
||||
private IdentityHashMap<TextureFX, Integer> effectTextures = new IdentityHashMap<TextureFX, Integer>();
|
||||
private ITexturePack earlyTexturePack;
|
||||
public void setTextureDimensions(int id, int width, int height, List<TextureFX> effects)
|
||||
{
|
||||
Dimension dim = new Dimension(width, height);
|
||||
textureDims.put(id, dim);
|
||||
|
||||
for (TextureFX tex : effects)
|
||||
{
|
||||
if (getEffectTexture(tex) == id && tex instanceof ITextureFX)
|
||||
{
|
||||
((ITextureFX)tex).onTextureDimensionsUpdate(width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dimension getTextureDimensions(TextureFX effect)
|
||||
{
|
||||
return getTextureDimensions(getEffectTexture(effect));
|
||||
}
|
||||
|
||||
public Dimension getTextureDimensions(int id)
|
||||
{
|
||||
return textureDims.get(id);
|
||||
}
|
||||
|
||||
public void addAnimation(TextureFX anim)
|
||||
{
|
||||
OverrideInfo info=new OverrideInfo();
|
||||
info.index=anim.field_76850_b;
|
||||
info.imageIndex=anim.field_76847_f;
|
||||
info.textureFX=anim;
|
||||
if (animationSet.contains(info)) {
|
||||
animationSet.remove(info);
|
||||
}
|
||||
animationSet.add(info);
|
||||
}
|
||||
|
||||
|
||||
public void loadTextures(ITexturePack texturePack)
|
||||
{
|
||||
registerTextureOverrides(client.field_71446_o);
|
||||
}
|
||||
|
||||
|
||||
public void registerTextureOverrides(RenderEngine renderer) {
|
||||
for (OverrideInfo animationOverride : animationSet) {
|
||||
renderer.func_78355_a(animationOverride.textureFX);
|
||||
addedTextureFX.add(animationOverride.textureFX);
|
||||
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Registered texture override %d (%d) on %s (%d)", animationOverride.index, animationOverride.textureFX.field_76850_b, animationOverride.textureFX.getClass().getSimpleName(), animationOverride.textureFX.field_76847_f));
|
||||
}
|
||||
|
||||
for (String fileToOverride : overrideInfo.keySet()) {
|
||||
for (OverrideInfo override : overrideInfo.get(fileToOverride)) {
|
||||
try
|
||||
{
|
||||
BufferedImage image=loadImageFromTexturePack(renderer, override.override);
|
||||
ModTextureStatic mts=new ModTextureStatic(override.index, 1, override.texture, image);
|
||||
renderer.func_78355_a(mts);
|
||||
addedTextureFX.add(mts);
|
||||
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Registered texture override %d (%d) on %s (%d)", override.index, mts.field_76850_b, override.texture, mts.field_76847_f));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("FMLClientHandler", "registerTextureOverrides", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void registerAnimatedTexturesFor(ModContainer mod)
|
||||
{
|
||||
}
|
||||
|
||||
public void onEarlyTexturePackLoad(ITexturePack fallback)
|
||||
{
|
||||
if (client==null) {
|
||||
// We're far too early- let's wait
|
||||
this.earlyTexturePack = fallback;
|
||||
} else {
|
||||
loadTextures(fallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void pruneOldTextureFX(ITexturePack var1, List<TextureFX> effects)
|
||||
{
|
||||
ListIterator<TextureFX> li = addedTextureFX.listIterator();
|
||||
while (li.hasNext())
|
||||
{
|
||||
TextureFX tex = li.next();
|
||||
if (tex instanceof FMLTextureFX)
|
||||
{
|
||||
if (((FMLTextureFX)tex).unregister(client.field_71446_o, effects))
|
||||
{
|
||||
li.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
effects.remove(tex);
|
||||
li.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void addNewTextureOverride(String textureToOverride, String overridingTexturePath, int location) {
|
||||
OverrideInfo info = new OverrideInfo();
|
||||
info.index = location;
|
||||
info.override = overridingTexturePath;
|
||||
info.texture = textureToOverride;
|
||||
overrideInfo.put(textureToOverride, info);
|
||||
FMLLog.fine("Overriding %s @ %d with %s. %d slots remaining",textureToOverride, location, overridingTexturePath, SpriteHelper.freeSlotCount(textureToOverride));
|
||||
}
|
||||
|
||||
public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
|
||||
{
|
||||
InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
|
||||
if (image==null) {
|
||||
throw new RuntimeException(String.format("The requested image path %s is not found",path));
|
||||
}
|
||||
BufferedImage result=ImageIO.read(image);
|
||||
if (result==null)
|
||||
{
|
||||
throw new RuntimeException(String.format("The requested image path %s appears to be corrupted",path));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static TextureFXManager instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
+15
-12
@@ -12,41 +12,42 @@
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client;
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class BlockRenderInfo
|
||||
public class ModLoaderBlockRendererHandler implements ISimpleBlockRenderingHandler
|
||||
{
|
||||
private int renderId;
|
||||
private boolean render3dInInventory;
|
||||
private ModContainer modContainer;
|
||||
private BaseMod mod;
|
||||
|
||||
/**
|
||||
* @param modContainer
|
||||
*
|
||||
* @param mod
|
||||
*
|
||||
*/
|
||||
public BlockRenderInfo(int renderId, boolean render3dInInventory, ModContainer modContainer)
|
||||
public ModLoaderBlockRendererHandler(int renderId, boolean render3dInInventory, BaseMod mod)
|
||||
{
|
||||
this.renderId=renderId;
|
||||
this.render3dInInventory=render3dInInventory;
|
||||
this.modContainer=modContainer;
|
||||
this.mod=mod;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getRenderId()
|
||||
{
|
||||
return renderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender3DInInventory()
|
||||
{
|
||||
return render3dInInventory;
|
||||
@@ -61,9 +62,10 @@ public class BlockRenderInfo
|
||||
* @param modelId
|
||||
* @param renderer
|
||||
*/
|
||||
@Override
|
||||
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
|
||||
{
|
||||
return ((BaseMod)modContainer.getMod()).renderWorldBlock(renderer, world, x, y, z, block, modelId);
|
||||
return mod.renderWorldBlock(renderer, world, x, y, z, block, modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,9 +74,10 @@ public class BlockRenderInfo
|
||||
* @param modelID
|
||||
* @param renderer
|
||||
*/
|
||||
@Override
|
||||
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer)
|
||||
{
|
||||
((BaseMod)modContainer.getMod()).renderInvBlock(renderer, block, metadata, modelID);
|
||||
mod.renderInvBlock(renderer, block, metadata, modelID);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.BaseMod;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityClientPlayerMP;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.NetClientHandler;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.INetworkManager;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderManager;
|
||||
|
||||
import com.google.common.base.Equivalences;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.MapDifference.ValueDifference;
|
||||
import com.google.common.collect.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
|
||||
{
|
||||
public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
|
||||
{
|
||||
int renderId=RenderingRegistry.getNextAvailableRenderId();
|
||||
ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
|
||||
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(RenderManager.field_78727_a.field_78729_o);
|
||||
|
||||
try
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.client.modloader;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
import com.google.common.primitives.Booleans;
|
||||
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import cpw.mods.fml.client.registry.KeyBindingRegistry;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
|
||||
{
|
||||
private ModLoaderModContainer modContainer;
|
||||
private List<KeyBinding> helper;
|
||||
private boolean[] active = new boolean[0];
|
||||
private boolean[] mlRepeats = new boolean[0];
|
||||
private boolean[] armed = new boolean[0];
|
||||
|
||||
public ModLoaderKeyBindingHandler()
|
||||
{
|
||||
super(new KeyBinding[0], new boolean[0]);
|
||||
}
|
||||
|
||||
void setModContainer(ModLoaderModContainer modContainer)
|
||||
{
|
||||
this.modContainer = modContainer;
|
||||
}
|
||||
|
||||
public void fireKeyEvent(KeyBinding kb)
|
||||
{
|
||||
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(kb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyDown(EnumSet<TickType> type, KeyBinding kb, boolean end, boolean repeats)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int idx = helper.indexOf(kb);
|
||||
if (type.contains(TickType.CLIENT))
|
||||
{
|
||||
armed[idx] = true;
|
||||
}
|
||||
if (armed[idx] && type.contains(TickType.RENDER) && (!active[idx] || mlRepeats[idx]))
|
||||
{
|
||||
fireKeyEvent(kb);
|
||||
active[idx] = true;
|
||||
armed[idx] = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyUp(EnumSet<TickType> type, KeyBinding kb, boolean end)
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int idx = helper.indexOf(kb);
|
||||
active[idx] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<TickType> ticks()
|
||||
{
|
||||
return EnumSet.of(TickType.CLIENT, TickType.RENDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import net.minecraft.src.TileEntity;
|
||||
import net.minecraft.src.TileEntityRenderer;
|
||||
import net.minecraft.src.TileEntitySpecialRenderer;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
|
||||
public class ClientRegistry
|
||||
{
|
||||
/**
|
||||
*
|
||||
* Utility method for registering a tile entity and it's renderer at once - generally you should register them separately
|
||||
*
|
||||
* @param tileEntityClass
|
||||
* @param id
|
||||
* @param specialRenderer
|
||||
*/
|
||||
public static void registerTileEntity(Class <? extends TileEntity > tileEntityClass, String id, TileEntitySpecialRenderer specialRenderer)
|
||||
{
|
||||
GameRegistry.registerTileEntity(tileEntityClass, id);
|
||||
bindTileEntitySpecialRenderer(tileEntityClass, specialRenderer);
|
||||
}
|
||||
|
||||
public static void bindTileEntitySpecialRenderer(Class <? extends TileEntity> tileEntityClass, TileEntitySpecialRenderer specialRenderer)
|
||||
{
|
||||
TileEntityRenderer.field_76963_a.field_76966_m.put(tileEntityClass, specialRenderer);
|
||||
specialRenderer.func_76893_a(TileEntityRenderer.field_76963_a);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
|
||||
public interface ISimpleBlockRenderingHandler
|
||||
{
|
||||
public abstract void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer);
|
||||
|
||||
public abstract boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer);
|
||||
|
||||
public abstract boolean shouldRender3DInInventory();
|
||||
|
||||
public abstract int getRenderId();
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.src.GameSettings;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import 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;
|
||||
|
||||
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[] keyBindings;
|
||||
protected boolean[] keyDown;
|
||||
protected boolean[] repeatings;
|
||||
private boolean isDummy;
|
||||
|
||||
/**
|
||||
* Pass an array of keybindings and a repeat flag for each one
|
||||
*
|
||||
* @param keyBindings
|
||||
* @param repeatings
|
||||
*/
|
||||
public KeyHandler(KeyBinding[] keyBindings, boolean[] repeatings)
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
keyTick(type, true);
|
||||
}
|
||||
|
||||
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
|
||||
{
|
||||
for (int i = 0; i < keyBindings.length; i++)
|
||||
{
|
||||
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]))
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
keyDown(type, keyBinding, tickEnd, state!=keyDown[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyUp(type, keyBinding, tickEnd);
|
||||
}
|
||||
if (tickEnd)
|
||||
{
|
||||
keyDown[i] = state;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 final KeyBindingRegistry INSTANCE = new KeyBindingRegistry();
|
||||
|
||||
private Set<KeyHandler> keyHandlers = Sets.newLinkedHashSet();
|
||||
|
||||
@Deprecated
|
||||
public static KeyBindingRegistry instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
public void uploadKeyBindingsToGame(GameSettings settings)
|
||||
{
|
||||
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
|
||||
for (KeyHandler key : keyHandlers)
|
||||
{
|
||||
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];
|
||||
System.arraycopy(settings.field_74324_K, 0, allKeys, 0, settings.field_74324_K.length);
|
||||
System.arraycopy(modKeyBindings, 0, allKeys, settings.field_74324_K.length, modKeyBindings.length);
|
||||
settings.field_74324_K = allKeys;
|
||||
settings.func_74300_a();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package cpw.mods.fml.client.registry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBiped;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.RenderManager;
|
||||
import net.minecraft.src.RenderPlayer;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.ObjectArrays;
|
||||
|
||||
import cpw.mods.fml.client.SpriteHelper;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class RenderingRegistry
|
||||
{
|
||||
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
|
||||
|
||||
private int nextRenderId = 36;
|
||||
|
||||
private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
|
||||
|
||||
private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 static class EntityRendererInfo
|
||||
{
|
||||
public EntityRendererInfo(Class<? extends Entity> target, Render renderer)
|
||||
{
|
||||
this.target = target;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
private Class<? extends Entity> target;
|
||||
private Render renderer;
|
||||
}
|
||||
|
||||
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
|
||||
{
|
||||
if (!blockRenderers.containsKey(modelId)) { return false; }
|
||||
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
|
||||
return bri.renderWorldBlock(world, x, y, z, block, modelId, renderer);
|
||||
}
|
||||
|
||||
public void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
if (!blockRenderers.containsKey(modelID)) { return; }
|
||||
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelID);
|
||||
bri.renderInventoryBlock(block, metadata, modelID, renderer);
|
||||
}
|
||||
|
||||
public boolean renderItemAsFull3DBlock(int modelId)
|
||||
{
|
||||
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
|
||||
return bri != null && bri.shouldRender3DInInventory();
|
||||
}
|
||||
|
||||
public void loadEntityRenderers(Map<Class<? extends Entity>, Render> rendererMap)
|
||||
{
|
||||
for (EntityRendererInfo info : entityRenderers)
|
||||
{
|
||||
rendererMap.put(info.target, info.renderer);
|
||||
info.renderer.func_76976_a(RenderManager.field_78727_a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,58 +12,51 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static cpw.mods.fml.common.Side.CLIENT;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.IConsoleHandler;
|
||||
import cpw.mods.fml.common.ICraftingHandler;
|
||||
import cpw.mods.fml.common.IDispenseHandler;
|
||||
import cpw.mods.fml.common.INetworkHandler;
|
||||
import cpw.mods.fml.common.IPickupNotifier;
|
||||
import cpw.mods.fml.common.IPlayerTracker;
|
||||
import cpw.mods.fml.common.IWorldGenerator;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.TickType;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
|
||||
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModProxy
|
||||
{
|
||||
// CALLBACK MECHANISMS
|
||||
|
||||
public void keyBindingEvent(Object keybinding)
|
||||
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object... data)
|
||||
{
|
||||
this.keyboardEvent((KeyBinding)keybinding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param minecraftInstance
|
||||
* @return
|
||||
*/
|
||||
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object minecraftInstance, Object... data)
|
||||
{
|
||||
Minecraft mc = (Minecraft) minecraftInstance;
|
||||
boolean hasWorld = mc.field_6324_e != null;
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
boolean hasWorld = mc.field_71441_e != null;
|
||||
// World and render ticks
|
||||
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.GAME ) && hasWorld) {
|
||||
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT ) && hasWorld) {
|
||||
return onTickInGame((Float) data[0], mc);
|
||||
} else if (tickEnd && (tick==TickType.WORLDGUI || tick==TickType.GUI) && data[1]!=null) {
|
||||
return onTickInGUI((Float) data[0], mc, (GuiScreen)data[1]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param renderers
|
||||
*/
|
||||
public final boolean doTickInGUI(TickType tick, boolean tickEnd, Object... data)
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
public final void onRenderHarvest(Map renderers)
|
||||
{
|
||||
addRenderer((Map<Class<? extends Entity>,Render>)renderers);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public final void onRegisterAnimations()
|
||||
{
|
||||
registerAnimation(FMLClientHandler.instance().getClient());
|
||||
@@ -82,7 +75,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean dispense(double x, double y, double z, byte xVelocity, byte zVelocity, Object... data)
|
||||
public final boolean dispense(double x, double y, double z, int xVelocity, int zVelocity, Object... data)
|
||||
{
|
||||
return dispenseEntity((World)data[0], x, y, z, xVelocity, zVelocity, (ItemStack)data[1]);
|
||||
}
|
||||
@@ -90,7 +83,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
@Override
|
||||
public final boolean onChat(Object... data)
|
||||
{
|
||||
receiveChatPacket(((Packet3Chat)data[0]).field_517_a);
|
||||
receiveChatPacket(((Packet3Chat)data[0]).field_73476_b);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,11 +92,11 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
public final void onServerLogin(Object handler) {
|
||||
serverConnect((NetClientHandler) handler);
|
||||
}
|
||||
|
||||
|
||||
public final void onServerLogout() {
|
||||
serverDisconnect();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void onPlayerLogin(Object player)
|
||||
{
|
||||
@@ -133,7 +126,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
{
|
||||
EntityItem item = (EntityItem) pickupData[0];
|
||||
EntityPlayer player = (EntityPlayer) pickupData[1];
|
||||
onItemPickup(player, item.field_801_a);
|
||||
onItemPickup(player, item.field_70294_a);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,35 +145,33 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NO-OP on client side
|
||||
*/
|
||||
@Override
|
||||
public final boolean handleCommand(String command, Object... data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*/
|
||||
// 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
|
||||
@@ -188,16 +179,16 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
* @param xVel
|
||||
* @param zVel
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
|
||||
@Override
|
||||
public int dispenseEntity(World world, ItemStack item, Random rnd, int x, int y, int z, int xVel, int zVel, double entX, double entY, double entZ)
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override if you wish to generate Nether (Hell biome) blocks
|
||||
*
|
||||
*
|
||||
* @param world
|
||||
* @param random
|
||||
* @param chunkX
|
||||
@@ -209,7 +200,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
|
||||
/**
|
||||
* Override if you wish to generate Overworld (not hell or the end) blocks
|
||||
*
|
||||
*
|
||||
* @param world
|
||||
* @param random
|
||||
* @param chunkX
|
||||
@@ -219,10 +210,22 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
@@ -231,8 +234,6 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
|
||||
/**
|
||||
* Get your mod priorities
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPriorities()
|
||||
{
|
||||
@@ -241,11 +242,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
|
||||
/**
|
||||
* Return the version of your mod
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public void keyboardEvent(KeyBinding event)
|
||||
{
|
||||
|
||||
@@ -265,7 +265,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
|
||||
/**
|
||||
* Handle item pickup
|
||||
*
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
*/
|
||||
@@ -275,16 +275,23 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
|
||||
/**
|
||||
* Ticked every game tick if you have subscribed to tick events through {@link ModLoader#setInGameHook(BaseMod, boolean, boolean)}
|
||||
*
|
||||
*
|
||||
* @param time the rendering subtick time (0.0-1.0)
|
||||
* @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;
|
||||
@@ -292,52 +299,81 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
|
||||
/**
|
||||
* Only implemented on the client side
|
||||
* {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)}
|
||||
*
|
||||
* {@link #serverChat(EntityPlayer, Packet3Chat)}
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
public void receiveChatPacket(String text)
|
||||
@Override
|
||||
public void clientChat(String text)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called on the client side
|
||||
* {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)}
|
||||
*
|
||||
* @param packet
|
||||
* Called when a client connects
|
||||
* @param handler
|
||||
*/
|
||||
public void receiveCustomPacket(Packet250CustomPayload packet)
|
||||
@SideOnly(CLIENT)
|
||||
public void clientConnect(NetClientHandler handler)
|
||||
{
|
||||
// TODO
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
}
|
||||
|
||||
public void serverConnect(NetClientHandler handler) {
|
||||
|
||||
@Override
|
||||
public void serverConnect(NetHandler handler) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void serverCustomPayload(NetServerHandler handler, Packet250CustomPayload packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverDisconnect() {
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Called when someone crafts an item from a crafting table
|
||||
*
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
* @param matrix
|
||||
@@ -365,63 +401,42 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
|
||||
return getName() + " " + getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a 250 packet is received on a channel registered to this mod
|
||||
*
|
||||
* @param source
|
||||
* @param payload
|
||||
*/
|
||||
public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@Override
|
||||
public void serverChat(NetServerHandler source, String message)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Called when a server command is received
|
||||
* @param command
|
||||
* @return true if you want to consume the message so it is not available for further processing
|
||||
*/
|
||||
public boolean onServerCommand(String command, String sender, Object listener)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new client logs in.
|
||||
*
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
@Override
|
||||
public void onClientLogin(EntityPlayer player)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a client logs out of the server.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void onClientLogout(EntityPlayer player)
|
||||
@Override
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.registry.FMLRegistry;
|
||||
import cpw.mods.fml.common.registry.IMinecraftRegistry;
|
||||
|
||||
public class ClientRegistry implements IMinecraftRegistry
|
||||
{
|
||||
|
||||
public static ClientRegistry instance() {
|
||||
return (ClientRegistry) FMLRegistry.instance();
|
||||
}
|
||||
@Override
|
||||
public void addRecipe(ItemStack output, Object... params)
|
||||
{
|
||||
CraftingManager.func_1120_a().func_1121_a(output, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addShapelessRecipe(ItemStack output, Object... params)
|
||||
{
|
||||
CraftingManager.func_1120_a().func_21187_b(output, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRecipe(IRecipe recipe)
|
||||
{
|
||||
CraftingManager.func_1120_a().func_25193_b().add(recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSmelting(int input, ItemStack output)
|
||||
{
|
||||
FurnaceRecipes.func_21200_a().func_21199_a(input, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBlock(Block block)
|
||||
{
|
||||
registerBlock(block, ItemBlock.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBlock(Block block, Class <? extends ItemBlock > itemclass)
|
||||
{
|
||||
try
|
||||
{
|
||||
assert block != null : "registerBlock: block cannot be null";
|
||||
assert itemclass != null : "registerBlock: itemclass cannot be null";
|
||||
int blockItemId = block.field_376_bc - 256;
|
||||
itemclass.getConstructor(int.class).newInstance(blockItemId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//HMMM
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEntityID(Class <? extends Entity > entityClass, String entityName, int id)
|
||||
{
|
||||
EntityList.addNewEntityListMapping(entityClass, entityName, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEntityID(Class <? extends Entity > entityClass, String entityName, int id, int backgroundEggColour, int foregroundEggColour)
|
||||
{
|
||||
EntityList.addNewEntityListMapping(entityClass, entityName, id, backgroundEggColour, foregroundEggColour);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTileEntity(Class <? extends TileEntity > tileEntityClass, String id)
|
||||
{
|
||||
TileEntity.addNewTileEntityMapping(tileEntityClass, id);
|
||||
}
|
||||
|
||||
public void registerTileEntity(Class <? extends TileEntity > tileEntityClass, String id, TileEntitySpecialRenderer specialRenderer)
|
||||
{
|
||||
registerTileEntity(tileEntityClass, id);
|
||||
TileEntityRenderer.setTileEntityRenderer(tileEntityClass, specialRenderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBiome(BiomeGenBase biome)
|
||||
{
|
||||
FMLClientHandler.instance().addBiomeToDefaultWorldGenerator(biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSpawn(Class <? extends EntityLiving > entityClass, int weightedProb, int min, int max, EnumCreatureType typeOfCreature, BiomeGenBase... biomes)
|
||||
{
|
||||
for (BiomeGenBase biome : biomes)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<SpawnListEntry> spawns = biome.func_25063_a(typeOfCreature);
|
||||
|
||||
for (SpawnListEntry entry : spawns)
|
||||
{
|
||||
//Adjusting an existing spawn entry
|
||||
if (entry.field_25212_a == entityClass)
|
||||
{
|
||||
entry.field_35590_d = weightedProb;
|
||||
entry.field_35591_b = min;
|
||||
entry.field_35592_c = max;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spawns.add(new SpawnListEntry(entityClass, weightedProb, min, max));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
Class <? extends Entity > entityClazz = EntityList.getEntityToClassMapping().get(entityName);
|
||||
|
||||
if (EntityLiving.class.isAssignableFrom(entityClazz))
|
||||
{
|
||||
addSpawn((Class <? extends EntityLiving >) entityClazz, weightedProb, min, max, spawnList, biomes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBiome(BiomeGenBase biome)
|
||||
{
|
||||
FMLClientHandler.instance().removeBiomeFromDefaultWorldGenerator(biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSpawn(Class <? extends EntityLiving > entityClass, EnumCreatureType typeOfCreature, BiomeGenBase... biomes)
|
||||
{
|
||||
for (BiomeGenBase biome : biomes)
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<SpawnListEntry> spawns = biome.func_25063_a(typeOfCreature).iterator();
|
||||
|
||||
while (spawns.hasNext())
|
||||
{
|
||||
SpawnListEntry entry = spawns.next();
|
||||
if (entry.field_25212_a == entityClass)
|
||||
{
|
||||
spawns.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
Class <? extends Entity > entityClazz = EntityList.getEntityToClassMapping().get(entityName);
|
||||
|
||||
if (EntityLiving.class.isAssignableFrom(entityClazz))
|
||||
{
|
||||
removeSpawn((Class <? extends EntityLiving >) entityClazz, spawnList, biomes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +1,36 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class EntityRendererProxy extends EntityRenderer
|
||||
{
|
||||
|
||||
private Minecraft game;
|
||||
|
||||
public EntityRendererProxy(Minecraft minecraft)
|
||||
{
|
||||
super(minecraft);
|
||||
game = minecraft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_4136_b(float tick)
|
||||
{
|
||||
super.func_4136_b(tick);
|
||||
//This is where ModLoader does all of it's ticking
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class EntityRendererProxy extends EntityRenderer
|
||||
{
|
||||
public static final String fmlMarker = "This is an FML marker";
|
||||
private Minecraft game;
|
||||
|
||||
public EntityRendererProxy(Minecraft minecraft)
|
||||
{
|
||||
super(minecraft);
|
||||
game = minecraft;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_78480_b(float tick)
|
||||
{
|
||||
super.func_78480_b(tick);
|
||||
//This is where ModLoader does all of it's ticking
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,14 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* A static hook library for optifine and other basemod editing code to access FML functions
|
||||
*
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@@ -33,56 +34,59 @@ public class FMLRenderAccessLibrary
|
||||
{
|
||||
public static Logger getLogger()
|
||||
{
|
||||
return FMLCommonHandler.instance().getFMLLogger();
|
||||
return FMLLog.getLogger();
|
||||
}
|
||||
|
||||
|
||||
public static void log(Level level, String message)
|
||||
{
|
||||
getLogger().log(level, message);
|
||||
FMLLog.log(level, message);
|
||||
}
|
||||
|
||||
|
||||
public static void log(Level level, String message, Throwable throwable)
|
||||
{
|
||||
getLogger().log(level, message, throwable);
|
||||
FMLLog.log(level, throwable, message);
|
||||
}
|
||||
|
||||
|
||||
public static void setTextureDimensions(int textureId, int width, int height, List<TextureFX> textureFXList)
|
||||
{
|
||||
FMLClientHandler.instance().setTextureDimensions(textureId, width, height, textureFXList);
|
||||
TextureFXManager.instance().setTextureDimensions(textureId, width, height, textureFXList);
|
||||
}
|
||||
|
||||
|
||||
public static void preRegisterEffect(TextureFX textureFX)
|
||||
{
|
||||
FMLClientHandler.instance().onPreRegisterEffect(textureFX);
|
||||
TextureFXManager.instance().onPreRegisterEffect(textureFX);
|
||||
}
|
||||
|
||||
|
||||
public static boolean onUpdateTextureEffect(TextureFX textureFX)
|
||||
{
|
||||
return FMLClientHandler.instance().onUpdateTextureEffect(textureFX);
|
||||
return TextureFXManager.instance().onUpdateTextureEffect(textureFX);
|
||||
}
|
||||
|
||||
|
||||
public static Dimension getTextureDimensions(TextureFX textureFX)
|
||||
{
|
||||
return FMLClientHandler.instance().getTextureDimensions(textureFX);
|
||||
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)
|
||||
{
|
||||
FMLClientHandler.instance().onTexturePackChange(engine, texturePack, 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 FMLClientHandler.instance().renderWorldBlock(renderer, world, x, y, z, block, 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)
|
||||
{
|
||||
FMLClientHandler.instance().renderInventoryBlock(renderer, block, metadata, modelID);
|
||||
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean renderItemAsFull3DBlock(int modelId)
|
||||
{
|
||||
return FMLClientHandler.instance().renderItemAsFull3DBlock(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,40 +12,56 @@
|
||||
*/
|
||||
package net.minecraft.src;
|
||||
|
||||
import static cpw.mods.fml.common.Side.CLIENT;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.SpriteHelper;
|
||||
import cpw.mods.fml.client.TextureFXManager;
|
||||
import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
|
||||
import cpw.mods.fml.client.modloader.ModLoaderKeyBindingHandler;
|
||||
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.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ReflectionHelper;
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderHelper;
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
import cpw.mods.fml.common.registry.FMLRegistry;
|
||||
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.server.FMLServerHandler;
|
||||
|
||||
public class ModLoader
|
||||
{
|
||||
public static final String fmlMarker = "This is an FML marker";
|
||||
// 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)
|
||||
{
|
||||
String achName=achievement.func_44020_i();
|
||||
String achName=achievement.func_75970_i();
|
||||
addLocalization(achName, name);
|
||||
addLocalization(achName+".desc", description);
|
||||
}
|
||||
@@ -53,11 +69,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)
|
||||
@@ -66,41 +82,55 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers)
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void addAnimation(TextureFX anim)
|
||||
{
|
||||
FMLClientHandler.instance().addAnimation(anim);
|
||||
TextureFXManager.instance().addAnimation(anim);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is unimplemented in server versions to date.
|
||||
*
|
||||
* @param armor
|
||||
* @return
|
||||
* Adds a new prefix to the armor texture list
|
||||
*
|
||||
* {@link RenderingRegistry#addNewArmourRendererPrefix(String))}
|
||||
*
|
||||
* @param armor The new armor prefix
|
||||
* @return The new armor index
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int addArmor(String armor)
|
||||
{
|
||||
return FMLClientHandler.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)
|
||||
{
|
||||
FMLClientHandler.instance().addBiomeToDefaultWorldGenerator(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 localization for the specified string
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param key Key
|
||||
* @param value Value
|
||||
*/
|
||||
public static void addLocalization(String key, String value)
|
||||
{
|
||||
@@ -110,20 +140,20 @@ 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)
|
||||
{
|
||||
FMLCommonHandler.instance().addStringLocalization(key, lang, value);
|
||||
LanguageRegistry.instance().addStringLocalization(key, lang, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
@@ -133,61 +163,73 @@ 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)
|
||||
{
|
||||
FMLCommonHandler.instance().addNameForObject(instance, lang, name);
|
||||
LanguageRegistry.instance().addNameForObject(instance, lang, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
FMLClientHandler.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)
|
||||
{
|
||||
FMLRegistry.addRecipe(output, params);
|
||||
GameRegistry.addRecipe(output, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a shapeless recipe
|
||||
*
|
||||
* @param output
|
||||
* @param params
|
||||
* @param output The result
|
||||
* @param params The input
|
||||
*/
|
||||
public static void addShapelessRecipe(ItemStack output, Object... params)
|
||||
{
|
||||
FMLRegistry.addShapelessRecipe(output, params);
|
||||
GameRegistry.addShapelessRecipe(output, params);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,9 +240,19 @@ public class ModLoader
|
||||
*/
|
||||
public static void addSmelting(int input, ItemStack output)
|
||||
{
|
||||
FMLRegistry.addSmelting(input, output);
|
||||
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
|
||||
*
|
||||
@@ -212,7 +264,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void addSpawn(Class<? extends EntityLiving> entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList)
|
||||
{
|
||||
FMLRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, FMLClientHandler.instance().getDefaultOverworldBiomes());
|
||||
EntityRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, WorldType.base12Biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +279,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void addSpawn(Class<? extends EntityLiving> entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
FMLRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, biomes);
|
||||
EntityRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +293,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList)
|
||||
{
|
||||
FMLRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, FMLClientHandler.instance().getDefaultOverworldBiomes());
|
||||
EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, WorldType.base12Biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,12 +308,24 @@ public class ModLoader
|
||||
*/
|
||||
public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
FMLRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
|
||||
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
|
||||
@@ -270,7 +334,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)
|
||||
@@ -288,7 +352,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void genericContainerRemoval(World world, int x, int y, int z)
|
||||
{
|
||||
TileEntity te = world.func_603_b(x, y, z);
|
||||
/* TileEntity te = world.func_603_b(x, y, z);
|
||||
|
||||
if (!(te instanceof IInventory))
|
||||
{
|
||||
@@ -334,13 +398,13 @@ public class ModLoader
|
||||
world.func_674_a(entityitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/ }
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
@@ -350,77 +414,74 @@ public class ModLoader
|
||||
/**
|
||||
* Get a logger instance {@link FMLCommonHandler#getFMLLogger()}
|
||||
*
|
||||
* @return
|
||||
* @return The current logger
|
||||
*/
|
||||
public static Logger getLogger()
|
||||
{
|
||||
return FMLCommonHandler.instance().getFMLLogger();
|
||||
return FMLLog.getLogger();
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static Minecraft getMinecraftInstance()
|
||||
{
|
||||
return FMLClientHandler.instance().getClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is not the server
|
||||
* {@link FMLClientHandler#getServer()}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Object getMinecraftServerInstance()
|
||||
public static MinecraftServer getMinecraftServerInstance()
|
||||
{
|
||||
return getMinecraftInstance();
|
||||
return FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from a field using reflection
|
||||
* {@link ReflectionHelper#getPrivateValue(Class, Object, int)}
|
||||
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, int)}
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
return ReflectionHelper.getPrivateValue(instanceclass, instance, fieldindex);
|
||||
return ObfuscationReflectionHelper.getPrivateValue(instanceclass, instance, fieldindex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from a field using reflection
|
||||
* {@link ReflectionHelper#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)
|
||||
{
|
||||
return ReflectionHelper.getPrivateValue(instanceclass, instance, field);
|
||||
return ObfuscationReflectionHelper.getPrivateValue(instanceclass, instance, field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stubbed method on the server to return a unique model id
|
||||
*
|
||||
*/
|
||||
@SideOnly(CLIENT)
|
||||
public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
|
||||
{
|
||||
return FMLClientHandler.instance().obtainBlockModelIdFor(mod, inventoryRenderer);
|
||||
return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new unique entity id
|
||||
* {@link Entity#getNextId()}
|
||||
* {@link EntityRegistry#findGlobalUniqueEntityId()}
|
||||
*
|
||||
* @return
|
||||
* @return A unique entity ID
|
||||
*/
|
||||
public static int getUniqueEntityId()
|
||||
{
|
||||
return FMLCommonHandler.instance().nextUniqueEntityListId();
|
||||
return EntityRegistry.findGlobalUniqueEntityId();
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static int getUniqueSpriteIndex(String path)
|
||||
{
|
||||
return SpriteHelper.getUniqueSpriteIndex(path);
|
||||
@@ -432,16 +493,17 @@ 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 FMLCommonHandler.instance().isChannelActive(channel, player);
|
||||
return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean isGUIOpen(Class<? extends GuiScreen> gui)
|
||||
{
|
||||
return FMLClientHandler.instance().getClient().field_6313_p!=null && FMLClientHandler.instance().getClient().field_6313_p.equals(gui);
|
||||
return FMLClientHandler.instance().getClient().field_71462_r != null && FMLClientHandler.instance().getClient().field_71462_r.equals(gui);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,7 +511,7 @@ public class ModLoader
|
||||
* {@link Loader#isModLoaded(String)}
|
||||
*
|
||||
* @param modname
|
||||
* @return
|
||||
* @return If the specified mod is loaded
|
||||
*/
|
||||
public static boolean isModLoaded(String modname)
|
||||
{
|
||||
@@ -464,9 +526,10 @@ public class ModLoader
|
||||
{
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
|
||||
{
|
||||
return FMLClientHandler.instance().loadImageFromTexturePack(renderEngine, path);
|
||||
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,10 +545,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);
|
||||
@@ -498,7 +563,7 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLServerHandler#handlePacket250(Packet250CustomPayload, EntityPlayer)}
|
||||
* {@link FMLNetworkHandler#handlePacket250(Packet250CustomPayload, NetworkManager, NetHandler)}
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
@@ -508,12 +573,14 @@ public class ModLoader
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
|
||||
{
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerAllTextureOverrides(RenderEngine cache)
|
||||
{
|
||||
}
|
||||
@@ -525,7 +592,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void registerBlock(Block block)
|
||||
{
|
||||
FMLRegistry.registerBlock(block);
|
||||
GameRegistry.registerBlock(block);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -536,9 +603,13 @@ public class ModLoader
|
||||
*/
|
||||
public static void registerBlock(Block block, Class<? extends ItemBlock> itemclass)
|
||||
{
|
||||
FMLRegistry.registerBlock(block, itemclass);
|
||||
GameRegistry.registerBlock(block, itemclass);
|
||||
}
|
||||
|
||||
public static void registerContainerID(BaseMod mod, int id)
|
||||
{
|
||||
ModLoaderHelper.buildGuiHelper(mod, id);
|
||||
}
|
||||
/**
|
||||
* Register a new entity ID
|
||||
*
|
||||
@@ -548,7 +619,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id)
|
||||
{
|
||||
FMLRegistry.registerEntityID(entityClass, entityName, id);
|
||||
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -562,26 +633,25 @@ public class ModLoader
|
||||
*/
|
||||
public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id, int background, int foreground)
|
||||
{
|
||||
FMLRegistry.registerEntityID(entityClass, entityName, id, background, foreground);
|
||||
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
|
||||
{
|
||||
FMLClientHandler.instance().registerKeyHandler(mod, keyHandler, allowRepeat);
|
||||
ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the mod for packets on this channel. This only registers the
|
||||
* channel with Forge Mod Loader, not with clients connecting- use
|
||||
* BaseMod.onClientLogin to tell them about your custom channel
|
||||
* {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)}
|
||||
* Register the mod for packets on this channel.
|
||||
* {@link NetworkRegistry#registerChannel(IPacketHandler, String)}
|
||||
*
|
||||
* @param mod
|
||||
* @param channel
|
||||
*/
|
||||
public static void registerPacketChannel(BaseMod mod, String channel)
|
||||
{
|
||||
FMLCommonHandler.instance().registerChannel(FMLCommonHandler.instance().findContainerFor(mod), channel);
|
||||
NetworkRegistry.instance().registerChannel(ModLoaderHelper.buildPacketHandlerFor(mod), channel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,12 +662,13 @@ public class ModLoader
|
||||
*/
|
||||
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id)
|
||||
{
|
||||
FMLRegistry.registerTileEntity(tileEntityClass, id);
|
||||
GameRegistry.registerTileEntity(tileEntityClass, id);
|
||||
}
|
||||
|
||||
@SideOnly(CLIENT)
|
||||
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
|
||||
{
|
||||
ClientRegistry.instance().registerTileEntity(tileEntityClass, id, renderer);
|
||||
ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -607,7 +678,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void removeBiome(BiomeGenBase biome)
|
||||
{
|
||||
FMLRegistry.removeBiome(biome);
|
||||
GameRegistry.removeBiome(biome);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -618,7 +689,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList)
|
||||
{
|
||||
FMLRegistry.removeSpawn(entityClass, spawnList, FMLClientHandler.instance().getDefaultOverworldBiomes());
|
||||
EntityRegistry.removeSpawn(entityClass, spawnList, WorldType.base12Biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -630,7 +701,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
FMLRegistry.removeSpawn(entityClass, spawnList, biomes);
|
||||
EntityRegistry.removeSpawn(entityClass, spawnList, biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -641,7 +712,7 @@ public class ModLoader
|
||||
*/
|
||||
public static void removeSpawn(String entityName, EnumCreatureType spawnList)
|
||||
{
|
||||
FMLRegistry.removeSpawn(entityName, spawnList, FMLClientHandler.instance().getDefaultOverworldBiomes());
|
||||
EntityRegistry.removeSpawn(entityName, spawnList, WorldType.base12Biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,25 +724,28 @@ public class ModLoader
|
||||
*/
|
||||
public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
|
||||
{
|
||||
FMLRegistry.removeSpawn(entityName, spawnList, biomes);
|
||||
EntityRegistry.removeSpawn(entityName, spawnList, biomes);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static boolean renderBlockIsItemFull3D(int modelID)
|
||||
{
|
||||
return FMLClientHandler.instance().renderItemAsFull3DBlock(modelID);
|
||||
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SideOnly(CLIENT)
|
||||
public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
|
||||
{
|
||||
FMLClientHandler.instance().renderInventoryBlock(renderer, block, metadata, 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 FMLClientHandler.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
|
||||
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -683,12 +757,17 @@ public class ModLoader
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet from client to server
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
public static void sendPacket(Packet packet) {
|
||||
FMLClientHandler.instance().sendPacket(packet);
|
||||
PacketDispatcher.sendPacketToServer(packet);
|
||||
}
|
||||
/**
|
||||
* Send a chat message to the server
|
||||
* {@link FMLClientHandler#handleChatPacket(Packet3Chat, EntityPlayer)}
|
||||
* {@link FMLNetworkHandler#handleChatMessage(NetHandler, Packet3Chat)}
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
@@ -699,11 +778,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
|
||||
*
|
||||
@@ -724,7 +816,7 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* Set a private field to a value using reflection
|
||||
* {@link ReflectionHelper#setPrivateValue(Class, Object, int, Object)}
|
||||
* {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, int, Object)}
|
||||
*
|
||||
* @param instanceclass
|
||||
* @param instance
|
||||
@@ -733,12 +825,12 @@ public class ModLoader
|
||||
*/
|
||||
public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, int fieldindex, E value)
|
||||
{
|
||||
ReflectionHelper.setPrivateValue(instanceclass, instance, fieldindex, value);
|
||||
ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, fieldindex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a private field to a value using reflection
|
||||
* {@link ReflectionHelper#setPrivateValue(Class, Object, String, Object)}
|
||||
* {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, String, Object)}
|
||||
*
|
||||
* @param instanceclass
|
||||
* @param instance
|
||||
@@ -747,12 +839,11 @@ public class ModLoader
|
||||
*/
|
||||
public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, String field, E value)
|
||||
{
|
||||
ReflectionHelper.setPrivateValue(instanceclass, instance, field, value);
|
||||
ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, field);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a call in hook from modified external code. Implemented elsewhere.
|
||||
* {@link FMLClientHandler#onItemCrafted(EntityPlayer, ItemStack, IInventory)}
|
||||
*
|
||||
* @param player
|
||||
* @param item
|
||||
@@ -765,7 +856,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
|
||||
@@ -777,7 +867,6 @@ public class ModLoader
|
||||
|
||||
/**
|
||||
* Throw the offered exception. Likely will stop the game.
|
||||
* {@link FMLClientHandler#raiseException(Throwable, String, boolean)}
|
||||
*
|
||||
* @param message
|
||||
* @param e
|
||||
|
||||
@@ -1,128 +1,139 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
/**
|
||||
* A texture override for animations, it takes a vertical image of
|
||||
* texture frames and constantly rotates them in the texture.
|
||||
*/
|
||||
public class ModTextureAnimation extends FMLTextureFX
|
||||
{
|
||||
private final int tickRate;
|
||||
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)
|
||||
{
|
||||
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_6315_n;
|
||||
|
||||
targetTex = target;
|
||||
field_1129_e = size;
|
||||
field_1128_f = re.func_1070_a(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)
|
||||
{
|
||||
throw new IllegalArgumentException(String.format("Attempted to create a TextureAnimation with no complete frames: %dx%d", sWidth, sHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
images = new byte[frames][];
|
||||
BufferedImage image = imgData;
|
||||
|
||||
if (sWidth != tWidth)
|
||||
{
|
||||
BufferedImage b = new BufferedImage(tWidth, tHeight * frames, 6);
|
||||
Graphics2D g = b.createGraphics();
|
||||
g.drawImage(imgData, 0, 0, tWidth, tHeight * frames, 0, 0, sWidth, sHeight, (ImageObserver)null);
|
||||
g.dispose();
|
||||
image = b;
|
||||
}
|
||||
|
||||
for (int frame = 0; frame < frames; frame++)
|
||||
{
|
||||
int[] pixels = new int[tileSizeSquare];
|
||||
image.getRGB(0, tHeight * frame, tWidth, tHeight, pixels, 0, tWidth);
|
||||
images[frame] = new byte[tileSizeSquare << 2];
|
||||
|
||||
for (int i = 0; i < pixels.length; i++)
|
||||
{
|
||||
int i4 = i * 4;
|
||||
images[frame][i4 + 0] = (byte)(pixels[i] >> 16 & 255);
|
||||
images[frame][i4 + 1] = (byte)(pixels[i] >> 8 & 255);
|
||||
images[frame][i4 + 2] = (byte)(pixels[i] >> 0 & 255);
|
||||
images[frame][i4 + 3] = (byte)(pixels[i] >> 24 & 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void func_783_a()
|
||||
{
|
||||
if (++ticks >= tickRate)
|
||||
{
|
||||
if (++index >= images.length)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
field_1127_a = images[index];
|
||||
ticks = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
private final int tickRate;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
throw new IllegalArgumentException(String.format("Attempted to create a TextureAnimation with no complete frames: %dx%d", sWidth, sHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
images = new byte[frames][];
|
||||
BufferedImage image = imgData;
|
||||
|
||||
if (sWidth != tWidth)
|
||||
{
|
||||
BufferedImage b = new BufferedImage(tWidth, tHeight * frames, 6);
|
||||
Graphics2D g = b.createGraphics();
|
||||
g.drawImage(imgData, 0, 0, tWidth, tHeight * frames, 0, 0, sWidth, sHeight, (ImageObserver)null);
|
||||
g.dispose();
|
||||
image = b;
|
||||
}
|
||||
|
||||
for (int frame = 0; frame < frames; frame++)
|
||||
{
|
||||
int[] pixels = new int[tileSizeSquare];
|
||||
image.getRGB(0, tHeight * frame, tWidth, tHeight, pixels, 0, tWidth);
|
||||
images[frame] = new byte[tileSizeSquare << 2];
|
||||
|
||||
for (int i = 0; i < pixels.length; i++)
|
||||
{
|
||||
int i4 = i * 4;
|
||||
images[frame][i4 + 0] = (byte)(pixels[i] >> 16 & 255);
|
||||
images[frame][i4 + 1] = (byte)(pixels[i] >> 8 & 255);
|
||||
images[frame][i4 + 2] = (byte)(pixels[i] >> 0 & 255);
|
||||
images[frame][i4 + 3] = (byte)(pixels[i] >> 24 & 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void func_76846_a()
|
||||
{
|
||||
if (++ticks >= tickRate)
|
||||
{
|
||||
if (++index >= images.length)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
field_76852_a = images[index];
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +1,181 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class ModTextureStatic extends FMLTextureFX
|
||||
{
|
||||
private boolean oldanaglyph = false;
|
||||
private int[] pixels = null;
|
||||
private String targetTex = null;
|
||||
private int storedSize;
|
||||
private BufferedImage overrideData = null;
|
||||
private int needApply = 2;
|
||||
|
||||
|
||||
public ModTextureStatic(int icon, int target, BufferedImage image)
|
||||
{
|
||||
this(icon, 1, target, image);
|
||||
}
|
||||
|
||||
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
|
||||
{
|
||||
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_6315_n;
|
||||
|
||||
targetTex = target;
|
||||
storedSize = size;
|
||||
field_1129_e = size;
|
||||
field_1128_f = re.func_1070_a(target);
|
||||
overrideData = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup()
|
||||
{
|
||||
super.setup();
|
||||
int sWidth = overrideData.getWidth();
|
||||
int sHeight = overrideData.getHeight();
|
||||
|
||||
pixels = new int[tileSizeSquare];
|
||||
if (tileSizeBase == sWidth && tileSizeBase == sHeight)
|
||||
{
|
||||
overrideData.getRGB(0, 0, sWidth, sHeight, pixels, 0, sWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferedImage tmp = new BufferedImage(tileSizeBase, tileSizeBase, 6);
|
||||
Graphics2D gfx = tmp.createGraphics();
|
||||
gfx.drawImage(overrideData, 0, 0, tileSizeBase, tileSizeBase, 0, 0, sWidth, sHeight, (ImageObserver)null);
|
||||
tmp.getRGB(0, 0, tileSizeBase, tileSizeBase, pixels, 0, tileSizeBase);
|
||||
gfx.dispose();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
public void func_783_a()
|
||||
{
|
||||
if (oldanaglyph != field_1131_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.
|
||||
field_1129_e = (needApply == 0 ? 0 : storedSize);
|
||||
if (needApply > 0)
|
||||
{
|
||||
needApply--;
|
||||
}
|
||||
}
|
||||
|
||||
public void func_782_a(RenderEngine p_782_1_)
|
||||
{
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, p_782_1_.func_1070_a(targetTex));
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
needApply = 2;
|
||||
for (int idx = 0; idx < pixels.length; idx++)
|
||||
{
|
||||
int i = idx * 4;
|
||||
int a = pixels[idx] >> 24 & 255;
|
||||
int r = pixels[idx] >> 16 & 255;
|
||||
int g = pixels[idx] >> 8 & 255;
|
||||
int b = pixels[idx] >> 0 & 255;
|
||||
|
||||
if (field_1131_c)
|
||||
{
|
||||
r = g = b = (r + g + b) / 3;
|
||||
}
|
||||
|
||||
field_1127_a[i + 0] = (byte)r;
|
||||
field_1127_a[i + 1] = (byte)g;
|
||||
field_1127_a[i + 2] = (byte)b;
|
||||
field_1127_a[i + 3] = (byte)a;
|
||||
}
|
||||
|
||||
oldanaglyph = field_1131_c;
|
||||
}
|
||||
|
||||
//Implementation of http://scale2x.sourceforge.net/algorithm.html
|
||||
public static BufferedImage scale2x(BufferedImage image)
|
||||
{
|
||||
int w = image.getWidth();
|
||||
int h = image.getHeight();
|
||||
BufferedImage tmp = new BufferedImage(w * 2, h * 2, 2);
|
||||
|
||||
for (int x = 0; x < h; ++x)
|
||||
{
|
||||
int x2 = x * 2;
|
||||
for (int y = 0; y < w; ++y)
|
||||
{
|
||||
int y2 = y * 2;
|
||||
int E = image.getRGB(y, x);
|
||||
int D = (x == 0 ? E : image.getRGB(y, x - 1));
|
||||
int B = (y == 0 ? E : image.getRGB(y - 1, x ));
|
||||
int H = (y >= w - 1 ? E : image.getRGB(y + 1, x ));
|
||||
int F = (x >= h - 1 ? E : image.getRGB(y, x + 1));
|
||||
|
||||
int e0, e1, e2, e3;
|
||||
|
||||
if (B != H && D != F)
|
||||
{
|
||||
e0 = D == B ? D : E;
|
||||
e1 = B == F ? F : E;
|
||||
e2 = D == H ? D : E;
|
||||
e3 = H == F ? F : E;
|
||||
}
|
||||
else
|
||||
{
|
||||
e0 = e1 = e2 = e3 = E;
|
||||
}
|
||||
|
||||
tmp.setRGB(y2, x2, e0);
|
||||
tmp.setRGB(y2 + 1, x2, e1);
|
||||
tmp.setRGB(y2, x2 + 1, e2);
|
||||
tmp.setRGB(y2 + 1, x2 + 1, e3);
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ModTextureStatic %s @ %d", targetTex, field_1126_b);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
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 org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.client.FMLTextureFX;
|
||||
|
||||
public class ModTextureStatic extends FMLTextureFX
|
||||
{
|
||||
private boolean oldanaglyph = false;
|
||||
private int[] pixels = null;
|
||||
private String targetTex = null;
|
||||
private int storedSize;
|
||||
private BufferedImage overrideData = null;
|
||||
private int needApply = 2;
|
||||
|
||||
|
||||
public ModTextureStatic(int icon, int target, BufferedImage image)
|
||||
{
|
||||
this(icon, 1, target, image);
|
||||
}
|
||||
|
||||
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
|
||||
{
|
||||
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()
|
||||
{
|
||||
super.setup();
|
||||
int sWidth = overrideData.getWidth();
|
||||
int sHeight = overrideData.getHeight();
|
||||
|
||||
pixels = new int[tileSizeSquare];
|
||||
if (tileSizeBase == sWidth && tileSizeBase == sHeight)
|
||||
{
|
||||
overrideData.getRGB(0, 0, sWidth, sHeight, pixels, 0, sWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
BufferedImage tmp = new BufferedImage(tileSizeBase, tileSizeBase, 6);
|
||||
Graphics2D gfx = tmp.createGraphics();
|
||||
gfx.drawImage(overrideData, 0, 0, tileSizeBase, tileSizeBase, 0, 0, sWidth, sHeight, (ImageObserver)null);
|
||||
tmp.getRGB(0, 0, tileSizeBase, tileSizeBase, pixels, 0, tileSizeBase);
|
||||
gfx.dispose();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@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.
|
||||
field_76849_e = (needApply == 0 ? 0 : storedSize);
|
||||
if (needApply > 0)
|
||||
{
|
||||
needApply--;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_76845_a(RenderEngine p_76845_1_)
|
||||
{
|
||||
GL11.glBindTexture(GL_TEXTURE_2D, p_76845_1_.func_78341_b(targetTex));
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
needApply = 2;
|
||||
for (int idx = 0; idx < pixels.length; idx++)
|
||||
{
|
||||
int i = idx * 4;
|
||||
int a = pixels[idx] >> 24 & 255;
|
||||
int r = pixels[idx] >> 16 & 255;
|
||||
int g = pixels[idx] >> 8 & 255;
|
||||
int b = pixels[idx] >> 0 & 255;
|
||||
|
||||
if (field_76851_c)
|
||||
{
|
||||
r = g = b = (r + g + b) / 3;
|
||||
}
|
||||
|
||||
field_76852_a[i + 0] = (byte)r;
|
||||
field_76852_a[i + 1] = (byte)g;
|
||||
field_76852_a[i + 2] = (byte)b;
|
||||
field_76852_a[i + 3] = (byte)a;
|
||||
}
|
||||
|
||||
oldanaglyph = field_76851_c;
|
||||
}
|
||||
|
||||
//Implementation of http://scale2x.sourceforge.net/algorithm.html
|
||||
public static BufferedImage scale2x(BufferedImage image)
|
||||
{
|
||||
int w = image.getWidth();
|
||||
int h = image.getHeight();
|
||||
BufferedImage tmp = new BufferedImage(w * 2, h * 2, 2);
|
||||
|
||||
for (int x = 0; x < h; ++x)
|
||||
{
|
||||
int x2 = x * 2;
|
||||
for (int y = 0; y < w; ++y)
|
||||
{
|
||||
int y2 = y * 2;
|
||||
int E = image.getRGB(y, x);
|
||||
int D = (x == 0 ? E : image.getRGB(y, x - 1));
|
||||
int B = (y == 0 ? E : image.getRGB(y - 1, x ));
|
||||
int H = (y >= w - 1 ? E : image.getRGB(y + 1, x ));
|
||||
int F = (x >= h - 1 ? E : image.getRGB(y, x + 1));
|
||||
|
||||
int e0, e1, e2, e3;
|
||||
|
||||
if (B != H && D != F)
|
||||
{
|
||||
e0 = D == B ? D : E;
|
||||
e1 = B == F ? F : E;
|
||||
e2 = D == H ? D : E;
|
||||
e3 = H == F ? F : E;
|
||||
}
|
||||
else
|
||||
{
|
||||
e0 = e1 = e2 = e3 = E;
|
||||
}
|
||||
|
||||
tmp.setRGB(y2, x2, e0);
|
||||
tmp.setRGB(y2 + 1, x2, e1);
|
||||
tmp.setRGB(y2, x2 + 1, e2);
|
||||
tmp.setRGB(y2 + 1, x2 + 1, e3);
|
||||
}
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("ModTextureStatic %s @ %d", targetTex, field_76850_b);
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
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 "";
|
||||
|
||||
/**
|
||||
* The name of the a special bukkit plugin class to load and populate
|
||||
*/
|
||||
String bukkitSide() default "";
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package fml.stubs.mcp;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
public interface BaseMod {
|
||||
int addFuel(int id, int metadata);
|
||||
|
||||
void addRenderer(Map<Class<? extends Entity>, Render> renderers);
|
||||
|
||||
boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item);
|
||||
|
||||
void generateNether(World world, Random random, int chunkX, int chunkZ);
|
||||
|
||||
void generateSurface(World world, Random random, int chunkX, int chunkZ);
|
||||
|
||||
String getName();
|
||||
|
||||
String getPriorities();
|
||||
|
||||
abstract String getVersion();
|
||||
|
||||
void keyboardEvent(KeyBinding event);
|
||||
|
||||
abstract void load();
|
||||
|
||||
void modsLoaded();
|
||||
|
||||
void onItemPickup(EntityPlayer player, ItemStack item);
|
||||
|
||||
boolean onTickInGame(float tick, Minecraft game);
|
||||
|
||||
boolean onTickInGUI(float tick, Minecraft game, GuiScreen gui);
|
||||
|
||||
void receiveChatPacket(String text);
|
||||
|
||||
void receiveCustomPacket(Packet250CustomPayload packet);
|
||||
|
||||
void registerAnimation(Minecraft game);
|
||||
|
||||
void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID);
|
||||
|
||||
boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID);
|
||||
|
||||
void takenFromCrafting(EntityPlayer player, ItemStack item, IInventory matrix);
|
||||
|
||||
void takenFromFurnace(EntityPlayer player, ItemStack item);
|
||||
|
||||
String toString();
|
||||
}
|
||||
@@ -1,250 +0,0 @@
|
||||
package fml.stubs.mcp;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.src.Achievement;
|
||||
import net.minecraft.src.BiomeGenBase;
|
||||
import net.minecraft.src.Block;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityLiving;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.EnumCreatureType;
|
||||
import net.minecraft.src.GuiScreen;
|
||||
import net.minecraft.src.IBlockAccess;
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.ItemBlock;
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.KeyBinding;
|
||||
import net.minecraft.src.NetClientHandler;
|
||||
import net.minecraft.src.Packet1Login;
|
||||
import net.minecraft.src.Packet250CustomPayload;
|
||||
import net.minecraft.src.Render;
|
||||
import net.minecraft.src.RenderBlocks;
|
||||
import net.minecraft.src.RenderEngine;
|
||||
import net.minecraft.src.TextureFX;
|
||||
import net.minecraft.src.TileEntity;
|
||||
import net.minecraft.src.TileEntitySpecialRenderer;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
public class ModLoader {
|
||||
static void addAchievementDesc(Achievement achievement, String name, String description) {
|
||||
}
|
||||
|
||||
static int addAllFuel(int id, int metadata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers) {
|
||||
}
|
||||
|
||||
static void addAnimation(TextureFX anim) {
|
||||
}
|
||||
|
||||
static int addArmor(String armor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void addBiome(BiomeGenBase biome) {
|
||||
}
|
||||
|
||||
static void addLocalization(String key, String value) {
|
||||
}
|
||||
|
||||
static void addLocalization(String key, String lang, String value) {
|
||||
}
|
||||
|
||||
static void addName(Object instance, String name) {
|
||||
}
|
||||
|
||||
static void addName(Object instance, String lang, String name) {
|
||||
}
|
||||
|
||||
static int addOverride(String fileToOverride, String fileToAdd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void addOverride(String path, String overlayPath, int index) {
|
||||
}
|
||||
|
||||
static void addRecipe(ItemStack output, Object... params) {
|
||||
}
|
||||
|
||||
static void addShapelessRecipe(ItemStack output, Object... params) {
|
||||
}
|
||||
|
||||
static void addSmelting(int input, ItemStack output) {
|
||||
}
|
||||
|
||||
static void addSpawn(Class<? extends EntityLiving> entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList) {
|
||||
}
|
||||
|
||||
static void addSpawn(Class<? extends EntityLiving> entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes) {
|
||||
}
|
||||
|
||||
static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList) {
|
||||
}
|
||||
|
||||
static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes) {
|
||||
}
|
||||
|
||||
static boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void genericContainerRemoval(World world, int x, int y, int z) {
|
||||
}
|
||||
|
||||
static List<BaseMod> getLoadedMods() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static Logger getLogger() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static Minecraft getMinecraftInstance() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, int fieldindex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, String field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static int getUniqueBlockModelID(BaseMod mod, boolean full3DItem) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getUniqueEntityId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getUniqueSpriteIndex(String path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static boolean isGUIOpen(Class<? extends GuiScreen> gui) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean isModLoaded(String modname) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void loadConfig() {
|
||||
}
|
||||
|
||||
static BufferedImage loadImage(RenderEngine texCache, String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static void onItemPickup(EntityPlayer player, ItemStack item) {
|
||||
}
|
||||
|
||||
static void onTick(float tick, net.minecraft.client.Minecraft game) {
|
||||
}
|
||||
|
||||
static void openGUI(EntityPlayer player, GuiScreen gui) {
|
||||
}
|
||||
|
||||
static void populateChunk(IChunkProvider generator, int chunkX, int chunkZ, World world) {
|
||||
}
|
||||
|
||||
static void receivePacket(Packet250CustomPayload packet) {
|
||||
}
|
||||
|
||||
static KeyBinding[] registerAllKeys(KeyBinding[] keys) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
static void registerAllTextureOverrides(RenderEngine cache) {
|
||||
}
|
||||
|
||||
static void registerBlock(Block block) {
|
||||
}
|
||||
|
||||
static void registerBlock(Block block, Class<? extends ItemBlock> itemclass) {
|
||||
}
|
||||
|
||||
static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id) {
|
||||
}
|
||||
|
||||
static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id, int background, int foreground) {
|
||||
}
|
||||
|
||||
static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat) {
|
||||
}
|
||||
|
||||
static void registerPacketChannel(BaseMod mod, String channel) {
|
||||
}
|
||||
|
||||
static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id) {
|
||||
}
|
||||
|
||||
static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer) {
|
||||
}
|
||||
|
||||
static void removeBiome(BiomeGenBase biome) {
|
||||
}
|
||||
|
||||
static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList) {
|
||||
}
|
||||
|
||||
static void removeSpawn(Class<? extends EntityLiving> entityClass, EnumCreatureType spawnList, BiomeGenBase... biomes) {
|
||||
}
|
||||
|
||||
static void removeSpawn(String entityName, EnumCreatureType spawnList) {
|
||||
}
|
||||
|
||||
static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes) {
|
||||
}
|
||||
|
||||
static boolean renderBlockIsItemFull3D(int modelID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID) {
|
||||
}
|
||||
|
||||
static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void saveConfig() {
|
||||
}
|
||||
|
||||
static void serverChat(String text) {
|
||||
}
|
||||
|
||||
static void serverLogin(NetClientHandler handler, Packet1Login loginPacket) {
|
||||
}
|
||||
|
||||
static void setInGameHook(BaseMod mod, boolean enable, boolean useClock) {
|
||||
}
|
||||
|
||||
static void setInGUIHook(BaseMod mod, boolean enable, boolean useClock) {
|
||||
}
|
||||
|
||||
static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, int fieldindex, E value) {
|
||||
}
|
||||
|
||||
static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, String field, E value) {
|
||||
}
|
||||
|
||||
static void takenFromCrafting(EntityPlayer player, ItemStack item, IInventory matrix) {
|
||||
}
|
||||
|
||||
static void takenFromFurnace(EntityPlayer player, ItemStack item) {
|
||||
}
|
||||
|
||||
static void throwException(String message, Throwable e) {
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package fml.stubs.obf;
|
||||
|
||||
public interface BaseMod {
|
||||
int addFuel(int id, int metadata);
|
||||
|
||||
void addRenderer(java.util.Map<java.lang.Class<? extends nn>, um> renderers);
|
||||
|
||||
boolean dispenseEntity(xd world, double x, double y, double z, int xVel, int zVel, aan item);
|
||||
|
||||
void generateNether(xd world, java.util.Random random, int chunkX, int chunkZ);
|
||||
|
||||
void generateSurface(xd world, java.util.Random random, int chunkX, int chunkZ);
|
||||
|
||||
java.lang.String getName();
|
||||
|
||||
java.lang.String getPriorities();
|
||||
|
||||
abstract java.lang.String getVersion();
|
||||
|
||||
void keyboardEvent(afu event);
|
||||
|
||||
abstract void load();
|
||||
|
||||
void modsLoaded();
|
||||
|
||||
void onItemPickup(yw player, aan item);
|
||||
|
||||
boolean onTickInGame(float tick, net.minecraft.client.Minecraft game);
|
||||
|
||||
boolean onTickInGUI(float tick, net.minecraft.client.Minecraft game, vp gui);
|
||||
|
||||
void receiveChatPacket(java.lang.String text);
|
||||
|
||||
void receiveCustomPacket(ee packet);
|
||||
|
||||
void registerAnimation(net.minecraft.client.Minecraft game);
|
||||
|
||||
void renderInvBlock(vl renderer, pb block, int metadata, int modelID);
|
||||
|
||||
boolean renderWorldBlock(vl renderer, ali world, int x, int y, int z, pb block, int modelID);
|
||||
|
||||
void takenFromCrafting(yw player, aan item, io matrix);
|
||||
|
||||
void takenFromFurnace(yw player, aan item);
|
||||
|
||||
java.lang.String toString();
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
package fml.stubs.obf;
|
||||
|
||||
public interface ModLoader {
|
||||
static void addAchievementDesc(aeb achievement, java.lang.String name, java.lang.String description);
|
||||
|
||||
static int addAllFuel(int id, int metadata);
|
||||
|
||||
static void addAllRenderers(java.util.Map<java.lang.Class<? extends nn>, um> renderers);
|
||||
|
||||
static void addAnimation(tt anim);
|
||||
|
||||
static int addArmor(java.lang.String armor);
|
||||
|
||||
static void addBiome(abn biome);
|
||||
|
||||
static void addLocalization(java.lang.String key, java.lang.String value);
|
||||
|
||||
static void addLocalization(java.lang.String key, java.lang.String lang, java.lang.String value);
|
||||
|
||||
static void addName(java.lang.Object instance, java.lang.String name);
|
||||
|
||||
static void addName(java.lang.Object instance, java.lang.String lang, java.lang.String name);
|
||||
|
||||
static int addOverride(java.lang.String fileToOverride, java.lang.String fileToAdd);
|
||||
|
||||
static void addOverride(java.lang.String path, java.lang.String overlayPath, int index);
|
||||
|
||||
static void addRecipe(aan output, java.lang.Object... params);
|
||||
|
||||
static void addShapelessRecipe(aan output, java.lang.Object... params);
|
||||
|
||||
static void addSmelting(int input, aan output);
|
||||
|
||||
static void addSpawn(java.lang.Class<? extends acq> entityClass, int weightedProb, int min, int max, acf spawnList);
|
||||
|
||||
static void addSpawn(java.lang.Class<? extends acq> entityClass, int weightedProb, int min, int max, acf spawnList, abn... biomes);
|
||||
|
||||
static void addSpawn(java.lang.String entityName, int weightedProb, int min, int max, acf spawnList);
|
||||
|
||||
static void addSpawn(java.lang.String entityName, int weightedProb, int min, int max, acf spawnList, abn... biomes);
|
||||
|
||||
static boolean dispenseEntity(xd world, double x, double y, double z, int xVel, int zVel, aan item);
|
||||
|
||||
static void genericContainerRemoval(xd world, int x, int y, int z);
|
||||
|
||||
static java.util.List<BaseMod> getLoadedMods();
|
||||
|
||||
static java.util.logging.Logger getLogger();
|
||||
|
||||
static net.minecraft.client.Minecraft getMinecraftInstance();
|
||||
|
||||
static <T, E> T getPrivateValue(java.lang.Class<? super E> instanceclass, E instance, int fieldindex);
|
||||
|
||||
static <T, E> T getPrivateValue(java.lang.Class<? super E> instanceclass, E instance, java.lang.String field);
|
||||
|
||||
static int getUniqueBlockModelID(BaseMod mod, boolean full3DItem);
|
||||
|
||||
static int getUniqueEntityId();
|
||||
|
||||
static int getUniqueSpriteIndex(java.lang.String path);
|
||||
|
||||
static boolean isGUIOpen(java.lang.Class<? extends vp> gui);
|
||||
|
||||
static boolean isModLoaded(java.lang.String modname);
|
||||
|
||||
static void loadConfig();
|
||||
|
||||
static java.awt.image.BufferedImage loadImage(aaw texCache, java.lang.String path);
|
||||
|
||||
static void onItemPickup(yw player, aan item);
|
||||
|
||||
static void onTick(float tick, net.minecraft.client.Minecraft game);
|
||||
|
||||
static void openGUI(yw player, vp gui);
|
||||
|
||||
static void populateChunk(ca generator, int chunkX, int chunkZ, xd world);
|
||||
|
||||
static void receivePacket(ee packet);
|
||||
|
||||
static afu[] registerAllKeys(afu[] keys);
|
||||
|
||||
static void registerAllTextureOverrides(aaw cache);
|
||||
|
||||
static void registerBlock(pb block);
|
||||
|
||||
static void registerBlock(pb block, java.lang.Class<? extends vd> itemclass);
|
||||
|
||||
static void registerEntityID(java.lang.Class<? extends nn> entityClass, java.lang.String entityName, int id);
|
||||
|
||||
static void registerEntityID(java.lang.Class<? extends nn> entityClass, java.lang.String entityName, int id, int background, int foreground);
|
||||
|
||||
static void registerKey(BaseMod mod, afu keyHandler, boolean allowRepeat);
|
||||
|
||||
static void registerPacketChannel(BaseMod mod, java.lang.String channel);
|
||||
|
||||
static void registerTileEntity(java.lang.Class<? extends kw> tileEntityClass, java.lang.String id);
|
||||
|
||||
static void registerTileEntity(java.lang.Class<? extends kw> tileEntityClass, java.lang.String id, aar renderer);
|
||||
|
||||
static void removeBiome(abn biome);
|
||||
|
||||
static void removeSpawn(java.lang.Class<? extends acq> entityClass, acf spawnList);
|
||||
|
||||
static void removeSpawn(java.lang.Class<? extends acq> entityClass, acf spawnList, abn... biomes);
|
||||
|
||||
static void removeSpawn(java.lang.String entityName, acf spawnList);
|
||||
|
||||
static void removeSpawn(java.lang.String entityName, acf spawnList, abn... biomes);
|
||||
|
||||
static boolean renderBlockIsItemFull3D(int modelID);
|
||||
|
||||
static void renderInvBlock(vl renderer, pb block, int metadata, int modelID);
|
||||
|
||||
static boolean renderWorldBlock(vl renderer, ali world, int x, int y, int z, pb block, int modelID);
|
||||
|
||||
static void saveConfig();
|
||||
|
||||
static void serverChat(java.lang.String text);
|
||||
|
||||
static void serverLogin(adl handler, aec loginPacket);
|
||||
|
||||
static void setInGameHook(BaseMod mod, boolean enable, boolean useClock);
|
||||
|
||||
static void setInGUIHook(BaseMod mod, boolean enable, boolean useClock);
|
||||
|
||||
static <T, E> void setPrivateValue(java.lang.Class<? super T> instanceclass, T instance, int fieldindex, E value);
|
||||
|
||||
static <T, E> void setPrivateValue(java.lang.Class<? super T> instanceclass, T instance, java.lang.String field, E value);
|
||||
|
||||
static void takenFromCrafting(yw player, aan item, io matrix);
|
||||
|
||||
static void takenFromFurnace(yw player, aan item);
|
||||
|
||||
static void throwException(java.lang.String message, java.lang.Throwable e);
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
--- commands.py
|
||||
+++ commands.py
|
||||
@@ -58,6 +58,8 @@
|
||||
|
||||
|
||||
def reallyrmtree(path):
|
||||
+ if os.path.isfile(os.path.join(path, 'asm-all-4.0.jar')): #Check if asm exists, indicating the libs folder, if so, don't delete it
|
||||
+ return
|
||||
if not sys.platform.startswith('win'):
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
@@ -584,6 +586,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"""
|
||||
@@ -781,7 +786,8 @@
|
||||
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
|
||||
|
||||
if not os.path.exists(os.path.join(srclk[side], os.path.normpath(testlk[side] + '.java'))):
|
||||
- return False
|
||||
+ if not os.path.exists(os.path.join(self.srcshared, os.path.normpath(testlk[side] + '.java'))):
|
||||
+ return False
|
||||
return True
|
||||
|
||||
def checkbins(self, side):
|
||||
@@ -1029,6 +1035,10 @@
|
||||
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
pathlog = {CLIENT: self.clientrecomplog, SERVER: self.serverrecomplog}
|
||||
|
||||
+ if side == SERVER: #Disable server because FML recombines it into client
|
||||
+ self.logger.info('Server side recompiling skipped, this is normal')
|
||||
+ return
|
||||
+
|
||||
if not os.path.exists(pathbinlk[side]):
|
||||
os.makedirs(pathbinlk[side])
|
||||
|
||||
@@ -1041,6 +1051,7 @@
|
||||
all_files = True
|
||||
append_pattern = False
|
||||
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
|
||||
+ 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],
|
||||
@@ -1062,7 +1073,7 @@
|
||||
raise
|
||||
|
||||
def startserver(self):
|
||||
- classpath = [self.binserver] + self.cpathserver
|
||||
+ classpath = [self.binserver, self.srcshared] + self.cpathserver
|
||||
classpath = [os.path.join('..', p) for p in classpath]
|
||||
classpath = os.pathsep.join(classpath)
|
||||
os.chdir(self.dirjars)
|
||||
@@ -1070,7 +1081,7 @@
|
||||
self.runmc(forkcmd)
|
||||
|
||||
def startclient(self):
|
||||
- classpath = [self.binclient] + self.cpathclient
|
||||
+ classpath = [self.binclient, self.srcshared] + self.cpathclient
|
||||
classpath = [os.path.join('..', p) for p in classpath]
|
||||
classpath = os.pathsep.join(classpath)
|
||||
natives = os.path.join('..', self.dirnatives)
|
||||
@@ -1197,20 +1208,20 @@
|
||||
with open(self.csvmethods, 'rb') as fh:
|
||||
methodsreader = csv.DictReader(fh)
|
||||
for row in methodsreader:
|
||||
- if int(row['side']) == side:
|
||||
+ if int(row['side']) == side or int(row['side']) == 2:
|
||||
if row['name'] != row['searge']:
|
||||
names['methods'][row['searge']] = row['name']
|
||||
with open(self.csvfields, 'rb') as fh:
|
||||
fieldsreader = csv.DictReader(fh)
|
||||
for row in fieldsreader:
|
||||
- if int(row['side']) == side:
|
||||
+ if int(row['side']) == side or int(row['side']) == 2:
|
||||
if row['name'] != row['searge']:
|
||||
names['fields'][row['searge']] = row['name']
|
||||
if self.has_param_csv:
|
||||
with open(self.csvparams, 'rb') as fh:
|
||||
paramsreader = csv.DictReader(fh)
|
||||
for row in paramsreader:
|
||||
- if int(row['side']) == side:
|
||||
+ if int(row['side']) == side or int(row['side']) == 2:
|
||||
names['params'][row['param']] = row['name']
|
||||
|
||||
regexps = {
|
||||
@@ -1240,6 +1251,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
|
||||
@@ -1322,12 +1338,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"""
|
||||
@@ -1336,6 +1354,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'))
|
||||
@@ -1344,13 +1377,13 @@
|
||||
methods = {}
|
||||
for row in methodsreader:
|
||||
#HINT: Only include methods that have a non-empty description
|
||||
- if int(row['side']) == side and row['desc']:
|
||||
+ if (int(row['side']) == side or int(row['side']) == 2) and row['desc']:
|
||||
methods[row['searge']] = row['desc'].replace('*/', '* /')
|
||||
|
||||
fields = {}
|
||||
for row in fieldsreader:
|
||||
#HINT: Only include fields that have a non-empty description
|
||||
- if int(row['side']) == side and row['desc']:
|
||||
+ if (int(row['side']) == side or int(row['side']) == 2) and row['desc']:
|
||||
fields[row['searge']] = row['desc'].replace('*/', '* /')
|
||||
|
||||
regexps = {
|
||||
@@ -1422,12 +1455,13 @@
|
||||
|
||||
# HINT: We create the list of source directories based on the list of packages
|
||||
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
|
||||
+ 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)
|
||||
self.runcmd(forkcmd)
|
||||
return True
|
||||
|
||||
- def gathermd5s(self, side, reobf=False):
|
||||
+ def gathermd5s(self, side, reobf=False, skip_fml=False):
|
||||
if not reobf:
|
||||
md5lk = {CLIENT: self.md5client, SERVER: self.md5server}
|
||||
else:
|
||||
@@ -1442,6 +1476,9 @@
|
||||
class_path = ''
|
||||
else:
|
||||
class_path += '/'
|
||||
+ if skip_fml:
|
||||
+ if class_path.startswith('cpw/'):
|
||||
+ continue
|
||||
for class_file in fnmatch.filter(filelist, '*.class'):
|
||||
class_name = class_path + os.path.splitext(class_file)[0]
|
||||
bin_file = os.path.normpath(os.path.join(path, class_file))
|
||||
@@ -1594,6 +1631,9 @@
|
||||
sys.exit(1)
|
||||
|
||||
for entry in newfiles:
|
||||
+ if 'commands.py' in entry[0]: #FML, Disable updating of Commands.py
|
||||
+ print 'Update to runtime/commands.py found, but disbled due to using fml'
|
||||
+ continue
|
||||
if entry[3] == 'U':
|
||||
self.logger.info('Retrieving file from server : %s', entry[0])
|
||||
cur_file = os.path.normpath(entry[0])
|
||||
@@ -1614,6 +1654,9 @@
|
||||
md5reoblk = {CLIENT: self.md5reobfclient, SERVER: self.md5reobfserver}
|
||||
outpathlk = {CLIENT: self.srcmodclient, SERVER: self.srcmodserver}
|
||||
src = {CLIENT: self.srcclient, SERVER: self.srcserver}
|
||||
+
|
||||
+ if side == SERVER: #Noop out server side stuff
|
||||
+ return
|
||||
|
||||
# HINT: We need a table for the old md5 and the new ones
|
||||
md5table = {}
|
||||
@@ -1646,6 +1689,7 @@
|
||||
# HINT: We extract the source files for the modified class files
|
||||
for in_class in trgclasses:
|
||||
src_file = os.path.normpath(os.path.join(src[side], in_class + '.java'))
|
||||
+ cmn_file = os.path.normpath(os.path.join(self.srcshared, in_class + '.java'))
|
||||
dest_file = os.path.normpath(os.path.join(outpathlk[side], in_class + '.java'))
|
||||
if os.path.isfile(src_file):
|
||||
if not os.path.exists(os.path.dirname(dest_file)):
|
||||
@@ -1655,4 +1699,15 @@
|
||||
self.logger.info('> Outputted %s to %s', in_class.ljust(35), outpathlk[side])
|
||||
except IOError:
|
||||
self.logger.error('* File %s copy failed', in_class)
|
||||
-
|
||||
+ elif os.path.isfile(cmn_file):
|
||||
+ if not os.path.exists(os.path.dirname(dest_file)):
|
||||
+ os.makedirs(os.path.dirname(dest_file))
|
||||
+ try:
|
||||
+ shutil.copyfile(cmn_file, dest_file)
|
||||
+ self.logger.info('> Outputted %s to %s', in_class.ljust(35), outpathlk[side])
|
||||
+ 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
|
||||
*/
|
||||
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,141 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
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.DefaultArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class DummyModContainer implements ModContainer
|
||||
{
|
||||
private ModMetadata md;
|
||||
private ArtifactVersion processedVersion;
|
||||
|
||||
public DummyModContainer(ModMetadata md)
|
||||
{
|
||||
this.md = md;
|
||||
}
|
||||
|
||||
public DummyModContainer()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindMetadata(MetadataCollection mc)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getDependants()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ArtifactVersion> getDependencies()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModMetadata getMetadata()
|
||||
{
|
||||
return md;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getMod()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModId()
|
||||
{
|
||||
return md.modId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return md.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSortingRules()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getSource()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion()
|
||||
{
|
||||
return md.version;
|
||||
}
|
||||
|
||||
public boolean matches(Object mod)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabledState(boolean enabled)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
if (processedVersion == null)
|
||||
{
|
||||
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
|
||||
}
|
||||
return processedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmutable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkMod()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return md.version;
|
||||
}
|
||||
@Override
|
||||
public VersionRange acceptableMinecraftVersionRange()
|
||||
{
|
||||
return Loader.instance().getMinecraftModContainer().getStaticVersionRange();
|
||||
}
|
||||
}
|
||||
@@ -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,32 +13,44 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
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.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
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 cpw.mods.fml.common.ModContainer.SourceType;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.CrashReport;
|
||||
import net.minecraft.src.DedicatedServer;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.EntityPlayerMP;
|
||||
import net.minecraft.src.NBTBase;
|
||||
import net.minecraft.src.NBTTagCompound;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import net.minecraft.src.SaveHandler;
|
||||
import net.minecraft.src.ServerListenThread;
|
||||
import net.minecraft.src.ThreadMinecraftServer;
|
||||
import net.minecraft.src.World;
|
||||
import net.minecraft.src.WorldInfo;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
import cpw.mods.fml.common.registry.TickRegistry;
|
||||
import cpw.mods.fml.server.FMLServerHandler;
|
||||
|
||||
|
||||
/**
|
||||
* The main class for non-obfuscated hook handling code
|
||||
@@ -59,148 +71,72 @@ public class FMLCommonHandler
|
||||
* The singleton
|
||||
*/
|
||||
private static final FMLCommonHandler INSTANCE = new FMLCommonHandler();
|
||||
private static final Pattern metadataFile = Pattern.compile("$/modinfo.json$");;
|
||||
/**
|
||||
* A map of mods to their network channels
|
||||
*/
|
||||
private Map<ModContainer, Set<String>> channelList = new HashMap<ModContainer, Set<String>>();
|
||||
/**
|
||||
* A map of channels to mods
|
||||
*/
|
||||
private Map<String, ModContainer> modChannels = new HashMap<String, ModContainer>();
|
||||
/**
|
||||
* A map of active channels per player
|
||||
*/
|
||||
private Map<Object, Set<String>> activeChannels = new HashMap<Object, Set<String>>();
|
||||
/**
|
||||
* The delegate for side specific data and functions
|
||||
*/
|
||||
private IFMLSidedHandler sidedDelegate;
|
||||
|
||||
private int uniqueEntityListId = 220;
|
||||
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());
|
||||
|
||||
private List<ModContainer> auxilliaryContainers = new ArrayList<ModContainer>();
|
||||
|
||||
private Map<String,Properties> modLanguageData=new HashMap<String,Properties>();
|
||||
|
||||
private PriorityQueue<TickQueueElement> tickHandlers = new PriorityQueue<TickQueueElement>();
|
||||
|
||||
private List<IScheduledTickHandler> scheduledTicks = new ArrayList<IScheduledTickHandler>();
|
||||
|
||||
private Set<IWorldGenerator> worldGenerators = new HashSet<IWorldGenerator>();
|
||||
/**
|
||||
* We register our delegate here
|
||||
* @param handler
|
||||
*/
|
||||
|
||||
private static class TickQueueElement implements Comparable<TickQueueElement>
|
||||
{
|
||||
static long tickCounter = 0;
|
||||
public TickQueueElement(IScheduledTickHandler ticker)
|
||||
{
|
||||
this.ticker = ticker;
|
||||
update();
|
||||
}
|
||||
@Override
|
||||
public int compareTo(TickQueueElement o)
|
||||
{
|
||||
return (int)(next - o.next);
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
next = tickCounter + Math.max(ticker.nextTickSpacing(),1);
|
||||
}
|
||||
|
||||
private long next;
|
||||
private IScheduledTickHandler ticker;
|
||||
|
||||
public boolean scheduledNow()
|
||||
{
|
||||
return tickCounter >= next;
|
||||
}
|
||||
}
|
||||
|
||||
public void beginLoading(IFMLSidedHandler handler)
|
||||
{
|
||||
sidedDelegate = handler;
|
||||
getFMLLogger().info("Attempting early MinecraftForge initialization");
|
||||
FMLLog.info("Attempting early MinecraftForge initialization");
|
||||
callForgeMethod("initialize");
|
||||
getFMLLogger().info("Completed early MinecraftForge initialization");
|
||||
callForgeMethod("registerCrashCallable");
|
||||
FMLLog.info("Completed early MinecraftForge initialization");
|
||||
}
|
||||
|
||||
public void rescheduleTicks()
|
||||
public void rescheduleTicks(Side side)
|
||||
{
|
||||
sidedDelegate.profileStart("modTickScheduling");
|
||||
TickQueueElement.tickCounter++;
|
||||
scheduledTicks.clear();
|
||||
while (true)
|
||||
{
|
||||
if (tickHandlers.size()==0 || !tickHandlers.peek().scheduledNow())
|
||||
{
|
||||
break;
|
||||
}
|
||||
TickQueueElement tickQueueElement = tickHandlers.poll();
|
||||
tickQueueElement.update();
|
||||
tickHandlers.offer(tickQueueElement);
|
||||
scheduledTicks.add(tickQueueElement.ticker);
|
||||
}
|
||||
sidedDelegate.profileEnd();
|
||||
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
|
||||
}
|
||||
public void tickStart(EnumSet<TickType> ticks, Object ... data)
|
||||
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
|
||||
{
|
||||
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
|
||||
|
||||
if (scheduledTicks.size()==0)
|
||||
{
|
||||
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, Object ... data)
|
||||
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
|
||||
{
|
||||
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
|
||||
|
||||
if (scheduledTicks.size()==0)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
public List<IKeyHandler> gatherKeyBindings() {
|
||||
List<IKeyHandler> allKeys=new ArrayList<IKeyHandler>();
|
||||
for (ModContainer mod : Loader.getModList())
|
||||
{
|
||||
allKeys.addAll(mod.getKeys());
|
||||
}
|
||||
for (ModContainer mod : auxilliaryContainers)
|
||||
{
|
||||
allKeys.addAll(mod.getKeys());
|
||||
}
|
||||
return allKeys;
|
||||
}
|
||||
/**
|
||||
* @return the instance
|
||||
*/
|
||||
@@ -211,229 +147,18 @@ public class FMLCommonHandler
|
||||
/**
|
||||
* Find the container that associates with the supplied mod object
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
public ModContainer findContainerFor(Object mod)
|
||||
{
|
||||
for (ModContainer mc : Loader.getModList())
|
||||
{
|
||||
if (mc.matches(mod))
|
||||
{
|
||||
return mc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Loader.instance().getReversedModObjectList().get(mod);
|
||||
}
|
||||
/**
|
||||
* Lookup the mod for a channel
|
||||
* @param channel
|
||||
* @return
|
||||
*/
|
||||
public ModContainer getModForChannel(String channel)
|
||||
{
|
||||
return modChannels.get(channel);
|
||||
}
|
||||
/**
|
||||
* Get the channel list for a mod
|
||||
* @param modLoaderModContainer
|
||||
* @return
|
||||
*/
|
||||
public Set<String> getChannelListFor(ModContainer container)
|
||||
{
|
||||
return channelList.get(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* register a channel to a mod
|
||||
* @param container
|
||||
* @param channelName
|
||||
*/
|
||||
public void registerChannel(ModContainer container, String channelName)
|
||||
{
|
||||
if (modChannels.containsKey(channelName))
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
Set<String> list = channelList.get(container);
|
||||
|
||||
if (list == null)
|
||||
{
|
||||
list = new HashSet<String>();
|
||||
channelList.put(container, list);
|
||||
}
|
||||
|
||||
list.add(channelName);
|
||||
modChannels.put(channelName, container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the channel for the player
|
||||
* @param player
|
||||
*/
|
||||
public void activateChannel(Object player, String channel)
|
||||
{
|
||||
Set<String> active = activeChannels.get(player);
|
||||
|
||||
if (active == null)
|
||||
{
|
||||
active = new HashSet<String>();
|
||||
activeChannels.put(player, active);
|
||||
}
|
||||
|
||||
active.add(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the channel for the player
|
||||
* @param player
|
||||
* @param channel
|
||||
*/
|
||||
public void deactivateChannel(Object player, String channel)
|
||||
{
|
||||
Set<String> active = activeChannels.get(player);
|
||||
|
||||
if (active == null)
|
||||
{
|
||||
active = new HashSet<String>();
|
||||
activeChannels.put(player, active);
|
||||
}
|
||||
|
||||
active.remove(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet 250 channel registration string
|
||||
* @return
|
||||
*/
|
||||
public byte[] getPacketRegistry()
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (String chan : modChannels.keySet())
|
||||
{
|
||||
sb.append(chan).append("\0");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return sb.toString().getBytes("UTF8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
Loader.log.warning("Error building registration list");
|
||||
Loader.log.throwing("FMLHooks", "getPacketRegistry", e);
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the specified channel active for the player?
|
||||
* @param channel
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isChannelActive(String channel, Object player)
|
||||
{
|
||||
return activeChannels.get(player).contains(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the forge mod loader logging instance (goes to the forgemodloader log file)
|
||||
* @return
|
||||
*/
|
||||
public Logger getFMLLogger()
|
||||
{
|
||||
return Loader.log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minecraft logger (goes to the server log file)
|
||||
* @return
|
||||
*/
|
||||
public Logger getMinecraftLogger()
|
||||
{
|
||||
if (sidedDelegate == null)
|
||||
{
|
||||
throw new RuntimeException("sidedDelegate null when attempting to getMinecraftLogger, this is generally caused by you not installing FML properly, " +
|
||||
"or installing some other mod that edits Minecraft.class on top of FML such as ModLoader, do not do this. Reinstall FML properly and try again.");
|
||||
}
|
||||
return sidedDelegate.getMinecraftLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a modloader mod?
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public boolean isModLoaderMod(Class<?> clazz)
|
||||
{
|
||||
return sidedDelegate.isModLoaderMod(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the modloader mod
|
||||
* @param clazz
|
||||
* @param canonicalPath
|
||||
* @return
|
||||
*/
|
||||
public ModContainer loadBaseModMod(Class<?> clazz, File canonicalFile)
|
||||
{
|
||||
return sidedDelegate.loadBaseModMod(clazz, canonicalFile);
|
||||
}
|
||||
|
||||
public File getMinecraftRootDirectory() {
|
||||
return sidedDelegate.getMinecraftRootDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Object getMinecraftInstance()
|
||||
{
|
||||
return sidedDelegate.getMinecraftInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public int nextUniqueEntityListId()
|
||||
{
|
||||
return uniqueEntityListId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @param lang
|
||||
* @param value
|
||||
*/
|
||||
public void addStringLocalization(String key, String lang, String value)
|
||||
{
|
||||
Properties langPack=modLanguageData.get(lang);
|
||||
if (langPack==null) {
|
||||
langPack=new Properties();
|
||||
modLanguageData.put(lang, langPack);
|
||||
}
|
||||
langPack.put(key,value);
|
||||
|
||||
handleLanguageLoad(sidedDelegate.getCurrentLanguageTable(), lang);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param languagePack
|
||||
* @param lang
|
||||
*/
|
||||
public void handleLanguageLoad(Properties languagePack, String lang)
|
||||
{
|
||||
Properties usPack=modLanguageData.get("en_US");
|
||||
if (usPack!=null) {
|
||||
languagePack.putAll(usPack);
|
||||
}
|
||||
Properties langPack=modLanguageData.get(lang);
|
||||
if (langPack==null) {
|
||||
return;
|
||||
}
|
||||
languagePack.putAll(langPack);
|
||||
return FMLLog.getLogger();
|
||||
}
|
||||
|
||||
public Side getSide()
|
||||
@@ -441,66 +166,42 @@ public class FMLCommonHandler
|
||||
return sidedDelegate.getSide();
|
||||
}
|
||||
|
||||
public void addAuxilliaryModContainer(ModContainer ticker)
|
||||
{
|
||||
auxilliaryContainers.add(ticker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the furnace to lookup fuel values
|
||||
*
|
||||
* @param itemId
|
||||
* @param itemDamage
|
||||
* @return
|
||||
* 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 int fuelLookup(int itemId, int itemDamage)
|
||||
public Side getEffectiveSide()
|
||||
{
|
||||
int fv = 0;
|
||||
|
||||
for (ModContainer mod : Loader.getModList())
|
||||
Thread thr = Thread.currentThread();
|
||||
if ((thr instanceof ThreadMinecraftServer) || (thr instanceof ServerListenThread))
|
||||
{
|
||||
fv = Math.max(fv, mod.lookupFuelValue(itemId, itemDamage));
|
||||
return Side.SERVER;
|
||||
}
|
||||
|
||||
return fv;
|
||||
return Side.CLIENT;
|
||||
}
|
||||
|
||||
public void addNameForObject(Object minecraftObject, String lang, String name) {
|
||||
String label=sidedDelegate.getObjectName(minecraftObject);
|
||||
addStringLocalization(label, lang, name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Raise an exception
|
||||
*
|
||||
* @param exception
|
||||
* @param message
|
||||
* @param stopGame
|
||||
*/
|
||||
public void raiseException(Throwable exception, String message, boolean stopGame)
|
||||
{
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("FMLHandler", "raiseException", exception);
|
||||
throw new RuntimeException(exception);
|
||||
if (stopGame)
|
||||
{
|
||||
getSidedDelegate().haltGame(message,exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Class<?> forge;
|
||||
private boolean noForge;
|
||||
|
||||
private Class<?> findMinecraftForge()
|
||||
{
|
||||
if (forge==null && !noForge)
|
||||
{
|
||||
try {
|
||||
forge = Class.forName("forge.MinecraftForge");
|
||||
forge = Class.forName("net.minecraftforge.common.MinecraftForge");
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
forge = Class.forName("net.minecraft.src.forge.MinecraftForge");
|
||||
} catch (Exception ex2) {
|
||||
// Ignore- forge isn't loaded
|
||||
noForge = true;
|
||||
}
|
||||
noForge = true;
|
||||
}
|
||||
}
|
||||
return forge;
|
||||
@@ -520,138 +221,219 @@ public class FMLCommonHandler
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string
|
||||
* @return
|
||||
*/
|
||||
public String[] getBrandingStrings(String mcVersion)
|
||||
|
||||
public void computeBranding()
|
||||
{
|
||||
ArrayList<String> brandings=new ArrayList<String>();
|
||||
brandings.add(mcVersion);
|
||||
brandings.add(Loader.instance().getFMLVersionString());
|
||||
String forgeVersion = (String)callForgeMethod("getVersionString");
|
||||
if (forgeVersion != null)
|
||||
if (brandings == null)
|
||||
{
|
||||
brandings.add(forgeVersion);
|
||||
Builder brd = ImmutableList.<String>builder();
|
||||
brd.add(Loader.instance().getMCVersionString());
|
||||
brd.add("FML v"+Loader.instance().getFMLVersionString());
|
||||
String forgeBranding = (String) callForgeMethod("getBrandingVersion");
|
||||
if (!Strings.isNullOrEmpty(forgeBranding))
|
||||
{
|
||||
brd.add(forgeBranding);
|
||||
}
|
||||
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
|
||||
try {
|
||||
Properties props=new Properties();
|
||||
props.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
|
||||
brd.add(props.getProperty("fmlbranding"));
|
||||
} catch (Exception ex) {
|
||||
// Ignore - no branding file found
|
||||
}
|
||||
int tModCount = Loader.instance().getModList().size();
|
||||
int aModCount = Loader.instance().getActiveModList().size();
|
||||
brd.add(String.format("%d mod%s loaded, %d mod%s active", tModCount, tModCount!=1 ? "s" :"", aModCount, aModCount!=1 ? "s" :"" ));
|
||||
brandings = brd.build();
|
||||
}
|
||||
brandings.addAll(sidedDelegate.getAdditionalBrandingInformation());
|
||||
try {
|
||||
Properties props=new Properties();
|
||||
props.load(FMLCommonHandler.class.getClassLoader().getResourceAsStream("fmlbranding.properties"));
|
||||
brandings.add(props.getProperty("fmlbranding"));
|
||||
} catch (Exception ex) {
|
||||
// Ignore - no branding file found
|
||||
}
|
||||
brandings.add(String.format("%d mod%s loaded",Loader.getModList().size(), Loader.getModList().size()!=1?"s":""));
|
||||
Collections.reverse(brandings);
|
||||
return brandings.toArray(new String[brandings.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
*/
|
||||
public void loadMetadataFor(ModContainer mod)
|
||||
public List<String> getBrandings()
|
||||
{
|
||||
if (mod.getSourceType()==SourceType.JAR) {
|
||||
ZipFile jar = null;
|
||||
try
|
||||
{
|
||||
jar = new ZipFile(mod.getSource());
|
||||
ZipEntry infoFile=jar.getEntry("mcmod.info");
|
||||
if (infoFile!=null) {
|
||||
InputStream input=jar.getInputStream(infoFile);
|
||||
ModMetadata data=sidedDelegate.readMetadataFrom(input, mod);
|
||||
mod.setMetadata(data);
|
||||
} else {
|
||||
getFMLLogger().fine(String.format("Failed to find mcmod.info file in %s for %s", mod.getSource().getName(), mod.getName()));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Something wrong but we don't care
|
||||
getFMLLogger().fine(String.format("Failed to find mcmod.info file in %s for %s", mod.getSource().getName(), mod.getName()));
|
||||
getFMLLogger().throwing("FMLCommonHandler", "loadMetadataFor", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (jar!=null)
|
||||
{
|
||||
try
|
||||
{
|
||||
jar.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// GO AWAY
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try
|
||||
{
|
||||
InputStream input=Loader.instance().getModClassLoader().getResourceAsStream(mod.getName()+".info");
|
||||
if (input==null) {
|
||||
input=Loader.instance().getModClassLoader().getResourceAsStream("net/minecraft/src/"+mod.getName()+".info");
|
||||
}
|
||||
if (input!=null) {
|
||||
ModMetadata data=sidedDelegate.readMetadataFrom(input, mod);
|
||||
mod.setMetadata(data);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Something wrong but we don't care
|
||||
getFMLLogger().fine(String.format("Failed to find %s.info file in %s for %s", mod.getName(), mod.getSource().getName(), mod.getName()));
|
||||
getFMLLogger().throwing("FMLCommonHandler", "loadMetadataFor", e);
|
||||
}
|
||||
if (brandings == null)
|
||||
{
|
||||
computeBranding();
|
||||
}
|
||||
return ImmutableList.copyOf(brandings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public IFMLSidedHandler getSidedDelegate()
|
||||
{
|
||||
return sidedDelegate;
|
||||
}
|
||||
|
||||
public void onPostServerTick()
|
||||
{
|
||||
tickEnd(EnumSet.of(TickType.SERVER), Side.SERVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mod
|
||||
* Every tick just after world and other ticks occur
|
||||
*/
|
||||
public void injectSidedProxyDelegate(ModContainer mod)
|
||||
public void onPostWorldTick(Object world)
|
||||
{
|
||||
ProxyInjector injector = mod.findSidedProxy();
|
||||
if (injector != null)
|
||||
tickEnd(EnumSet.of(TickType.WORLD), Side.SERVER, world);
|
||||
}
|
||||
|
||||
public void onPreServerTick()
|
||||
{
|
||||
tickStart(EnumSet.of(TickType.SERVER), Side.SERVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Every tick just before world and other ticks occur
|
||||
*/
|
||||
public void onPreWorldTick(Object world)
|
||||
{
|
||||
tickStart(EnumSet.of(TickType.WORLD), Side.SERVER, world);
|
||||
}
|
||||
|
||||
public void onWorldLoadTick(World[] worlds)
|
||||
{
|
||||
rescheduleTicks(Side.SERVER);
|
||||
for (World w : worlds)
|
||||
{
|
||||
injector.inject(mod, sidedDelegate.getSide());
|
||||
tickStart(EnumSet.of(TickType.WORLDLOAD), Side.SERVER, w);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleWorldGeneration(int chunkX, int chunkZ, long worldSeed, Object... data)
|
||||
public void handleServerStarting(MinecraftServer server)
|
||||
{
|
||||
Random fmlRandom = new Random(worldSeed);
|
||||
long xSeed = fmlRandom.nextLong() >> 2 + 1L;
|
||||
long zSeed = fmlRandom.nextLong() >> 2 + 1L;
|
||||
fmlRandom.setSeed((xSeed * chunkX + zSeed * chunkZ) ^ worldSeed);
|
||||
Loader.instance().serverStarting(server);
|
||||
}
|
||||
|
||||
for (IWorldGenerator generator : worldGenerators)
|
||||
public void handleServerStarted()
|
||||
{
|
||||
Loader.instance().serverStarted();
|
||||
}
|
||||
|
||||
public void handleServerStopping()
|
||||
{
|
||||
Loader.instance().serverStopping();
|
||||
}
|
||||
|
||||
public MinecraftServer getMinecraftServerInstance()
|
||||
{
|
||||
return sidedDelegate.getServer();
|
||||
}
|
||||
|
||||
public void showGuiScreen(Object clientGuiElement)
|
||||
{
|
||||
sidedDelegate.showGuiScreen(clientGuiElement);
|
||||
}
|
||||
|
||||
public Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket entitySpawnPacket)
|
||||
{
|
||||
return sidedDelegate.spawnEntityIntoClientWorld(registration, entitySpawnPacket);
|
||||
}
|
||||
|
||||
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
|
||||
{
|
||||
sidedDelegate.adjustEntityLocationOnClient(entitySpawnAdjustmentPacket);
|
||||
}
|
||||
|
||||
public void onServerStart(DedicatedServer dedicatedServer)
|
||||
{
|
||||
FMLServerHandler.instance();
|
||||
sidedDelegate.beginServerLoading(dedicatedServer);
|
||||
}
|
||||
|
||||
public void onServerStarted()
|
||||
{
|
||||
sidedDelegate.finishServerLoading();
|
||||
}
|
||||
|
||||
|
||||
public void onPreClientTick()
|
||||
{
|
||||
tickStart(EnumSet.of(TickType.CLIENT), Side.CLIENT);
|
||||
|
||||
}
|
||||
|
||||
public void onPostClientTick()
|
||||
{
|
||||
tickEnd(EnumSet.of(TickType.CLIENT), Side.CLIENT);
|
||||
}
|
||||
|
||||
public void onRenderTickStart(float timer)
|
||||
{
|
||||
tickStart(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
|
||||
}
|
||||
|
||||
public void onRenderTickEnd(float timer)
|
||||
{
|
||||
tickEnd(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
|
||||
}
|
||||
|
||||
public void onPlayerPreTick(EntityPlayer player)
|
||||
{
|
||||
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
|
||||
tickStart(EnumSet.of(TickType.PLAYER), side, player);
|
||||
}
|
||||
|
||||
public void onPlayerPostTick(EntityPlayer player)
|
||||
{
|
||||
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
|
||||
tickEnd(EnumSet.of(TickType.PLAYER), side, player);
|
||||
}
|
||||
|
||||
public void registerCrashCallable(ICrashCallable callable)
|
||||
{
|
||||
crashCallables.add(callable);
|
||||
}
|
||||
|
||||
public void enhanceCrashReport(CrashReport crashReport)
|
||||
{
|
||||
for (ICrashCallable call: crashCallables)
|
||||
{
|
||||
generator.generate(fmlRandom, chunkX, chunkZ, data);
|
||||
crashReport.func_71500_a(call.getLabel(), call);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTickHandler(ITickHandler handler)
|
||||
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
|
||||
{
|
||||
registerScheduledTickHandler(new SingleIntervalHandler(handler));
|
||||
sidedDelegate.handleTinyPacket(handler, mapData);
|
||||
}
|
||||
|
||||
public void registerScheduledTickHandler(IScheduledTickHandler handler)
|
||||
public void handleWorldDataSave(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
|
||||
{
|
||||
tickHandlers.add(new TickQueueElement(handler));
|
||||
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 registerWorldGenerator(IWorldGenerator generator)
|
||||
public void handleWorldDataLoad(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
|
||||
{
|
||||
worldGenerators.add(generator);
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import net.minecraft.src.NBTBase;
|
||||
import net.minecraft.src.NBTTagCompound;
|
||||
import net.minecraft.src.NBTTagList;
|
||||
import net.minecraft.src.NBTTagString;
|
||||
import net.minecraft.src.SaveHandler;
|
||||
import net.minecraft.src.WorldInfo;
|
||||
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class FMLDummyContainer extends DummyModContainer implements WorldAccessContainer
|
||||
{
|
||||
public FMLDummyContainer()
|
||||
{
|
||||
super(new ModMetadata());
|
||||
ModMetadata meta = getMetadata();
|
||||
meta.modId="FML";
|
||||
meta.name="Forge Mod Loader";
|
||||
meta.version=Loader.instance().getFMLVersionString();
|
||||
meta.credits="Made possible with help from many people";
|
||||
meta.authorList=Arrays.asList("cpw, LexManos");
|
||||
meta.description="The Forge Mod Loader provides the ability for systems to load mods " +
|
||||
"from the file system. It also provides key capabilities for mods to be able " +
|
||||
"to cooperate and provide a good modding environment. " +
|
||||
"The mod loading system is compatible with ModLoader, all your ModLoader " +
|
||||
"mods should work.";
|
||||
meta.url="https://github.com/cpw/FML/wiki";
|
||||
meta.updateUrl="https://github.com/cpw/FML/wiki";
|
||||
meta.screenshots=new String[0];
|
||||
meta.logoFile="";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
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);
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class FMLLog
|
||||
{
|
||||
private static cpw.mods.fml.relauncher.FMLRelaunchLog coreLog = cpw.mods.fml.relauncher.FMLRelaunchLog.log;
|
||||
|
||||
public static void log(Level level, String format, Object... data)
|
||||
{
|
||||
coreLog.log(level, format, data);
|
||||
}
|
||||
|
||||
public static void log(Level level, Throwable ex, String format, Object... data)
|
||||
{
|
||||
coreLog.log(level, ex, format, data);
|
||||
}
|
||||
|
||||
public static void severe(String format, Object... data)
|
||||
{
|
||||
log(Level.SEVERE, format, data);
|
||||
}
|
||||
|
||||
public static void warning(String format, Object... data)
|
||||
{
|
||||
log(Level.WARNING, format, data);
|
||||
}
|
||||
|
||||
public static void info(String format, Object... data)
|
||||
{
|
||||
log(Level.INFO, format, data);
|
||||
}
|
||||
|
||||
public static void fine(String format, Object... data)
|
||||
{
|
||||
log(Level.FINE, format, data);
|
||||
}
|
||||
|
||||
public static void finer(String format, Object... data)
|
||||
{
|
||||
log(Level.FINER, format, data);
|
||||
}
|
||||
|
||||
public static void finest(String format, Object... data)
|
||||
{
|
||||
log(Level.FINEST, format, data);
|
||||
}
|
||||
public static Logger getLogger()
|
||||
{
|
||||
return coreLog.getLogger();
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,51 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
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.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.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
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.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.event.FMLConstructionEvent;
|
||||
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 cpw.mods.fml.common.event.FMLStateEvent;
|
||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||
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
|
||||
{
|
||||
@@ -23,101 +65,53 @@ public class FMLModContainer implements ModContainer
|
||||
private Object modInstance;
|
||||
private File source;
|
||||
private ModMetadata modMetadata;
|
||||
private String className;
|
||||
private Map<String, Object> descriptor;
|
||||
private boolean enabled = true;
|
||||
private String internalVersion;
|
||||
private boolean overridesMetadata;
|
||||
private EventBus eventBus;
|
||||
private LoadController controller;
|
||||
private Multimap<Class<? extends Annotation>, Object> annotations;
|
||||
private DefaultArtifactVersion processedVersion;
|
||||
private boolean isNetworkMod;
|
||||
|
||||
public FMLModContainer(String dummy)
|
||||
private static final BiMap<Class<? extends FMLStateEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLStateEvent>, 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)
|
||||
.build();
|
||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||
private String annotationDependencies;
|
||||
private VersionRange minecraftAccepted;
|
||||
|
||||
|
||||
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
||||
{
|
||||
this(new File(dummy));
|
||||
}
|
||||
public FMLModContainer(File source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public FMLModContainer(Class<?> clazz)
|
||||
{
|
||||
if (clazz == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
modDescriptor = clazz.getAnnotation(Mod.class);
|
||||
|
||||
try
|
||||
{
|
||||
modInstance = clazz.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.className = className;
|
||||
this.source = modSource;
|
||||
this.descriptor = modDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantsPreInit()
|
||||
public String getModId()
|
||||
{
|
||||
return modDescriptor.wantsPreInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantsPostInit()
|
||||
{
|
||||
return modDescriptor.wantsPostInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preInit()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public static ModContainer buildFor(Class<?> clazz)
|
||||
{
|
||||
return new FMLModContainer(clazz);
|
||||
return (String) descriptor.get("modid");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return modMetadata.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModState getModState()
|
||||
public String getVersion()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public String getSortingRules()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object mod)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
return internalVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,267 +120,360 @@ public class FMLModContainer implements ModContainer
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getMod()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lookupFuelValue(int itemId, int itemDamage)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantsPickupNotification()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPickupNotifier getPickupNotifier()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#wantsToDispense()
|
||||
*/
|
||||
@Override
|
||||
public boolean wantsToDispense()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getDispenseHandler()
|
||||
*/
|
||||
@Override
|
||||
public IDispenseHandler getDispenseHandler()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#wantsCraftingNotification()
|
||||
*/
|
||||
@Override
|
||||
public boolean wantsCraftingNotification()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getCraftingHandler()
|
||||
*/
|
||||
@Override
|
||||
public ICraftingHandler getCraftingHandler()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getDependencies()
|
||||
*/
|
||||
@Override
|
||||
public List<String> getDependencies()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return new ArrayList<String>(0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getPreDepends()
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPreDepends()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return new ArrayList<String>(0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getPostDepends()
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPostDepends()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return new ArrayList<String>(0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getSource().getName();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#wantsNetworkPackets()
|
||||
*/
|
||||
@Override
|
||||
public boolean wantsNetworkPackets()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getNetworkHandler()
|
||||
*/
|
||||
@Override
|
||||
public INetworkHandler getNetworkHandler()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#ownsNetworkChannel(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean ownsNetworkChannel(String channel)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#wantsConsoleCommands()
|
||||
*/
|
||||
@Override
|
||||
public boolean wantsConsoleCommands()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getConsoleHandler()
|
||||
*/
|
||||
@Override
|
||||
public IConsoleHandler getConsoleHandler()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#wantsPlayerTracking()
|
||||
*/
|
||||
@Override
|
||||
public boolean wantsPlayerTracking()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getPlayerTracker()
|
||||
*/
|
||||
@Override
|
||||
public IPlayerTracker getPlayerTracker()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getKeys()
|
||||
*/
|
||||
@Override
|
||||
public List<IKeyHandler> getKeys()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getSourceType()
|
||||
*/
|
||||
@Override
|
||||
public SourceType getSourceType()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#setSourceType(cpw.mods.fml.common.ModContainer.SourceType)
|
||||
*/
|
||||
@Override
|
||||
public void setSourceType(SourceType type)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getMetadata()
|
||||
*/
|
||||
@Override
|
||||
public ModMetadata getMetadata()
|
||||
{
|
||||
return modMetadata;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#setMetadata(cpw.mods.fml.common.ModMetadata)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void setMetadata(ModMetadata meta)
|
||||
public void bindMetadata(MetadataCollection mc)
|
||||
{
|
||||
this.modMetadata=meta;
|
||||
modMetadata = mc.getMetadataForId(getModId(), descriptor);
|
||||
|
||||
if (descriptor.containsKey("useMetadata"))
|
||||
{
|
||||
overridesMetadata = !((Boolean)descriptor.get("useMetadata")).booleanValue();
|
||||
}
|
||||
|
||||
if (overridesMetadata || !modMetadata.useDependencyInformation)
|
||||
{
|
||||
Set<ArtifactVersion> requirements = Sets.newHashSet();
|
||||
List<ArtifactVersion> dependencies = Lists.newArrayList();
|
||||
List<ArtifactVersion> dependants = Lists.newArrayList();
|
||||
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();
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#gatherRenderers(java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
public void gatherRenderers(Map renderers)
|
||||
|
||||
public Properties searchForVersionProperties()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#requestAnimations()
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void requestAnimations()
|
||||
public void setEnabledState(boolean enabled)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
this.enabled = enabled;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#getVersion()
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getVersion()
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return modMetadata.requiredMods;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#findSidedProxy()
|
||||
*/
|
||||
|
||||
@Override
|
||||
public ProxyInjector findSidedProxy()
|
||||
public List<ArtifactVersion> getDependencies()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return modMetadata.dependencies;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.ModContainer#keyBindEvernt(java.lang.Object)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void keyBindEvent(Object keyBinding)
|
||||
public List<ArtifactVersion> getDependants()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return modMetadata.dependants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSortingRules()
|
||||
{
|
||||
return ((overridesMetadata || !modMetadata.useDependencyInformation) ? Strings.nullToEmpty(annotationDependencies) : modMetadata.printableSortingRules());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object mod)
|
||||
{
|
||||
return mod == modInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getMod()
|
||||
{
|
||||
return modInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
if (this.enabled)
|
||||
{
|
||||
FMLLog.fine("Enabling mod %s", getModId());
|
||||
this.eventBus = bus;
|
||||
this.controller = controller;
|
||||
eventBus.register(this);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Multimap<Class<? extends Annotation>, Object> gatherAnnotations(Class<?> clazz) throws Exception
|
||||
{
|
||||
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
|
||||
|
||||
for (Method m : clazz.getDeclaredMethods())
|
||||
{
|
||||
for (Annotation a : m.getAnnotations())
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return anns;
|
||||
}
|
||||
|
||||
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
|
||||
{
|
||||
SetMultimap<String, ASMData> annotations = asmDataTable.getAnnotationsFor(this);
|
||||
|
||||
parseSimpleFieldAnnotation(annotations, Instance.class.getName(), new Function<ModContainer, Object>()
|
||||
{
|
||||
public Object apply(ModContainer mc)
|
||||
{
|
||||
return mc.getMod();
|
||||
}
|
||||
});
|
||||
parseSimpleFieldAnnotation(annotations, Metadata.class.getName(), new Function<ModContainer, Object>()
|
||||
{
|
||||
public Object apply(ModContainer mc)
|
||||
{
|
||||
return mc.getMetadata();
|
||||
}
|
||||
});
|
||||
|
||||
//TODO
|
||||
// for (Object o : annotations.get(Block.class))
|
||||
// {
|
||||
// Field f = (Field) o;
|
||||
// f.set(modInstance, GameRegistry.buildBlock(this, f.getType(), f.getAnnotation(Block.class)));
|
||||
// }
|
||||
}
|
||||
|
||||
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
|
||||
{
|
||||
String[] annName = annotationClassName.split("\\.");
|
||||
String annotationName = annName[annName.length - 1];
|
||||
for (ASMData targets : annotations.get(annotationClassName))
|
||||
{
|
||||
String targetMod = (String) targets.getAnnotationInfo().get("value");
|
||||
Field f = null;
|
||||
Object injectedMod = null;
|
||||
ModContainer mc = this;
|
||||
boolean isStatic = false;
|
||||
Class<?> clz = modInstance.getClass();
|
||||
if (!Strings.isNullOrEmpty(targetMod))
|
||||
{
|
||||
if (Loader.isModLoaded(targetMod))
|
||||
{
|
||||
mc = Loader.instance().getIndexedModList().get(targetMod);
|
||||
}
|
||||
else
|
||||
{
|
||||
mc = null;
|
||||
}
|
||||
}
|
||||
if (mc != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader());
|
||||
f = clz.getDeclaredField(targets.getObjectName());
|
||||
f.setAccessible(true);
|
||||
isStatic = Modifier.isStatic(f.getModifiers());
|
||||
injectedMod = retreiver.apply(mc);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
FMLLog.log(Level.WARNING, e, "Attempting to load @%s in class %s for %s and failing", annotationName, targets.getClassName(), mc.getModId());
|
||||
}
|
||||
}
|
||||
if (f != null)
|
||||
{
|
||||
Object target = null;
|
||||
if (!isStatic)
|
||||
{
|
||||
target = modInstance;
|
||||
if (!modInstance.getClass().equals(clz))
|
||||
{
|
||||
FMLLog.warning("Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f.set(target, injectedMod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void constructMod(FMLConstructionEvent event)
|
||||
{
|
||||
try
|
||||
{
|
||||
ModClassLoader modClassLoader = event.getModClassLoader();
|
||||
modClassLoader.addFile(source);
|
||||
Class<?> clazz = Class.forName(className, true, modClassLoader);
|
||||
ASMDataTable asmHarvestedAnnotations = event.getASMHarvestedData();
|
||||
// TODO
|
||||
asmHarvestedAnnotations.getAnnotationsFor(this);
|
||||
annotations = gatherAnnotations(clazz);
|
||||
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
|
||||
modInstance = clazz.newInstance();
|
||||
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
||||
processFieldAnnotations(event.getASMHarvestedData());
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
controller.errorOccurred(this, e);
|
||||
Throwables.propagateIfPossible(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleModStateEvent(FMLStateEvent event)
|
||||
{
|
||||
Class<? extends Annotation> annotation = modAnnotationTypes.get(event.getClass());
|
||||
if (annotation == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
for (Object o : annotations.get(annotation))
|
||||
{
|
||||
Method m = (Method) o;
|
||||
m.invoke(modInstance, event);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
controller.errorOccurred(this, t);
|
||||
Throwables.propagateIfPossible(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
if (processedVersion == null)
|
||||
{
|
||||
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
|
||||
}
|
||||
return processedVersion;
|
||||
}
|
||||
@Override
|
||||
public boolean isImmutable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkMod()
|
||||
{
|
||||
return isNetworkMod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayVersion()
|
||||
{
|
||||
return modMetadata.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionRange acceptableMinecraftVersionRange()
|
||||
{
|
||||
return minecraftAccepted;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class FMLModLoaderContainer extends FMLModContainer
|
||||
{
|
||||
|
||||
/**
|
||||
* @param dummy
|
||||
*/
|
||||
public FMLModLoaderContainer()
|
||||
{
|
||||
super("Forge Mod Loader");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.FMLModContainer#getMetadata()
|
||||
*/
|
||||
@Override
|
||||
public ModMetadata getMetadata()
|
||||
{
|
||||
if (super.getMetadata()==null) {
|
||||
ModMetadata md=new ModMetadata(this);
|
||||
setMetadata(md);
|
||||
md.name="Forge Mod Loader";
|
||||
md.version=Loader.instance().getFMLVersionString();
|
||||
md.credits="Made possible with help from many people";
|
||||
md.authorList=Arrays.asList("cpw, LexManos");
|
||||
md.description="The Forge Mod Loader provides the ability for systems to load mods " +
|
||||
"from the file system. It also provides key capabilities for mods to be able " +
|
||||
"to cooperate and provide a good modding environment. " +
|
||||
"The mod loading system is compatible with ModLoader, all your ModLoader " +
|
||||
"mods should work.";
|
||||
md.url="https://github.com/cpw/FML/wiki";
|
||||
md.updateUrl="https://github.com/cpw/FML/wiki";
|
||||
md.screenshots=new String[0];
|
||||
md.logoFile="";
|
||||
}
|
||||
return super.getMetadata();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.FMLModContainer#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "Forge Mod Loader";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see cpw.mods.fml.common.FMLModContainer#getVersion()
|
||||
*/
|
||||
@Override
|
||||
public String getVersion()
|
||||
{
|
||||
return Loader.instance().getFMLVersionString();
|
||||
}
|
||||
}
|
||||
@@ -13,28 +13,31 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
import net.minecraft.src.IInventory;
|
||||
import net.minecraft.src.ItemStack;
|
||||
|
||||
/**
|
||||
* Return a crafting handler for the mod container to call
|
||||
*
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface ICraftingHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* The object array contains these three arguments
|
||||
*
|
||||
*
|
||||
* @param player
|
||||
* @param craftedItem
|
||||
* @param craftingGrid
|
||||
* @param item
|
||||
* @param craftMatrix
|
||||
*/
|
||||
void onCrafting(Object... craftingParameters);
|
||||
void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix);
|
||||
|
||||
/**
|
||||
* The object array contains these two arguments
|
||||
* @param player
|
||||
* @param smeltedItem
|
||||
* @param item
|
||||
*/
|
||||
void onSmelting(Object... smeltingParameters);
|
||||
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,9 +12,30 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
|
||||
public interface IDispenseHandler
|
||||
{
|
||||
boolean dispense(double x, double y, double z, byte xVelocity, byte zVelocity, Object... data);
|
||||
|
||||
/**
|
||||
* 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 world
|
||||
* @param item
|
||||
* @param random
|
||||
* @param entX
|
||||
* @param entY
|
||||
* @param entZ
|
||||
*/
|
||||
@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,29 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IDispenserHandler
|
||||
{
|
||||
/**
|
||||
* Called to dispense an entity
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param xVelocity
|
||||
* @param zVelocity
|
||||
* @param world
|
||||
* @param item
|
||||
* @param random
|
||||
* @param entX
|
||||
* @param entY
|
||||
* @param entZ
|
||||
*/
|
||||
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,30 +1,44 @@
|
||||
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 cpw.mods.fml.common.modloader.BaseMod;
|
||||
import cpw.mods.fml.common.modloader.ModProperty;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.src.Entity;
|
||||
import net.minecraft.src.NetHandler;
|
||||
import net.minecraft.src.Packet;
|
||||
import net.minecraft.src.Packet131MapData;
|
||||
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
|
||||
import cpw.mods.fml.common.network.EntitySpawnPacket;
|
||||
import cpw.mods.fml.common.network.ModMissingPacket;
|
||||
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||
|
||||
public interface IFMLSidedHandler
|
||||
{
|
||||
Logger getMinecraftLogger();
|
||||
File getMinecraftRootDirectory();
|
||||
boolean isModLoaderMod(Class<?> clazz);
|
||||
ModContainer loadBaseModMod(Class<?> clazz, File canonicalFile);
|
||||
Object getMinecraftInstance();
|
||||
String getCurrentLanguage();
|
||||
Properties getCurrentLanguageTable();
|
||||
String getObjectName(Object minecraftObject);
|
||||
ModMetadata readMetadataFrom(InputStream input, ModContainer mod) throws Exception;
|
||||
void profileStart(String profileLabel);
|
||||
void profileEnd();
|
||||
ModProperty getModLoaderPropertyFor(Field f);
|
||||
List<String> getAdditionalBrandingInformation();
|
||||
|
||||
Side getSide();
|
||||
ProxyInjector findSidedProxyOn(BaseMod mod);
|
||||
|
||||
void haltGame(String message, Throwable exception);
|
||||
|
||||
void showGuiScreen(Object clientGuiElement);
|
||||
|
||||
Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket packet);
|
||||
|
||||
void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket);
|
||||
|
||||
void beginServerLoading(MinecraftServer server);
|
||||
|
||||
void finishServerLoading();
|
||||
|
||||
MinecraftServer getServer();
|
||||
|
||||
void sendPacket(Packet packet);
|
||||
|
||||
void displayMissingMods(ModMissingPacket modMissingPacket);
|
||||
|
||||
void handleTinyPacket(NetHandler handler, Packet131MapData mapData);
|
||||
|
||||
void setClientCompatibilityLevel(byte compatibilityLevel);
|
||||
|
||||
byte getClientCompatibilityLevel();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.ItemStack;
|
||||
|
||||
public interface IFuelHandler
|
||||
{
|
||||
int getBurnTime(ItemStack fuel);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite.
|
||||
* Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IKeyHandler
|
||||
{
|
||||
|
||||
Object getKeyBinding();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
ModContainer getOwningContainer();
|
||||
|
||||
void onEndTick();
|
||||
|
||||
}
|
||||
@@ -13,7 +13,10 @@
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.EntityItem;
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
|
||||
public interface IPickupNotifier
|
||||
{
|
||||
void notifyPickup(Object... pickupData);
|
||||
void notifyPickup(EntityItem item, EntityPlayer player);
|
||||
}
|
||||
@@ -14,13 +14,19 @@
|
||||
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import net.minecraft.src.EntityPlayer;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface IPlayerTracker
|
||||
{
|
||||
void onPlayerLogin(Object player);
|
||||
void onPlayerLogout(Object player);
|
||||
void onPlayerChangedDimension(Object player);
|
||||
void onPlayerLogin(EntityPlayer player);
|
||||
|
||||
void onPlayerLogout(EntityPlayer player);
|
||||
|
||||
void onPlayerChangedDimension(EntityPlayer player);
|
||||
|
||||
void onPlayerRespawn(EntityPlayer player);
|
||||
}
|
||||
@@ -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,10 +15,12 @@ package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.src.IChunkProvider;
|
||||
import net.minecraft.src.World;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
@@ -26,14 +28,14 @@ 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public void generate(Random random, int chunkX, int chunkZ, Object...additionalData);
|
||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider);
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
public class InjectedModContainer implements ModContainer
|
||||
{
|
||||
private File source;
|
||||
private ModContainer wrappedContainer;
|
||||
|
||||
public InjectedModContainer(ModContainer mc, File source)
|
||||
{
|
||||
this.source = source;
|
||||
this.wrappedContainer = mc;
|
||||
}
|
||||
|
||||
public String getModId()
|
||||
{
|
||||
return wrappedContainer.getModId();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return wrappedContainer.getName();
|
||||
}
|
||||
|
||||
public String getVersion()
|
||||
{
|
||||
return wrappedContainer.getVersion();
|
||||
}
|
||||
|
||||
public File getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
public ModMetadata getMetadata()
|
||||
{
|
||||
return wrappedContainer.getMetadata();
|
||||
}
|
||||
|
||||
public void bindMetadata(MetadataCollection mc)
|
||||
{
|
||||
wrappedContainer.bindMetadata(mc);
|
||||
}
|
||||
|
||||
public void setEnabledState(boolean enabled)
|
||||
{
|
||||
wrappedContainer.setEnabledState(enabled);
|
||||
}
|
||||
|
||||
public Set<ArtifactVersion> getRequirements()
|
||||
{
|
||||
return wrappedContainer.getRequirements();
|
||||
}
|
||||
|
||||
public List<ArtifactVersion> getDependencies()
|
||||
{
|
||||
return wrappedContainer.getDependencies();
|
||||
}
|
||||
|
||||
public List<ArtifactVersion> getDependants()
|
||||
{
|
||||
return wrappedContainer.getDependants();
|
||||
}
|
||||
|
||||
public String getSortingRules()
|
||||
{
|
||||
return wrappedContainer.getSortingRules();
|
||||
}
|
||||
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
return wrappedContainer.registerBus(bus, controller);
|
||||
}
|
||||
|
||||
public boolean matches(Object mod)
|
||||
{
|
||||
return wrappedContainer.matches(mod);
|
||||
}
|
||||
|
||||
public Object getMod()
|
||||
{
|
||||
return wrappedContainer.getMod();
|
||||
}
|
||||
|
||||
public ArtifactVersion getProcessedVersion()
|
||||
{
|
||||
return wrappedContainer.getProcessedVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkMod()
|
||||
{
|
||||
return wrappedContainer.isNetworkMod();
|
||||
}
|
||||
@Override
|
||||
public boolean isImmutable()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
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.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.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.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
|
||||
public class LoadController
|
||||
{
|
||||
private Loader loader;
|
||||
private EventBus masterChannel;
|
||||
private ImmutableMap<String,EventBus> eventChannels;
|
||||
private LoaderState state;
|
||||
private Multimap<String, ModState> modStates = ArrayListMultimap.create();
|
||||
private Multimap<String, Throwable> errors = ArrayListMultimap.create();
|
||||
private Map<String, ModContainer> modList;
|
||||
private List<ModContainer> activeModList = Lists.newArrayList();
|
||||
private ModContainer activeContainer;
|
||||
private BiMap<ModContainer, Object> modObjectList;
|
||||
|
||||
public LoadController(Loader loader)
|
||||
{
|
||||
this.loader = loader;
|
||||
this.masterChannel = new EventBus("FMLMainChannel");
|
||||
this.masterChannel.register(this);
|
||||
|
||||
state = LoaderState.NOINIT;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void buildModList(FMLLoadEvent event)
|
||||
{
|
||||
this.modList = loader.getIndexedModList();
|
||||
Builder<String, EventBus> eventBus = ImmutableMap.builder();
|
||||
|
||||
for (ModContainer mod : loader.getModList())
|
||||
{
|
||||
EventBus bus = new EventBus(mod.getModId());
|
||||
boolean isActive = mod.registerBus(bus, this);
|
||||
if (isActive)
|
||||
{
|
||||
FMLLog.fine("Activating mod %s", mod.getModId());
|
||||
activeModList.add(mod);
|
||||
modStates.put(mod.getModId(), ModState.UNLOADED);
|
||||
eventBus.put(mod.getModId(), bus);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.warning("Mod %s has been disabled through configuration", mod.getModId());
|
||||
modStates.put(mod.getModId(), ModState.UNLOADED);
|
||||
modStates.put(mod.getModId(), ModState.DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
eventChannels = eventBus.build();
|
||||
}
|
||||
|
||||
public void distributeStateMessage(LoaderState state, Object... eventData)
|
||||
{
|
||||
if (state.hasEvent())
|
||||
{
|
||||
masterChannel.post(state.getEvent(eventData));
|
||||
}
|
||||
}
|
||||
|
||||
public void transition(LoaderState desiredState)
|
||||
{
|
||||
LoaderState oldState = state;
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ModContainer activeContainer()
|
||||
{
|
||||
return activeContainer;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void propogateStateMessage(FMLStateEvent stateEvent)
|
||||
{
|
||||
if (stateEvent instanceof FMLPreInitializationEvent)
|
||||
{
|
||||
modObjectList = buildModObjectList();
|
||||
}
|
||||
for (ModContainer mc : activeModList)
|
||||
{
|
||||
activeContainer = mc;
|
||||
String modId = mc.getModId();
|
||||
stateEvent.applyModContainer(activeContainer());
|
||||
FMLLog.finer("Posting state event %s to mod %s", stateEvent.getEventType(), modId);
|
||||
eventChannels.get(modId).post(stateEvent);
|
||||
FMLLog.finer("State event %s delivered to mod %s", stateEvent.getEventType(), modId);
|
||||
activeContainer = null;
|
||||
if (!errors.containsKey(modId))
|
||||
{
|
||||
modStates.put(modId, stateEvent.getModState());
|
||||
}
|
||||
else
|
||||
{
|
||||
modStates.put(modId, ModState.ERRORED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableBiMap<ModContainer, Object> buildModObjectList()
|
||||
{
|
||||
ImmutableBiMap.Builder<ModContainer, Object> builder = ImmutableBiMap.<ModContainer, Object>builder();
|
||||
for (ModContainer mc : activeModList)
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public void errorOccurred(ModContainer modContainer, Throwable exception)
|
||||
{
|
||||
if (exception instanceof InvocationTargetException)
|
||||
{
|
||||
errors.put(modContainer.getModId(), ((InvocationTargetException)exception).getCause());
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.put(modContainer.getModId(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void printModStates(StringBuilder ret)
|
||||
{
|
||||
for (ModContainer mc : loader.getModList())
|
||||
{
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
public List<ModContainer> getActiveModList()
|
||||
{
|
||||
return activeModList;
|
||||
}
|
||||
|
||||
public ModState getModState(ModContainer selectedMod)
|
||||
{
|
||||
return Iterables.getLast(modStates.get(selectedMod.getModId()), ModState.AVAILABLE);
|
||||
}
|
||||
|
||||
public void distributeStateMessage(Class<?> customEvent)
|
||||
{
|
||||
try
|
||||
{
|
||||
masterChannel.post(customEvent.newInstance());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "An unexpected exception");
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,103 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartedEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
|
||||
/**
|
||||
* The state enum used to help track state progression for the loader
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public enum LoaderState
|
||||
{
|
||||
NOINIT("Uninitialized",null),
|
||||
LOADING("Loading",null),
|
||||
CONSTRUCTING("Constructing mods",FMLConstructionEvent.class),
|
||||
PREINITIALIZATION("Pre-initializing mods", FMLPreInitializationEvent.class),
|
||||
INITIALIZATION("Initializing mods", FMLInitializationEvent.class),
|
||||
POSTINITIALIZATION("Post-initializing mods", FMLPostInitializationEvent.class),
|
||||
AVAILABLE("Mod loading complete", FMLLoadCompleteEvent.class),
|
||||
SERVER_STARTING("Server starting", FMLServerStartingEvent.class),
|
||||
SERVER_STARTED("Server started", FMLServerStartedEvent.class),
|
||||
SERVER_STOPPING("Server stopping", FMLServerStoppingEvent.class),
|
||||
ERRORED("Mod Loading errored",null);
|
||||
|
||||
|
||||
private Class<? extends FMLStateEvent> eventClass;
|
||||
private String name;
|
||||
|
||||
private LoaderState(String name, Class<? extends FMLStateEvent> event)
|
||||
{
|
||||
this.name = name;
|
||||
this.eventClass = event;
|
||||
}
|
||||
|
||||
public LoaderState transition(boolean errored)
|
||||
{
|
||||
if (errored)
|
||||
{
|
||||
return ERRORED;
|
||||
}
|
||||
// stopping -> available
|
||||
if (this == SERVER_STOPPING)
|
||||
{
|
||||
return AVAILABLE;
|
||||
}
|
||||
return values()[ordinal() < values().length ? ordinal()+1 : ordinal()];
|
||||
}
|
||||
|
||||
public boolean hasEvent()
|
||||
{
|
||||
return eventClass != null;
|
||||
}
|
||||
|
||||
public FMLStateEvent getEvent(Object... eventData)
|
||||
{
|
||||
try
|
||||
{
|
||||
return eventClass.getConstructor(Object[].class).newInstance((Object)eventData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
public LoaderState requiredState()
|
||||
{
|
||||
if (this == NOINIT) return NOINIT;
|
||||
return LoaderState.values()[this.ordinal()-1];
|
||||
}
|
||||
public enum ModState
|
||||
{
|
||||
UNLOADED("Unloaded"),
|
||||
LOADED("Loaded"),
|
||||
CONSTRUCTED("Constructed"),
|
||||
PREINITIALIZED("Pre-initialized"),
|
||||
INITIALIZED("Initialized"),
|
||||
POSTINITIALIZED("Post-initialized"),
|
||||
AVAILABLE("Available"),
|
||||
DISABLED("Disabled"),
|
||||
ERRORED("Errored");
|
||||
|
||||
private String label;
|
||||
|
||||
private ModState(String label)
|
||||
{
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.label;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import argo.jdom.JdomParser;
|
||||
import argo.jdom.JsonNode;
|
||||
import argo.jdom.JsonRootNode;
|
||||
import argo.saj.InvalidSyntaxException;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class MetadataCollection
|
||||
{
|
||||
private static JdomParser parser = new JdomParser();
|
||||
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
|
||||
private int metadataVersion = 1;
|
||||
|
||||
public static MetadataCollection from(InputStream inputStream, String sourceName)
|
||||
{
|
||||
if (inputStream == null)
|
||||
{
|
||||
return new MetadataCollection();
|
||||
}
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(inputStream);
|
||||
try
|
||||
{
|
||||
JsonRootNode root = parser.parse(reader);
|
||||
if (root.hasElements())
|
||||
{
|
||||
return parse10ModInfo(root);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private static MetadataCollection parseModInfo(JsonRootNode root)
|
||||
{
|
||||
MetadataCollection mc = new MetadataCollection();
|
||||
mc.metadataVersion = Integer.parseInt(root.getNumberValue("modinfoversion"));
|
||||
mc.parseModMetadataList(root.getNode("modlist"));
|
||||
return mc;
|
||||
}
|
||||
|
||||
private static MetadataCollection parse10ModInfo(JsonRootNode root)
|
||||
{
|
||||
MetadataCollection mc = new MetadataCollection();
|
||||
mc.parseModMetadataList(root);
|
||||
return mc;
|
||||
}
|
||||
|
||||
private void parseModMetadataList(JsonNode metadataList)
|
||||
{
|
||||
for (JsonNode node : metadataList.getElements())
|
||||
{
|
||||
ModMetadata mmd = new ModMetadata(node);
|
||||
metadatas.put(mmd.modId, mmd);
|
||||
}
|
||||
}
|
||||
|
||||
public ModMetadata getMetadataForId(String modId, Map<String, Object> extraData)
|
||||
{
|
||||
if (!metadatas.containsKey(modId))
|
||||
{
|
||||
ModMetadata dummy = new ModMetadata();
|
||||
dummy.modId = modId;
|
||||
dummy.name = (String) extraData.get("name");
|
||||
dummy.version = (String) extraData.get("version");
|
||||
dummy.autogenerated = true;
|
||||
metadatas.put(modId, dummy);
|
||||
}
|
||||
return metadatas.get(modId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -13,23 +13,165 @@
|
||||
*/
|
||||
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;
|
||||
|
||||
import net.minecraft.src.ItemBlock;
|
||||
|
||||
/**
|
||||
* A possible future way to indicate mods to the system is to use an annotation style
|
||||
*
|
||||
* The new mod style in FML 1.3
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Mod
|
||||
{
|
||||
String name() default "";
|
||||
String version() default "";
|
||||
boolean wantsPreInit() default false;
|
||||
boolean wantsPostInit() default false;
|
||||
/**
|
||||
* The unique mod identifier for this mod
|
||||
*/
|
||||
String modid();
|
||||
/**
|
||||
* A user friendly name for the mod
|
||||
*/
|
||||
String name() default "";
|
||||
/**
|
||||
* A version string for this mod
|
||||
*/
|
||||
String version() default "";
|
||||
/**
|
||||
* A simple dependency string for this mod (see modloader's "priorities" string specification)
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
String bukkitPlugin() default "";
|
||||
/**
|
||||
* Mark the designated method as being called at the "pre-initialization" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface PreInit {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "initialization" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Init {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface PostInit {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "server-starting" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStarting {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStarted {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStopping {}
|
||||
/**
|
||||
* Populate the annotated field with the mod instance.
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Instance {
|
||||
/**
|
||||
* The mod object to inject into this field
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
/**
|
||||
* Populate the annotated field with the mod's metadata.
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Metadata {
|
||||
/**
|
||||
* The mod id specifying the metadata to load here
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
/**
|
||||
* Populate the annotated field with an instance of the Block as specified
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Block {
|
||||
/**
|
||||
* The block's name
|
||||
*/
|
||||
String name();
|
||||
/**
|
||||
* The associated ItemBlock subtype for the item (can be null for an ItemBlock)
|
||||
*/
|
||||
Class<?> itemTypeClass() default ItemBlock.class;
|
||||
}
|
||||
/**
|
||||
* Populate the annotated field with an Item
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Item {
|
||||
/**
|
||||
* The name of the item
|
||||
*/
|
||||
String name();
|
||||
/**
|
||||
* The type of the item
|
||||
*/
|
||||
String typeClass();
|
||||
}
|
||||
}
|
||||
@@ -14,66 +14,76 @@
|
||||
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;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import cpw.mods.fml.common.asm.ASMTransformer;
|
||||
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
/**
|
||||
* A simple delegating class loader used to load mods into the system
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ModClassLoader extends URLClassLoader
|
||||
{
|
||||
|
||||
public ModClassLoader()
|
||||
{
|
||||
super(new URL[0], ModClassLoader.class.getClassLoader());
|
||||
}
|
||||
private static final List<String> STANDARD_LIBRARIES = ImmutableList.of("jinput.jar", "lwjgl.jar", "lwjgl_util.jar");
|
||||
private RelaunchClassLoader mainClassLoader;
|
||||
|
||||
public ModClassLoader(ClassLoader parent) {
|
||||
super(new URL[0], null);
|
||||
this.mainClassLoader = (RelaunchClassLoader)parent;
|
||||
}
|
||||
|
||||
public void addFile(File modFile) throws MalformedURLException
|
||||
{
|
||||
ClassLoader cl=getParent();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader ucl=(URLClassLoader) cl;
|
||||
URL url = modFile.toURI().toURL();
|
||||
try {
|
||||
Method addUrl=URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
addUrl.setAccessible(true);
|
||||
addUrl.invoke(ucl, url);
|
||||
} catch (Exception e) {
|
||||
Loader.log.severe("A fatal error occured attempting to load a file into the classloader");
|
||||
throw new LoaderException(e);
|
||||
mainClassLoader.addURL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
return mainClassLoader.loadClass(name);
|
||||
}
|
||||
|
||||
public File[] getParentSources() {
|
||||
List<URL> urls=mainClassLoader.getSources();
|
||||
File[] sources=new File[urls.size()];
|
||||
try
|
||||
{
|
||||
for (int i = 0; i<urls.size(); i++)
|
||||
{
|
||||
sources[i]=new File(urls.get(i).toURI());
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, "Unable to process our input to locate the minecraft code", e);
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public File[] getParentSources() {
|
||||
ClassLoader cl=getParent();
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URLClassLoader ucl=(URLClassLoader) cl;
|
||||
URL[] pUrl=ucl.getURLs();
|
||||
File[] sources=new File[pUrl.length];
|
||||
try
|
||||
{
|
||||
for (int i=0; i<pUrl.length; i++) {
|
||||
sources[i]=new File(pUrl[i].toURI());
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
catch (URISyntaxException e)
|
||||
{
|
||||
Loader.log.throwing("ModClassLoader", "getParentSources", e);
|
||||
}
|
||||
}
|
||||
Loader.log.severe("Unable to process our input to locate the minecraft code");
|
||||
throw new LoaderException();
|
||||
|
||||
public List<String> getDefaultLibraries()
|
||||
{
|
||||
return STANDARD_LIBRARIES;
|
||||
}
|
||||
|
||||
public Class<? extends BaseModProxy> loadBaseModClass(String modClazzName) throws Exception
|
||||
{
|
||||
AccessTransformer transformer = (AccessTransformer)mainClassLoader.getTransformers().get(0);
|
||||
transformer.ensurePublicAccessFor(modClazzName);
|
||||
return (Class<? extends BaseModProxy>) Class.forName(modClazzName, true, this);
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,21 @@ package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer.SourceType;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
/**
|
||||
* The container that wraps around mods in the system.
|
||||
* <p>The philosophy is that individual mod implementation technologies should not impact the actual loading and management
|
||||
* of mod code. This interface provides a mechanism by which we can wrap actual mod code so that the loader and other
|
||||
* facilities can treat mods at arms length.</p>
|
||||
* <p>
|
||||
* The philosophy is that individual mod implementation technologies should not
|
||||
* impact the actual loading and management of mod code. This interface provides
|
||||
* a mechanism by which we can wrap actual mod code so that the loader and other
|
||||
* facilities can treat mods at arms length.
|
||||
* </p>
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
@@ -31,183 +37,96 @@ import cpw.mods.fml.common.ModContainer.SourceType;
|
||||
|
||||
public interface ModContainer
|
||||
{
|
||||
public enum ModState {
|
||||
UNLOADED("Unloaded"), LOADED("Loaded"), PREINITIALIZED("Pre-initialized"), INITIALIZED("Initialized"), POSTINITIALIZED("Post-initialized"), AVAILABLE("Available");
|
||||
private String label;
|
||||
/**
|
||||
* The globally unique modid for this mod
|
||||
*/
|
||||
String getModId();
|
||||
|
||||
private ModState(String label) {
|
||||
this.label=label;
|
||||
}
|
||||
public String toString() {
|
||||
return this.label;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SourceType {
|
||||
JAR, CLASSPATH, DIR;
|
||||
}
|
||||
/**
|
||||
* The enclosed mod wants to be called during pre-initialization.
|
||||
* @return
|
||||
*/
|
||||
boolean wantsPreInit();
|
||||
/**
|
||||
* The enclosed mod wants to be called during post-initialization.
|
||||
* @return
|
||||
*/
|
||||
boolean wantsPostInit();
|
||||
/**
|
||||
* Called when pre-initialization occurs.
|
||||
*/
|
||||
void preInit();
|
||||
/**
|
||||
* Called when main initialization occurs.
|
||||
*/
|
||||
void init();
|
||||
/**
|
||||
* Called when post-initialization occurs.
|
||||
*/
|
||||
void postInit();
|
||||
/**
|
||||
* The name of the mod
|
||||
* @return
|
||||
* A human readable name
|
||||
*/
|
||||
|
||||
String getName();
|
||||
/**
|
||||
* The state of the mod
|
||||
* @return
|
||||
*/
|
||||
ModState getModState();
|
||||
/**
|
||||
* Move to the next mod state
|
||||
*/
|
||||
void nextState();
|
||||
/**
|
||||
* Does this mod match the supplied mod?
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
boolean matches(Object mod);
|
||||
/**
|
||||
* The source of this mod: the file on the file system
|
||||
* @return
|
||||
*/
|
||||
File getSource();
|
||||
/**
|
||||
* Returns the sorting rules as a string for printing
|
||||
* @return
|
||||
*/
|
||||
String getSortingRules();
|
||||
/**
|
||||
* The actual mod object itself
|
||||
* @return
|
||||
*/
|
||||
Object getMod();
|
||||
/**
|
||||
* Lookup the fuel value for the supplied item/damage with this mod.
|
||||
* @param itemId
|
||||
* @param itemDamage
|
||||
* @return
|
||||
*/
|
||||
int lookupFuelValue(int itemId, int itemDamage);
|
||||
/**
|
||||
* This mod wants to be notified when an object is picked up.
|
||||
* @return
|
||||
*/
|
||||
boolean wantsPickupNotification();
|
||||
/**
|
||||
* The pickup notifier for this mod.
|
||||
* @return
|
||||
*/
|
||||
IPickupNotifier getPickupNotifier();
|
||||
/**
|
||||
* This mod wants to have special dispenser handling.
|
||||
* @return
|
||||
*/
|
||||
boolean wantsToDispense();
|
||||
/**
|
||||
* The dispensing handler.
|
||||
* @return
|
||||
*/
|
||||
IDispenseHandler getDispenseHandler();
|
||||
/**
|
||||
* This mod wants notification of crafting and/or smelting events.
|
||||
* @return
|
||||
*/
|
||||
boolean wantsCraftingNotification();
|
||||
/**
|
||||
* The crafting and smelting handler for this mod.
|
||||
* @return
|
||||
*/
|
||||
ICraftingHandler getCraftingHandler();
|
||||
/**
|
||||
* The strong dependencies of this mod. If the named mods in this list are not present, the game will abort.
|
||||
* @return
|
||||
*/
|
||||
List<String> getDependencies();
|
||||
/**
|
||||
* Get a list of mods to load before this one. The special value "*" indicates to load <i>after</i> all other mods (except other "*" mods).
|
||||
* @return
|
||||
*/
|
||||
List<String> getPreDepends();
|
||||
/**
|
||||
* Get a list of mods to load after this one. The special value "*" indicates to load <i>before</i> all other mods (except other "*" mods).
|
||||
* @return
|
||||
*/
|
||||
List<String> getPostDepends();
|
||||
/**
|
||||
* This mod wants packets from the client, and wants them handled by FML.
|
||||
* @return
|
||||
*/
|
||||
boolean wantsNetworkPackets();
|
||||
/**
|
||||
* The network handler for this mod.
|
||||
* @return
|
||||
*/
|
||||
INetworkHandler getNetworkHandler();
|
||||
/**
|
||||
* Does this mod own this channel?
|
||||
* @param channel
|
||||
* @return
|
||||
*/
|
||||
boolean ownsNetworkChannel(String channel);
|
||||
|
||||
/**
|
||||
* Does this mod want commands from the console?
|
||||
* @return
|
||||
*/
|
||||
boolean wantsConsoleCommands();
|
||||
|
||||
IConsoleHandler getConsoleHandler();
|
||||
|
||||
boolean wantsPlayerTracking();
|
||||
|
||||
IPlayerTracker getPlayerTracker();
|
||||
|
||||
List<IKeyHandler> getKeys();
|
||||
|
||||
SourceType getSourceType();
|
||||
|
||||
void setSourceType(SourceType type);
|
||||
|
||||
ModMetadata getMetadata();
|
||||
void setMetadata(ModMetadata meta);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void gatherRenderers(Map renderers);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void requestAnimations();
|
||||
/**
|
||||
* @return
|
||||
* A human readable version identifier
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* @return
|
||||
* The location on the file system which this mod came from
|
||||
*/
|
||||
ProxyInjector findSidedProxy();
|
||||
|
||||
void keyBindEvent(Object keyBinding);
|
||||
File getSource();
|
||||
|
||||
/**
|
||||
* The metadata for this mod
|
||||
*/
|
||||
ModMetadata getMetadata();
|
||||
|
||||
/**
|
||||
* Attach this mod to it's metadata from the supplied metadata collection
|
||||
*/
|
||||
void bindMetadata(MetadataCollection mc);
|
||||
|
||||
/**
|
||||
* Set the enabled/disabled state of this mod
|
||||
*/
|
||||
void setEnabledState(boolean enabled);
|
||||
|
||||
/**
|
||||
* A list of the modids that this mod requires loaded prior to loading
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
List<ArtifactVersion> getDependencies();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
List<ArtifactVersion> getDependants();
|
||||
|
||||
/**
|
||||
* A representative string encapsulating the sorting preferences for this
|
||||
* mod
|
||||
*/
|
||||
String getSortingRules();
|
||||
|
||||
/**
|
||||
* Register the event bus for the mod and the controller for error handling
|
||||
* Returns if this bus was successfully registered - disabled mods and other
|
||||
* mods that don't need real events should return false and avoid further
|
||||
* processing
|
||||
*
|
||||
* @param bus
|
||||
* @param controller
|
||||
*/
|
||||
boolean registerBus(EventBus bus, LoadController controller);
|
||||
|
||||
/**
|
||||
* Does this mod match the supplied mod
|
||||
*
|
||||
* @param mod
|
||||
*/
|
||||
boolean matches(Object mod);
|
||||
|
||||
/**
|
||||
* Get the actual mod object
|
||||
*/
|
||||
Object getMod();
|
||||
|
||||
ArtifactVersion getProcessedVersion();
|
||||
|
||||
boolean isImmutable();
|
||||
|
||||
boolean isNetworkMod();
|
||||
|
||||
String getDisplayVersion();
|
||||
|
||||
VersionRange acceptableMinecraftVersionRange();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.io.File;
|
||||
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;
|
||||
|
||||
public class ModContainerFactory
|
||||
{
|
||||
private static Pattern modClass = Pattern.compile(".*(\\.|)(mod\\_[^\\s$]+)$");
|
||||
private static ModContainerFactory INSTANCE = new ModContainerFactory();
|
||||
public static ModContainerFactory instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
public ModContainer build(ASMModParser modParser, File modSource, ModCandidate container)
|
||||
{
|
||||
String className = modParser.getASMType().getClassName();
|
||||
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 an FMLMod type mod %s", className);
|
||||
return new FMLModContainer(className, modSource, ann.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -14,91 +14,151 @@
|
||||
|
||||
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.zip.ZipInputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import argo.jdom.JsonNode;
|
||||
import argo.jdom.JsonStringNode;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.functions.ModNameFunction;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
|
||||
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
|
||||
/**
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ModMetadata
|
||||
{
|
||||
public enum ModType { MODLOADER, FML };
|
||||
public ModContainer mod;
|
||||
public ModType type;
|
||||
|
||||
private static final class JsonStringConverter implements Function<JsonNode, Object>
|
||||
{
|
||||
public Object apply(JsonNode arg0)
|
||||
{
|
||||
if (arg0.hasElements())
|
||||
{
|
||||
return Lists.transform(arg0.getElements(), new JsonArrayConverter());
|
||||
}
|
||||
else
|
||||
{
|
||||
return arg0.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class JsonArrayConverter implements Function<JsonNode, String>
|
||||
{
|
||||
public String apply(JsonNode arg0)
|
||||
{
|
||||
return arg0.getText();
|
||||
}
|
||||
}
|
||||
|
||||
public String modId;
|
||||
public String name;
|
||||
public String description;
|
||||
|
||||
public String url="";
|
||||
public String updateUrl="";
|
||||
|
||||
public String logoFile="";
|
||||
public String version="";
|
||||
public List<String> authorList=new ArrayList<String>(1);
|
||||
public String credits="";
|
||||
public String parent="";
|
||||
|
||||
public String url = "";
|
||||
public String updateUrl = "";
|
||||
|
||||
public String logoFile = "";
|
||||
public String version = "";
|
||||
public List<String> authorList = Lists.newArrayList();
|
||||
public String credits = "";
|
||||
public String parent = "";
|
||||
public String[] screenshots;
|
||||
|
||||
|
||||
public ModContainer parentMod;
|
||||
public List<ModContainer> childMods = new ArrayList<ModContainer>(1);
|
||||
public List<ModContainer> childMods = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @param mod2
|
||||
* @param type2
|
||||
*/
|
||||
public ModMetadata(ModContainer mod)
|
||||
public boolean useDependencyInformation;
|
||||
public Set<ArtifactVersion> requiredMods;
|
||||
public List<ArtifactVersion> dependencies;
|
||||
public List<ArtifactVersion> dependants;
|
||||
public boolean autogenerated;
|
||||
|
||||
public ModMetadata(JsonNode node)
|
||||
{
|
||||
this.mod=mod;
|
||||
this.type=(mod instanceof FMLModContainer ? ModType.FML : ModType.MODLOADER);
|
||||
}
|
||||
|
||||
public void associate(Map<String, ModContainer> mods) {
|
||||
if (parent!=null && parent.length() > 0) {
|
||||
ModContainer mc=mods.get(parent);
|
||||
if (mc!=null && mc.getMetadata()!=null) {
|
||||
mc.getMetadata().childMods.add(mod);
|
||||
parentMod = mc;
|
||||
}
|
||||
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")));
|
||||
updateUrl = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("updateUrl")));
|
||||
logoFile = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("logoFile")));
|
||||
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 = 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"))));
|
||||
}
|
||||
|
||||
public ModMetadata()
|
||||
{
|
||||
}
|
||||
|
||||
private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
|
||||
{
|
||||
T res = null;
|
||||
try
|
||||
{
|
||||
res = retType.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// unpossible
|
||||
}
|
||||
|
||||
if (refs == null)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
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" : "");
|
||||
return String.format("%d child mod%s", childMods.size(), childMods.size() != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
public String getAuthorList() {
|
||||
StringBuilder sb=new StringBuilder();
|
||||
for (int i=0; i<authorList.size(); i++) {
|
||||
sb.append(authorList.get(i));
|
||||
if (i<authorList.size()-1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
public String getAuthorList()
|
||||
{
|
||||
return Joiner.on(", ").join(authorList);
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
||||
public String getChildModList()
|
||||
{
|
||||
StringBuilder sb=new StringBuilder();
|
||||
for (int i=0; i<childMods.size(); i++) {
|
||||
sb.append(childMods.get(i).getMetadata().name);
|
||||
if (i<childMods.size()-1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
return Joiner.on(", ").join(Lists.transform(childMods, new ModNameFunction()));
|
||||
}
|
||||
|
||||
public String printableSortingRules()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite. Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper.UnableToAccessFieldException;
|
||||
import cpw.mods.fml.relauncher.ReflectionHelper.UnableToFindFieldException;
|
||||
|
||||
/**
|
||||
* Some reflection helper code.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ObfuscationReflectionHelper
|
||||
{
|
||||
public static boolean obfuscation;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, int fieldIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ReflectionHelper.getPrivateValue(classToAccess, instance, fieldIndex);
|
||||
}
|
||||
catch (UnableToAccessFieldException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "There was a problem getting field index %d from %s", fieldIndex, classToAccess.getName());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, String... fieldNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ReflectionHelper.getPrivateValue(classToAccess, instance, fieldNames);
|
||||
}
|
||||
catch (UnableToFindFieldException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE,e,"Unable to locate any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
|
||||
throw e;
|
||||
}
|
||||
catch (UnableToAccessFieldException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to access any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, int fieldIndex, E value)
|
||||
{
|
||||
setPrivateValue(classToAccess, instance, value, fieldIndex);
|
||||
}
|
||||
|
||||
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, E value, int fieldIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
ReflectionHelper.setPrivateValue(classToAccess, instance, value, fieldIndex);
|
||||
}
|
||||
catch (UnableToAccessFieldException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "There was a problem setting field index %d on type %s", fieldIndex, classToAccess.getName());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, String fieldName, E value)
|
||||
{
|
||||
setPrivateValue(classToAccess, instance, value, fieldName);
|
||||
}
|
||||
|
||||
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, E value, String... fieldNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
ReflectionHelper.setPrivateValue(classToAccess, instance, value, fieldNames);
|
||||
}
|
||||
catch (UnableToFindFieldException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to locate any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
|
||||
throw e;
|
||||
}
|
||||
catch (UnableToAccessFieldException e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Unable to set any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void detectObfuscation(Class<?> clazz)
|
||||
{
|
||||
obfuscation = !clazz.getSimpleName().equals("World");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,12 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
|
||||
/**
|
||||
* @author cpw
|
||||
@@ -22,55 +28,45 @@ import java.lang.reflect.Field;
|
||||
*/
|
||||
public class ProxyInjector
|
||||
{
|
||||
private String clientName;
|
||||
private String serverName;
|
||||
private String bukkitName;
|
||||
private Field target;
|
||||
public static void inject(ModContainer mod, ASMDataTable data, Side side)
|
||||
{
|
||||
FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
|
||||
Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
|
||||
ClassLoader mcl = Loader.instance().getModClassLoader();
|
||||
|
||||
public ProxyInjector(String clientName, String serverName, String bukkitName, Field target)
|
||||
{
|
||||
this.clientName = clientName;
|
||||
this.serverName = serverName;
|
||||
this.bukkitName = bukkitName;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean isValidFor(Side type)
|
||||
{
|
||||
if (type == Side.CLIENT)
|
||||
for (ASMData targ : targets)
|
||||
{
|
||||
return !this.clientName.isEmpty();
|
||||
}
|
||||
else if (type == Side.SERVER)
|
||||
{
|
||||
return !this.serverName.isEmpty();
|
||||
}
|
||||
else if (type == Side.BUKKIT)
|
||||
{
|
||||
return this.bukkitName.isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void inject(ModContainer mod, Side side)
|
||||
{
|
||||
String targetType = side == Side.CLIENT ? clientName : serverName;
|
||||
try
|
||||
{
|
||||
Object proxy=Class.forName(targetType, false, Loader.instance().getModClassLoader()).newInstance();
|
||||
if (target.getType().isAssignableFrom(proxy.getClass()))
|
||||
try
|
||||
{
|
||||
target.set(mod.getMod(), proxy);
|
||||
} else {
|
||||
FMLCommonHandler.instance().getFMLLogger().severe(String.format("Attempted to load a proxy type %s into %s, but the types don't match", targetType, target.getName()));
|
||||
throw new LoaderException();
|
||||
Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl);
|
||||
Field target = proxyTarget.getDeclaredField(targ.getObjectName());
|
||||
if (target == null)
|
||||
{
|
||||
// Impossible?
|
||||
FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName());
|
||||
throw new LoaderException();
|
||||
}
|
||||
|
||||
String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
|
||||
Object proxy=Class.forName(targetType, true, mcl).newInstance();
|
||||
|
||||
if ((target.getModifiers() & Modifier.STATIC) == 0 )
|
||||
{
|
||||
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName());
|
||||
throw new LoaderException();
|
||||
}
|
||||
if (!target.getType().isAssignableFrom(proxy.getClass()))
|
||||
{
|
||||
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName());
|
||||
throw new LoaderException();
|
||||
}
|
||||
target.set(null, proxy);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName());
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLCommonHandler.instance().getFMLLogger().severe(String.format("An error occured trying to load a proxy type %s into %s", targetType, target.getName()));
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("ProxyInjector", "inject", e);
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* The FML Forge Mod Loader suite. Copyright (C) 2012 cpw
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
/**
|
||||
* Some reflection helper code.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class ReflectionHelper
|
||||
{
|
||||
public static boolean obfuscation;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, E> T getPrivateValue(Class <? super E > classToAccess, E instance, int fieldIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field f = classToAccess.getDeclaredFields()[fieldIndex];
|
||||
f.setAccessible(true);
|
||||
return (T) f.get(instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem getting field %d from %s", fieldIndex, classToAccess.getName()));
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, E> T getPrivateValue(Class <? super E > classToAccess, E instance, String fieldName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field f = classToAccess.getDeclaredField(fieldName);
|
||||
f.setAccessible(true);
|
||||
return (T) f.get(instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if ((fieldName.length() > 3 && !obfuscation) || (fieldName.length() <= 3 && obfuscation)) {
|
||||
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem getting field %s from %s", fieldName, classToAccess.getName()));
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T, E> void setPrivateValue(Class <? super T > classToAccess, T instance, int fieldIndex, E value)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field f = classToAccess.getDeclaredFields()[fieldIndex];
|
||||
f.setAccessible(true);
|
||||
f.set(instance, value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem setting field %d from %s", fieldIndex, classToAccess.getName()));
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T, E> void setPrivateValue(Class <? super T > classToAccess, T instance, String fieldName, E value)
|
||||
{
|
||||
try
|
||||
{
|
||||
Field f = classToAccess.getDeclaredField(fieldName);
|
||||
f.setAccessible(true);
|
||||
f.set(instance, value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if ((fieldName.length() > 3 && !obfuscation) || (fieldName.length() <= 3 && obfuscation)) {
|
||||
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem setting field %s from %s", fieldName, classToAccess.getName()));
|
||||
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void detectObfuscation(Class<?> clazz)
|
||||
{
|
||||
obfuscation=!clazz.getSimpleName().equals("World");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public enum Side {
|
||||
CLIENT, SERVER, BUKKIT;
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @return If this is the server environment
|
||||
*/
|
||||
public boolean isServer()
|
||||
{
|
||||
@@ -26,7 +26,7 @@ public enum Side {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @return if this is the Client environment
|
||||
*/
|
||||
public boolean isClient()
|
||||
{
|
||||
|
||||
+4
-6
@@ -12,7 +12,7 @@
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraft.src;
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -29,18 +29,16 @@ 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 "";
|
||||
|
||||
|
||||
/**
|
||||
* The name of the a special bukkit plugin class to load and populate
|
||||
* The name of a special bukkit plugin class to load and populate
|
||||
*/
|
||||
String bukkitSide() default "";
|
||||
}
|
||||
@@ -34,31 +34,25 @@ public enum TickType {
|
||||
* client side
|
||||
* Fired during the render processing phase if a GUI is open
|
||||
* arg 0 : float "partial render time"
|
||||
* arg 1 : the open gui
|
||||
* arg 1 : the open gui or null if no gui is open
|
||||
*/
|
||||
GUI,
|
||||
/**
|
||||
* client side
|
||||
* Fired during the world evaluation loop if a gui is open
|
||||
* arg 0 : The open gui
|
||||
* Fired during the client evaluation loop
|
||||
* arg 0 : The open gui or null if no gui is open
|
||||
*/
|
||||
WORLDGUI,
|
||||
CLIENTGUI,
|
||||
/**
|
||||
* client side
|
||||
* server side
|
||||
* Fired once as the world loads from disk
|
||||
*/
|
||||
WORLDLOAD,
|
||||
/**
|
||||
* client side
|
||||
* Fired once as the world loads from disk
|
||||
* arg 0 : the open gui
|
||||
* client side only
|
||||
* Fired once per client tick loop.
|
||||
*/
|
||||
GUILOAD,
|
||||
/**
|
||||
* client and server side
|
||||
* Fired once per "global tick loop"
|
||||
*/
|
||||
GAME,
|
||||
CLIENT,
|
||||
/**
|
||||
* client and server side.
|
||||
* Fired whenever the players update loop runs.
|
||||
@@ -67,24 +61,21 @@ public enum TickType {
|
||||
*/
|
||||
PLAYER,
|
||||
/**
|
||||
* This is a special internal tick type that is
|
||||
* not sent to mods. It resets the scheduler for
|
||||
* the next tick pass.
|
||||
* server side only.
|
||||
* This is the server game tick.
|
||||
* Fired once per tick loop on the server.
|
||||
*/
|
||||
RESETMARKER;
|
||||
SERVER;
|
||||
|
||||
/**
|
||||
* Partner ticks that are also cancelled by returning false from onTickInGame
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public EnumSet<TickType> partnerTicks()
|
||||
{
|
||||
if (this==GAME) return EnumSet.of(RENDER);
|
||||
if (this==RENDER) return EnumSet.of(GAME);
|
||||
if (this==GUI) return EnumSet.of(WORLDGUI, GUILOAD);
|
||||
if (this==WORLDGUI) return EnumSet.of(GUI, GUILOAD);
|
||||
if (this==GUILOAD) return EnumSet.of(GUI, WORLDGUI);
|
||||
if (this==CLIENT) return EnumSet.of(RENDER);
|
||||
if (this==RENDER) return EnumSet.of(CLIENT);
|
||||
if (this==GUI) return EnumSet.of(CLIENTGUI);
|
||||
if (this==CLIENTGUI) return EnumSet.of(GUI);
|
||||
return EnumSet.noneOf(TickType.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.src.NBTBase;
|
||||
import net.minecraft.src.NBTTagCompound;
|
||||
import net.minecraft.src.SaveHandler;
|
||||
import net.minecraft.src.WorldInfo;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cpw.mods.fml.common.asm;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import cpw.mods.fml.common.registry.BlockProxy;
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class ASMTransformer implements IClassTransformer
|
||||
{
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
if ("net.minecraft.src.Block".equals(name))
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassNode cn = new ClassNode(Opcodes.ASM4);
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
cn.interfaces.add(Type.getInternalName(BlockProxy.class));
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package cpw.mods.fml.common.asm;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
||||
|
||||
public class FMLSanityChecker implements IFMLCallHook
|
||||
{
|
||||
static class MLDetectorClassVisitor extends ClassVisitor
|
||||
{
|
||||
private boolean foundMarker = false;
|
||||
private MLDetectorClassVisitor()
|
||||
{
|
||||
super(Opcodes.ASM4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4)
|
||||
{
|
||||
if ("fmlMarker".equals(arg1))
|
||||
{
|
||||
foundMarker = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private RelaunchClassLoader cl;
|
||||
|
||||
@Override
|
||||
public Void call() throws Exception
|
||||
{
|
||||
byte[] mlClass = cl.getClassBytes("ModLoader");
|
||||
// Only care in obfuscated env
|
||||
if (mlClass == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
MLDetectorClassVisitor mlTester = new MLDetectorClassVisitor();
|
||||
ClassReader cr = new ClassReader(mlClass);
|
||||
cr.accept(mlTester, ClassReader.SKIP_CODE);
|
||||
if (!mlTester.foundMarker)
|
||||
{
|
||||
JOptionPane.showMessageDialog(null, "<html>CRITICAL ERROR<br/>" +
|
||||
"ModLoader was detected in this environment<br/>" +
|
||||
"ForgeModLoader cannot be installed alongside ModLoader<br/>" +
|
||||
"All mods should work without ModLoader being installed<br/>" +
|
||||
"Because ForgeModLoader is 100% compatible with ModLoader<br/>" +
|
||||
"Re-install Minecraft Forge or Forge ModLoader into a clean<br/>" +
|
||||
"jar and try again.",
|
||||
"ForgeModLoader critical error",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
throw new RuntimeException("Invalid ModLoader class detected");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectData(Map<String, Object> data)
|
||||
{
|
||||
cl = (RelaunchClassLoader) data.get("classLoader");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
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;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
|
||||
public @interface SideOnly
|
||||
{
|
||||
public Side value();
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
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 java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
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.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.io.LineProcessor;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class AccessTransformer implements IClassTransformer
|
||||
{
|
||||
private static final boolean DEBUG = false;
|
||||
private class Modifier
|
||||
{
|
||||
public String name = "";
|
||||
public String desc = "";
|
||||
public int oldAccess = 0;
|
||||
public int newAccess = 0;
|
||||
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;
|
||||
markFinal = false;
|
||||
}
|
||||
else if (name.endsWith("+f"))
|
||||
{
|
||||
changeFinal = true;
|
||||
markFinal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Multimap<String, Modifier> modifiers = ArrayListMultimap.create();
|
||||
|
||||
public AccessTransformer() throws IOException
|
||||
{
|
||||
this("fml_at.cfg");
|
||||
}
|
||||
protected AccessTransformer(String rulesFile) throws IOException
|
||||
{
|
||||
readMapFile(rulesFile);
|
||||
}
|
||||
|
||||
private void readMapFile(String rulesFile) throws IOException
|
||||
{
|
||||
File file = new File(rulesFile);
|
||||
URL rulesResource;
|
||||
if (file.exists())
|
||||
{
|
||||
rulesResource = file.toURI().toURL();
|
||||
}
|
||||
else
|
||||
{
|
||||
rulesResource = Resources.getResource(rulesFile);
|
||||
}
|
||||
Resources.readLines(rulesResource, Charsets.UTF_8, new LineProcessor<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void getResult()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processLine(String input) throws IOException
|
||||
{
|
||||
String line = Iterables.getFirst(Splitter.on('#').limit(2).split(input), "").trim();
|
||||
if (line.length()==0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
|
||||
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)));
|
||||
if (descriptor.size() == 1)
|
||||
{
|
||||
m.modifyClassVisibility = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
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).replace('/', '.'), m);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
if (!modifiers.containsKey(name)) { return bytes; }
|
||||
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
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) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (MethodNode n : (List<MethodNode>) classNode.methods)
|
||||
{
|
||||
if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*"))
|
||||
{
|
||||
n.access = getFixedAccess(n.access, m);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
private String toBinary(int num)
|
||||
{
|
||||
return String.format("%16s", Integer.toBinaryString(num)).replace(' ', '0');
|
||||
}
|
||||
|
||||
private int getFixedAccess(int access, Modifier target)
|
||||
{
|
||||
target.oldAccess = access;
|
||||
int t = target.targetAccess;
|
||||
int ret = (access & ~7);
|
||||
|
||||
switch (access & 7)
|
||||
{
|
||||
case ACC_PRIVATE:
|
||||
ret |= t;
|
||||
break;
|
||||
case 0: // default
|
||||
ret |= (t != ACC_PRIVATE ? t : 0 /* default */);
|
||||
break;
|
||||
case ACC_PROTECTED:
|
||||
ret |= (t != ACC_PRIVATE && t != 0 /* default */? t : ACC_PROTECTED);
|
||||
break;
|
||||
case ACC_PUBLIC:
|
||||
ret |= (t != ACC_PRIVATE && t != 0 /* default */&& t != ACC_PROTECTED ? t : ACC_PUBLIC);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("The fuck?");
|
||||
}
|
||||
|
||||
// Clear the "final" marker on fields only if specified in control field
|
||||
if (target.changeFinal && target.desc == "")
|
||||
{
|
||||
if (target.markFinal)
|
||||
{
|
||||
ret |= ACC_FINAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret &= ~ACC_FINAL;
|
||||
}
|
||||
}
|
||||
target.newAccess = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length < 2)
|
||||
{
|
||||
System.out.println("Usage: AccessTransformer <JarPath> <MapFile> [MapFile2]... ");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
boolean hasTransformer = false;
|
||||
AccessTransformer[] trans = new AccessTransformer[args.length - 1];
|
||||
for (int x = 1; x < args.length; x++)
|
||||
{
|
||||
try
|
||||
{
|
||||
trans[x - 1] = new AccessTransformer(args[x]);
|
||||
hasTransformer = true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Could not read Transformer Map: " + args[x]);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTransformer)
|
||||
{
|
||||
System.out.println("Culd not find a valid transformer to perform");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File orig = new File(args[0]);
|
||||
File temp = new File(args[0] + ".ATBack");
|
||||
if (!orig.exists() && !temp.exists())
|
||||
{
|
||||
System.out.println("Could not find target jar: " + orig);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!orig.renameTo(temp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + orig + " -> " + temp);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
processJar(temp, orig, trans);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!temp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + temp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processJar(File inFile, File outFile, AccessTransformer[] transformers) throws IOException
|
||||
{
|
||||
ZipInputStream inJar = null;
|
||||
ZipOutputStream outJar = null;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
inJar = new ZipInputStream(new BufferedInputStream(new FileInputStream(inFile)));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
outJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
|
||||
}
|
||||
|
||||
ZipEntry entry;
|
||||
while ((entry = inJar.getNextEntry()) != null)
|
||||
{
|
||||
if (entry.isDirectory())
|
||||
{
|
||||
outJar.putNextEntry(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] data = new byte[4096];
|
||||
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
|
||||
|
||||
int len;
|
||||
do
|
||||
{
|
||||
len = inJar.read(data);
|
||||
if (len > 0)
|
||||
{
|
||||
entryBuffer.write(data, 0, len);
|
||||
}
|
||||
}
|
||||
while (len != -1);
|
||||
|
||||
byte[] entryData = entryBuffer.toByteArray();
|
||||
|
||||
String entryName = entry.getName();
|
||||
|
||||
if (entryName.endsWith(".class") && !entryName.startsWith("."))
|
||||
{
|
||||
ClassNode cls = new ClassNode();
|
||||
ClassReader rdr = new ClassReader(entryData);
|
||||
rdr.accept(cls, 0);
|
||||
String name = cls.name.replace('/', '.').replace('\\', '.');
|
||||
|
||||
for (AccessTransformer trans : transformers)
|
||||
{
|
||||
entryData = trans.transform(name, entryData);
|
||||
}
|
||||
}
|
||||
|
||||
ZipEntry newEntry = new ZipEntry(entryName);
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(entryData);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (outJar != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
outJar.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (inJar != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
inJar.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ensurePublicAccessFor(String modClazzName)
|
||||
{
|
||||
Modifier m = new Modifier();
|
||||
m.setTargetAccess("public");
|
||||
m.modifyClassVisibility = true;
|
||||
modifiers.put(modClazzName, m);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,636 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
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.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
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.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.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
|
||||
public class MCPMerger
|
||||
{
|
||||
private static Hashtable<String, ClassInfo> clients = new Hashtable<String, ClassInfo>();
|
||||
private static Hashtable<String, ClassInfo> shared = new Hashtable<String, ClassInfo>();
|
||||
private static Hashtable<String, ClassInfo> servers = new Hashtable<String, ClassInfo>();
|
||||
private static HashSet<String> copyToServer = new HashSet<String>();
|
||||
private static HashSet<String> copyToClient = new HashSet<String>();
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length != 3)
|
||||
{
|
||||
System.out.println("Usage: MCPMerger <MapFile> <minecraft.jar> <minecraft_server.jar>");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File map_file = new File(args[0]);
|
||||
File client_jar = new File(args[1]);
|
||||
File server_jar = new File(args[2]);
|
||||
File client_jar_tmp = new File(args[1] + ".MergeBack");
|
||||
File server_jar_tmp = new File(args[2] + ".MergeBack");
|
||||
|
||||
|
||||
if (client_jar_tmp.exists() && !client_jar_tmp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + client_jar_tmp);
|
||||
}
|
||||
|
||||
if (server_jar_tmp.exists() && !server_jar_tmp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + server_jar_tmp);
|
||||
}
|
||||
|
||||
if (!client_jar.exists())
|
||||
{
|
||||
System.out.println("Could not find minecraft.jar: " + client_jar);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!server_jar.exists())
|
||||
{
|
||||
System.out.println("Could not find minecraft_server.jar: " + server_jar);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!client_jar.renameTo(client_jar_tmp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!server_jar.renameTo(server_jar_tmp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!readMapFile(map_file))
|
||||
{
|
||||
System.out.println("Could not read map file: " + map_file);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
processJar(client_jar_tmp, server_jar_tmp, client_jar, server_jar);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (!client_jar_tmp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + client_jar_tmp);
|
||||
}
|
||||
|
||||
if (!server_jar_tmp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + server_jar_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean readMapFile(File mapFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileInputStream fstream = new FileInputStream(mapFile);
|
||||
DataInputStream in = new DataInputStream(fstream);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
in.close();
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Error: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void processJar(File clientInFile, File serverInFile, File clientOutFile, File serverOutFile) throws IOException
|
||||
{
|
||||
ZipFile cInJar = null;
|
||||
ZipFile sInJar = null;
|
||||
ZipOutputStream cOutJar = null;
|
||||
ZipOutputStream sOutJar = null;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
cInJar = new ZipFile(clientInFile);
|
||||
sInJar = new ZipFile(serverInFile);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
|
||||
}
|
||||
try
|
||||
{
|
||||
cOutJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(clientOutFile)));
|
||||
sOutJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(serverOutFile)));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
|
||||
}
|
||||
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())
|
||||
{
|
||||
String name = entry.getKey();
|
||||
ZipEntry cEntry = entry.getValue();
|
||||
ZipEntry sEntry = sClasses.get(name);
|
||||
|
||||
if (sEntry == null)
|
||||
{
|
||||
if (!copyToServer.contains(name))
|
||||
{
|
||||
copyClass(cInJar, cEntry, cOutJar, null, true);
|
||||
cAdded.add(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println("Copy class c->s : " + name);
|
||||
}
|
||||
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
|
||||
cAdded.add(name);
|
||||
sAdded.add(name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
sClasses.remove(name);
|
||||
ClassInfo info = new ClassInfo(name);
|
||||
shared.put(name, info);
|
||||
|
||||
byte[] cData = readEntry(cInJar, entry.getValue());
|
||||
byte[] sData = readEntry(sInJar, sEntry);
|
||||
byte[] data = processClass(cData, sData, info);
|
||||
|
||||
ZipEntry newEntry = new ZipEntry(cEntry.getName());
|
||||
cOutJar.putNextEntry(newEntry);
|
||||
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()))
|
||||
{
|
||||
copyClass(sInJar, entry.getValue(), null, sOutJar, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println("Copy class s->c : " + entry.getKey());
|
||||
}
|
||||
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : new String[]{SideOnly.class.getName(), Side.class.getName()})
|
||||
{
|
||||
String eName = name.replace(".", "/");
|
||||
byte[] data = getClassBytes(name);
|
||||
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
|
||||
if (!cAdded.contains(eName))
|
||||
{
|
||||
cOutJar.putNextEntry(newEntry);
|
||||
cOutJar.write(data);
|
||||
}
|
||||
if (!sAdded.contains(eName))
|
||||
{
|
||||
sOutJar.putNextEntry(newEntry);
|
||||
sOutJar.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (cInJar != null)
|
||||
{
|
||||
try { cInJar.close(); } catch (IOException e){}
|
||||
}
|
||||
|
||||
if (sInJar != null)
|
||||
{
|
||||
try { sInJar.close(); } catch (IOException e) {}
|
||||
}
|
||||
if (cOutJar != null)
|
||||
{
|
||||
try { cOutJar.close(); } catch (IOException e){}
|
||||
}
|
||||
|
||||
if (sOutJar != null)
|
||||
{
|
||||
try { sOutJar.close(); } catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyClass(ZipFile inJar, ZipEntry entry, ZipOutputStream outJar, ZipOutputStream outJar2, boolean isClientOnly) throws IOException
|
||||
{
|
||||
ClassReader reader = new ClassReader(readEntry(inJar, entry));
|
||||
ClassNode classNode = new ClassNode();
|
||||
|
||||
reader.accept(classNode, 0);
|
||||
|
||||
if (!classNode.name.equals("bct")) //Special case CodecMus so I dont have to make a new patch, anyone who uses this in production code is.. bad.
|
||||
{
|
||||
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
byte[] data = writer.toByteArray();
|
||||
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
if (outJar != null)
|
||||
{
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(data);
|
||||
}
|
||||
if (outJar2 != null)
|
||||
{
|
||||
outJar2.putNextEntry(newEntry);
|
||||
outJar2.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
private static AnnotationNode getSideAnn(boolean isClientOnly)
|
||||
{
|
||||
AnnotationNode ann = new AnnotationNode(Type.getDescriptor(SideOnly.class));
|
||||
ann.values = new ArrayList<Object>();
|
||||
ann.values.add("value");
|
||||
ann.values.add(new String[]{ Type.getDescriptor(Side.class), (isClientOnly ? "CLIENT" : "SERVER")});
|
||||
return ann;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Hashtable<String, ZipEntry> getClassEntries(ZipFile inFile, ZipOutputStream outFile) throws IOException
|
||||
{
|
||||
Hashtable<String, ZipEntry> ret = new Hashtable<String, ZipEntry>();
|
||||
for (ZipEntry entry : Collections.list((Enumeration<ZipEntry>)inFile.entries()))
|
||||
{
|
||||
if (entry.isDirectory())
|
||||
{
|
||||
outFile.putNextEntry(entry);
|
||||
continue;
|
||||
}
|
||||
String entryName = entry.getName();
|
||||
if (!entryName.endsWith(".class") || entryName.startsWith("."))
|
||||
{
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
outFile.putNextEntry(newEntry);
|
||||
outFile.write(readEntry(inFile, entry));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.put(entryName.replace(".class", ""), entry);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
|
||||
{
|
||||
return readFully(inFile.getInputStream(entry));
|
||||
}
|
||||
private static byte[] readFully(InputStream stream) throws IOException
|
||||
{
|
||||
byte[] data = new byte[4096];
|
||||
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
|
||||
int len;
|
||||
do
|
||||
{
|
||||
len = stream.read(data);
|
||||
if (len > 0)
|
||||
{
|
||||
entryBuffer.write(data, 0, len);
|
||||
}
|
||||
} while (len != -1);
|
||||
|
||||
return entryBuffer.toByteArray();
|
||||
}
|
||||
private static class ClassInfo
|
||||
{
|
||||
public String name;
|
||||
public ArrayList<FieldNode> cField = new ArrayList<FieldNode>();
|
||||
public ArrayList<FieldNode> sField = new ArrayList<FieldNode>();
|
||||
public ArrayList<MethodNode> cMethods = new ArrayList<MethodNode>();
|
||||
public ArrayList<MethodNode> sMethods = new ArrayList<MethodNode>();
|
||||
public ClassInfo(String name){ this.name = name; }
|
||||
public boolean isSame() { return (cField.size() == 0 && sField.size() == 0 && cMethods.size() == 0 && sMethods.size() == 0); }
|
||||
}
|
||||
|
||||
public static byte[] processClass(byte[] cIn, byte[] sIn, ClassInfo info)
|
||||
{
|
||||
ClassNode cClassNode = getClassNode(cIn);
|
||||
ClassNode sClassNode = getClassNode(sIn);
|
||||
|
||||
processFields(cClassNode, sClassNode, info);
|
||||
processMethods(cClassNode, sClassNode, info);
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
cClassNode.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
private static ClassNode getClassNode(byte[] data)
|
||||
{
|
||||
ClassReader reader = new ClassReader(data);
|
||||
ClassNode classNode = new ClassNode();
|
||||
reader.accept(classNode, 0);
|
||||
return classNode;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void processFields(ClassNode cClass, ClassNode sClass, ClassInfo info)
|
||||
{
|
||||
List<FieldNode> cFields = cClass.fields;
|
||||
List<FieldNode> sFields = sClass.fields;
|
||||
|
||||
int sI = 0;
|
||||
for (int x = 0; x < cFields.size(); x++)
|
||||
{
|
||||
FieldNode cF = cFields.get(x);
|
||||
if (sI < sFields.size())
|
||||
{
|
||||
if (!cF.name.equals(sFields.get(sI).name))
|
||||
{
|
||||
boolean serverHas = false;
|
||||
for (int y = sI + 1; y < sFields.size(); y++)
|
||||
{
|
||||
if (cF.name.equals(sFields.get(y).name))
|
||||
{
|
||||
serverHas = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (serverHas)
|
||||
{
|
||||
boolean clientHas = false;
|
||||
FieldNode sF = sFields.get(sI);
|
||||
for (int y = x + 1; y < cFields.size(); y++)
|
||||
{
|
||||
if (sF.name.equals(cFields.get(y).name))
|
||||
{
|
||||
clientHas = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!clientHas)
|
||||
{
|
||||
if (sF.visibleAnnotations == null) sF.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
sF.visibleAnnotations.add(getSideAnn(false));
|
||||
cFields.add(x++, sF);
|
||||
info.sField.add(sF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cF.visibleAnnotations == null) cF.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
cF.visibleAnnotations.add(getSideAnn(true));
|
||||
sFields.add(sI, cF);
|
||||
info.cField.add(cF);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cF.visibleAnnotations == null) cF.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
cF.visibleAnnotations.add(getSideAnn(true));
|
||||
sFields.add(sI, cF);
|
||||
info.cField.add(cF);
|
||||
}
|
||||
sI++;
|
||||
}
|
||||
if (sFields.size() != cFields.size())
|
||||
{
|
||||
for (int x = cFields.size(); x < sFields.size(); x++)
|
||||
{
|
||||
FieldNode sF = sFields.get(x);
|
||||
if (sF.visibleAnnotations == null) sF.visibleAnnotations = new ArrayList<AnnotationNode>();
|
||||
sF.visibleAnnotations.add(getSideAnn(true));
|
||||
cFields.add(x++, sF);
|
||||
info.sField.add(sF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MethodWrapper
|
||||
{
|
||||
private MethodNode node;
|
||||
public boolean client;
|
||||
public boolean server;
|
||||
public MethodWrapper(MethodNode node)
|
||||
{
|
||||
this.node = node;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null || !(obj instanceof MethodWrapper)) return false;
|
||||
MethodWrapper mw = (MethodWrapper) obj;
|
||||
boolean eq = Objects.equal(node.name, mw.node.name) && Objects.equal(node.desc, mw.node.desc);
|
||||
if (eq)
|
||||
{
|
||||
mw.client = this.client | mw.client;
|
||||
mw.server = this.server | mw.server;
|
||||
this.client = this.client | mw.client;
|
||||
this.server = this.server | mw.server;
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.printf(" eq: %s %s\n", this, mw);
|
||||
}
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(node.name, node.desc);
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Objects.toStringHelper(this).add("name", node.name).add("desc",node.desc).add("server",server).add("client",client).toString();
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void processMethods(ClassNode cClass, ClassNode sClass, ClassInfo info)
|
||||
{
|
||||
List<MethodNode> cMethods = (List<MethodNode>)cClass.methods;
|
||||
List<MethodNode> sMethods = (List<MethodNode>)sClass.methods;
|
||||
LinkedHashSet<MethodWrapper> allMethods = Sets.newLinkedHashSet();
|
||||
|
||||
int cPos = 0;
|
||||
int sPos = 0;
|
||||
int cLen = cMethods.size();
|
||||
int sLen = sMethods.size();
|
||||
String clientName = "";
|
||||
String lastName = clientName;
|
||||
String serverName = "";
|
||||
while (cPos < cLen || sPos < sLen)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (sPos>=sLen)
|
||||
{
|
||||
break;
|
||||
}
|
||||
MethodNode sM = sMethods.get(sPos);
|
||||
serverName = sM.name;
|
||||
if (!serverName.equals(lastName) && cPos != cLen)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
do
|
||||
{
|
||||
if (cPos>=cLen)
|
||||
{
|
||||
break;
|
||||
}
|
||||
MethodNode cM = cMethods.get(cPos);
|
||||
lastName = clientName;
|
||||
clientName = cM.name;
|
||||
if (!clientName.equals(lastName) && sPos != sLen)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
cMethods.clear();
|
||||
sMethods.clear();
|
||||
|
||||
for (MethodWrapper mw : allMethods)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(mw);
|
||||
}
|
||||
cMethods.add(mw.node);
|
||||
sMethods.add(mw.node);
|
||||
if (mw.server && mw.client)
|
||||
{
|
||||
// no op
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mw.node.visibleAnnotations == null) mw.node.visibleAnnotations = Lists.newArrayListWithExpectedSize(1);
|
||||
mw.node.visibleAnnotations.add(getSideAnn(mw.client));
|
||||
if (mw.client)
|
||||
{
|
||||
info.sMethods.add(mw.node);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.cMethods.add(mw.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getClassBytes(String name) throws IOException
|
||||
{
|
||||
InputStream classStream = null;
|
||||
try
|
||||
{
|
||||
classStream = MCPMerger.class.getResourceAsStream("/" + name.replace('.', '/').concat(".class"));
|
||||
return readFully(classStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (classStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
classStream.close();
|
||||
}
|
||||
catch (IOException e){}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
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.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Splitter;
|
||||
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.io.LineProcessor;
|
||||
import com.google.common.io.Resources;
|
||||
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class MarkerTransformer implements IClassTransformer
|
||||
{
|
||||
private ListMultimap<String, String> markers = ArrayListMultimap.create();
|
||||
|
||||
public MarkerTransformer() throws IOException
|
||||
{
|
||||
this("fml_marker.cfg");
|
||||
}
|
||||
protected MarkerTransformer(String rulesFile) throws IOException
|
||||
{
|
||||
readMapFile(rulesFile);
|
||||
}
|
||||
|
||||
private void readMapFile(String rulesFile) throws IOException
|
||||
{
|
||||
File file = new File(rulesFile);
|
||||
URL rulesResource;
|
||||
if (file.exists())
|
||||
{
|
||||
rulesResource = file.toURI().toURL();
|
||||
}
|
||||
else
|
||||
{
|
||||
rulesResource = Resources.getResource(rulesFile);
|
||||
}
|
||||
Resources.readLines(rulesResource, Charsets.UTF_8, new LineProcessor<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void getResult()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processLine(String input) throws IOException
|
||||
{
|
||||
String line = Iterables.getFirst(Splitter.on('#').limit(2).split(input), "").trim();
|
||||
if (line.length()==0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
|
||||
if (parts.size()!=2)
|
||||
{
|
||||
throw new RuntimeException("Invalid config file line "+ input);
|
||||
}
|
||||
List<String> markerInterfaces = Lists.newArrayList(Splitter.on(",").trimResults().split(parts.get(1)));
|
||||
for (String marker : markerInterfaces)
|
||||
{
|
||||
markers.put(parts.get(0), marker);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
if (bytes == null) { return null; }
|
||||
if (!markers.containsKey(name)) { return bytes; }
|
||||
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader classReader = new ClassReader(bytes);
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
for (String marker : markers.get(name))
|
||||
{
|
||||
classNode.interfaces.add(marker);
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length < 2)
|
||||
{
|
||||
System.out.println("Usage: MarkerTransformer <JarPath> <MapFile> [MapFile2]... ");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasTransformer = false;
|
||||
MarkerTransformer[] trans = new MarkerTransformer[args.length - 1];
|
||||
for (int x = 1; x < args.length; x++)
|
||||
{
|
||||
try
|
||||
{
|
||||
trans[x - 1] = new MarkerTransformer(args[x]);
|
||||
hasTransformer = true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Could not read Transformer Map: " + args[x]);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTransformer)
|
||||
{
|
||||
System.out.println("Culd not find a valid transformer to perform");
|
||||
return;
|
||||
}
|
||||
|
||||
File orig = new File(args[0]);
|
||||
File temp = new File(args[0] + ".ATBack");
|
||||
if (!orig.exists() && !temp.exists())
|
||||
{
|
||||
System.out.println("Could not find target jar: " + orig);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if (temp.exists())
|
||||
{
|
||||
if (orig.exists() && !orig.renameTo(new File(args[0] + (new SimpleDateFormat(".yyyy.MM.dd.HHmmss")).format(new Date()))))
|
||||
{
|
||||
System.out.println("Could not backup existing file: " + orig);
|
||||
return;
|
||||
}
|
||||
if (!temp.renameTo(orig))
|
||||
{
|
||||
System.out.println("Could not restore backup from previous run: " + temp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!orig.renameTo(temp))
|
||||
{
|
||||
System.out.println("Could not rename file: " + orig + " -> " + temp);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
processJar(temp, orig, trans);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!temp.delete())
|
||||
{
|
||||
System.out.println("Could not delete temp file: " + temp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processJar(File inFile, File outFile, MarkerTransformer[] transformers) throws IOException
|
||||
{
|
||||
ZipInputStream inJar = null;
|
||||
ZipOutputStream outJar = null;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
inJar = new ZipInputStream(new BufferedInputStream(new FileInputStream(inFile)));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
outJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
|
||||
}
|
||||
|
||||
ZipEntry entry;
|
||||
while ((entry = inJar.getNextEntry()) != null)
|
||||
{
|
||||
if (entry.isDirectory())
|
||||
{
|
||||
outJar.putNextEntry(entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] data = new byte[4096];
|
||||
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
|
||||
|
||||
int len;
|
||||
do
|
||||
{
|
||||
len = inJar.read(data);
|
||||
if (len > 0)
|
||||
{
|
||||
entryBuffer.write(data, 0, len);
|
||||
}
|
||||
}
|
||||
while (len != -1);
|
||||
|
||||
byte[] entryData = entryBuffer.toByteArray();
|
||||
|
||||
String entryName = entry.getName();
|
||||
|
||||
if (entryName.endsWith(".class") && !entryName.startsWith("."))
|
||||
{
|
||||
ClassNode cls = new ClassNode();
|
||||
ClassReader rdr = new ClassReader(entryData);
|
||||
rdr.accept(cls, 0);
|
||||
String name = cls.name.replace('/', '.').replace('\\', '.');
|
||||
|
||||
for (MarkerTransformer trans : transformers)
|
||||
{
|
||||
entryData = trans.transform(name, entryData);
|
||||
}
|
||||
}
|
||||
|
||||
ZipEntry newEntry = new ZipEntry(entryName);
|
||||
outJar.putNextEntry(newEntry);
|
||||
outJar.write(entryData);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (outJar != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
outJar.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (inJar != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
inJar.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package cpw.mods.fml.common.asm.transformers;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
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 cpw.mods.fml.common.asm.SideOnly;
|
||||
import cpw.mods.fml.relauncher.FMLRelauncher;
|
||||
import cpw.mods.fml.relauncher.IClassTransformer;
|
||||
|
||||
public class SideTransformer implements IClassTransformer
|
||||
{
|
||||
private static String SIDE = FMLRelauncher.side();
|
||||
private static final boolean DEBUG = false;
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public byte[] transform(String name, byte[] bytes)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
|
||||
}
|
||||
fields.remove();
|
||||
}
|
||||
}
|
||||
Iterator<MethodNode> methods = classNode.methods.iterator();
|
||||
while(methods.hasNext())
|
||||
{
|
||||
MethodNode method = methods.next();
|
||||
if (remove((List<AnnotationNode>)method.visibleAnnotations, SIDE))
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
|
||||
}
|
||||
methods.remove();
|
||||
}
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
classNode.accept(writer);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
private boolean remove(List<AnnotationNode> anns, String side)
|
||||
{
|
||||
if (anns == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (AnnotationNode ann : anns)
|
||||
{
|
||||
if (ann.desc.equals(Type.getDescriptor(SideOnly.class)))
|
||||
{
|
||||
if (ann.values != null)
|
||||
{
|
||||
for (int x = 0; x < ann.values.size() - 1; x += 2)
|
||||
{
|
||||
Object key = ann.values.get(x);
|
||||
Object value = ann.values.get(x+1);
|
||||
if (key instanceof String && key.equals("value"))
|
||||
{
|
||||
if (value instanceof String[] )
|
||||
{
|
||||
if (!((String[])value)[1].equals(side))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package cpw.mods.fml.common.discovery;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
public class ASMDataTable
|
||||
{
|
||||
public static class ASMData
|
||||
{
|
||||
private ModCandidate candidate;
|
||||
private String annotationName;
|
||||
private String className;
|
||||
private String objectName;
|
||||
private Map<String,Object> annotationInfo;
|
||||
public ASMData(ModCandidate candidate, String annotationName, String className, String objectName, Map<String,Object> info)
|
||||
{
|
||||
this.candidate = candidate;
|
||||
this.annotationName = annotationName;
|
||||
this.className = className;
|
||||
this.objectName = objectName;
|
||||
this.annotationInfo = info;
|
||||
}
|
||||
public ModCandidate getCandidate()
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
public String getAnnotationName()
|
||||
{
|
||||
return annotationName;
|
||||
}
|
||||
public String getClassName()
|
||||
{
|
||||
return className;
|
||||
}
|
||||
public String getObjectName()
|
||||
{
|
||||
return objectName;
|
||||
}
|
||||
public Map<String, Object> getAnnotationInfo()
|
||||
{
|
||||
return annotationInfo;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ModContainerPredicate implements Predicate<ASMData>
|
||||
{
|
||||
private ModContainer container;
|
||||
public ModContainerPredicate(ModContainer container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
public boolean apply(ASMData data)
|
||||
{
|
||||
return container.getSource().equals(data.candidate.getModContainer());
|
||||
}
|
||||
}
|
||||
private SetMultimap<String, ASMData> globalAnnotationData = HashMultimap.create();
|
||||
private Map<ModContainer, SetMultimap<String,ASMData>> containerAnnotationData;
|
||||
|
||||
private List<ModContainer> containers = Lists.newArrayList();
|
||||
|
||||
public SetMultimap<String,ASMData> getAnnotationsFor(ModContainer container)
|
||||
{
|
||||
if (containerAnnotationData == null)
|
||||
{
|
||||
ImmutableMap.Builder<ModContainer, SetMultimap<String, ASMData>> mapBuilder = ImmutableMap.<ModContainer, SetMultimap<String,ASMData>>builder();
|
||||
for (ModContainer cont : containers)
|
||||
{
|
||||
Multimap<String, ASMData> values = Multimaps.filterValues(globalAnnotationData, new ModContainerPredicate(cont));
|
||||
mapBuilder.put(cont, ImmutableSetMultimap.copyOf(values));
|
||||
}
|
||||
containerAnnotationData = mapBuilder.build();
|
||||
}
|
||||
return containerAnnotationData.get(container);
|
||||
}
|
||||
|
||||
public Set<ASMData> getAll(String annotation)
|
||||
{
|
||||
return globalAnnotationData.get(annotation);
|
||||
}
|
||||
|
||||
public void addASMData(ModCandidate candidate, String annotation, String className, String objectName, Map<String,Object> annotationInfo)
|
||||
{
|
||||
globalAnnotationData.put(annotation, new ASMData(candidate, annotation, className, objectName, annotationInfo));
|
||||
}
|
||||
|
||||
public void addContainer(ModContainer container)
|
||||
{
|
||||
this.containers.add(container);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 392 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user