Compare commits

...
142 Commits
Author SHA1 Message Date
Christian b33cff3613 Fix NPE for server relaunch 2012-08-11 12:05:13 -04:00
Christian afc2a4a75c Fix up Package.getPackage(), also fix up loadcontroller construction 2012-08-11 11:44:55 -04:00
Christian 7c4583c87a Add in Package.getPackage() support for sengir 2012-08-11 11:12:16 -04:00
Christian f563815961 Lost of work to try and complete ML support - probably still bits missing, but mostly there 2012-08-11 11:02:09 -04:00
LexManos 0ce38f747c Newlines in diff file 2012-08-11 02:27:19 -07:00
LexManos efce8e916b Add special case to add Side/SideOnly to difflist 2012-08-11 02:25:40 -07:00
Christian 44728c9f93 Fix up some network related stuff and optimize mod lookup a bit 2012-08-11 02:43:04 -04:00
Christian d96a81e4f2 Fix up proxy injector to inject properly 2012-08-11 02:24:29 -04:00
LexManos f11844374e Fix decompile 2012-08-10 20:41:59 -07:00
Christian 8c63203bb4 Fix NPE on missing mods - still need to actually handle missing mods properly on client 2012-08-10 23:27:11 -04:00
Christian 751299d5f1 New downloader UI and new downloader backend - should be more robust now 2012-08-10 23:18:52 -04:00
LexManos 7d479bf854 Added -no_gen_conf to jenkins build 2012-08-10 20:09:47 -07:00
LexManos c812a4ede5 Added some extra error prints, hopeully get something useful when installed in the client. 2012-08-10 18:54:06 -07:00
LexManos a826283111 Updated conf merger script to just merge everything, and normalize the line endings so git doesn't complain. 2012-08-10 18:25:11 -07:00
Christian f61f30c1e6 SidedProxy should work again - anywhere. Make sure it's on a static field though 2012-08-10 17:42:43 -04:00
Christian 8f76e8ba8b More ticking hooks, and some other bits of clean up. Very close to "done" now. 2012-08-10 17:11:01 -04:00
Christian 537d89b9e0 Fix up modloader and clean up junk method 2012-08-10 16:42:21 -04:00
Christian 0927aaa0f1 A lot of missing patches to code re-added. Almost all functionality should now
be restored.

ModLoader compatibility is not yet assured, there are some wrapper classes that
need re-writing first
2012-08-10 16:39:03 -04:00
LexManos d17aad797d Readded common folder to startclient/server. 2012-08-10 12:38:59 -07:00
Christian 53e611a03a Add in a registration method for gui handlers 2012-08-10 11:12:57 -04:00
Christian 7ac1be8a9a Overwrote lex's command patch 2012-08-10 10:57:18 -04:00
Christian dd7d70d619 Fix up MCP merger - it definitely works now - the game runs and runs well.
Fix up a couple of small network related issues.
Fix up the server launching fml properly.
2012-08-10 10:03:33 -04:00
LexManos b9d1d1e2f4 Added common folder support to startclient/startserver 2012-08-09 20:34:16 -07:00
LexManos 2dc00adec8 Added some missing quotes that caused issues if your workspace had a space in it. 2012-08-09 20:01:51 -07:00
LexManos b97e937f28 Add lib folder to installed eclipse 2012-08-09 19:02:28 -07:00
Christian c54c4e73e6 Add in missing patch - also, launch FML properly from the server 2012-08-09 09:21:16 -04:00
Christian 93528597f4 Entity spawn adjustment - tracker 2012-08-09 08:40:32 -04:00
LexManos a85bb7bfdb Fix ModLoader compilation, and MCPmerger invocation for Forge. 2012-08-09 03:04:25 -07:00
LexManos 0f2d00abf3 Include conf folder and merge config in source zip 2012-08-08 23:44:32 -07:00
Christian 0e4c716177 Entity spawning - done 2012-08-09 01:58:14 -04:00
Christian 85b77c3d12 Generate a universal binary package since we can now :) 2012-08-09 01:57:42 -04:00
Christian 03884b1aaa Merge branch 'MergingClientServer' 2012-08-08 22:58:33 -04:00
Christian dbdc76e6ea Reorganized all the current patches 2012-08-08 22:57:37 -04:00
Christian b8aaed368b Fix up annotation parser to parse arrays and enums 2012-08-08 22:10:56 -04:00
LexManos 6ec3379153 Added SideTransformer to strip side only functions/fields out. 2012-08-08 18:53:41 -07:00
LexManos b177aad1ee Stage 1 of merging the client and server for MCP.
Results:
Client: 362
Server: 3 (Only due to issues of FF decompilation inconsistancies)
Common: 910

Stage 2: Write runtime transformer to remove annotated fields/methods with invalid side annotation.
2012-08-08 05:48:06 -07:00
Christian e050c7807d Gui Handler ported from MC forge 2012-08-08 00:31:24 -04:00
Christian f3f7398a8b Revert dumb stuff with commands patch - lots of gfx patching 2012-08-07 23:11:37 -04:00
Christian da4311dc74 Almost finished basic network stuff now 2012-08-07 20:41:37 -04:00
Christian 59471f6cac Update some patches- more network work 2012-08-07 20:10:36 -04:00
Christian d8b92064d7 Bunch of hooks re-added : network is more complete now, lot of basemod cleanup, moving stuff into
the registry area
2012-08-06 22:30:13 -04:00
Christian 8e96e60179 Fix location of forge in common handler - also some tweaks to modloader and other stuff 2012-08-06 17:27:21 -04:00
Christian 54877176a6 Network support - there's still some work to do and full id sync isn't done yet, but it has proper registration
semantics and hooks for 250 handling
2012-08-06 16:12:50 -04:00
Christian a3ad32a3e5 Add in a lot of network handler stuff - also, expose the asm harvested data 2012-08-06 09:52:42 -04:00
Christian 602a4f219c Remove some unneeded fields from the annotations 2012-08-05 02:24:02 -04:00
LexManos f24977dc3d Made empty constructor for ModMetadata public 2012-08-04 22:51:57 -07:00
LexManos 4607f9ebb0 Fix path trimming for copytree 2012-08-04 20:36:27 -07:00
Christian 672f4a03f2 Change property name to fml.modStates not fml.disabledMods- it makes more sense that way 2012-08-04 12:35:46 -04:00
Christian f0736ade3d Add in a bit of logging when events get sent to mod containers 2012-08-04 11:45:40 -04:00
Christian 4da48cea7a Allow coremods to inject a modcontainer and run code
this will mean that FML is deliberately and very obviously incompatible with a modloader installation.

Fix up worldtype so that the server can run.
2012-08-04 11:31:06 -04:00
LexManos 1b02ea0677 Patch commands.py to support side '2' as common, as well as fix a few small errors in the update_patches and fml scripts. 2012-08-04 03:34:34 -07:00
LexManos 0d1bd4c5d0 Merged transformers/ to /common and renamed the asm source download to align better with the asm bin file name. 2012-08-03 23:51:49 -07:00
LexManos 3f08f1a94c Change place commands.py backup is stored. 2012-08-03 23:24:58 -07:00
LexManos 1069366219 FML finish won't updatemcp automatically, easier integration with forge. 2012-08-03 17:36:16 -07:00
LexManos 0002bd2875 Fix packaging and install to not have the src/ folder, making it align better with the dev env. 2012-08-03 17:32:23 -07:00
LexManos 823077dd7d Moved setting up eclipse to setup_mcp 2012-08-03 16:56:00 -07:00
LexManos 34971ff3e0 Fixed ant script to support common folder building and add the new files to the dist archives. 2012-08-03 03:37:45 -07:00
LexManos 965069ba3a setup_fml's decompile will result in proper md5 files now {if there is no compiler issues} 2012-08-03 03:35:38 -07:00
LexManos 43766751a4 Removed FMLRegistry, and IMinecraftRegistry.
Updated server side to use the seperated registry classes like the client does.
Updated searge name references on server
Made StatBase.statName public using AccessTransformer
Server should compile now
2012-08-03 01:50:48 -07:00
LexManos a92da71c6b Fix MockBlock compile 2012-08-03 01:47:09 -07:00
LexManos da47985361 Download argo/guava source references in install, and updated eclipse workspaces to reference them. 2012-08-02 23:36:00 -07:00
LexManos 68ae32c48c Cleaned up commands.patch, removed debug print in fml.py 2012-08-02 21:14:06 -07:00
LexManos 3373e33d4b Remove clientdrop, old reference files. 2012-08-02 20:32:51 -07:00
LexManos 2839e79ab0 Delete some dead files 2012-08-02 19:42:12 -07:00
Christian 5bffbfbe0d Fix commands patch, WorldType patch and some ML compat stuff 2012-08-02 20:09:18 -02:30
Christian 4080338c1b More fixes 2012-08-02 16:50:30 -02:30
Christian e06e9393c1 More build fixes for jenkins 2012-08-02 10:33:29 -02:30
Christian 4bb9fd7226 Try and fix the jenkins build 2012-08-02 10:30:52 -02:30
Christian 7edc7d74d4 Change some event names, hook up the event code for server events for FML 2012-08-02 09:31:03 -02:30
Christian 9a5dac605c Merge branch 'newfmlmod' 2012-08-02 08:52:11 -02:30
LexManos c0a781c0bd Introduced patching of runtime/commands.py to allow for usage of the src/common folder. 2012-08-02 00:51:51 -07:00
Christian 719bea515e Change some stuff around - begin launching the server through the wrapper too.
A lot of patches went in - the client and server both launch and start up mods.
2012-08-02 02:08:30 -02:30
Christian 153eafdcb0 More stuff 2012-08-01 21:19:11 -02:30
Christian 2f588cf6ef Fix classpath for Client, maybe? 2012-08-01 21:19:11 -02:30
Christian 3ad3c474b5 Line endings for this branch 2012-08-01 21:18:55 -02:30
Christian 73ba4b68be A load of transformer accesses- also a few tweaks to the transformer, and linux support in the fml python 2012-08-01 18:59:45 -02:30
LexManos b786d8909a Rewrote patch generation and application to no longer need diff, and attempt to apply common patches on decompiles that don't have one side or the other. 2012-08-01 06:54:57 -07:00
LexManos ab45ec9fa4 Updated eclipse projects to have src-common linked resources 2012-08-01 03:52:03 -07:00
LexManos fcbe56b504 Modified the decompiler stage to:
Compile and run AccessTransformer during the pre-RG stage of decompilation.
Merge resulting sources that are identical to src/common

ToDo:
Finish the common intergration:
-update_patches - Add common folder support
-apply_patches:
--patch each side, also patch all common patches to each side incase they are not merged, only if file exists.
2012-08-01 03:25:45 -07:00
LexManos 693ec7ddf6 Add temp AccessTransformer config for FML 2012-08-01 03:18:31 -07:00
LexManos 61b83ab992 Discard old setup script 2012-08-01 03:18:02 -07:00
LexManos 6ce9b1ab05 Fixed AccessTransformer issue with trying to load files, instead of resources. 2012-08-01 03:17:36 -07:00
Christian a5d58d79fc Commit the start of some pluggable transformers 2012-07-31 09:46:45 -04:00
Christian dac3249dc4 XP for smelting 2012-07-30 23:07:53 -04:00
Christian 99eddbfa13 Beginning the 1.3.1 update 2012-07-30 22:31:07 -04:00
Christian ea1fc8f358 Add in the ability to create versioned dependencies for mod relationships
BaseMod versions are loaded too late so will never work as a versioned
dependency requirement, but can have versioned deps of others
2012-07-30 17:01:27 -04:00
Christian bbb5a0e891 Fix up coremods with relaunch, add in a sample "coremod" 2012-07-30 11:34:30 -04:00
Christian 3f491fa7cb Add in events for the method pre/init/post annotations so we can add in extra data during the event phase 2012-07-30 00:33:21 -04:00
Christian ae007fcebc Fix whitespace issue 2012-07-29 23:54:07 -04:00
Christian 8580a99728 Fix window sticking around - it doesn't anymore 2012-07-29 23:46:52 -04:00
Christian 3257d2595d Add in "transform excluded" classes that we still need to take loading responsibility for 2012-07-29 23:30:37 -04:00
Christian 5434b3ca24 Added in some dialogs when things don't go so well 2012-07-29 22:55:53 -04:00
Christian 1ea6ba273b New logging stuff, also the early plugin api for forge 2012-07-29 22:54:59 -04:00
Christian 039d9252c6 Merge branch 'minecraft1.3' into newfmlmod 2012-07-23 23:02:25 -02:30
Christian ca67d6eb6d Fix up mod classloading delegation 2012-07-23 22:54:36 -02:30
Christian 7179edfba7 Some patches to go along with the other changes 2012-07-23 22:51:16 -02:30
Christian baec9785a2 More stuff as I roll out the changes 2012-07-23 22:50:37 -02:30
Christian ae2039c65d A bunch more fixes for FML mods 2012-07-23 16:33:17 -02:30
Christian 3f803653c4 Merge remote-tracking branch 'mainlap/newkeys' into newfmlmod
Conflicts:
	client/cpw/mods/fml/client/FMLClientHandler.java
2012-07-22 20:30:42 -02:30
Christian 6ff67693b9 New key handling 2012-07-22 20:25:18 -02:30
Christian 5501d644b9 Check in a lot of recent work 2012-07-22 11:56:38 -02:30
Christian 276fccb170 Check in new fml mod work so far. Lots still to do. 2012-07-14 13:58:46 -04:00
LexManos e2fac06f64 Cleaned up the install script for the source distrabution to setup the workspace properly, delete argo, and download all required dependancies. 2012-07-12 18:07:58 -07:00
LexManos 25def1ceaf Added call to clean_source to build script to fix patch fuzz on windows. 2012-07-12 18:06:39 -07:00
LexManos c0f70309dd Fix Client-Clean project to use relative path to argo. 2012-07-12 18:06:01 -07:00
Christian 899c1f519c Another bloody ticking fix. This should fix mods that use ML.setInGameHook(true,false) on the
server side to recieve ticks.
2012-07-08 22:06:11 -04:00
Christian 5c1363150e Fix up mod classloading delegation 2012-07-06 15:59:16 -04:00
Christian 4153584392 Fixes 2012-07-06 10:42:49 -04:00
Christian 2858731063 Incorporate server patches into client 2012-07-06 10:29:17 -04:00
Christian 874a0c32e0 Remove two places that are unpatchable now 2012-07-06 09:52:21 -04:00
Christian 4f845befaa Server repatching 2012-07-06 09:44:00 -04:00
Christian 95194f1c5b Add a "checkpatches" target and check if your patches are up to date before running a repatch operation 2012-07-06 09:19:58 -04:00
Christian df6bbaa7c5 Launch through the applet launcher too 2012-07-06 01:04:33 -04:00
Christian b1ca21a161 Some patches for the server 2012-07-05 22:31:46 -04:00
Christian bc42a54a51 Lots of client patch fixup 2012-07-05 18:13:47 -04:00
Christian 1555bd8c53 Update git ignore to ignore a fernflowerzip that's lying around 2012-07-05 15:38:37 -04:00
Christian 649e3e7bc5 And we have a brand, "fml". We're definitely modded :) 2012-07-05 15:36:31 -04:00
Christian ead4e5255e UnexpectedThrowable is now the much more awesome CrashReport! 2012-07-05 15:35:38 -04:00
Christian 5eafb71083 Merge branch 'master' into minecraft1.3
Bring some of the ticking fixes in

Conflicts:
	client/cpw/mods/fml/client/FMLClientHandler.java
	patches/minecraft_server/net/minecraft/server/MinecraftServer.java.patch
2012-07-05 15:30:21 -04:00
Christian 8ed36f583d Got the relauncher downloading and injecting library files 2012-07-05 15:23:37 -04:00
Christian 3e311fd4c1 Tweak ticking YET AGAIN. Should fire a solitary GUILOAD tick right as the game screen loads.
Hopefully fixes worldload tick issue too
2012-07-04 00:16:30 -04:00
Christian a4ce90a918 FFS let this fix that bloody ticking mess that is ML compatibility. 2012-07-03 23:03:51 -04:00
Christian ba46389a87 Separate gui ticking completely. send it as if it's a world tick. ML gui ticks are epically dumb.
Fix Worldload being filtered from the trigger arming.
Also, improve errors going to an error screen. There should be more information now.
2012-07-03 22:39:35 -04:00
Christian f7e07ca7d8 Change gui ticking and world load tick. Should close issue #40 and kill it deader
than a very very dead thing. *$^*(#% Modloader ticking b#%$hit
2012-07-03 21:37:54 -04:00
Christian 3e80a9ee7d Merge branch 'master' into minecraft1.3 2012-07-03 08:15:58 -04:00
Christian dfc6f7b1c1 Tweak build xml for more cleanliness 2012-07-03 08:14:35 -04:00
Christian 753f5f7bc8 Merge branch 'antscriptupdates' 2012-07-02 23:50:49 -04:00
Christian 982271e8ec Update some stuff 2012-07-02 23:49:40 -04:00
Christian 802ec3d86a Merge branch 'antscriptupdates' into minecraft1.3 2012-07-02 23:49:06 -04:00
Christian f1b0e33694 Add in more options for ant script and clean up needing to clean every time. 2012-07-02 23:43:29 -04:00
Christian 1d64fb01bd Merge branch 'testrecover' 2012-07-02 20:19:23 -04:00
Christian 086f575a41 Merge branch 'antscriptupdates' into minecraft1.3 2012-07-02 15:56:33 -04:00
Christian 3cda115cd5 Merge branch 'antscriptupdates' 2012-07-02 15:55:24 -04:00
Christian d491502750 Some more fixes to the ant stuff: apply patches now happens at the right time, I grab fernflower as part of
setup and added an updatepatches call too
2012-07-02 15:54:25 -04:00
Christian 1d4c33d161 Merge branch 'antscriptupdates' into minecraft1.3
Conflicts:
	build.xml
2012-07-02 15:21:15 -04:00
Christian 47a879a961 Merge branch 'antscriptupdates' 2012-07-02 15:17:32 -04:00
Christian b59184424b Add in a setupenvironment ant target specifically for setting up an FML environment from scratch 2012-07-02 15:16:40 -04:00
Christian a7803d1785 Harvest MC version from MCP 2012-07-02 13:31:45 -04:00
Christian 5415bf87ce fix sided proxy bukkit test (not used so not a biggie) 2012-07-02 12:32:41 -04:00
Christian a33f2dde77 Harvest MC version from MCP 2012-07-02 12:24:37 -04:00
Christian bb7ef791de Initial checkin. Some patches are probably missing, but client compiles. 2012-06-29 20:18:04 -04:00
Christian d00e229198 ModSorting test case 2012-06-21 21:56:16 -04:00
322 changed files with 63877 additions and 8559 deletions

No files matched your search

-10
View File
@@ -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>
+1
View File
@@ -0,0 +1 @@
* text=auto
+12 -10
View File
@@ -1,10 +1,12 @@
/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
/.metadata/
/eclipse/.metadata/
/target
fmlbranding.properties
/fernflower.zip
/commands.py.bck
-3
View File
@@ -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
-4
View File
@@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
+6
View File
@@ -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
View File
@@ -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()
+235 -55
View File
@@ -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}"/>
@@ -52,29 +53,34 @@
<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,7 +92,30 @@
</exec>
</target>
<target name="buildandreobfmcp" depends="init">
<target name="buildandreobfmcp" depends="buildenvsetup,recompile">
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
<arg value="${mcp.home}/runtime/reobfuscate.py" />
</exec>
<fail message="Reobfuscation failed">
<condition>
<not>
<and>
<available file="${mcp.home}/temp/server.md5"/>
<available file="${mcp.home}/temp/server_reobf.md5"/>
<available file="${mcp.home}/temp/client.md5"/>
<available file="${mcp.home}/temp/client_reobf.md5"/>
</and>
</not>
</condition>
</fail>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${basedir}/generatechangedfilelist.py"/>
<arg value="${mcp.home}"/>
<arg value="${basedir}/difflist.txt"/>
</exec>
</target>
<target name="recompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
<arg value="${mcp.home}/runtime/recompile.py" />
</exec>
@@ -94,51 +123,41 @@
<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}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
<available file="${mcp.home}/bin/minecraft_server/net/minecraft/server/MinecraftServer.class"/>
</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}"/>
<arg value="${basedir}/difflist.txt"/>
</exec>
</target>
<target name="merge-client" depends="init,clean">
<antcall target="merge-source">
<param name="side" value="client" />
</antcall>
</target>
<target name="merge-server" depends="init,clean">
<antcall target="merge-source">
<param name="side" value="server" />
</antcall>
</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" />
<fileset dir="${common.src.dir}" includes="**/*.java" />
<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="build-client" depends="init,merge-client,buildandreobfmcp">
<target name="merge-server" depends="buildenvsetup">
<copy todir="${server.mcp.srcdir}" overwrite="true" verbose="true">
<fileset dir="${server.src.dir}" includes="**/*.java" />
</copy>
</target>
<target name="merge-common">
<copy todir="${common.mcp.srcdir}" overwrite="true" verbose="true">
<fileset dir="${common.src.dir}" includes="**/*.java" />
</copy>
</target>
<target name="merge-source" depends="buildenvsetup,merge-client,merge-server,merge-common" />
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,buildandreobfmcp,makeversion">
<antcall target="extract-built-jar">
<param name="side" value="client" />
</antcall>
</target>
<target name="build-server" depends="init,clean,merge-server,buildandreobfmcp">
<target name="build-server" depends="buildenvsetup,merge-server,merge-common,buildandreobfmcp,makeversion">
<antcall target="extract-built-jar">
<param name="side" value="server" />
</antcall>
@@ -153,6 +172,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 +191,48 @@
</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">
<property name="universal.jarname" value="${modname}-universal-${version}" />
<mkdir dir="${basedir}/target" />
<jar destfile="${basedir}/target/${universal.jarname}.zip">
<manifest>
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
</manifest>
<fileset dir="${server.mcp.obfoutput}" includes="**/*.class" />
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" />
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
<mappedresources>
<concat>
<fileset dir="${basedir}/install" includes="README.txt" />
<filterchain>
<replacetokens>
<token key="MAJOR" value="${version.major}" />
<token key="MINOR" value="${version.minor}" />
<token key="REV" value="${version.rev}" />
<token key="BUILD" value="${version.build}" />
<token key="MCVERSION" value="${version.minecraft}" />
</replacetokens>
</filterchain>
</concat>
<mergemapper to="README-fml.txt" />
</mappedresources>
</jar>
</target>
<target name="build-source-pack" depends="makeversion">
<property name="srcpack.jarname" value="${modname}-src-${version}" />
<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="${server.src.dir}" includes="**/*.java" prefix="fml/server" />
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/common" />
<zipfileset dir="${common.src.dir}" includes="*.cfg" prefix="fml/common" />
<zipfileset dir="${patch.src.dir}" includes="**/*.patch" prefix="fml/patches" />
<zipfileset dir="${fml.conf.dir}" prefix="fml/conf" />
<mappedresources>
<concat>
<fileset dir="${basedir}/install" includes="README.txt" />
@@ -197,20 +248,149 @@
</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-server,merge-client,merge-common,build-server,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>
<!--<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/download_fernflower.py" />
<arg value="${mcp.home}"/>
</exec>-->
<antcall target="fmldecompile"/>
<echo>Moving old patched sources at ${patch.mcp.srcdir} out of the way</echo>
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
<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-server,buildandreobfmcp">
<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
View File
@@ -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()
File diff suppressed because it is too large. Load diff
+69 -69
View File
@@ -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 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_76852_a = new byte[tileSizeSquare << 2];
}
public boolean unregister(RenderEngine engine, List<TextureFX> effects)
{
effects.remove(this);
return true;
}
}
+47 -42
View File
@@ -22,7 +22,7 @@ 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.FMLDummyContainer;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.client.Minecraft;
@@ -39,7 +39,6 @@ import net.minecraft.src.Tessellator;
*/
public class GuiModList extends GuiScreen
{
private GuiScreen mainMenu;
private GuiSlotModList modList;
private int selected = -1;
@@ -55,98 +54,104 @@ public class GuiModList extends GuiScreen
this.mainMenu=mainMenu;
this.mods=new ArrayList<ModContainer>();
FMLClientHandler.instance().addSpecialModEntries(mods);
for (ModContainer mod : Loader.getModList()) {
for (ModContainer mod : Loader.instance().getModList()) {
if (mod.getMetadata()!=null && mod.getMetadata().parentMod != null) {
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) {
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("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);
}
}
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;
}
/**
@@ -117,15 +117,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 +249,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 +283,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 +311,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 +350,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 +382,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 -6
View File
@@ -17,6 +17,7 @@ package cpw.mods.fml.client;
import java.util.ArrayList;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
import net.minecraft.client.Minecraft;
@@ -36,7 +37,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 +63,7 @@ public class GuiSlotModList extends GuiScrollingList
@Override
protected void drawBackground()
{
this.parent.func_578_i();
this.parent.func_73873_v_();
}
@Override
@@ -70,14 +71,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 - 11), this.left + 3 , var3 + 2, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 11), this.left + 3 , var3 + 22, 0xFF2222);
}
else
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFFFFFF);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 9), this.left + 3 , var3 + 22, 0xCCCCCC);
}
}
}
+30 -30
View File
@@ -1,30 +1,30 @@
/*
* 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.*;
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();
}
@@ -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;
}
}
+11 -10
View File
@@ -16,10 +16,11 @@ 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.FMLLog;
import cpw.mods.fml.common.LoaderException;
/**
@@ -31,7 +32,7 @@ public class SpriteHelper
private static HashMap<String, BitSet> spriteInfo = new HashMap<String, BitSet>();
private static void initMCSpriteMaps() {
BitSet slots =
BitSet slots =
SpriteHelper.toBitSet(
"0000000000000000" +
"0000000000000000" +
@@ -50,7 +51,7 @@ public class SpriteHelper
"0000000111111000" +
"0000000000000000");
spriteInfo.put("/terrain.png", slots);
slots = SpriteHelper.toBitSet(
"0000000000000000" +
"0000000000000000" +
@@ -73,8 +74,8 @@ public class SpriteHelper
/**
* 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 +87,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 +109,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;
@@ -0,0 +1,347 @@
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 org.lwjgl.opengl.GL11;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import net.minecraft.client.Minecraft;
import net.minecraft.src.KeyBinding;
import net.minecraft.src.ModTextureStatic;
import net.minecraft.src.Profiler;
import net.minecraft.src.RenderEngine;
import net.minecraft.src.TextureFX;
import net.minecraft.src.TexturePackBase;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
public class TextureFXManager
{
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();
FMLClientHandler.instance().profileStart(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);
}
FMLClientHandler.instance().profileEnd();
return false;
}
FMLClientHandler.instance().profileEnd();
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, TexturePackBase 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 TexturePackBase 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);
}
/**
* @param anim
*/
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);
}
/**
* @param p_6531_1_
*/
public void loadTextures(TexturePackBase texturePack)
{
registerTextureOverrides(client.field_71446_o);
}
public void registerTextureOverrides(RenderEngine renderer) {
for (ModContainer mod : Loader.instance().getActiveModList()) {
registerAnimatedTexturesFor(mod);
}
for (OverrideInfo animationOverride : animationSet) {
renderer.func_78355_a(animationOverride.textureFX);
addedTextureFX.add(animationOverride.textureFX);
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);
}
}
}
}
/**
* @param mod
*/
private void registerAnimatedTexturesFor(ModContainer mod)
{
}
/**
* @param field_6539_c
*/
public void onEarlyTexturePackLoad(TexturePackBase fallback)
{
if (client==null) {
// We're far too early- let's wait
this.earlyTexturePack = fallback;
} else {
loadTextures(fallback);
}
}
public void pruneOldTextureFX(TexturePackBase 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));
}
/**
* @param renderEngine
* @param path
* @return
*/
public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
{
InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
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;
}
}
@@ -12,12 +12,13 @@
* 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.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
@@ -25,28 +26,30 @@ import cpw.mods.fml.common.modloader.ModLoaderModContainer;
* @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 +64,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 +76,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,63 @@
package cpw.mods.fml.client.modloader;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.Maps;
import net.minecraft.client.Minecraft;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Entity;
import net.minecraft.src.Render;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
import cpw.mods.fml.common.modloader.ModLoaderHelper;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
public class ModLoaderClientHelper implements IModLoaderSidedHelper
{
/**
* @param mod
* @param inventoryRenderer
* @return
*/
public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
{
int renderId=RenderingRegistry.instance().getNextAvailableRenderId();
ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
RenderingRegistry.instance().registerBlockHandler(bri);
return renderId;
}
public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
{
BaseMod mod = (BaseMod) mc.getMod();
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap();
mod.addRenderer(renderers);
for (Entry<Class<? extends Entity>, Render> e : renderers.entrySet())
{
RenderingRegistry.instance().registerEntityRenderingHandler(e.getKey(), e.getValue());
}
mod.registerAnimation(game);
}
public ModLoaderClientHelper(Minecraft client)
{
this.client = client;
ModLoaderHelper.sidedHelper = this;
}
private Minecraft client;
@Override
public void finishModLoading(ModLoaderModContainer mc)
{
handleFinishLoadingFor(mc, client);
}
}
@@ -0,0 +1,104 @@
/*
* 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.EnumSet;
import net.minecraft.src.KeyBinding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.registry.TickRegistry;
/**
* @author cpw
*
*/
public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
{
private ModLoaderModContainer modContainer;
private boolean downArmed;
private boolean upArmed;
/**
* @param keyHandler
* @param allowRepeat
* @param modContainer
*/
public ModLoaderKeyBindingHandler(KeyBinding keyBinding, boolean allowRepeat, ModLoaderModContainer modContainer)
{
super(keyBinding, allowRepeat);
this.modContainer=modContainer;
}
public void onRenderEndTick()
{
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(keyBinding);
}
@Override
public void keyDown(EnumSet<TickType> type, boolean end, boolean repeats)
{
if (!end)
{
return;
}
upArmed = false;
if (type.contains(TickType.CLIENT))
{
downArmed = true;
}
if (type.contains(TickType.RENDER) && downArmed)
{
onRenderEndTick();
downArmed = false;
}
}
@Override
public void keyUp(EnumSet<TickType> type, boolean end)
{
if (!end)
{
return;
}
downArmed = false;
if (type.contains(TickType.CLIENT))
{
upArmed = true;
}
if (type.contains(TickType.RENDER) && upArmed)
{
onRenderEndTick();
upArmed = false;
}
}
@Override
public EnumSet<TickType> ticks()
{
return EnumSet.of(TickType.CLIENT, TickType.RENDER);
}
@Override
public String getLabel()
{
return modContainer.getModId() +" KB "+keyBinding.field_74512_d;
}
}
@@ -0,0 +1,35 @@
package cpw.mods.fml.client.registry;
import java.util.Collections;
import net.minecraft.src.BiomeGenBase;
import net.minecraft.src.TileEntity;
import net.minecraft.src.TileEntityRenderer;
import net.minecraft.src.TileEntitySpecialRenderer;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.common.registry.GameRegistry;
public class ClientRegistry
{
/**
*
* 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,94 @@
package cpw.mods.fml.client.registry;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.google.common.collect.Lists;
import net.minecraft.src.GameSettings;
import net.minecraft.src.KeyBinding;
import 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
{
public static abstract class KeyHandler implements ITickHandler
{
protected KeyBinding keyBinding;
protected boolean keyDown;
protected boolean repeating;
public KeyHandler(KeyBinding keyBinding, boolean repeating)
{
this.keyBinding = keyBinding;
this.repeating = repeating;
}
public KeyBinding getKeyBinding()
{
return this.keyBinding;
}
@Override
public final void tickStart(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, false);
}
@Override
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, true);
}
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
{
int keyCode = keyBinding.field_74512_d;
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state != keyDown || (state && repeating))
{
if (state)
{
keyDown(type, tickEnd, state!=keyDown);
}
else
{
keyUp(type, tickEnd);
}
keyDown = state;
}
}
public abstract void keyDown(EnumSet<TickType> types, boolean tickEnd, boolean isRepeat);
public abstract void keyUp(EnumSet<TickType> types, boolean tickEnd);
}
private static List<KeyHandler> keyHandlers = Lists.newArrayList();
public static void registerKeyBinding(KeyHandler handler) {
keyHandlers.add(handler);
TickRegistry.registerTickHandler(handler, Side.CLIENT);
}
public static void uploadKeyBindingsToGame(GameSettings settings)
{
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
for (KeyHandler key : keyHandlers)
{
harvestedBindings.add(key.keyBinding);
}
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,113 @@
package cpw.mods.fml.client.registry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.ObjectArrays;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.Render;
import net.minecraft.src.RenderBlocks;
import net.minecraft.src.RenderPlayer;
import cpw.mods.fml.client.modloader.ModLoaderBlockRendererHandler;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
public class RenderingRegistry
{
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
private int nextRenderId = 30;
private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
public int addNewArmourRendererPrefix(String armor)
{
RenderPlayer.field_77110_j = ObjectArrays.concat(RenderPlayer.field_77110_j, armor);
return RenderPlayer.field_77110_j.length - 1;
}
public static RenderingRegistry instance()
{
return INSTANCE;
}
private 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 void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
{
entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
}
public void registerBlockHandler(ISimpleBlockRenderingHandler handler)
{
blockRenderers.put(handler.getRenderId(), handler);
}
public int getNextAvailableRenderId()
{
return nextRenderId++;
}
/**
* @param renderer
* @param world
* @param x
* @param y
* @param z
* @param block
* @param modelId
* @return
*/
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
{
if (!blockRenderers.containsKey(modelId)) { return false; }
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
return bri.renderWorldBlock(world, x, y, z, block, modelId, renderer);
}
/**
* @param renderer
* @param block
* @param metadata
* @param modelID
*/
public void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
if (!blockRenderers.containsKey(modelID)) { return; }
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelID);
bri.renderInventoryBlock(block, metadata, modelID, renderer);
}
/**
* @param p_1219_0_
* @return
*/
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);
}
}
}
+62 -51
View File
@@ -26,44 +26,47 @@ import cpw.mods.fml.common.IPlayerTracker;
import cpw.mods.fml.common.IWorldGenerator;
import cpw.mods.fml.common.TickType;
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 = true;
// 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;
}
public final boolean doTickInGUI(TickType tick, boolean tickEnd, Object... data)
{
Minecraft mc = FMLClientHandler.instance().getClient();
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT)) {
return onTickInGUI((Float) data[0], mc, mc.field_71462_r);
}
return true;
}
/**
* @param minecraftInstance
* @return
*//*
*//**
* @param renderers
*/
*//*
public final void onRenderHarvest(Map renderers)
{
addRenderer((Map<Class<? extends Entity>,Render>)renderers);
}
/**
*
*/
*//**
*
*//*
public final void onRegisterAnimations()
{
registerAnimation(FMLClientHandler.instance().getClient());
@@ -82,7 +85,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 +93,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 +102,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 +136,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,18 +155,19 @@ 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
*/ // 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
@@ -180,7 +184,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Override if you wish to perform some action other than just dispensing the item from the dispenser
*
*
* @param world
* @param x
* @param y
@@ -197,7 +201,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Override if you wish to generate Nether (Hell biome) blocks
*
*
* @param world
* @param random
* @param chunkX
@@ -209,7 +213,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
@@ -221,7 +225,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Return the name of your mod. Defaults to the class name
*
*
* @return
*/
public String getName()
@@ -231,7 +235,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Get your mod priorities
*
*
* @return
*/
public String getPriorities()
@@ -241,7 +245,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Return the version of your mod
*
*
* @return
*/
public abstract String getVersion();
@@ -265,7 +269,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Handle item pickup
*
*
* @param player
* @param item
*/
@@ -275,7 +279,7 @@ 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
@@ -293,9 +297,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Only implemented on the client side
* {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)}
*
*
* @param text
*/
@Override
public void receiveChatPacket(String text)
{
// TODO
@@ -304,9 +309,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Only called on the client side
* {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)}
*
*
* @param packet
*/
@Override
public void receiveCustomPacket(Packet250CustomPayload packet)
{
// TODO
@@ -328,16 +334,18 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
}
public void serverConnect(NetClientHandler handler) {
@Override
public void serverConnect(NetHandler handler) {
}
@Override
public void serverDisconnect() {
}
/**
* Called when someone crafts an item from a crafting table
*
*
* @param player
* @param item
* @param matrix
@@ -371,13 +379,14 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
* @param source
* @param payload
*/
@Override
public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload)
{
}
/**
* Called when a chat message is received. Return true to stop further processing
*
*
* @param source
* @param chat
* @return true if you want to consume the message so it is not available for further processing
@@ -398,27 +407,29 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* 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(NetworkManager mgr)
{
}
/**
*
*
* Called when a client changes dimensions on the server.
*
*
* @param player
*/
public void onClientDimensionChanged(EntityPlayer player)
@@ -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
}
}
@@ -20,12 +20,15 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.TextureFXManager;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
/**
*
*
* A static hook library for optifine and other basemod editing code to access FML functions
*
*
* @author cpw
*
*/
@@ -33,56 +36,56 @@ 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)
{
FMLClientHandler.instance().onTexturePackChange(engine, texturePack, textureFXList);
TextureFXManager.instance().onTexturePackChange(engine, texturePack, textureFXList);
}
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);
}
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);
}
public static boolean renderItemAsFull3DBlock(int modelId)
{
return FMLClientHandler.instance().renderItemAsFull3DBlock(modelId);
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelId);
}
}
+67 -54
View File
@@ -21,18 +21,31 @@ 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.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.Player;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
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();
@@ -45,7 +58,7 @@ public class ModLoader
*/
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);
}
@@ -72,7 +85,7 @@ public class ModLoader
public static void addAnimation(TextureFX anim)
{
FMLClientHandler.instance().addAnimation(anim);
TextureFXManager.instance().addAnimation(anim);
}
/**
@@ -83,7 +96,7 @@ public class ModLoader
*/
public static int addArmor(String armor)
{
return FMLClientHandler.instance().addNewArmourRendererPrefix(armor);
return RenderingRegistry.instance().addNewArmourRendererPrefix(armor);
}
/**
@@ -93,7 +106,7 @@ public class ModLoader
*/
public static void addBiome(BiomeGenBase biome)
{
FMLClientHandler.instance().addBiomeToDefaultWorldGenerator(biome);
GameRegistry.addBiome(biome);
}
/**
@@ -116,7 +129,7 @@ public class ModLoader
*/
public static void addLocalization(String key, String lang, String value)
{
FMLCommonHandler.instance().addStringLocalization(key, lang, value);
LanguageRegistry.instance().addStringLocalization(key, lang, value);
}
/**
@@ -139,7 +152,7 @@ public class ModLoader
*/
public static void addName(Object instance, String lang, String name)
{
FMLCommonHandler.instance().addNameForObject(instance, lang, name);
LanguageRegistry.instance().addNameForObject(instance, lang, name);
}
/**
@@ -165,7 +178,7 @@ public class ModLoader
*/
public static void addOverride(String path, String overlayPath, int index)
{
FMLClientHandler.instance().addNewTextureOverride(path, overlayPath, index);
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
}
/**
@@ -176,7 +189,7 @@ public class ModLoader
*/
public static void addRecipe(ItemStack output, Object... params)
{
FMLRegistry.addRecipe(output, params);
GameRegistry.addRecipe(output, params);
}
/**
@@ -187,7 +200,7 @@ public class ModLoader
*/
public static void addShapelessRecipe(ItemStack output, Object... params)
{
FMLRegistry.addShapelessRecipe(output, params);
GameRegistry.addShapelessRecipe(output, params);
}
/**
@@ -198,7 +211,7 @@ public class ModLoader
*/
public static void addSmelting(int input, ItemStack output)
{
FMLRegistry.addSmelting(input, output);
GameRegistry.addSmelting(input, output, 1.0f);
}
/**
@@ -212,7 +225,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 +240,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 +254,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,7 +269,7 @@ 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);
}
/**
@@ -288,7 +301,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,7 +347,7 @@ public class ModLoader
world.func_674_a(entityitem);
}
}
}
*/ }
/**
* Get a list of all BaseMod loaded into the system
@@ -354,7 +367,7 @@ public class ModLoader
*/
public static Logger getLogger()
{
return FMLCommonHandler.instance().getFMLLogger();
return FMLLog.getLogger();
}
public static Minecraft getMinecraftInstance()
@@ -368,14 +381,14 @@ public class ModLoader
*
* @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
@@ -384,12 +397,12 @@ public class ModLoader
*/
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
@@ -398,7 +411,7 @@ public class ModLoader
*/
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);
}
/**
@@ -407,7 +420,7 @@ public class ModLoader
*/
public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
{
return FMLClientHandler.instance().obtainBlockModelIdFor(mod, inventoryRenderer);
return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
}
/**
@@ -418,7 +431,7 @@ public class ModLoader
*/
public static int getUniqueEntityId()
{
return FMLCommonHandler.instance().nextUniqueEntityListId();
return EntityRegistry.findGlobalUniqueEntityId();
}
public static int getUniqueSpriteIndex(String path)
@@ -436,12 +449,12 @@ public class ModLoader
*/
public static boolean isChannelActive(EntityPlayer player, String channel)
{
return FMLCommonHandler.instance().isChannelActive(channel, player);
return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
}
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);
}
/**
@@ -466,7 +479,7 @@ public class ModLoader
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
{
return FMLClientHandler.instance().loadImageFromTexturePack(renderEngine, path);
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
}
/**
@@ -525,7 +538,7 @@ public class ModLoader
*/
public static void registerBlock(Block block)
{
FMLRegistry.registerBlock(block);
GameRegistry.registerBlock(block);
}
/**
@@ -536,7 +549,7 @@ public class ModLoader
*/
public static void registerBlock(Block block, Class<? extends ItemBlock> itemclass)
{
FMLRegistry.registerBlock(block, itemclass);
GameRegistry.registerBlock(block, itemclass);
}
/**
@@ -548,7 +561,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,18 +575,17 @@ 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);
}
public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
{
FMLClientHandler.instance().registerKeyHandler(mod, keyHandler, allowRepeat);
ModLoaderModContainer mlmc=ModLoaderHelper.registerKeyHelper(mod);
KeyBindingRegistry.registerKeyBinding(new ModLoaderKeyBindingHandler(keyHandler, allowRepeat, mlmc));
}
/**
* 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
* Register the mod for packets on this channel.
* {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)}
*
* @param mod
@@ -581,7 +593,7 @@ public class ModLoader
*/
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 +604,12 @@ public class ModLoader
*/
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id)
{
FMLRegistry.registerTileEntity(tileEntityClass, id);
GameRegistry.registerTileEntity(tileEntityClass, id);
}
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 +619,7 @@ public class ModLoader
*/
public static void removeBiome(BiomeGenBase biome)
{
FMLRegistry.removeBiome(biome);
GameRegistry.removeBiome(biome);
}
/**
@@ -618,7 +630,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 +642,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 +653,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 +665,25 @@ public class ModLoader
*/
public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
{
FMLRegistry.removeSpawn(entityName, spawnList, biomes);
EntityRegistry.removeSpawn(entityName, spawnList, biomes);
}
@Deprecated
public static boolean renderBlockIsItemFull3D(int modelID)
{
return FMLClientHandler.instance().renderItemAsFull3DBlock(modelID);
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
}
@Deprecated
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
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);
}
/**
@@ -684,7 +696,8 @@ public class ModLoader
}
public static void sendPacket(Packet packet) {
FMLClientHandler.instance().sendPacket(packet);
// TODO
// FMLClientHandler.instance().sendPacket(packet);
}
/**
* Send a chat message to the server
@@ -724,7 +737,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 +746,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,7 +760,7 @@ 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);
}
/**
+128 -128
View File
@@ -1,128 +1,128 @@
/*
* 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;
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_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_783_a()
{
if (++ticks >= tickRate)
{
if (++index >= images.length)
{
index = 0;
}
field_76852_a = images[index];
ticks = 0;
}
}
}
+179 -179
View File
@@ -1,179 +1,179 @@
/*
* 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 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_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();
}
public void func_783_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--;
}
}
public void func_782_a(RenderEngine p_782_1_)
{
GL11.glBindTexture(GL_TEXTURE_2D, p_782_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);
}
}
-46
View File
@@ -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 "";
}
-64
View File
@@ -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();
}
-250
View File
@@ -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) {
}
}
-47
View File
@@ -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();
}
-135
View File
@@ -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);
}
+164
View File
@@ -0,0 +1,164 @@
--- 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)
@@ -582,6 +584,9 @@
self.has_astyle_cfg = False
if os.path.isfile(self.astyleconf):
self.has_astyle_cfg = True
+
+ #FML Entries
+ self.srcshared = os.path.normpath(os.path.join(self.dirsrc, 'common'))
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
"""Create the files necessary for RetroGuard"""
@@ -779,7 +784,8 @@
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):
@@ -1039,6 +1045,7 @@
all_files = True
append_pattern = False
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=append_pattern, all_files=all_files) #FML, Add Common folder
dirs = ' '.join(pkglist)
classpath = os.pathsep.join(cplk[side])
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
@@ -1060,7 +1067,7 @@
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)
@@ -1068,7 +1075,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)
@@ -1195,20 +1202,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 = {
@@ -1238,6 +1245,11 @@
# HINT: We pathwalk the sources
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
+ for cur_file in fnmatch.filter(filelist, '*.java'):
+ updatefile(os.path.normpath(os.path.join(path, cur_file)))
+
+ # FML, copy of the above, for the common folder
+ for path, _, filelist in os.walk(self.srcshared, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.java'):
updatefile(os.path.normpath(os.path.join(path, cur_file)))
return True
@@ -1320,12 +1332,14 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
strip_comments(pathsrclk[side])
+ strip_comments(self.srcshared)
def process_cleanup(self, side):
"""Do lots of random cleanups including stripping comments, trailing whitespace and extra blank lines"""
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
src_cleanup(pathsrclk[side], fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
+ src_cleanup(self.srcshared, fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
def process_javadoc(self, side):
"""Add CSV descriptions to methods and fields as javadoc"""
@@ -1334,6 +1348,21 @@
if not self.has_doc_csv:
self.logger.warning('!! javadoc disabled due to no csvs !!')
return False
+
+ #FML Recall this function on the common folder
+ #Potential bug: If this is called without a subsiquent rename call, will cause double comments
+ if pathsrclk[side] != self.srcshared:
+ if side == CLIENT:
+ tmp = self.srcclient
+ self.srcclient = self.srcshared
+ self.process_javadoc(side)
+ self.srcclient = tmp
+ else:
+ tmp = self.srcserver
+ self.srcserver = self.srcshared
+ self.process_javadoc(side)
+ self.srcserver = tmp
+
#HINT: We read the relevant CSVs
methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
@@ -1342,13 +1371,13 @@
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 = {
@@ -1420,6 +1449,7 @@
# HINT: We create the list of source directories based on the list of packages
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=True) #FML, Add Common folder
dirs = ' '.join(pkglist)
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
self.runcmd(forkcmd)
@@ -1592,6 +1622,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])
@@ -0,0 +1,125 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class DummyModContainer implements ModContainer
{
private ModMetadata md;
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 List<ArtifactVersion> getRequirements()
{
return Collections.emptyList();
}
@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()
{
return null;
}
@Override
public boolean isImmutable()
{
return false;
}
@Override
public boolean isNetworkMod()
{
return false;
}
}
+162 -425
View File
@@ -16,20 +16,17 @@ 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.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -38,7 +35,24 @@ 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.DedicatedServer;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.World;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
/**
* The main class for non-obfuscated hook handling code
@@ -59,96 +73,32 @@ 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<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;
}
}
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
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");
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);
}
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
sidedDelegate.profileEnd();
}
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;
@@ -168,8 +118,10 @@ public class FMLCommonHandler
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;
@@ -189,18 +141,6 @@ public class FMLCommonHandler
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
*/
@@ -215,191 +155,15 @@ public class FMLCommonHandler
*/
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++;
return FMLLog.getLogger();
}
/**
@@ -407,70 +171,16 @@ public class FMLCommonHandler
* @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);
}
public Side getSide()
{
return sidedDelegate.getSide();
}
public void addAuxilliaryModContainer(ModContainer ticker)
{
auxilliaryContainers.add(ticker);
}
/**
* Called from the furnace to lookup fuel values
*
* @param itemId
* @param itemDamage
* @return
*/
public int fuelLookup(int itemId, int itemDamage)
{
int fv = 0;
for (ModContainer mod : Loader.getModList())
{
fv = Math.max(fv, mod.lookupFuelValue(itemId, itemDamage));
}
return fv;
}
public void addNameForObject(Object minecraftObject, String lang, String name) {
String label=sidedDelegate.getObjectName(minecraftObject);
addStringLocalization(label, lang, name);
}
/**
* Raise an exception
*
@@ -481,26 +191,24 @@ public class FMLCommonHandler
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 List<String> brandings;
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;
@@ -524,87 +232,34 @@ public class FMLCommonHandler
* @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(Loader.instance().getFMLVersionString());
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);
}
/**
@@ -615,43 +270,125 @@ public class FMLCommonHandler
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(Class<? extends Entity> cls, EntitySpawnPacket entitySpawnPacket)
{
return sidedDelegate.spawnEntityIntoClientWorld(cls, entitySpawnPacket);
}
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
{
sidedDelegate.adjustEntityLocationOnClient(entitySpawnAdjustmentPacket);
}
public void onServerStart(DedicatedServer dedicatedServer)
{
try
{
generator.generate(fmlRandom, chunkX, chunkZ, data);
// Done this way so that the client doesn't depend on server side handler
Class<?> cls = Class.forName("cpw.mods.fml.server.FMLServerHandler", true, getClass().getClassLoader());
}
catch (ClassNotFoundException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to load the FML server handler");
throw Throwables.propagate(e);
}
sidedDelegate.beginServerLoading(dedicatedServer);
}
public void registerTickHandler(ITickHandler handler)
public void onServerStarted()
{
registerScheduledTickHandler(new SingleIntervalHandler(handler));
sidedDelegate.finishServerLoading();
}
public void registerScheduledTickHandler(IScheduledTickHandler handler)
public void onPreClientTick()
{
tickHandlers.add(new TickQueueElement(handler));
tickStart(EnumSet.of(TickType.CLIENT), Side.CLIENT);
}
public void registerWorldGenerator(IWorldGenerator generator)
public void onPostClientTick()
{
worldGenerators.add(generator);
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)
{
tickStart(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
}
public void onPlayerPostTick(EntityPlayer player)
{
tickEnd(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
}
}
@@ -0,0 +1,52 @@
/*
* 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 com.google.common.eventbus.EventBus;
/**
* @author cpw
*
*/
public class FMLDummyContainer extends DummyModContainer
{
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;
}
}
+53
View File
@@ -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, String.format(format, data));
}
public static void log(Level level, Throwable ex, String format, Object... data)
{
coreLog.log(level, String.format(format, data), ex);
}
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();
}
}
+256 -320
View File
@@ -13,111 +13,101 @@
package cpw.mods.fml.common;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.ImmutableBiMap.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.Mod.Block;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.Metadata;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
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.registry.GameRegistry;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
public class FMLModContainer implements ModContainer
{
private Mod modDescriptor;
private Object modInstance;
private File source;
private ModMetadata modMetadata;
private String className;
private Map<String, Object> descriptor;
private boolean enabled = true;
private List<ArtifactVersion> requirements;
private List<ArtifactVersion> dependencies;
private List<ArtifactVersion> dependants;
private 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();
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 modMetadata.version;
}
@Override
@@ -126,267 +116,213 @@ 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("usesMetadata"))
{
overridesMetadata = !((Boolean)descriptor.get("usesMetadata")).booleanValue();
}
if (overridesMetadata || !modMetadata.useDependencyInformation)
{
List<ArtifactVersion> requirements = Lists.newArrayList();
List<ArtifactVersion> dependencies = Lists.newArrayList();
List<ArtifactVersion> dependants = Lists.newArrayList();
Loader.instance().computeDependencies((String) descriptor.get("dependencies"), requirements, dependencies, dependants);
modMetadata.requiredMods = requirements;
modMetadata.dependencies = dependencies;
modMetadata.dependants = dependants;
}
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#gatherRenderers(java.util.Map)
*/
@Override
public void gatherRenderers(Map renderers)
public void setEnabledState(boolean enabled)
{
// TODO Auto-generated method stub
this.enabled = enabled;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#requestAnimations()
*/
@Override
public void requestAnimations()
public List<ArtifactVersion> getRequirements()
{
// TODO Auto-generated method stub
return modMetadata.requiredMods;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getVersion()
*/
@Override
public String getVersion()
public List<ArtifactVersion> getDependencies()
{
// TODO Auto-generated method stub
return null;
return modMetadata.dependencies;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#findSidedProxy()
*/
@Override
public ProxyInjector findSidedProxy()
public List<ArtifactVersion> getDependants()
{
// TODO Auto-generated method stub
return null;
return modMetadata.dependants;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#keyBindEvernt(java.lang.Object)
*/
@Override
public void keyBindEvent(Object keyBinding)
public String getSortingRules()
{
// TODO Auto-generated method stub
return 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 (Field f : clazz.getDeclaredFields())
{
for (Annotation a : f.getAnnotations())
{
f.setAccessible(true);
anns.put(a.annotationType(), f);
}
}
for (Method m : clazz.getDeclaredMethods())
{
for (Annotation a : m.getAnnotations())
{
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
if (Arrays.equals(m.getParameterTypes(), paramTypes))
{
m.setAccessible(true);
anns.put(a.annotationType(), m);
}
else
{
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
}
}
}
return anns;
}
private void processFieldAnnotations() throws Exception
{
// Instance annotation
for (Object o : annotations.get(Instance.class))
{
Field f = (Field) o;
f.set(modInstance, modInstance);
}
for (Object o : annotations.get(Metadata.class))
{
Field f = (Field) o;
f.set(modInstance, modMetadata);
}
//TODO
// for (Object o : annotations.get(Block.class))
// {
// Field f = (Field) o;
// f.set(modInstance, GameRegistry.buildBlock(this, f.getType(), f.getAnnotation(Block.class)));
// }
}
@Subscribe
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();
}
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;
}
}
@@ -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
*/
void onCrafting(Object... craftingParameters);
void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix);
/**
* The object array contains these two arguments
* @param player
* @param smeltedItem
*/
void onSmelting(Object... smeltingParameters);
void onSmelting(EntityPlayer player, ItemStack item);
}
@@ -12,9 +12,22 @@
*/
package cpw.mods.fml.common;
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 data
* @return
*/
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item);
}
@@ -7,24 +7,36 @@ import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import cpw.mods.fml.common.modloader.BaseMod;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.DedicatedServer;
import net.minecraft.src.Entity;
import net.minecraft.src.World;
import cpw.mods.fml.common.modloader.ModProperty;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
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(Class<? extends Entity> entityClass, EntitySpawnPacket packet);
void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket);
void beginServerLoading(MinecraftServer server);
void finishServerLoading();
MinecraftServer getServer();
}
@@ -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();
}
@@ -15,10 +15,13 @@ 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
* 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.
*
*
* @author cpw
*
*/
@@ -26,14 +29,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 world : additionalData[0] The minecraft {@link World} we're generating for.
* @param generator : additionalData[1] The {@link IChunkProvider} that is generating.
* @param chunkProvider : additionalData[2] {@link IChunkProvider} that is requesting the world generation.
*
*
*/
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,106 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.List;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
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 List<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;
}
}
@@ -0,0 +1,193 @@
package cpw.mods.fml.common;
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.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimap;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
public class LoadController
{
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 String 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)
{
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());
}
// Throw embedding the first error (usually the only one)
throw new LoaderException(errors.values().iterator().next());
}
}
public ModContainer activeContainer()
{
return activeContainer!=null ? modList.get(activeContainer) : null;
}
@Subscribe
public void propogateStateMessage(FMLStateEvent stateEvent)
{
for (Map.Entry<String,EventBus> entry : eventChannels.entrySet())
{
activeContainer = entry.getKey();
stateEvent.applyModContainer(activeContainer());
FMLLog.finer("Posting state event %s to mod %s", stateEvent, entry.getKey());
entry.getValue().post(stateEvent);
FMLLog.finer("State event %s delivered to mod %s", stateEvent, entry.getKey());
activeContainer = null;
if (!errors.containsKey(entry.getKey()))
{
modStates.put(entry.getKey(), stateEvent.getModState());
}
else
{
modStates.put(entry.getKey(), ModState.ERRORED);
}
}
if (stateEvent instanceof FMLConstructionEvent)
{
buildModObjectList();
}
}
public void buildModObjectList()
{
ImmutableBiMap.Builder<ModContainer, Object> builder = ImmutableBiMap.<ModContainer, Object>builder();
for (ModContainer mc : activeModList)
{
builder.put(mc, mc.getMod());
}
modObjectList = builder.build();
}
public void errorOccurred(ModContainer modContainer, Throwable exception)
{
errors.put(modContainer.getModId(), exception);
}
public void printModStates(StringBuilder ret)
{
for (String modId : modStates.keySet())
{
ModContainer mod = modList.get(modId);
ret.append("\n\t").append(mod.getName()).append(" (").append(mod.getSource().getName()).append(") ");
Joiner.on("->"). appendTo(ret, modStates.get(modId));
}
}
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()
{
return ImmutableBiMap.copyOf(modObjectList);
}
}
File diff suppressed because it is too large. Load diff
+103
View File
@@ -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,90 @@
package cpw.mods.fml.common;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import argo.jdom.JdomParser;
import argo.jdom.JsonNode;
import argo.jdom.JsonRootNode;
import argo.saj.InvalidSyntaxException;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class MetadataCollection
{
private static JdomParser parser = new JdomParser();
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
private int metadataVersion = 1;
public static MetadataCollection from(InputStream inputStream)
{
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 (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);
}
}
+152 -6
View File
@@ -13,23 +13,169 @@
*/
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 cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import net.minecraft.src.ItemBlock;
/**
* 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
* @return
*/
String modid();
/**
* A user friendly name for the mod
* @return
*/
String name() default "";
/**
* A version string for this mod
* @return
*/
String version() default "";
/**
* A simple dependency string for this mod (see modloader's "priorities" string specification)
* @return
*/
String dependencies() default "";
/**
* Whether to use the mcmod.info metadata by default for this mod.
* If true, settings in the mcmod.info file will override settings in these annotations.
* @return
*/
boolean useMetadata() default false;
/**
* 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
* @return
*/
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
* @return
*/
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
* @return
*/
String name();
/**
* The associated ItemBlock subtype for the item (can be null for an ItemBlock)
* @return
*/
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
* @return
*/
String name();
/**
* The type of the item
* @return
*/
String typeClass();
}
}
+41 -38
View File
@@ -19,61 +19,64 @@ 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.discovery.ModCandidate;
import cpw.mods.fml.relauncher.FMLRelauncher;
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;
}
}
+104 -164
View File
@@ -15,15 +15,20 @@ package cpw.mods.fml.common;
import java.io.File;
import java.util.List;
import java.util.Map;
import cpw.mods.fml.common.ModContainer.SourceType;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.versioning.ArtifactVersion;
/**
* 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 +36,118 @@ 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
*
* @return
*/
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
* A human readable name
*
* @return
*/
String getName();
/**
* The state of the mod
* A human readable version identifier
*
* @return
*/
ModState getModState();
String getVersion();
/**
* Move to the next mod state
* The location on the file system which this mod came from
*
* @return
*/
void nextState();
File getSource();
/**
* Does this mod match the supplied mod?
* The metadata for this mod
*
* @return
*/
ModMetadata getMetadata();
/**
* Attach this mod to it's metadata from the supplied metadata collection
*
* @param mc
*/
void bindMetadata(MetadataCollection mc);
/**
* Set the enabled/disabled state of this mod
*
* @param enabled
*/
void setEnabledState(boolean enabled);
/**
* A list of the modids that this mod requires loaded prior to loading
*
* @return
*/
List<ArtifactVersion> getRequirements();
/**
* A list of modids that should be loaded prior to this one. The special
* value <strong>*</strong> indicates to load <em>before</em> any other mod.
*
* @return
*/
List<ArtifactVersion> getDependencies();
/**
* A list of modids that should be loaded <em>after</em> this one. The
* special value <strong>*</strong> indicates to load <em>after</em> any
* other mod.
*
* @return
*/
List<ArtifactVersion> getDependants();
/**
* A representative string encapsulating the sorting preferences for this
* mod
*
* @return
*/
String getSortingRules();
/**
* 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
* @return
*/
boolean registerBus(EventBus bus, LoadController controller);
/**
* 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
* Get the actual mod object
*
* @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
*/
String getVersion();
/**
* @return
*/
ProxyInjector findSidedProxy();
void keyBindEvent(Object keyBinding);
ArtifactVersion getProcessedVersion();
boolean isImmutable();
boolean isNetworkMod();
}
@@ -0,0 +1,39 @@
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.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)
{
String className = modParser.getASMType().getClassName();
if (modParser.isBaseMod() && modClass.matcher(className).find())
{
FMLLog.fine("Identified a BaseMod type mod %s", className);
return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties());
}
for (ModAnnotation ann : modParser.getAnnotations())
{
if (ann.getASMType().equals(Type.getType(Mod.class)))
{
FMLLog.fine("Identified a FMLMod type mod %s", className);
return new FMLModContainer(className, modSource, ann.getValues());
}
}
return null;
}
}
+103 -46
View File
@@ -20,85 +20,142 @@ import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.zip.ZipInputStream;
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.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import static argo.jdom.JsonNodeBuilders.*;
/**
* @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();
public boolean useDependencyInformation;
public List<ArtifactVersion> requiredMods;
public List<ArtifactVersion> dependencies;
public List<ArtifactVersion> dependants;
public boolean autogenerated;
/**
* @param mod2
* @param type2
*/
public ModMetadata(ModContainer mod)
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"));
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 = Optional.fromNullable((List<String>)processedFields.get(aStringBuilder("authorList"))).or(authorList);
requiredMods = processReferences((List<String>)processedFields.get(aStringBuilder("requiredMods")));
dependencies = processReferences((List<String>)processedFields.get(aStringBuilder("dependencies")));
dependants = processReferences((List<String>)processedFields.get(aStringBuilder("dependants")));
useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
}
public ModMetadata()
{
}
private List<ArtifactVersion> processReferences(List<String> refs)
{
List<ArtifactVersion> res = Lists.newArrayList();
if (refs == null)
{
return res;
}
for (String ref : 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 null;
}
}
@@ -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");
}
}
+43 -45
View File
@@ -15,6 +15,14 @@
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 org.objectweb.asm.Type;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
/**
* @author cpw
@@ -22,55 +30,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");
}
}
@@ -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;
@@ -32,15 +32,15 @@ public @interface SidedProxy
* @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 "";
}
+16 -23
View File
@@ -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,11 +61,11 @@ 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
@@ -80,11 +74,10 @@ public enum TickType {
*/
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,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,73 @@
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.FMLRelauncher;
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,14 @@
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,389 @@
package cpw.mods.fml.common.asm.transformers;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
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 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;
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 || parts.get(1).indexOf('.') == -1)
{
throw new RuntimeException("Invalid config file line "+ input);
}
Modifier m = new Modifier();
m.setTargetAccess(parts.get(0));
List<String> descriptor = Lists.newArrayList(Splitter.on(".").trimResults().split(parts.get(1)));
String nameReference = descriptor.get(1);
int parenIdx = nameReference.indexOf('(');
if (parenIdx>0)
{
m.desc = nameReference.substring(parenIdx);
m.name = nameReference.substring(0,parenIdx);
}
else
{
m.name = nameReference;
}
modifiers.put(descriptor.get(0), m);
return true;
}
});
}
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
{
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.desc.isEmpty())
{
for (FieldNode n : (List<FieldNode>) classNode.fields)
{
if (n.name.equals(m.name))
{
n.access = getFixedAccess(n.access, m);
System.out.println(String.format("Field: %s.%s %s -> %s", name, m.name, Integer.toBinaryString(m.oldAccess),
Integer.toBinaryString(m.newAccess)));
break;
}
}
}
else
{
for (MethodNode n : (List<MethodNode>) classNode.methods)
{
if (n.name.equals(m.name) && n.desc.equals(m.desc))
{
n.access = getFixedAccess(n.access, m);
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, m.name, m.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
break;
}
}
}
}
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]... ");
return;
}
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");
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 (!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, 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)
{
}
}
}
}
}
@@ -0,0 +1,570 @@
package cpw.mods.fml.common.asm.transformers;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.Map.Entry;
import java.util.zip.*;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
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>();
public static void main(String[] args)
{
if (args.length != 3)
{
System.out.println("Usage: AccessTransformer <MapFile> <minecraft.jar> <minecraft_server.jar>");
return;
}
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);
return;
}
if (!server_jar.exists())
{
System.out.println("Could not find minecraft_server.jar: " + server_jar);
return;
}
if (!client_jar.renameTo(client_jar_tmp))
{
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
return;
}
if (!server_jar.renameTo(server_jar_tmp))
{
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
return;
}
if (!readMapFile(map_file))
{
System.out.println("Could not read map file: " + map_file);
return;
}
try
{
processJar(client_jar_tmp, server_jar_tmp, client_jar, server_jar);
}
catch (IOException e)
{
e.printStackTrace();
}
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);
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))
{
copyEntry(cInJar, cEntry, cOutJar);
}
else
{
System.out.println("Copy class c->s : " + name);
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
}
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);
}
for (Entry<String, ZipEntry> entry : sClasses.entrySet())
{
if (!copyToClient.contains(entry.getKey()))
{
copyEntry(sInJar, entry.getValue(), sOutJar);
}
else
{
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()})
{
byte[] data = getClassBytes(name);
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
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.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
byte[] data = writer.toByteArray();
ZipEntry newEntry = new ZipEntry(entry.getName());
outJar.putNextEntry(newEntry);
outJar.write(data);
outJar2.putNextEntry(newEntry);
outJar2.write(data);
}
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("."))
{
copyEntry(inFile, entry, outFile);
}
else
{
ret.put(entryName.replace(".class", ""), entry);
}
}
return ret;
}
private static void copyEntry(ZipFile inFile, ZipEntry entry, ZipOutputStream outFile) throws IOException
{
ZipEntry newEntry = new ZipEntry(entry.getName());
outFile.putNextEntry(newEntry);
outFile.write(readEntry(inFile, entry));
}
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
{
return readFully(inFile.getInputStream(entry));
}
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;
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)
{
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
break;
}
MethodWrapper mw = new MethodWrapper(sM);
mw.server = true;
allMethods.add(mw);
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
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)
{
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
break;
}
MethodWrapper mw = new MethodWrapper(cM);
mw.client = true;
allMethods.add(mw);
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
cPos++;
}
while (cPos < cLen);
}
cMethods.clear();
sMethods.clear();
for (MethodWrapper mw : allMethods)
{
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,295 @@
package cpw.mods.fml.common.asm.transformers;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
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 (!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,88 @@
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.Side;
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();
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
{
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
Iterator<FieldNode> fields = classNode.fields.iterator();
while(fields.hasNext())
{
FieldNode field = fields.next();
if (remove((List<AnnotationNode>)field.visibleAnnotations, SIDE))
{
System.out.println("Removing Field: " + field.name);
fields.remove();
}
}
Iterator<MethodNode> methods = classNode.methods.iterator();
while(methods.hasNext())
{
MethodNode method = methods.next();
if (remove((List<AnnotationNode>)method.visibleAnnotations, SIDE))
{
System.out.println("Removing Method: " + 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,107 @@
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Predicate;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.ImmutableBiMap.Builder;
import cpw.mods.fml.common.ModContainer;
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);
}
}
@@ -0,0 +1,32 @@
package cpw.mods.fml.common.discovery;
import java.util.List;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.ModContainer;
public enum ContainerType
{
JAR(JarDiscoverer.class),
DIR(DirectoryDiscoverer.class);
private ITypeDiscoverer discoverer;
private ContainerType(Class<? extends ITypeDiscoverer> discovererClass)
{
try
{
this.discoverer = discovererClass.newInstance();
}
catch (Exception e)
{
throw Throwables.propagate(e);
}
}
public List<ModContainer> findMods(ModCandidate candidate, ASMDataTable table)
{
return discoverer.discover(candidate, table);
}
}
@@ -0,0 +1,108 @@
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.MetadataCollection;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModContainerFactory;
import cpw.mods.fml.common.discovery.asm.ASMModParser;
public class DirectoryDiscoverer implements ITypeDiscoverer
{
private class ClassFilter implements FileFilter
{
@Override
public boolean accept(File file)
{
return (file.isFile() && classFile.matcher(file.getName()).find()) || file.isDirectory();
}
}
private ASMDataTable table;
@Override
public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table)
{
this.table = table;
List<ModContainer> found = Lists.newArrayList();
FMLLog.fine("Examining directory %s for potential mods", candidate.getModContainer().getName());
exploreFileSystem("", candidate.getModContainer(), found, candidate, null);
for (ModContainer mc : found)
{
table.addContainer(mc);
}
return found;
}
public void exploreFileSystem(String path, File modDir, List<ModContainer> harvestedMods, ModCandidate candidate, MetadataCollection mc)
{
if (path.length() == 0)
{
File metadata = new File(modDir, "mcmod.info");
try
{
FileInputStream fis = new FileInputStream(metadata);
mc = MetadataCollection.from(fis);
fis.close();
}
catch (Exception e)
{
mc = MetadataCollection.from(null);
}
}
File[] content = modDir.listFiles(new ClassFilter());
// Always sort our content
Arrays.sort(content);
for (File file : content)
{
if (file.isDirectory())
{
FMLLog.finest("Recursing into package %s", path + file.getName());
exploreFileSystem(path + file.getName() + ".", file, harvestedMods, candidate, mc);
continue;
}
Matcher match = classFile.matcher(file.getName());
if (match.matches())
{
ASMModParser modParser = null;
try
{
FileInputStream fis = new FileInputStream(file);
modParser = new ASMModParser(fis);
fis.close();
}
catch (Exception e)
{
Throwables.propagate(e);
}
modParser.validate();
modParser.sendToTable(table, candidate);
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
if (container!=null)
{
harvestedMods.add(container);
container.bindMetadata(mc);
}
}
}
}
}
@@ -0,0 +1,13 @@
package cpw.mods.fml.common.discovery;
import java.util.List;
import java.util.regex.Pattern;
import cpw.mods.fml.common.ModContainer;
public interface ITypeDiscoverer
{
public static Pattern classFile = Pattern.compile("([^\\s$]+).class$");
public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table);
}
@@ -0,0 +1,75 @@
package cpw.mods.fml.common.discovery;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.MetadataCollection;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModContainerFactory;
import cpw.mods.fml.common.discovery.asm.ASMModParser;
public class JarDiscoverer implements ITypeDiscoverer
{
@Override
public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table)
{
List<ModContainer> foundMods = Lists.newArrayList();
FMLLog.fine("Examining file %s for potential mods", candidate.getModContainer().getName());
ZipFile jar = null;
try
{
jar = new ZipFile(candidate.getModContainer());
ZipEntry modInfo = jar.getEntry("mcmod.info");
MetadataCollection mc = null;
if (modInfo != null)
{
FMLLog.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName());
mc = MetadataCollection.from(jar.getInputStream(modInfo));
}
for (ZipEntry ze : Collections.list(jar.entries()))
{
Matcher match = classFile.matcher(ze.getName());
if (match.matches())
{
ASMModParser modParser = new ASMModParser(jar.getInputStream(ze));
modParser.validate();
modParser.sendToTable(table, candidate);
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
if (container!=null)
{
table.addContainer(container);
foundMods.add(container);
container.bindMetadata(mc);
}
}
}
}
catch (Exception e)
{
FMLLog.warning("Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
}
finally
{
if (jar != null)
{
try
{
jar.close();
}
catch (Exception e)
{
}
}
}
return foundMods;
}
}
@@ -0,0 +1,46 @@
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.util.List;
import cpw.mods.fml.common.ModContainer;
public class ModCandidate
{
private File classPathRoot;
private File modContainer;
private ContainerType sourceType;
private boolean classpath;
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType)
{
this(classPathRoot, modContainer, sourceType, false);
}
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean classpath)
{
this.classPathRoot = classPathRoot;
this.modContainer = modContainer;
this.sourceType = sourceType;
this.classpath = classpath;
}
public File getClassPathRoot()
{
return classPathRoot;
}
public File getModContainer()
{
return modContainer;
}
public ContainerType getSourceType()
{
return sourceType;
}
public List<ModContainer> explore(ASMDataTable table)
{
return sourceType.findMods(this, table);
}
}
@@ -0,0 +1,151 @@
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Tables;
import com.google.common.collect.ImmutableTable.Builder;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.ModClassLoader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.RelaunchLibraryManager;
public class ModDiscoverer
{
private static Pattern zipJar = Pattern.compile("(.+).(zip|jar)$");
private List<ModCandidate> candidates = Lists.newArrayList();
private ASMDataTable dataTable = new ASMDataTable();
public void findClasspathMods(ModClassLoader modClassLoader)
{
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries()).addAll(RelaunchLibraryManager.getLibraries()).build();
File[] minecraftSources = modClassLoader.getParentSources();
if (minecraftSources.length == 1 && minecraftSources[0].isFile())
{
FMLLog.fine("Minecraft is a file at %s, loading", minecraftSources[0].getAbsolutePath());
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR));
}
else
{
for (int i = 0; i < minecraftSources.length; i++)
{
if (minecraftSources[i].isFile())
{
if (knownLibraries.contains(minecraftSources[i].getName()))
{
FMLLog.fine("Skipping known library file %s", minecraftSources[i].getAbsolutePath());
}
else
{
FMLLog.fine("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, true));
}
}
else if (minecraftSources[i].isDirectory())
{
FMLLog.fine("Found a minecraft related directory at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, true));
}
}
}
}
public void findModDirMods(File modsDir)
{
File[] modList = modsDir.listFiles();
// Sort the files into alphabetical order first
Arrays.sort(modList);
for (File modFile : modList)
{
if (modFile.isDirectory())
{
FMLLog.fine("Found a candidate mod directory %s", modFile.getName());
candidates.add(new ModCandidate(modFile, modFile, ContainerType.DIR));
}
else
{
Matcher matcher = zipJar.matcher(modFile.getName());
if (matcher.matches())
{
FMLLog.fine("Found a candidate zip or jar file %s", matcher.group(0));
candidates.add(new ModCandidate(modFile, modFile, ContainerType.JAR));
}
else
{
FMLLog.fine("Ignoring unknown file %s in mods directory", modFile.getName());
}
}
}
}
public List<ModContainer> identifyMods()
{
List<ModContainer> modList = Lists.newArrayList();
for (ModCandidate candidate : candidates)
{
try
{
List<ModContainer> mods = candidate.explore(dataTable);
modList.addAll(mods);
}
catch (LoaderException le)
{
FMLLog.log(Level.WARNING, le, "Identified a problem with the mod candidate %s, ignoring this source", candidate.getModContainer());
}
catch (Throwable t)
{
Throwables.propagate(t);
}
}
return modList;
}
public ASMDataTable getASMTable()
{
return dataTable;
}
}
@@ -0,0 +1,159 @@
package cpw.mods.fml.common.discovery.asm;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.src.BaseMod;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ModCandidate;
import cpw.mods.fml.common.discovery.ModDiscoverer;
public class ASMModParser
{
private Type asmType;
private int classVersion;
private Type asmSuperType;
private LinkedList<ModAnnotation> annotations = Lists.newLinkedList();
private String baseModProperties;
static enum AnnotationType
{
CLASS, FIELD, METHOD, SUBTYPE;
}
public ASMModParser(InputStream stream) throws IOException
{
ClassReader reader = new ClassReader(stream);
reader.accept(new ModClassVisitor(this), 0);
}
public void beginNewTypeName(String typeQName, int classVersion, String superClassQName)
{
this.asmType = Type.getObjectType(typeQName);
this.classVersion = classVersion;
this.asmSuperType = Type.getObjectType(superClassQName);
}
public void startClassAnnotation(String annotationName)
{
ModAnnotation ann = new ModAnnotation(AnnotationType.CLASS, Type.getType(annotationName), this.asmType.getClassName());
annotations.addFirst(ann);
}
public void addAnnotationProperty(String key, Object value)
{
annotations.getFirst().addProperty(key, value);
}
public void startFieldAnnotation(String fieldName, String annotationName)
{
ModAnnotation ann = new ModAnnotation(AnnotationType.FIELD, Type.getType(annotationName), fieldName);
annotations.addFirst(ann);
}
@Override
public String toString()
{
return Objects.toStringHelper("ASMAnnotationDiscoverer")
.add("className", asmType.getClassName())
.add("classVersion", classVersion)
.add("superName", asmSuperType.getClassName())
.add("annotations", annotations)
.add("isBaseMod", isBaseMod())
.add("baseModProperties", baseModProperties)
.toString();
}
public Type getASMType()
{
return asmType;
}
public int getClassVersion()
{
return classVersion;
}
public Type getASMSuperType()
{
return asmSuperType;
}
public LinkedList<ModAnnotation> getAnnotations()
{
return annotations;
}
public void validate()
{
// if (classVersion > 50.0)
// {
//
// throw new LoaderException(new RuntimeException("Mod compiled for Java 7 detected"));
// }
}
public boolean isBaseMod()
{
return getASMSuperType().equals(Type.getType(BaseMod.class));
}
public void setBaseModProperties(String foundProperties)
{
this.baseModProperties = foundProperties;
}
public String getBaseModProperties()
{
return this.baseModProperties;
}
public void sendToTable(ASMDataTable table, ModCandidate candidate)
{
for (ModAnnotation ma : annotations)
{
table.addASMData(candidate, ma.asmType.getClassName(), this.asmType.getClassName(), ma.member, ma.values);
}
}
public void addAnnotationArray(String name)
{
annotations.getFirst().addArray(name);
}
public void addAnnotationEnumProperty(String name, String desc, String value)
{
annotations.getFirst().addEnumProperty(name, desc, value);
}
public void endArray()
{
annotations.getFirst().endArray();
}
public void addSubAnnotation(String name, String desc)
{
ModAnnotation ma = annotations.getFirst();
annotations.addFirst(ma.addChildAnnotation(name, desc));
}
public void endSubAnnotation()
{
// take the child and stick it at the end
ModAnnotation child = annotations.removeFirst();
annotations.addLast(child);
}
}
@@ -0,0 +1,107 @@
package cpw.mods.fml.common.discovery.asm;
import java.util.ArrayList;
import java.util.Map;
import org.objectweb.asm.Type;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.discovery.asm.ASMModParser.AnnotationType;
public class ModAnnotation
{
public class EnumHolder
{
private String desc;
private String value;
public EnumHolder(String desc, String value)
{
this.desc = desc;
this.value = value;
}
}
AnnotationType type;
Type asmType;
String member;
Map<String,Object> values = Maps.newHashMap();
private ArrayList<Object> arrayList;
private Object array;
private String arrayName;
private ModAnnotation parent;
public ModAnnotation(AnnotationType type, Type asmType, String member)
{
this.type = type;
this.asmType = asmType;
this.member = member;
}
public ModAnnotation(AnnotationType type, Type asmType, ModAnnotation parent)
{
this.type = type;
this.asmType = asmType;
this.parent = parent;
}
@Override
public String toString()
{
return Objects.toStringHelper("Annotation")
.add("type",type)
.add("name",asmType.getClassName())
.add("member",member)
.add("values", values)
.toString();
}
public AnnotationType getType()
{
return type;
}
public Type getASMType()
{
return asmType;
}
public String getMember()
{
return member;
}
public Map<String, Object> getValues()
{
return values;
}
public void addArray(String name)
{
this.arrayList = Lists.newArrayList();
this.arrayName = name;
}
public void addProperty(String key, Object value)
{
if (this.arrayList != null)
{
arrayList.add(value);
}
else
{
values.put(key, value);
}
}
public void addEnumProperty(String key, String enumName, String value)
{
values.put(key, new EnumHolder(enumName, value));
}
public void endArray()
{
values.put(arrayName, arrayList);
arrayList = null;
}
public ModAnnotation addChildAnnotation(String name, String desc)
{
return new ModAnnotation(AnnotationType.SUBTYPE, Type.getType(desc), this);
}
}
@@ -0,0 +1,69 @@
package cpw.mods.fml.common.discovery.asm;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
public class ModAnnotationVisitor extends AnnotationVisitor
{
private ASMModParser discoverer;
private boolean array;
private String name;
private boolean isSubAnnotation;
public ModAnnotationVisitor(ASMModParser discoverer)
{
super(Opcodes.ASM4);
this.discoverer = discoverer;
}
public ModAnnotationVisitor(ASMModParser discoverer, String name)
{
this(discoverer);
this.array = true;
this.name = name;
discoverer.addAnnotationArray(name);
}
public ModAnnotationVisitor(ASMModParser discoverer, boolean isSubAnnotation)
{
this(discoverer);
this.isSubAnnotation = true;
}
@Override
public void visit(String key, Object value)
{
discoverer.addAnnotationProperty(key, value);
}
@Override
public void visitEnum(String name, String desc, String value)
{
discoverer.addAnnotationEnumProperty(name, desc, value);
}
@Override
public AnnotationVisitor visitArray(String name)
{
return new ModAnnotationVisitor(discoverer, name);
}
@Override
public AnnotationVisitor visitAnnotation(String name, String desc)
{
discoverer.addSubAnnotation(name, desc);
return new ModAnnotationVisitor(discoverer, true);
}
@Override
public void visitEnd()
{
if (array)
{
discoverer.endArray();
}
if (isSubAnnotation)
{
discoverer.endSubAnnotation();
}
}
}
@@ -0,0 +1,50 @@
package cpw.mods.fml.common.discovery.asm;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
public class ModClassVisitor extends ClassVisitor
{
private ASMModParser discoverer;
public ModClassVisitor(ASMModParser discoverer)
{
super(Opcodes.ASM4);
this.discoverer = discoverer;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
{
discoverer.beginNewTypeName(name, version, superName);
}
@Override
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
{
discoverer.startClassAnnotation(annotationName);
return new ModAnnotationVisitor(discoverer);
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value)
{
return new ModFieldVisitor(name, discoverer);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
{
if (discoverer.isBaseMod() && name.equals("getPriorities") && desc.equals(Type.getMethodDescriptor(Type.getType(String.class))))
{
return new ModMethodVisitor(name, discoverer);
}
return null;
}
}
@@ -0,0 +1,26 @@
package cpw.mods.fml.common.discovery.asm;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
public class ModFieldVisitor extends FieldVisitor
{
private String fieldName;
private ASMModParser discoverer;
public ModFieldVisitor(String name, ASMModParser discoverer)
{
super(Opcodes.ASM4);
this.fieldName = name;
this.discoverer = discoverer;
}
@Override
public AnnotationVisitor visitAnnotation(String annotationName, boolean runtimeVisible)
{
discoverer.startFieldAnnotation(fieldName, annotationName);
return new ModAnnotationVisitor(discoverer);
}
}
@@ -0,0 +1,62 @@
package cpw.mods.fml.common.discovery.asm;
import java.util.LinkedList;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import com.google.common.collect.Lists;
public class ModMethodVisitor extends MethodVisitor
{
private ASMModParser discoverer;
private boolean inCode;
private LinkedList<Label> labels = Lists.newLinkedList();
private String foundProperties;
private boolean validProperties;
public ModMethodVisitor(String name, ASMModParser discoverer)
{
super(Opcodes.ASM4);
this.discoverer = discoverer;
}
@Override
public void visitCode()
{
labels.clear();
}
@Override
public void visitLdcInsn(Object cst)
{
if (cst instanceof String && labels.size() == 1)
{
foundProperties = (String) cst;
}
}
@Override
public void visitInsn(int opcode)
{
if (Opcodes.ARETURN == opcode && labels.size() == 1 && foundProperties != null)
{
validProperties = true;
}
}
@Override
public void visitLabel(Label label)
{
labels.push(label);
}
@Override
public void visitEnd()
{
if (validProperties)
{
discoverer.setBaseModProperties(foundProperties);
}
}
}
@@ -0,0 +1,41 @@
package cpw.mods.fml.common.event;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Table;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.ModClassLoader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.common.discovery.ModDiscoverer;
public class FMLConstructionEvent extends FMLStateEvent
{
private ModClassLoader modClassLoader;
private ASMDataTable asmData;
public FMLConstructionEvent(Object... eventData)
{
this.modClassLoader = (ModClassLoader)eventData[0];
this.asmData = (ASMDataTable) eventData[1];
}
public ModClassLoader getModClassLoader()
{
return modClassLoader;
}
@Override
public ModState getModState()
{
return ModState.CONSTRUCTED;
}
public ASMDataTable getASMHarvestedData()
{
return asmData;
}
}
@@ -0,0 +1,9 @@
package cpw.mods.fml.common.event;
public class FMLEvent
{
public final String getEventType()
{
return getClass().getSimpleName();
}
}
@@ -0,0 +1,19 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.LoaderState.ModState;
public class FMLInitializationEvent extends FMLStateEvent
{
public FMLInitializationEvent(Object... data)
{
super(data);
}
@Override
public ModState getModState()
{
return ModState.INITIALIZED;
}
}
@@ -0,0 +1,20 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.LoaderState.ModState;
public class FMLLoadCompleteEvent extends FMLStateEvent
{
public FMLLoadCompleteEvent(Object... data)
{
super(data);
}
@Override
public ModState getModState()
{
return ModState.AVAILABLE;
}
}
@@ -0,0 +1,6 @@
package cpw.mods.fml.common.event;
public class FMLLoadEvent
{
}
@@ -0,0 +1,18 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.LoaderState.ModState;
public class FMLPostInitializationEvent extends FMLStateEvent
{
public FMLPostInitializationEvent(Object... data)
{
super(data);
}
@Override
public ModState getModState()
{
return ModState.POSTINITIALIZED;
}
}
@@ -0,0 +1,65 @@
package cpw.mods.fml.common.event;
import java.io.File;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
public class FMLPreInitializationEvent extends FMLStateEvent
{
private ModMetadata modMetadata;
private File sourceFile;
private File configurationDir;
private File suggestedConfigFile;
private ASMDataTable asmData;
public FMLPreInitializationEvent(Object... data)
{
super(data);
this.asmData = (ASMDataTable)data[0];
this.configurationDir = (File)data[1];
}
@Override
public ModState getModState()
{
return ModState.PREINITIALIZED;
}
@Override
public void applyModContainer(ModContainer activeContainer)
{
this.modMetadata = activeContainer.getMetadata();
this.sourceFile = activeContainer.getSource();
this.suggestedConfigFile = new File(configurationDir, activeContainer.getModId()+".cfg");
}
public File getSourceFile()
{
return sourceFile;
}
public ModMetadata getModMetadata()
{
return modMetadata;
}
public File getModConfigurationDirectory()
{
return configurationDir;
}
public File getSuggestedConfigurationFile()
{
return suggestedConfigFile;
}
public ASMDataTable getAsmData()
{
return asmData;
}
}
@@ -0,0 +1,20 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.LoaderState.ModState;
public class FMLServerStartedEvent extends FMLStateEvent
{
public FMLServerStartedEvent(Object... data)
{
super(data);
}
@Override
public ModState getModState()
{
return ModState.AVAILABLE;
}
}
@@ -0,0 +1,22 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.LoaderState.ModState;
public class FMLServerStartingEvent extends FMLStateEvent
{
private Object server;
public FMLServerStartingEvent(Object... data)
{
super(data);
this.server = data[0];
}
@Override
public ModState getModState()
{
return ModState.AVAILABLE;
}
}
@@ -0,0 +1,20 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.LoaderState.ModState;
public class FMLServerStoppingEvent extends FMLStateEvent
{
public FMLServerStoppingEvent(Object... data)
{
super(data);
}
@Override
public ModState getModState()
{
return ModState.AVAILABLE;
}
}
@@ -0,0 +1,26 @@
package cpw.mods.fml.common.event;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.Side;
public abstract class FMLStateEvent extends FMLEvent
{
public FMLStateEvent(Object... data)
{
}
public abstract ModState getModState();
public void applyModContainer(ModContainer activeContainer)
{
// NO OP
}
public Side getSide()
{
return FMLCommonHandler.instance().getSide();
}
}
@@ -0,0 +1,13 @@
package cpw.mods.fml.common.functions;
import com.google.common.base.Function;
import cpw.mods.fml.common.ModContainer;
public final class ModIdFunction implements Function<ModContainer, String>
{
public String apply(ModContainer container)
{
return container.getModId();
}
}
@@ -0,0 +1,15 @@
package cpw.mods.fml.common.functions;
import com.google.common.base.Function;
import cpw.mods.fml.common.ModContainer;
public class ModNameFunction implements Function<ModContainer, String>
{
@Override
public String apply(ModContainer input)
{
return input.getName();
}
}
Loaded 100 of 322 files, more files were not shown because too many files have changed in this diff. Show more