Compare commits

...
444 Commits
Author SHA1 Message Date
Christian db12af48fa Update to 1.4.3 2012-11-01 23:53:13 -04:00
Christian a0f574a0ac A useful tool for performing updates 2012-11-01 23:11:21 -04:00
Christian 8356fe9a7b FUUUUUU! Stupid ticking. STOP REGISTERING TICK HANDLERS IN YOUR CONSTRUCTORS.
I'm looking at you Rei's!
2012-11-01 10:51:17 -04:00
Christian 6edce8b5f4 Patch a file handle leak in RegionFileCache handling when under memory pressure. 2012-10-31 22:58:01 -04:00
LexManos ca2bbe0b5f Update MCP mapings again, yay bad syncs. 2012-10-31 09:23:17 -07:00
LexManos c8941a7faa Updated MCP mapings. 2012-10-31 07:40:53 -07:00
LexManos 5e20c03736 StartServer is now useable in merged code base. 2012-10-31 07:40:40 -07:00
Christian b19e882aab Remove some debug, closes #123 2012-10-30 21:53:08 -04:00
Christian 9d7d32a1b5 Fix up tick management outside of mod loading phases for ModLoader mods. 2012-10-30 21:47:06 -04:00
Christian d512539554 Negatively cache failed class lookups, should help with @SideOnly performance issues. 2012-10-30 21:17:17 -04:00
Christian a3a93f3387 Fix some whitespace issues, handle possibly bugged entities as well 2012-10-30 09:13:18 -04:00
Christian a7eb5dc773 Vanilla/mod bug fixes: CME on entity processing, TileEntity resetting chunk on save/load. 2012-10-29 17:41:08 -04:00
Christian b23081df78 Support for ModLoader 1.4.2. Good job Risu! 2012-10-28 23:55:58 -04:00
Christian 66db4ec46e Add in an exclusion list tag for @Mod. The backend code isn't yet implemented, but shows the basic idea. 2012-10-27 15:13:28 -04:00
Christian 8bd98c3a2d Fix a small problem with the new MCP container- it can cause NPEs. Nice. 2012-10-26 07:55:23 -04:00
Christian 34cc42d3cb Fix up some javadoc complaints 2012-10-25 16:18:42 -04:00
Christian 09eade4623 Update build - include MCP information in the source pack 2012-10-25 10:00:34 -04:00
Christian 9bfe7df373 MCP deserves lots of credit. So here it is. 2012-10-25 09:02:49 -04:00
Christian 8006b774bf Fix instantiation bug 2012-10-24 21:58:36 -04:00
Christian 7cc91cfb0c Simple InterMod comms. Send a message using FMLInterModComms.sendMessage(). Receive messages through an @IMCCallback 2012-10-24 16:39:55 -04:00
Christian 24d72852e7 Update for MC 1.4.2 2012-10-24 15:12:06 -04:00
Christian cedf3d55d5 Duplicate Mod display screen. 2012-10-24 09:41:46 -04:00
Christian d915f39996 Fix typo in access transformer 2012-10-23 21:21:28 -04:00
Christian 346691c298 Fix the merge for forge 2012-10-23 18:36:05 -04:00
Christian 6dadc1d889 Fix up references to minecraftDir in obf code 2012-10-23 18:10:06 -04:00
Christian 8a55f68a18 Update FML for Minecraft 1.4.1 2012-10-23 18:00:33 -04:00
LexManos 5645fa5847 First update to 1.4.1, patches need updating. 2012-10-23 14:44:04 -07:00
LexManos ff0f00f64f Add some null checks, and throw descriptive exception when SideTransformer prevents a class from loading. 2012-10-23 13:32:02 -07:00
Christian 7a34246dc9 Ship a client only class so the merge works both sides. 2012-10-21 22:50:20 -04:00
Christian 62a6b52487 Fix RenderRegistry render ID - now at 36
Fix SpriteMaps - they're running out fast! Switch to forge if you can!
RenderBiped now has an armorlist- so armortypes add to it as well
2012-10-21 12:41:53 -04:00
Christian b845cde73d Fix up FML python script for forge 2012-10-21 08:19:36 -04:00
Christian 2c36dfbb34 Update to MCP pre 3. Fixes some weirdnesses with explosions. 2012-10-21 07:11:09 -04:00
Christian acd880dd2a Merge branch '1.4' 2012-10-20 18:07:22 -04:00
Christian e6f57e5d94 Update for MCP release 2012-10-20 18:02:26 -04:00
Christian b1de0fc17c Remove fuzz from patches for INetworkManager change 2012-10-20 17:16:50 -04:00
Christian ad4461932f Fix for new names INetworkManager and ITexturePack. I also provide refactoring scripts for both, for your use... 2012-10-20 17:07:59 -04:00
Christian 3a94211377 Add a script to ignore git complaining about the eclipse workspace changing - run when you first open the eclipse workspace 2012-10-20 15:24:05 -04:00
Christian 9386e23b1f Update gitignore - ignore the files that will change or be deleted 2012-10-20 15:14:06 -04:00
Christian 10b318c71d Add in "starter" image for eclipse workspace 2012-10-20 15:02:37 -04:00
Christian 995d5b7b3a Eclipse workspace fixup 2? 2012-10-20 14:42:25 -04:00
Christian bbb12c84fd Clean up eclipse workspace- part 1 2012-10-20 14:09:44 -04:00
Christian b50058ee47 Clean up a bit of patch fuzz 2012-10-20 12:39:40 -04:00
Christian 4a0bfa937a Fix CommonHandler for rename of the server thread class 2012-10-20 12:31:35 -04:00
Christian 4d1ec666dd Update with RC2 MCP. Use the joined.exc file directly since MCP now provides it. 2012-10-20 12:27:30 -04:00
Christian b52e3d0e7d Fix exception for CodecMus 2012-10-20 12:12:43 -04:00
Christian a1011c99a9 Fix some compilation issues. Requires resolving the worldclient abstract method 2012-10-20 11:30:01 -04:00
LexManos 0ebd4f3d94 Inital patch update to 1.4 2012-10-20 02:43:03 -07:00
LexManos 89c68c46a2 Moved into EntityVillager 2012-10-20 02:42:34 -07:00
LexManos e4702cb09d Fix line ending detection during checkout. 2012-10-20 02:32:29 -07:00
LexManos 6e64fd7a11 We don't need logging here... 2012-10-20 02:27:26 -07:00
LexManos 014b3f4ad5 remove useless -Server projects 2012-10-20 00:43:02 -07:00
LexManos 7628c67883 Updated the AT config and Marker config for 1.4 obf 2012-10-20 00:36:33 -07:00
LexManos 54a322c09f Updae build to copy files that may decompile differently but are actually the same, and updated for 1.4 values. 2012-10-20 00:06:55 -07:00
LexManos aadf396244 Update MCP Merge config. 2012-10-19 23:57:49 -07:00
LexManos 81e18552e3 Pull in MCP's 1.4 conf files. 2012-10-19 23:57:05 -07:00
LexManos 5686fd40a4 Fix error in merging of exec's 2012-10-19 21:14:03 -07:00
Christian 989ab3e96b Update build.xml - add a classpath to the manifest. This means the universal jar is now a server side launcher. 2012-10-18 21:07:33 -04:00
Christian 88f1dc97b6 Typos! 2012-10-18 21:00:58 -04:00
Christian 470a18522c Try and avoid an NPE in crash reports 2012-10-18 14:41:32 -04:00
Christian 002951804a Fix logging problems- log death messages and re-route the server through FML logs properly. 2012-10-17 18:05:23 -04:00
Christian fe7a832fad Fix the test mod 2012-10-16 13:24:29 -04:00
Christian a2bc30b356 Coremods can be specified via the command line: fml.coreMod.load=<listofcommaseparatedclasses> This will help with developing coremods 2012-10-16 13:21:10 -04:00
Christian bae1f74681 Fix classpath for server 2012-10-16 12:40:01 -04:00
Christian 887aa277a4 Add in the ability for a client to throw a custom exception that displays a custom gui instead of the default error message. 2012-10-16 12:39:04 -04:00
Christian e17f2677c7 Update FML internal classpath. Helpful for coremod devs 2012-10-16 09:47:06 -04:00
Christian 3b9972af39 Don't use File to separate the last element of the path. It's a URL, they're always separated by '/' 2012-10-16 09:46:08 -04:00
keepcalm 5c96afec70 Changed RelauchLibraryManager so that files with different paths on the
same baseURL can be implemented in one ILibrarySet.
2012-10-16 09:46:08 -04:00
Christian 1bca393ecb FML as a whole is now subject to transformers. 2012-10-16 09:20:30 -04:00
Christian 27cf731552 Bonus extra character. thanks randomitter! 2012-10-16 09:06:13 -04:00
cpw 94c84cd994 Merge pull request #116 from Vazkii/patch-1
Add Null check to FMLClientHandler.sendPacket
2012-10-07 10:45:22 -07:00
Vazkii c2d3195e76 Add Null check to FMLClientHandler.sendPacket 2012-10-05 17:36:52 +02:00
Christian d0e7c9e2ea Update patches *sigh* 2012-10-02 22:04:25 -04:00
Christian f3e1cac5a1 Add in a savehandler strategy for reading and writing data to the
world save. This service is only available to coremods via the
WorldAccessContainer interface on the mod wrapper. This is deliberate
and will not change.
2012-10-02 21:54:47 -04:00
Christian 51fb513213 Add in some bukkit supporting code. Most of this is unimplemented
until the bukkit coremod is complete.
2012-10-02 20:26:47 -04:00
Christian 65c9fdd8d7 New stuff on the ModLoader! Risu has been busy. Closes #114 2012-10-02 08:29:12 -04:00
Christian c1d4458acc Mods can now declare a range of minecraft versions they will run against 2012-10-02 01:29:46 -04:00
Christian ca1ca4f944 Fix maps supporting greater than byte() dimension sizing 2012-09-29 00:21:42 -04:00
Christian 15ee8bf5a1 Fix language registry additions, closes #113 2012-09-28 22:12:23 -04:00
cpw a08b5b19d5 Merge pull request #112 from pahimar/master
Additonal Language Registry functionality
2012-09-26 21:57:53 -07:00
pahimar 8dac58ffc1 Added ability to query the Language Registry by key and language for specific localized text, as well as loading in localization text from a specific file/URL 2012-09-26 15:41:58 -04:00
Christian f0837070d6 Extreme headless mode is back! 2012-09-25 22:46:47 -04:00
Christian dd7502a051 Fix parent child counts showing properly. Closes #107 thanks scott! 2012-09-25 19:00:36 -04:00
Christian b36d4471e6 It's useMetadata, not usesMetadata. thanks myrathi and psx. closes #110 2012-09-25 18:57:42 -04:00
Christian efb1066a88 Fix random shuffling when manipulating biomes by using a LinkedHashSet to preserve iteration order. Closes #111 2012-09-25 18:54:46 -04:00
Christian dd39ae540b Try and fix the newline capture so consoles show on the server on windows again 2012-09-24 17:22:39 -04:00
Christian b39f808618 Readd ancient searge name so dan200 and computercraft can run again. REMOVE THAT CODE DAN. 2012-09-24 17:22:16 -04:00
Christian a2c059e562 Fix missing import. Thanks ichun :( 2012-09-21 18:17:56 -04:00
Christian 19316a0d38 Version file searching should work for directories too 2012-09-21 17:39:52 -04:00
Christian fbc7a5c063 Fix bug causing NPE if non-whitelisted player joins an FML server without FML installed 2012-09-21 10:12:39 -04:00
cpw e9cfd10e39 Merge pull request #103 from iChun/patch-2
Fixed ModTextureAnimation not updating and not binding to correct image.
2012-09-19 05:12:04 -07:00
iChun 1424883773 Fixed ModTextureAnimation not updating and not binding to correct image. 2012-09-17 23:46:09 +08:00
Christian 6c746ec6d9 Tidy code 2012-09-16 21:44:11 -04:00
Christian aacbfeb66e Change version.properties search slightly, allow access to found file from the preinit event 2012-09-16 21:42:59 -04:00
Christian 1513b369d3 Add in the capability to read an internal version as <modid>.version from a file
in the zip call version.properties. Handy for autobuilding scripts.
2012-09-16 21:05:56 -04:00
Christian 35852a69fb Fix up reversed assignment for version fallback 2012-09-16 21:05:56 -04:00
LexManos 96537dc091 Fixup Item in hand rendering of textures > 16x 2012-09-15 18:24:27 -07:00
LexManos e88ddc56ca Make the exception print for headless servers if the Downloader cant initalize. 2012-09-15 18:06:59 -07:00
LexManos f24ff07b30 Remove a bunch of warning about javadoc, not a real fix, but no more warning. 2012-09-15 18:04:56 -07:00
LexManos 3420ea7a2d Update MCP Mapings 2012-09-15 17:09:45 -07:00
LexManos 87104f0e2d Makes GetModSrc check the common folder when attempting to extract source files 2012-09-15 17:09:34 -07:00
Christian 640446b868 Tie parent/child containers together again. Should close #96 2012-09-15 15:58:20 -04:00
Christian 2cf4917ded Village mating produces added villagers, and the egg should place
added villagers too. Closes #97.
2012-09-15 15:49:08 -04:00
Christian 6394ee8714 Clean up stale references to the Player stored in the NetworkRegistry,
closes #100
2012-09-15 15:36:26 -04:00
cpw 7299e05fe1 Merge pull request #99 from CovertJaguar/patch-1
More readable state event logs
2012-09-15 12:20:26 -07:00
CovertJaguar c4bd0405fd More readable init logs 2012-09-14 00:47:48 -07:00
Christian 89b8236a9c Fix onConnectionClosed not being called on the client side of a connection 2012-09-09 11:29:08 -04:00
Christian 70f55c59c0 Add in exclusion list for IFMLLoadingPlugin. 2012-09-08 12:19:03 -04:00
Christian 1c1716d833 Remove debug cruft 2012-09-07 23:14:54 -04:00
Christian d567f79652 To properly align with packet9respawn, make packet1login's dimension an int as well 2012-09-07 22:57:01 -04:00
Christian ecd4e46a45 Attempt to build some protocol negotiation, and fix packet1login so that the dimension is a short, matching packet9respawn 2012-09-07 22:46:31 -04:00
Christian 16fe495d18 Compatibility level is now passed from server to client - and
the client tracks it. This means certain packet changes can be made
without breaking comms, hopefully
2012-09-07 19:32:36 -04:00
Christian 4f70d23d0e Fix dependency checking: you can depend on specific versions of FML 2012-09-07 19:08:28 -04:00
cpw 290a3c94b7 Merge pull request #94 from iChun/patch-1
Fix handleTinyPacket using short instead of int.
2012-09-07 05:43:39 -07:00
iChun 9485dc5a96 Fix handleTinyPacket using short instead of int.
Silly cpw :P
2012-09-07 18:35:26 +08:00
Christian e6abb69b0e Fix up tiny packet handler to actually work 2012-09-06 22:59:38 -04:00
Christian e862052bb4 Allow javax to be shipped by mods. Should allow some more modloader mods to work
unaltered
2012-09-06 22:03:02 -04:00
Christian 4071ad1278 Add in a little bit of protocol cleanup. Start work on allowing multiple
protocol versions
2012-09-06 21:54:43 -04:00
Christian 60619643e6 Give a way to build the packet131mapdata packet correctly populated 2012-09-06 10:12:37 -04:00
Christian b818769c1f Capture and leverage Packet131MapData 2012-09-06 10:03:30 -04:00
Christian 12bc4bab0c Make console logging pass through a single logging thread to avoid concurrency problems with launchers and stuff 2012-09-04 19:11:45 -04:00
Christian 8fccfa21df Overlooked chat message support *sigh*. Fixes wierd mods that communicate through custom
chat messages rather than anything else. Hi Superior enchanting!
2012-09-04 12:37:59 -04:00
Christian a697d043fc Rescan mod packages where there was a possible mod identified to try and make sure we load it. Fixes Matmos r16 2012-09-04 11:39:51 -04:00
Christian 9d812f12cc And handle the other way to globally register an entity 2012-09-03 21:37:20 -04:00
Christian 869cf78e98 Fix up mods trying to register entities outside of modloading. Now you'll get a big fat warning for doing such a derpy thing. 2012-09-03 21:32:21 -04:00
Christian 186680cd8c Fix CJB mod compatibilty for real. Gui container registration can now happen in the constructor. YUK! 2012-09-03 21:14:11 -04:00
Christian 5aed6d995d Fix compatibility with ModLoader dispenser hook. Fixes a bug with
IDispenseHandler too - though it means that interface is now
deprecated
2012-09-03 11:37:17 -04:00
Christian 3d7a665987 Fix headless operation, hopefully 2012-09-02 13:29:46 -04:00
Christian 10a716969b Fix up trying to re-add stuff to the classpath when it's already there 2012-09-02 12:56:08 -04:00
Christian 0eb7180fc1 Fix out of range entity id handling for ModLoader mods a bit more. Thanks Herobrine mod! 2012-09-02 12:39:06 -04:00
Christian b1b4c61b80 Expose GuiMerchantButton 2012-09-02 12:15:13 -04:00
Christian 359cfb5c98 Log a big fat warning for the developer in the case the network version
is not acceptable to the mod itself. (This can happen because of a bad range
specifier for example)
2012-08-31 23:41:29 -04:00
Christian 8656fd50ce Also, make missing entity not blow things up 2012-08-31 16:49:35 -04:00
Christian 25a4dcb653 Fix entity tracker "update" packet not computing correctly. Should work now.. 2012-08-31 16:41:05 -04:00
Christian c90a853377 Fix up addRenderer to catch exceptions from the basemod, also, addrenderer now supplies a list of the
default renderers from MC for editing and will note the changes made.
2012-08-31 11:18:17 -04:00
Christian 18069d8fd2 Change download location for FML libraries to files.minecraftforge.net, add an encoding param to the javac command line to force utf 8 2012-08-31 11:18:17 -04:00
Christian a40f4a75a9 Add in random jar/zip files to the classpath. UGH this is so fucking ugly it's not funny. 2012-08-30 20:10:53 -04:00
Christian 5b6460b68c Use a null socket and try to prefer the result of getLocalHost in the broadcast data. 2012-08-29 16:12:40 -04:00
Christian c0d1348e65 Add in an ItemRenderer null check so FML can run render adding mods 2012-08-29 13:58:56 -04:00
Christian 482c163344 Inverted boolean logic. Grrr. 2012-08-29 13:44:40 -04:00
Christian 221d1131b4 ModLoader mob spawns use packet 24- build a bypass system so that
they can still use it
2012-08-29 12:58:16 -04:00
Christian f19f426449 Remove debug statements 2012-08-28 23:07:37 -04:00
Christian 9dd9b6eb71 Fix keybindings not loading properly from gamesettings file after restart 2012-08-28 22:15:18 -04:00
Christian acb0b21d6d Fix so we always send received packets to handlers.
Renders 250 filtering useless unless i can figure a way to intercept *outbound* packets that isn't as messy as I'm
contemplating
2012-08-27 17:46:08 -04:00
Christian b17dd3c695 Some tests 2012-08-26 22:23:05 -04:00
Christian fa66ffaf3f Fix trying to load the client side packet handler, when on the server, hopefully? 2012-08-26 22:18:57 -04:00
Christian b106420774 Fix up network negotiation - now it will disconnect with a nice
error screen if there are missing mods on the client vs server
2012-08-26 22:13:43 -04:00
Christian c971adb59b Fix missing addCommand call: thanks "spawnwolf test command" 2012-08-26 13:07:35 -04:00
Christian d6326deeb0 Fix a couple of modloader mods. Thanks! 2012-08-26 12:52:50 -04:00
Christian 483667c919 Some functionality fixes for @Instance injection. 2012-08-26 10:55:55 -04:00
Christian 8bef512803 Versions now have two flavours: the @Mod(version) which is the "programmatic version" and
is used for all version relationship calculation. The "display version" as sourced from
mcmod.info is used for display purposes only and can be literally anything. Note: they fall back
to one another when they're missing, and to "1.0" if both are absent.

Also, changed @Instance. Now, you can inject *other* mods using @Instance as long as you depend
on them as a "before" or "dependency" relationship. Classes containing @Instance will only be
loaded if the Mod the @Instance refers is present. So you don't have to worry about runtime class
resolution.
2012-08-26 10:45:00 -04:00
Christian 501009c11f Always for ML mods into "public" class accessibility - we don't call from the default package like ML does. 2012-08-25 21:57:25 -04:00
Christian d3d430827f Add in a convenience method for getting a class instance based on
existence of another Mod. Useful for soft dependencies.
2012-08-25 21:26:41 -04:00
Christian 2d9b88bd52 And more mod sorting fixes. 2012-08-24 12:10:43 -04:00
Christian 93d5934ea7 Actually *use* the sorted mod list 2012-08-24 11:58:18 -04:00
cpw 180a279558 Merge pull request #82 from Chicken-Bones/master
The access transformer will now handle classes in packages.
2012-08-23 16:47:13 -07:00
Chicken Bones cf38461911 The access transformer will now handle classes in packages.
Eg.

public net/minecraft/client/Minecraft.T #timer
2012-08-24 08:09:10 +10:00
Christian 2c85539517 Reverse the meaning of state in fml.modStates system property and fmlModState.properties - it was very
derpy before. Now: true is enabled, false is disabled, as you would expect
2012-08-23 17:37:44 -04:00
Christian d651189581 Actually fix the corrupt JSON problem 2012-08-23 17:27:53 -04:00
Christian f6a8cd556e Fix isModLoaded for "disabled" mods, and the toposort as well 2012-08-23 17:08:18 -04:00
Christian 3bde961dc7 A bit more information for dependency handling 2012-08-23 16:46:23 -04:00
Christian 6396beaef7 Fix up handing corrupt mcmod.info 2012-08-23 16:43:28 -04:00
Christian 6bc6defb07 Fix a problem with network ids 2012-08-23 16:38:34 -04:00
Christian 732861092f Fix up version handling properly. Hopefully, and the error screen. 2012-08-23 15:29:17 -04:00
Christian 9fcc452ed3 Only active mods should have dependencies checked, and be sorted 2012-08-23 14:33:54 -04:00
Christian 26302a6ff2 Fix oddity with Screen, print a version out in the sorted list! 2012-08-23 14:28:49 -04:00
Christian 62dbfb3837 Fix metadata 2012-08-23 14:05:17 -04:00
Christian b91cbe9794 Fix up versioned dependencies so they work a lot better, also add in a missing mods screen 2012-08-23 13:43:25 -04:00
Christian 93b8ba9576 Fix missing serverSendPacket 2012-08-23 09:02:12 -04:00
Christian 23fdbbd03d Trading support for ModLoader - thanks Herblore! 2012-08-23 01:40:03 -04:00
Christian d7a74d84ea Close the jar, for cleanliness sake 2012-08-23 01:39:35 -04:00
Christian 58e6dd9794 Fix authors - it'll read both "authors" and "authorList" from the json now 2012-08-23 01:17:47 -04:00
Christian 907cf2d925 More ML compatibility - fix up dragon mounts, thanks! 2012-08-23 00:37:45 -04:00
Christian ee48a3673d Fix up loading mods that are grandchildren of BaseMod 2012-08-23 00:04:34 -04:00
Christian c6f362b77f Fix entity handling for ModLoader mods, thanks parachute mod! 2012-08-22 23:46:16 -04:00
Christian 6e01c59635 Merge ChickenBones pull into FML - adds player trackers 2012-08-22 18:00:55 -04:00
Christian d411f66903 Fix formatting 2012-08-22 18:00:38 -04:00
Christian 0768dc1610 Tweak patches and hooks slightly 2012-08-22 17:58:46 -04:00
Christian 4c3db16842 More precise error handling when an invalid class is present 2012-08-22 17:50:07 -04:00
Christian 805fd1dd90 Fix textures not applying properly 2012-08-22 17:50:07 -04:00
Christian c59996b24b Fix up entity spawning - hopefully they won't warp anymore. 2012-08-22 17:50:07 -04:00
Christian e0a1e8293b Add in a helper on the server start event for adding commands to
the server.
2012-08-22 17:50:07 -04:00
Christian e8af9c0233 Move villager trading hook up a bit. thanks sengir. 2012-08-22 17:50:07 -04:00
Christian a955d30d64 Fix LAN to try hard to find a real network interface, not just localhost
most of the time
2012-08-22 17:50:07 -04:00
Christian dbab3bb259 Update build to not bother building client jar. Universal is everything
now.
2012-08-22 17:50:07 -04:00
Christian bd9c4ee99a Null protection for ticks() -- probably should uses EnumSet.noneOf() but
you can also use null now to stop ticking. closes #77
2012-08-22 17:50:07 -04:00
Christian a0cbd3755d More precise error handling when an invalid class is present 2012-08-22 17:36:26 -04:00
Christian 12323e233f Fix textures not applying properly 2012-08-22 17:27:06 -04:00
Chicken Bones 8a308db3d4 FML will now search '<mcpdir>/forge/accesstransformers' for user defined access transformer config files to be applied during forge setup 2012-08-23 06:31:00 +10:00
Chicken Bones 0583dc8b74 Added IPlayerTracker hooks 2012-08-23 06:28:53 +10:00
Christian 789a4a3659 Fix up entity spawning - hopefully they won't warp anymore. 2012-08-22 15:11:59 -04:00
Christian a87d0451c8 Add in a helper on the server start event for adding commands to
the server.
2012-08-22 15:11:43 -04:00
Christian 82e9309d27 Move villager trading hook up a bit. thanks sengir. 2012-08-22 11:50:03 -04:00
Christian 8deaa378c9 Fix LAN to try hard to find a real network interface, not just localhost
most of the time
2012-08-22 11:48:30 -04:00
Christian b5363e3552 Update build to not bother building client jar. Universal is everything
now.
2012-08-22 11:12:26 -04:00
Christian 28a10ac340 Null protection for ticks() -- probably should uses EnumSet.noneOf() but
you can also use null now to stop ticking. closes #77
2012-08-22 09:43:32 -04:00
Christian c349d51923 Automatic mod entity registration into the global entity list. This might break
entity code out there, sorry, but this way for most entities you no longer
need to manage the global mod entity stuff at all. just remove it. FML will
take care of the rest (note, worlds won't load the old entities)
2012-08-21 19:34:33 -04:00
Christian ef01745e09 Add in a utility function that *might* tell you the context
you're running in on either client or server: FMLCommonHandler.getEffectiveSide
2012-08-21 19:15:07 -04:00
Christian c97d6a65d0 Try and stop sendPacketToAllAround from being crashy 2012-08-21 18:50:26 -04:00
Christian 2062273504 Mods can add mod specific crash information to the crash report now
Forge needs to implement MinecraftForge.getCrashCallable
2012-08-21 18:48:12 -04:00
Christian 6e6436ee41 Fix up dispenser handling, add in new params for the dispenser: breaks IDispenseHandler, sorry 2012-08-20 21:44:54 -04:00
Christian 38f4a22bc4 Fix up MLProp handling for null info 2012-08-20 21:44:47 -04:00
Christian 3a8b047e3c GUIs working in FML for ML mods 2012-08-20 21:44:28 -04:00
Christian 52483ee6bd Support gui opening for Shelf mod 2012-08-20 21:43:59 -04:00
LexManos dce1cbc096 Updated MCPMerger to annotate unique classes with there sides, and SideTransformer to null out any class that is loaded on the wrong side. 2012-08-19 22:26:52 -07:00
Christian 46c563a9a8 Expose more of the village construction parts for building village
pieces
2012-08-19 11:23:29 -04:00
Christian 1380c2ecce Allow access to the type "ComponentVillage" 2012-08-19 10:35:06 -04:00
Christian 71a3818bdd Documentation and registration for villager stuff 2012-08-19 10:30:24 -04:00
Christian e3a343c797 Fix javadoc derp 2012-08-19 10:21:19 -04:00
Christian 195b1a043e Villager trading, manipulation and village enhancement. Still WIP but should be functional 2012-08-19 10:13:15 -04:00
Christian 69e66c327f Fix exception based logging to actually log the exception! 2012-08-19 09:31:26 -04:00
Christian 885637cc7d Fix up keyboard events for modloader 2012-08-19 01:44:33 -04:00
Christian 90a7c8f787 Pickup notification 2012-08-19 00:26:55 -04:00
Christian 2171c0caa4 Update fml_at with new transforms 2012-08-18 20:08:27 -04:00
Christian 924a6f9254 Fix derp where client sided packet handler would be created on a dedi server env 2012-08-18 19:50:46 -04:00
Christian ad4cffb0c6 Add in support for "dummy" keybindings- ones that are added to the list but never do anything
so the mod can handle it all themselves.
2012-08-18 10:24:29 -04:00
Christian cf77ffb89d Don't complain about minecraft source code being in "net.minecraft.src". Derp. 2012-08-18 10:09:53 -04:00
Christian b2fdcd7f1c Fix ModLoader add XP Smelting 2012-08-18 10:09:25 -04:00
Christian 094ce2ae18 Actually register client/server packetspecs as their correct sides! fixes #71 2012-08-18 09:28:36 -04:00
Christian e8cb2c1bfe Error if channel name is invalid - either too short, or too long 2012-08-17 16:59:48 -04:00
Christian 9c6c56c49d Add a connect and read timeout for downloading libraries. This should really stop the "waiting forever" at startup screen. 2012-08-17 16:21:18 -04:00
Christian 0d5affede3 GIANT FAT WARNINGS if you use any code in net.minecraft.src or any subpackage thereof. Get it out of there, now! 2012-08-17 16:13:05 -04:00
Christian 13f210f403 Fix up ML GUI ticking. Thanks sharose! 2012-08-17 16:09:46 -04:00
Christian c61ad51883 Organize ALL the imports 2012-08-17 09:25:04 -04:00
Christian c0842b0797 Expose the server in serverstart event 2012-08-17 09:25:04 -04:00
Christian 2851079ff0 Fix up directory injection of log file locations 2012-08-17 09:25:04 -04:00
Christian 5197524d1c Refer to FMLLog, not FMLRelaunchLog 2012-08-17 09:25:04 -04:00
Christian 78efd1acc6 Tidy up server launch - reflection not required anymore 2012-08-17 09:25:04 -04:00
Christian eee0a99b88 Also, log what the directory discoverer finds for mcmod.info 2012-08-17 09:25:04 -04:00
Christian 10c96c394d And log the exception if it has a problem reading the jar file 2012-08-17 09:25:04 -04:00
Christian 07cc3fb2d9 Fix jar loader failing to inject any metadata at all if mcmod.info is not found. 2012-08-17 09:25:04 -04:00
LexManos e31f1433bf Change install.cmd to install.bat, why, cuz people are .... Updated readme to mention needing server and client. 2012-08-16 22:57:11 -07:00
Christian af06c97efd Some compatibility fixes for Rei's minimap, and tidy up a couple of things 2012-08-16 13:55:42 -04:00
Christian 400de1d66e Fix Forge branding string call 2012-08-16 13:01:48 -04:00
Christian 2a9285eee8 Update FML for mcp 72 final, change download location for FML files, and make the stop button work.
Hello is NOT going to go away :)
2012-08-16 12:22:56 -04:00
Christian 785bdde6bd Fix critical bug in FML load controller that complains about injected mod containers 2012-08-16 08:34:12 -04:00
Christian 071e2dc524 Handle the case where a mod tries to do something stateful during constructor phase, and log a big
fat message about it. Don't do it!
2012-08-15 20:05:12 -04:00
Christian fc08d072a4 Small fixes, including showing the FULL name of Forge Mod Loader 2012-08-15 19:54:56 -04:00
Christian 0019485aba Fix up null array in keybinding handler 2012-08-15 19:17:21 -04:00
Christian e76f145b65 Actually add in the system property for the minecraft home, should fix multimc too 2012-08-15 19:16:36 -04:00
Christian 27d5937f4c Add in support for setting the home dir via the applet launch, also a system property for forcing the home dir 2012-08-15 17:18:11 -04:00
LexManos 868c4c5977 Cleanup fml.py a little, should fix double printing of 'patching file' 2012-08-15 03:10:45 -07:00
LexManos 5a37929ceb Wrap mod description rendering in BLEND calls https://github.com/MinecraftForge/MinecraftForge/issues/96 2012-08-15 02:52:29 -07:00
LexManos b1dc2dbf8a Made getmodifiedsrc noop for server. 2012-08-15 00:50:40 -07:00
LexManos ecfbef95c7 Fix new eclipse workspace to load the project properly from start. 2012-08-15 00:50:16 -07:00
Christian bfd8fbefee Merge branch 'minecraft132'
Yes, we are already on 1.3.2
2012-08-14 22:33:28 -04:00
Christian f8c36104ad KeyBinding handler change: a handler now takes an array of keys and calls back with the
activated key. Sorry for the inconvenience but this improves the usability of this
API a lot
2012-08-14 22:32:19 -04:00
Christian e26230fb2d Fix renderer's not getting the rendermanager set on them at registration time 2012-08-14 22:32:19 -04:00
LexManos 6417ad0a3c Finished update to MCP 7.2, MC 1.3.2 pre. 2012-08-14 19:24:49 -07:00
Christian 0f988d087c KeyBinding handler change: a handler now takes an array of keys and calls back with the
activated key. Sorry for the inconvenience but this improves the usability of this
API a lot
2012-08-14 22:06:49 -04:00
Christian 7c01b64aed Fix renderer's not getting the rendermanager set on them at registration time 2012-08-14 21:59:47 -04:00
LexManos 03130c78a7 Fixup included workspace to have single project with client/server launches. 2012-08-14 17:42:40 -07:00
Christian 30ab326d2b Start working on MC 1.3.2 2012-08-14 20:09:24 -04:00
Christian 8d1cba57f8 Add in a helper for code migrating from ML renderer stuff 2012-08-14 19:09:22 -04:00
Christian cbfd6c1a66 Merge pull request #62 from calclavia/patch-1
Shortcut function for addNameForObject()
2012-08-14 13:52:58 -07:00
calclavia 81cb3c82f4 Shortcut function for addNameForObject()
Having that long line of code makes the code a bit ugly... Please make this shortcut function like ModLoader.addName() so I don't need to use ModLoader.addName(). :)
2012-08-15 04:45:32 +08:00
Christian e64296e109 Handle mod duplicate detection much better. Default the name of a mod to it's id.
Fix up the block registry problem. Fix the packetsend from c->s actually being
"disconnect" :)
2012-08-14 13:36:29 -04:00
Christian 5872b31781 Fix entity spawn packets 2012-08-14 08:20:28 -04:00
LexManos 51b801b1c6 Force a Jenkins build 2012-08-14 01:21:56 -07:00
LexManos 9ef153c0b6 Merge pull request #60 from remuladgryta/master
fixed 'derp' error on @NetworkMod
2012-08-14 01:16:29 -07:00
remuladgryta 2e236faec7 fixed java.lang.NoSuchMethodException
getServerHandlerSpecDefaultValue() and
getClientHandlerSpecDefaultValue() should no longer give derp exeption
2012-08-14 09:50:22 +03:00
LexManos 129c356ecf FML will skip gathering MD5s for classes in the cpw package during the the inital recompile {Make Side/SideOnly reobf properly} 2012-08-13 21:53:52 -07:00
LexManos d8316b0bdc Merge remote-tracking branch 'origin/master' 2012-08-13 21:05:14 -07:00
LexManos 1d3a92f3f1 Updated FML install to provide better error output, Updated commands.py patch to disable recompile of server project. 2012-08-13 21:02:55 -07:00
Christian 81c858c719 Hopefully let build continue if server reobf fails, and fix derp in FMLNetworkHandler for entities 2012-08-13 23:25:08 -04:00
Christian 341041aedb Fix up concurrent modification exception - ticks for players now occur on both sides 2012-08-13 22:55:23 -04:00
Christian 25256b2295 Merge the last bits of the server code into the common directory, and annotate ModLoader/BaseMod for sided use
This means the FML-Server project is now defunct as all code is either common, client or bukkit.
2012-08-13 22:51:53 -04:00
Christian 13874ba547 Actually fix the applet launch - it now launches properly *and* closes the window 2012-08-13 22:12:36 -04:00
Christian bde58add62 Fix up relaunch of the applet 2012-08-13 21:44:43 -04:00
Christian 9112c63347 Change language loading a bit 2012-08-13 20:28:53 -04:00
Christian 78fa2b8d78 Update spritehelper bitmaps for items and terrain 2012-08-13 20:08:03 -04:00
Christian 6922c369f3 Tidy up some APIs, expose the addOverride mechanism. This should be pluggable by forge
but may need work to allow for each mod to have it's own override set
2012-08-13 19:57:40 -04:00
Christian b0fd438a1d Fix derp in LanguageRegistry 2012-08-13 16:45:47 -04:00
Christian 99f4f0c7d3 FMLModcontainer should not complain about annotations it has no idea about. so stfu fmlmodcontainer 2012-08-13 16:15:11 -04:00
Christian b09c1cd242 Fix derp with EntityRegistry- bimap is not the right type for the name->container list 2012-08-13 15:55:24 -04:00
Christian 5ca3bf9362 Add in a sided variant of the packethandlers in the annotation - also, a bit more
explicit warning on when to register blocks - if you do it after pre-init, you'll
reset the achievements
2012-08-13 15:26:29 -04:00
Christian c6a9884bde Generate channel registration for client, also, do it before the login events so you can send packets 2012-08-13 11:58:44 -04:00
Christian 43825ca78e Capture server packet handling errors into the FML log file for diagnostics 2012-08-13 11:52:30 -04:00
Christian 44eeadb211 one more change for the road :) 2012-08-13 01:24:02 -04:00
Christian 7011da5fa9 Don't spit debug all over the floor 2012-08-13 00:24:15 -04:00
Christian c61ddfa9d1 updated conf, commands patch (missing newline?) and capturing the actual running
MC version and validating it at relaunch time is the correct MC version.
2012-08-13 00:17:34 -04:00
Christian e64b6dcb13 Add in callableminecraftversion 2012-08-12 23:54:41 -04:00
Christian 183dc236e4 Entity AI accessibility, also AccessTransformer can make certain classes public now 2012-08-12 23:50:27 -04:00
Christian ef5349dec2 Add in a simple packet dispatcher for sending packets around 2012-08-12 22:45:18 -04:00
Christian b39afc0711 Add in a sided packet registry so that client vs server can vary 2012-08-12 22:23:03 -04:00
Christian a8579b43ac Fix double forge init on server 2012-08-12 20:34:23 -04:00
Christian fa92eca328 Merge pull request #50 from Krapht/master
Fix for getNextAvailableRenderId() returning ids in use by vanilla - thanks krapht!
2012-08-12 06:55:23 -07:00
Krapht 42165df29f Fixed getNextAvailableRenderId() returning ids in use by vanilla 2012-08-12 14:45:03 +02:00
LexManos 9860569536 Fix MCPMerger injecting Side/SideOnly when it already exists. 2012-08-12 04:27:36 -07:00
LexManos 7aa48a167f Added patch verification to commands.py patch, and made it so MCP will check the original jars for the server, to prevent it from saying modified when it started out clean. 2012-08-12 02:49:39 -07:00
LexManos 6e3764da48 Add DEBUG constant to Access/Side Transformers to remove spam when not needed. Also AccessTransformer and MCPMerger should return a error code when it can not process causing MCP to stop decompile. 2012-08-12 01:23:10 -07:00
Christian 4d503d6925 Fix EntityRegistry - mods can specify update frequency, range and velocity data, and also
patch EntityTracker to actually track FML entities
2012-08-12 00:18:04 -04:00
Christian 8e04d40034 Fix NPE with no channels - always register FML 2012-08-12 00:17:07 -04:00
LexManos cb57cd02e0 Added missing quotes around compile command. 2012-08-11 16:03:33 -07:00
Christian 22fe48e477 Fix up the network mod issue properly. Maintain a real cache of mod objects 2012-08-11 16:21:03 -04:00
Christian 204f73cb05 Remove profiler stuff - it's been deeply reorged. I'll look at re-adding it later 2012-08-11 14:12:39 -04:00
Christian 28096abea5 Fix up command patch to actually work 2012-08-11 14:12:23 -04:00
Christian 2d7eb5cb7f Fix commands.py to always include the two side classes so the fml jars are valid. 2012-08-11 14:01:27 -04:00
Christian e6d6932e21 Fix build script- put client in first 2012-08-11 13:05:37 -04:00
Christian 406e5d64c0 Put the marker on the server ML file too 2012-08-11 13:04:59 -04:00
Christian 13756aad9f Fix universal not to dupe entries in the jar, also add in the fml mod as "untransformable" 2012-08-11 12:34:25 -04:00
Christian c1a8b16f30 Fix up launch when obfuscated *sigh* 2012-08-11 12:24:43 -04:00
Christian e3671285c3 Update netclienthandler patch. 2012-08-11 12:10:22 -04:00
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
401 changed files with 72163 additions and 9495 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>
+7
View File
@@ -0,0 +1,7 @@
* text eol=lf
*.bat text eol=crlf
*.patch text
*.png binary
*.exe binary
*.dll binary
*.zip binary
+10 -10
View File
@@ -1,10 +1,10 @@
/bin
/minecraft_server
/mods
/fmlbuild.properties
/fmlversion.properties
/difflist.txt
/.metadata/
/eclipse/.metadata/
/target
fmlbranding.properties
/bin
/minecraft_server
/mods
/fmlbuild.properties
/fmlversion.properties
/difflist.txt
/target
fmlbranding.properties
/fernflower.zip
/commands.py.bck
-24
View File
@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>fml</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources>
<link>
<name>minecraft_server</name>
<type>2</type>
<location>/home/cpw/projects/mcworkspace/vanilla125/src-work/minecraft_server</location>
</link>
</linkedResources>
</projectDescription>
-11
View File
@@ -1,11 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
-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()
+213 -58
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}"/>
@@ -50,31 +51,33 @@
</condition>
<property name="mcp.obfoutput" location="${mcp.home}/reobf" />
<property name="client.mcp.obfoutput" location="${mcp.obfoutput}/minecraft" />
<property name="server.mcp.obfoutput" location="${mcp.obfoutput}/minecraft_server" />
<property name="mcp.srcdir" location="${mcp.home}/src" />
<property name="common.mcp.srcdir" location="${mcp.srcdir}/common" />
<property name="client.mcp.srcdir" location="${mcp.srcdir}/minecraft" />
<property name="server.mcp.srcdir" location="${mcp.srcdir}/minecraft_server" />
<property name="clean.mcp.srcdir" location="${mcp.home}/src-base" />
<property name="patch.mcp.srcdir" location="${mcp.home}/src-work" />
<property name="tmp.mcp.srcdir" location="${mcp.home}/src-tmp" />
<property name="renamed.mcp.srcdir" location="${mcp.home}/src-renamed" />
<property name="common.src.dir" location="${basedir}/common" />
<property name="client.src.dir" location="${basedir}/client" />
<property name="server.src.dir" location="${basedir}/server" />
<property name="patch.src.dir" location="${basedir}/patches" />
<property name="fml.conf.dir" location="${basedir}/conf" />
<condition property="version.build" value="${env.BUILD_NUMBER}" else="1">
<isset property="env.BUILD_NUMBER" />
</condition>
</target>
<target name="init" depends="buildenvsetup">
<target name="makeversion" depends="buildenvsetup">
<antcall target="writeversion" />
<property file="fmlversion.properties" />
<property name="build.number" value="${fmlbuild.major.number}.${fmlbuild.minor.number}.${fmlbuild.revision.number}" />
<property name="version.minecraft" value="${fmlbuild.mcversion}" />
<property name="version.major" value="${fmlbuild.major.number}" />
<property name="version.minor" value="${fmlbuild.minor.number}" />
<property name="version.rev" value="${fmlbuild.revision.number}" />
<property name="version" value="${version.major}.${version.minor}.${version.rev}.${version.build}" />
</target>
<target name="clean">
<target name="clean" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/cleanup.py" />
<arg value="-f" />
@@ -86,23 +89,20 @@
</exec>
</target>
<target name="buildandreobfmcp" depends="init">
<target name="reobfuscate" depends="buildenvsetup,recompile">
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
<arg value="${mcp.home}/runtime/recompile.py" />
<arg value="${mcp.home}/runtime/reobfuscate.py" />
</exec>
<fail message="Compilation failed">
<fail message="Reobfuscation failed">
<condition>
<not>
<and>
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
<available file="${mcp.home}/bin/minecraft_server/net/minecraft/server/MinecraftServer.class"/>
<available file="${mcp.home}/temp/client.md5"/>
<available file="${mcp.home}/temp/client_reobf.md5"/>
</and>
</not>
</condition>
</fail>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/reobfuscate.py" />
</exec>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${basedir}/generatechangedfilelist.py"/>
<arg value="${mcp.home}"/>
@@ -110,39 +110,34 @@
</exec>
</target>
<target name="merge-client" depends="init,clean">
<antcall target="merge-source">
<param name="side" value="client" />
</antcall>
<target name="recompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
<arg value="${mcp.home}/runtime/recompile.py" />
</exec>
<fail message="Compilation failed">
<condition>
<not>
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
</not>
</condition>
</fail>
</target>
<target name="merge-server" depends="init,clean">
<antcall target="merge-source">
<param name="side" value="server" />
</antcall>
<target name="merge-client" depends="buildenvsetup">
<copy todir="${client.mcp.srcdir}" overwrite="true" verbose="true">
<fileset dir="${client.src.dir}" includes="**/*.java" />
</copy>
</target>
<target name="merge-source">
<side prop="merge-to" src="mcp.srcdir" side="${side}" />
<side prop="side-from" src="src.dir" side="${side}" />
<copy todir="${merge-to}" overwrite="true" verbose="true">
<fileset dir="${side-from}" includes="**/*.java" />
<target name="merge-common">
<copy todir="${common.mcp.srcdir}" overwrite="true" verbose="true">
<fileset dir="${common.src.dir}" includes="**/*.java" />
</copy>
</target>
<target name="build-client" depends="init,merge-client,buildandreobfmcp">
<antcall target="extract-built-jar">
<param name="side" value="client" />
</antcall>
</target>
<target name="merge-source" depends="buildenvsetup,merge-client,merge-common" />
<target name="build-server" depends="init,clean,merge-server,buildandreobfmcp">
<antcall target="extract-built-jar">
<param name="side" value="server" />
</antcall>
</target>
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion"/>
<target name="extract-built-jar">
<side prop="output" src="mcp.obfoutput" side="${side}" />
@@ -153,6 +148,7 @@
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
<mappedresources>
<concat>
<fileset dir="${basedir}/install" includes="README.txt" />
@@ -171,17 +167,51 @@
</zip>
</target>
<target name="build-source-pack">
<property name="jarname" value="${modname}-src-${version}" />
<zip destfile="${basedir}/target/${jarname}.zip">
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt" prefix="fml" />
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/src/minecraft_server" />
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/src/minecraft" />
<zipfileset dir="${client.src.dir}" includes="**/*.java" prefix="fml/src/minecraft" />
<zipfileset dir="${server.src.dir}" includes="**/*.java" prefix="fml/src/minecraft_server" />
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/src/minecraft" />
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/src/minecraft_server" />
<target name="build-universal" depends="build-client">
<property name="universal.jarname" value="${modname}-universal-${version}" />
<mkdir dir="${basedir}/target" />
<jar destfile="${basedir}/target/${universal.jarname}.zip" duplicate="preserve">
<manifest>
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
<attribute name="Class-Path" value="minecraft_server.jar"/>
</manifest>
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" />
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" />
<zipfileset dir="${client.src.dir}" includes="mcp.png" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
<mappedresources>
<concat>
<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="${client.src.dir}" includes="mcp.png" prefix="fml/client" />
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/common" />
<zipfileset dir="${common.src.dir}" includes="*.cfg" prefix="fml/common" />
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" prefix="fml/common" />
<zipfileset dir="${patch.src.dir}" includes="**/*.patch" prefix="fml/patches" />
<zipfileset dir="${fml.conf.dir}" prefix="fml/conf" />
<mappedresources>
<concat>
<fileset dir="${basedir}/install" includes="README.txt" />
@@ -197,20 +227,145 @@
</concat>
<mergemapper to="fml/README-fml.txt" />
</mappedresources>
<zipfileset dir="${basedir}/install" excludes="README.txt" prefix="fml" />
<zipfileset dir="${basedir}/install" excludes="README.txt,fml.pyc" prefix="fml" />
</zip>
</target>
<target name="build" depends="init,clean,merge-server,merge-client,patch,build-server,build-client,build-source-pack" />
<target name="build" depends="buildenvsetup,merge-client,merge-common,build-client,build-universal,build-source-pack" />
<target name="patch" depends="init">
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build"/>
<target name="patch" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/applypatches.py" />
<arg value="${patch.src.dir}" />
<arg value="${basedir}" />
<arg value="${mcp.srcdir}" />
<arg value="${mcp.home}" />
</exec>
</target>
<target name="setupenvironment" depends="buildenvsetup">
<input message="This will clean the mcp environment at ${mcp.home} and backup any src-work folder there (src-base will be erased). Continue?" validargs="y,n" addproperty="do.continue" />
<condition property="do.not.continue">
<equals arg1="n" arg2="${do.continue}" />
</condition>
<fail if="do.not.continue">You have decided not to continue. This script will stop now.</fail>
<echo>Preparing the MCP environment at ${mcp.home}</echo>
<antcall target="fmldecompile"/>
<echo>Moving old patched sources at ${patch.mcp.srcdir} out of the way</echo>
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
<fileset dir="${patch.mcp.srcdir}"/>
</move>
<echo>Deleting old patch references at ${clean.mcp.srcdir}</echo>
<delete dir="${clean.mcp.srcdir}" failonerror="false"/>
<echo>Creating new patch references at ${clean.mcp.srcdir}</echo>
<copy todir="${clean.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
</copy>
<antcall target="cleanargo"/>
<antcall target="patch"/>
<echo>Creating clean patched references at ${patch.mcp.srcdir}</echo>
<copy todir="${patch.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
</copy>
<antcall target="writeversion"/>
<echo>Setup complete! You should now be able to open ${basedir}/eclipse as a workspace in eclipse and import/refresh the FML-Server and FML-Client projects</echo>
</target>
<target name="fmldecompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/cleanup.py" />
<arg value="-f" />
</exec>
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/decompile.py" />
<arg value="${mcp.home}" />
<arg value="${basedir}" />
</exec>
</target>
<target name="jenkinsfmldecompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/cleanup.py" />
<arg value="-f" />
</exec>
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/decompile.py" />
<arg value="${mcp.home}" />
<arg value="${basedir}" />
<arg value="-no_gen_conf" />
</exec>
</target>
<target name="repatch" depends="buildenvsetup,checkpatches">
<echo>Moving old patched sources at ${mcp.home}/src-work out of the way</echo>
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
<fileset dir="${patch.mcp.srcdir}"/>
</move>
<delete dir="${mcp.srcdir}"/>
<copy todir="${mcp.srcdir}">
<fileset dir="${clean.mcp.srcdir}"/>
</copy>
<antcall target="cleanargo"/>
<antcall target="patch"/>
<copy todir="${patch.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
</copy>
</target>
<target name="repatchclean" depends="buildenvsetup">
<delete dir="${mcp.srcdir}"/>
<copy todir="${mcp.srcdir}">
<fileset dir="${clean.mcp.srcdir}"/>
</copy>
<antcall target="cleanargo"/>
<antcall target="patch"/>
</target>
<target name="cleanargo" depends="buildenvsetup">
<delete dir="${client.mcp.srcdir}/argo"/>
</target>
<target name="checkpatches" depends="buildenvsetup">
<uptodate property="checkUptodate.uptodate">
<srcfiles dir="${patch.mcp.srcdir}" includes="**/*.java">
<present targetdir="${patch.src.dir}">
<globmapper from="*.java" to="*.java.patch"/>
</present>
</srcfiles>
<globmapper from="*.java" to="${patch.src.dir}/*.java.patch"/>
</uptodate>
<fail unless="checkUptodate.uptodate">
A patch is out of date. Update your patches!
</fail>
</target>
<target name="updatepatches" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/update_patches.py" />
<arg value="${mcp.home}"/>
<arg value="${basedir}"/>
</exec>
</target>
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-common,reobfuscate">
<copy todir="${tmp.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
</copy>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/updatenames.py" />
<arg value="-f" />
</exec>
<copy todir="${renamed.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
</copy>
<move todir="${mcp.srcdir}">
<fileset dir="${tmp.mcp.srcdir}"/>
</move>
</target>
</project>
+43 -43
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()
@@ -0,0 +1,43 @@
package cpw.mods.fml.client;
import cpw.mods.fml.common.IFMLHandledException;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
import net.minecraft.src.FontRenderer;
import net.minecraft.src.GuiErrorScreen;
/**
* If a mod throws this exception during loading, it will be called back to render
* the error screen through the methods below. This error will not be cleared, and will
* not allow the game to carry on, but might be useful if your mod wishes to report
* a fatal configuration error in a pretty way.
*
* Throw this through a proxy. It won't work on the dedicated server environment.
* @author cpw
*
*/
@SideOnly(Side.CLIENT)
public abstract class CustomModLoadingErrorDisplayException extends RuntimeException implements IFMLHandledException
{
/**
* Called after the GUI is inited by the parent code. You can do extra stuff here, maybe?
*
* @param errorScreen The error screen we're painting
* @param fontRenderer A font renderer for you
*/
public abstract void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer);
/**
* Draw your error to the screen.
*
* <br/><em>Warning: Minecraft is in a deep error state.</em> <strong>All</strong> it can do is stop.
* Do not try and do anything involving complex user interaction here.
*
* @param errorScreen The error screen to draw to
* @param fontRenderer A font renderer for you
* @param mouseRelX Mouse X
* @param mouseRelY Mouse Y
* @param tickTime tick time
*/
public abstract void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime);
}
File diff suppressed because it is too large. Load diff
+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 net.minecraft.src.RenderEngine;
import net.minecraft.src.TextureFX;
import net.minecraft.src.ITexturePack;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
public class FMLTextureFX extends TextureFX implements ITextureFX
{
public int tileSizeBase = 16;
public int tileSizeSquare = 256;
public int tileSizeMask = 15;
public int tileSizeSquareMask = 255;
public boolean errored = false;
protected Logger log = FMLLog.getLogger();
public FMLTextureFX(int icon)
{
super(icon);
}
@Override public void setErrored(boolean err){ errored = err; }
@Override public boolean getErrored(){ return errored; }
@Override
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions)
{
onTextureDimensionsUpdate(dimensions.width, dimensions.height);
}
@Override
public void onTextureDimensionsUpdate(int width, int height)
{
tileSizeBase = width >> 4;
tileSizeSquare = tileSizeBase * tileSizeBase;
tileSizeMask = tileSizeBase - 1;
tileSizeSquareMask = tileSizeSquare - 1;
setErrored(false);
setup();
}
protected void setup()
{
field_76852_a = new byte[tileSizeSquare << 2];
}
public boolean unregister(RenderEngine engine, List<TextureFX> effects)
{
effects.remove(this);
return true;
}
}
@@ -0,0 +1,26 @@
package cpw.mods.fml.client;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.WrongMinecraftVersionException;
import net.minecraft.src.GuiErrorScreen;
public class GuiCustomModLoadingErrorScreen extends GuiErrorScreen
{
private CustomModLoadingErrorDisplayException customException;
public GuiCustomModLoadingErrorScreen(CustomModLoadingErrorDisplayException customException)
{
this.customException = customException;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
this.customException.initGui(this, field_73886_k);
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
this.customException.drawScreen(this, field_73886_k, p_73863_1_, p_73863_2_, p_73863_3_);
}
}
@@ -0,0 +1,44 @@
package cpw.mods.fml.client;
import java.io.File;
import java.util.Map.Entry;
import cpw.mods.fml.common.DuplicateModsFoundException;
import cpw.mods.fml.common.MissingModsException;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import net.minecraft.src.GuiErrorScreen;
public class GuiDupesFound extends GuiErrorScreen
{
private DuplicateModsFoundException dupes;
public GuiDupesFound(DuplicateModsFoundException dupes)
{
this.dupes = dupes;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = Math.max(85 - dupes.dupes.size() * 10, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "You have mod sources that are duplicate within your system", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "Mod Id : File name", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
for (Entry<ModContainer, File> mc : dupes.dupes.entries())
{
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s : %s", mc.getKey().getModId(), mc.getValue().getName()), this.field_73880_f / 2, offset, 0xEEEEEE);
}
}
}
+66 -57
View File
@@ -16,15 +16,7 @@ package cpw.mods.fml.client;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.common.FMLModContainer;
import cpw.mods.fml.common.FMLModLoaderContainer;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.client.Minecraft;
import net.minecraft.src.FontRenderer;
import net.minecraft.src.GuiButton;
@@ -33,13 +25,19 @@ import net.minecraft.src.GuiSmallButton;
import net.minecraft.src.StringTranslate;
import net.minecraft.src.Tessellator;
import org.lwjgl.opengl.GL11;
import com.google.common.base.Strings;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
/**
* @author cpw
*
*/
public class GuiModList extends GuiScreen
{
private GuiScreen mainMenu;
private GuiSlotModList modList;
private int selected = -1;
@@ -48,105 +46,120 @@ public class GuiModList extends GuiScreen
private ArrayList<ModContainer> mods;
/**
* @param guiMainMenu
* @param mainMenu
*/
public GuiModList(GuiScreen mainMenu)
{
this.mainMenu=mainMenu;
this.mods=new ArrayList<ModContainer>();
FMLClientHandler.instance().addSpecialModEntries(mods);
for (ModContainer mod : Loader.getModList()) {
if (mod.getMetadata()!=null && mod.getMetadata().parentMod != null) {
continue;
for (ModContainer mod : Loader.instance().getModList()) {
if (mod.getMetadata()!=null && !Strings.isNullOrEmpty(mod.getMetadata().parent)) {
String parentMod = mod.getMetadata().parent;
ModContainer parentContainer = Loader.instance().getIndexedModList().get(parentMod);
if (parentContainer != null)
{
mod.getMetadata().parentMod = parentContainer;
parentContainer.getMetadata().childMods.add(mod);
continue;
}
}
mods.add(mod);
}
}
public void func_6448_a()
@Override
public void func_73866_w_()
{
for (ModContainer mod : mods) {
listWidth=Math.max(listWidth,getFontRenderer().func_871_a(mod.getName()) + 10);
listWidth=Math.max(listWidth,getFontRenderer().func_871_a(mod.getVersion()) + 10);
listWidth=Math.max(listWidth,getFontRenderer().func_78256_a(mod.getName()) + 10);
listWidth=Math.max(listWidth,getFontRenderer().func_78256_a(mod.getVersion()) + 10);
}
listWidth=Math.min(listWidth, 150);
StringTranslate translations = StringTranslate.func_20162_a();
this.field_949_e.add(new GuiSmallButton(6, this.field_951_c / 2 - 75, this.field_950_d - 38, translations.func_20163_a("gui.done")));
StringTranslate translations = StringTranslate.func_74808_a();
this.field_73887_h.add(new GuiSmallButton(6, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
this.modList=new GuiSlotModList(this, mods, listWidth);
this.modList.registerScrollButtons(this.field_949_e, 7, 8);
this.modList.registerScrollButtons(this.field_73887_h, 7, 8);
}
protected void func_572_a(GuiButton button) {
if (button.field_937_g)
@Override
protected void func_73875_a(GuiButton button) {
if (button.field_73742_g)
{
switch (button.field_938_f)
switch (button.field_73741_f)
{
case 6:
this.field_945_b.func_6272_a(this.mainMenu);
this.field_73882_e.func_71373_a(this.mainMenu);
return;
}
}
super.func_572_a(button);
super.func_73875_a(button);
}
public int drawLine(String line, int offset, int shifty)
{
this.field_6451_g.func_873_b(line, offset, shifty, 0xd7edea);
this.field_73886_k.func_78276_b(line, offset, shifty, 0xd7edea);
return shifty + 10;
}
public void func_571_a(int p_571_1_, int p_571_2_, float p_571_3_)
@Override
public void func_73863_a(int p_571_1_, int p_571_2_, float p_571_3_)
{
this.modList.drawScreen(p_571_1_, p_571_2_, p_571_3_);
this.func_548_a(this.field_6451_g, "Mod List", this.field_951_c / 2, 16, 0xFFFFFF);
this.func_73732_a(this.field_73886_k, "Mod List", this.field_73880_f / 2, 16, 0xFFFFFF);
int offset = this.listWidth + 20;
if (selectedMod != null) {
if (selectedMod.getMetadata() != null) {
GL11.glEnable(GL11.GL_BLEND);
if (!selectedMod.getMetadata().autogenerated) {
int shifty = 35;
if (!selectedMod.getMetadata().logoFile.isEmpty())
{
int texture = this.field_945_b.field_6315_n.func_1070_a(selectedMod.getMetadata().logoFile);
int texture = this.field_73882_e.field_71446_o.func_78341_b(selectedMod.getMetadata().logoFile);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.field_945_b.field_6315_n.func_1076_b(texture);
Dimension dim = FMLClientHandler.instance().getTextureDimensions(texture);
this.field_73882_e.field_71446_o.func_78342_b(texture);
Dimension dim = TextureFXManager.instance().getTextureDimensions(texture);
int top = 32;
Tessellator tess = Tessellator.field_1512_a;
tess.func_977_b();
tess.func_983_a(offset, top + dim.height, field_923_k, 0, 1);
tess.func_983_a(offset + dim.width, top + dim.height, field_923_k, 1, 1);
tess.func_983_a(offset + dim.width, top, field_923_k, 1, 0);
tess.func_983_a(offset, top, field_923_k, 0, 0);
tess.func_982_a();
Tessellator tess = Tessellator.field_78398_a;
tess.func_78382_b();
tess.func_78374_a(offset, top + dim.height, field_73735_i, 0, 1);
tess.func_78374_a(offset + dim.width, top + dim.height, field_73735_i, 1, 1);
tess.func_78374_a(offset + dim.width, top, field_73735_i, 1, 0);
tess.func_78374_a(offset, top, field_73735_i, 0, 0);
tess.func_78381_a();
shifty += 65;
}
this.field_6451_g.func_50103_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
this.field_73886_k.func_78261_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
shifty += 12;
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getMetadata().version, selectedMod.getVersion()), offset, shifty);
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getDisplayVersion(), selectedMod.getVersion()), offset, shifty);
shifty = drawLine(String.format("Mod State: %s", Loader.instance().getModState(selectedMod)), offset, shifty);
if (!selectedMod.getMetadata().credits.isEmpty()) {
shifty = drawLine(String.format("Credits: %s", selectedMod.getMetadata().credits), offset, shifty);
}
shifty = drawLine(String.format("Authors: %s", selectedMod.getMetadata().getAuthorList()), offset, shifty);
shifty = drawLine(String.format("URL: %s", selectedMod.getMetadata().url), offset, shifty);
shifty = drawLine(selectedMod.getMetadata().childMods.isEmpty() ? "No child mods for this mod" : String.format("Child mods: %s", selectedMod.getMetadata().getChildModList()), offset, shifty);
this.getFontRenderer().func_27278_a(selectedMod.getMetadata().description, offset, shifty + 10, this.field_951_c - offset - 20, 0xDDDDDD);
this.getFontRenderer().func_78279_b(selectedMod.getMetadata().description, offset, shifty + 10, this.field_73880_f - offset - 20, 0xDDDDDD);
} else {
offset = ( this.listWidth + this.field_951_c ) / 2;
this.func_548_a(this.field_6451_g, selectedMod.getName(), offset, 35, 0xFFFFFF);
this.func_548_a(this.field_6451_g, String.format("Version: %s",selectedMod.getVersion()), offset, 45, 0xFFFFFF);
this.func_548_a(this.field_6451_g, "No mod information found", offset, 55, 0xDDDDDD);
this.func_548_a(this.field_6451_g, "Ask your mod author to provide a mod .info file", offset, 65, 0xDDDDDD);
offset = ( this.listWidth + this.field_73880_f ) / 2;
this.func_73732_a(this.field_73886_k, selectedMod.getName(), offset, 35, 0xFFFFFF);
this.func_73732_a(this.field_73886_k, String.format("Version: %s",selectedMod.getVersion()), offset, 45, 0xFFFFFF);
this.func_73732_a(this.field_73886_k, String.format("Mod State: %s",Loader.instance().getModState(selectedMod)), offset, 55, 0xFFFFFF);
this.func_73732_a(this.field_73886_k, "No mod information found", offset, 65, 0xDDDDDD);
this.func_73732_a(this.field_73886_k, "Ask your mod author to provide a mod mcmod.info file", offset, 75, 0xDDDDDD);
}
GL11.glDisable(GL11.GL_BLEND);
}
super.func_571_a(p_571_1_, p_571_2_, p_571_3_);
super.func_73863_a(p_571_1_, p_571_2_, p_571_3_);
}
Minecraft getMinecraftInstance() {
return field_945_b;
return field_73882_e;
}
FontRenderer getFontRenderer() {
return field_6451_g;
return field_73886_k;
}
/**
@@ -162,10 +175,6 @@ public class GuiModList extends GuiScreen
}
}
/**
* @param var1
* @return
*/
public boolean modIndexSelected(int var1)
{
return var1==selected;
@@ -0,0 +1,39 @@
package cpw.mods.fml.client;
import cpw.mods.fml.common.MissingModsException;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import net.minecraft.src.GuiErrorScreen;
public class GuiModsMissing extends GuiErrorScreen
{
private MissingModsException modsMissing;
public GuiModsMissing(MissingModsException modsMissing)
{
this.modsMissing = modsMissing;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = Math.max(85 - modsMissing.missingMods.size() * 10, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
for (ArtifactVersion v : modsMissing.missingMods)
{
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
}
offset+=20;
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
}
}
@@ -0,0 +1,52 @@
package cpw.mods.fml.client;
import net.minecraft.src.GuiButton;
import net.minecraft.src.GuiScreen;
import net.minecraft.src.GuiSmallButton;
import net.minecraft.src.StringTranslate;
import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class GuiModsMissingForServer extends GuiScreen
{
private ModMissingPacket modsMissing;
public GuiModsMissingForServer(ModMissingPacket modsMissing)
{
this.modsMissing = modsMissing;
}
@Override
public void func_73866_w_()
{
StringTranslate translations = StringTranslate.func_74808_a();
this.field_73887_h.add(new GuiSmallButton(1, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
}
@Override
protected void func_73875_a(GuiButton p_73875_1_)
{
if (p_73875_1_.field_73742_g && p_73875_1_.field_73741_f == 1)
{
FMLClientHandler.instance().getClient().func_71373_a(null);
}
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = Math.max(85 - modsMissing.getModList().size() * 10, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader could not connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
this.func_73732_a(this.field_73886_k, "They are required to play on this server", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 5;
for (ArtifactVersion v : modsMissing.getModList())
{
offset += 10;
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
}
super.func_73863_a(p_73863_1_, p_73863_2_, p_73863_3_);
}
}
@@ -1,6 +1,7 @@
package cpw.mods.fml.client;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.src.GuiButton;
import net.minecraft.src.Tessellator;
@@ -81,9 +82,10 @@ public abstract class GuiScrollingList
protected void func_27257_b(int p_27257_1_, int p_27257_2_) {}
public int func_27256_c(int p_27256_1_, int p_27256_2_)
{
int var3 = this.listWidth / 2 - 110;
int var4 = this.listWidth / 2 + 110;
int var3 = this.left + 1;
int var4 = this.left + this.listWidth - 7;
int var5 = p_27256_2_ - this.top - this.field_27261_r + (int)this.scrollDistance - 4;
int var6 = var5 / this.slotHeight;
return p_27256_1_ >= var3 && p_27256_1_ <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1;
@@ -117,15 +119,15 @@ public abstract class GuiScrollingList
public void actionPerformed(GuiButton button)
{
if (button.field_937_g)
if (button.field_73742_g)
{
if (button.field_938_f == this.scrollUpActionId)
if (button.field_73741_f == this.scrollUpActionId)
{
this.scrollDistance -= (float)(this.slotHeight * 2 / 3);
this.initialMouseClickY = -2.0F;
this.applyScrollLimits();
}
else if (button.field_938_f == this.scrollDownActionId)
else if (button.field_73741_f == this.scrollDownActionId)
{
this.scrollDistance += (float)(this.slotHeight * 2 / 3);
this.initialMouseClickY = -2.0F;
@@ -249,17 +251,17 @@ public abstract class GuiScrollingList
this.applyScrollLimits();
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_FOG);
Tessellator var18 = Tessellator.field_1512_a;
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_6315_n.func_1070_a("/gui/background.png"));
Tessellator var18 = Tessellator.field_78398_a;
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_71446_o.func_78341_b("/gui/background.png"));
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
float var17 = 32.0F;
var18.func_977_b();
var18.func_990_b(2105376);
var18.func_983_a((double)this.left, (double)this.bottom, 0.0D, (double)((float)this.left / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
var18.func_983_a((double)this.right, (double)this.bottom, 0.0D, (double)((float)this.right / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
var18.func_983_a((double)this.right, (double)this.top, 0.0D, (double)((float)this.right / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
var18.func_983_a((double)this.left, (double)this.top, 0.0D, (double)((float)this.left / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
var18.func_982_a();
var18.func_78382_b();
var18.func_78378_d(2105376);
var18.func_78374_a((double)this.left, (double)this.bottom, 0.0D, (double)((float)this.left / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
var18.func_78374_a((double)this.right, (double)this.bottom, 0.0D, (double)((float)this.right / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
var18.func_78374_a((double)this.right, (double)this.top, 0.0D, (double)((float)this.right / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
var18.func_78374_a((double)this.left, (double)this.top, 0.0D, (double)((float)this.left / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
var18.func_78381_a();
// boxRight = this.listWidth / 2 - 92 - 16;
var10 = this.top + 4 - (int)this.scrollDistance;
@@ -283,18 +285,18 @@ public abstract class GuiScrollingList
int var15 = boxRight;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glDisable(GL11.GL_TEXTURE_2D);
var18.func_977_b();
var18.func_990_b(8421504);
var18.func_983_a((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D);
var18.func_983_a((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D);
var18.func_990_b(0);
var18.func_983_a((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D);
var18.func_983_a((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D);
var18.func_982_a();
var18.func_78382_b();
var18.func_78378_d(8421504);
var18.func_78374_a((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D);
var18.func_78374_a((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D);
var18.func_78378_d(0);
var18.func_78374_a((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D);
var18.func_78374_a((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D);
var18.func_78381_a();
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
@@ -311,22 +313,22 @@ public abstract class GuiScrollingList
GL11.glDisable(GL11.GL_ALPHA_TEST);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glDisable(GL11.GL_TEXTURE_2D);
var18.func_977_b();
var18.func_6513_a(0, 0);
var18.func_983_a((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D);
var18.func_6513_a(0, 255);
var18.func_983_a((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D);
var18.func_982_a();
var18.func_977_b();
var18.func_6513_a(0, 255);
var18.func_983_a((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D);
var18.func_6513_a(0, 0);
var18.func_983_a((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D);
var18.func_982_a();
var18.func_78382_b();
var18.func_78384_a(0, 0);
var18.func_78374_a((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D);
var18.func_78384_a(0, 255);
var18.func_78374_a((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D);
var18.func_78381_a();
var18.func_78382_b();
var18.func_78384_a(0, 255);
var18.func_78374_a((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D);
var18.func_78384_a(0, 0);
var18.func_78374_a((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D);
var18.func_78381_a();
var19 = this.getContentHeight() - (this.bottom - this.top - 4);
if (var19 > 0)
@@ -350,27 +352,27 @@ public abstract class GuiScrollingList
var14 = this.top;
}
var18.func_977_b();
var18.func_6513_a(0, 255);
var18.func_983_a((double)scrollBarXStart, (double)this.bottom, 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)scrollBarXEnd, (double)this.bottom, 0.0D, 1.0D, 1.0D);
var18.func_983_a((double)scrollBarXEnd, (double)this.top, 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)scrollBarXStart, (double)this.top, 0.0D, 0.0D, 0.0D);
var18.func_982_a();
var18.func_977_b();
var18.func_6513_a(8421504, 255);
var18.func_983_a((double)scrollBarXStart, (double)(var14 + var13), 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)scrollBarXEnd, (double)(var14 + var13), 0.0D, 1.0D, 1.0D);
var18.func_983_a((double)scrollBarXEnd, (double)var14, 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
var18.func_982_a();
var18.func_977_b();
var18.func_6513_a(12632256, 255);
var18.func_983_a((double)scrollBarXStart, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D);
var18.func_983_a((double)(scrollBarXEnd - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D);
var18.func_983_a((double)(scrollBarXEnd - 1), (double)var14, 0.0D, 1.0D, 0.0D);
var18.func_983_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
var18.func_982_a();
var18.func_78382_b();
var18.func_78384_a(0, 255);
var18.func_78374_a((double)scrollBarXStart, (double)this.bottom, 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)scrollBarXEnd, (double)this.bottom, 0.0D, 1.0D, 1.0D);
var18.func_78374_a((double)scrollBarXEnd, (double)this.top, 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)scrollBarXStart, (double)this.top, 0.0D, 0.0D, 0.0D);
var18.func_78381_a();
var18.func_78382_b();
var18.func_78384_a(8421504, 255);
var18.func_78374_a((double)scrollBarXStart, (double)(var14 + var13), 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)scrollBarXEnd, (double)(var14 + var13), 0.0D, 1.0D, 1.0D);
var18.func_78374_a((double)scrollBarXEnd, (double)var14, 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
var18.func_78381_a();
var18.func_78382_b();
var18.func_78384_a(12632256, 255);
var18.func_78374_a((double)scrollBarXStart, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D);
var18.func_78374_a((double)(scrollBarXEnd - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D);
var18.func_78374_a((double)(scrollBarXEnd - 1), (double)var14, 0.0D, 1.0D, 0.0D);
var18.func_78374_a((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
var18.func_78381_a();
}
this.func_27257_b(mouseX, mouseY);
@@ -382,17 +384,17 @@ public abstract class GuiScrollingList
private void overlayBackground(int p_22239_1_, int p_22239_2_, int p_22239_3_, int p_22239_4_)
{
Tessellator var5 = Tessellator.field_1512_a;
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_6315_n.func_1070_a("/gui/background.png"));
Tessellator var5 = Tessellator.field_78398_a;
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_71446_o.func_78341_b("/gui/background.png"));
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
float var6 = 32.0F;
var5.func_977_b();
var5.func_6513_a(4210752, p_22239_4_);
var5.func_983_a(0.0D, (double)p_22239_2_, 0.0D, 0.0D, (double)((float)p_22239_2_ / var6));
var5.func_983_a((double)this.listWidth + 30, (double)p_22239_2_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_2_ / var6));
var5.func_6513_a(4210752, p_22239_3_);
var5.func_983_a((double)this.listWidth + 30, (double)p_22239_1_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_1_ / var6));
var5.func_983_a(0.0D, (double)p_22239_1_, 0.0D, 0.0D, (double)((float)p_22239_1_ / var6));
var5.func_982_a();
var5.func_78382_b();
var5.func_78384_a(4210752, p_22239_4_);
var5.func_78374_a(0.0D, (double)p_22239_2_, 0.0D, 0.0D, (double)((float)p_22239_2_ / var6));
var5.func_78374_a((double)this.listWidth + 30, (double)p_22239_2_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_2_ / var6));
var5.func_78384_a(4210752, p_22239_3_);
var5.func_78374_a((double)this.listWidth + 30, (double)p_22239_1_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_1_ / var6));
var5.func_78374_a(0.0D, (double)p_22239_1_, 0.0D, 0.0D, (double)((float)p_22239_1_ / var6));
var5.func_78381_a();
}
}
+18 -13
View File
@@ -16,14 +16,10 @@ package cpw.mods.fml.client;
import java.util.ArrayList;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
import net.minecraft.client.Minecraft;
import net.minecraft.src.GuiLanguage;
import net.minecraft.src.GuiSlot;
import net.minecraft.src.StringTranslate;
import net.minecraft.src.Tessellator;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.ModContainer;
/**
* @author cpw
@@ -36,7 +32,7 @@ public class GuiSlotModList extends GuiScrollingList
public GuiSlotModList(GuiModList parent, ArrayList<ModContainer> mods, int listWidth)
{
super(parent.getMinecraftInstance(), listWidth, parent.field_950_d, 32, parent.field_950_d - 65 + 4, 10, 35);
super(parent.getMinecraftInstance(), listWidth, parent.field_73881_g, 32, parent.field_73881_g - 65 + 4, 10, 35);
this.parent=parent;
this.mods=mods;
}
@@ -62,7 +58,7 @@ public class GuiSlotModList extends GuiScrollingList
@Override
protected void drawBackground()
{
this.parent.func_578_i();
this.parent.func_73873_v_();
}
@Override
@@ -70,14 +66,23 @@ public class GuiSlotModList extends GuiScrollingList
{
return (this.getSize()) * 35 + 1;
}
@Override
protected void drawSlot(int listIndex, int var2, int var3, int var4, Tessellator var5)
{
ModContainer mc=mods.get(listIndex);
this.parent.getFontRenderer().func_873_b(this.parent.getFontRenderer().func_50107_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFFFFFF);
this.parent.getFontRenderer().func_873_b(this.parent.getFontRenderer().func_50107_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_873_b(this.parent.getFontRenderer().func_50107_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 9), this.left + 3 , var3 + 22, 0xCCCCCC);
if (Loader.instance().getModState(mc)==ModState.DISABLED)
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 10), this.left + 3 , var3 + 22, 0xFF2222);
}
else
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFFFFFF);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 10), this.left + 3 , var3 + 22, 0xCCCCCC);
}
}
}
@@ -0,0 +1,35 @@
package cpw.mods.fml.client;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.WrongMinecraftVersionException;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import net.minecraft.src.GuiErrorScreen;
import net.minecraft.src.GuiScreen;
public class GuiWrongMinecraft extends GuiErrorScreen
{
private WrongMinecraftVersionException wrongMC;
public GuiWrongMinecraft(WrongMinecraftVersionException wrongMC)
{
this.wrongMC = wrongMC;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = 75;
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("The mod listed below does not want to run in Minecraft version %s", Loader.instance().getMinecraftModContainer().getVersion()), this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s (%s) wants Minecraft %s", wrongMC.mod.getName(), wrongMC.mod.getModId(), wrongMC.mod.acceptableMinecraftVersionRange()), this.field_73880_f / 2, offset, 0xEEEEEE);
offset+=20;
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
}
}
+31 -30
View File
@@ -1,30 +1,31 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.client;
import java.awt.Dimension;
import net.minecraft.src.*;
public interface ITextureFX
{
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions);
public void onTextureDimensionsUpdate(int width, int height);
public void setErrored(boolean errored);
public boolean getErrored();
}
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.client;
import java.awt.Dimension;
import net.minecraft.src.RenderEngine;
import net.minecraft.src.ITexturePack;
public interface ITextureFX
{
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions);
public void onTextureDimensionsUpdate(int width, int height);
public void setErrored(boolean errored);
public boolean getErrored();
}
@@ -1,74 +0,0 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.client;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import net.minecraft.src.KeyBinding;
import cpw.mods.fml.common.IKeyHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
/**
* @author cpw
*
*/
public class KeyBindingHandler implements IKeyHandler
{
private boolean shouldRepeat;
private KeyBinding keyBinding;
private ModContainer modContainer;
private boolean lastState = false;
/**
* @param keyHandler
* @param allowRepeat
* @param modContainer
*/
public KeyBindingHandler(KeyBinding keyHandler, boolean allowRepeat, ModContainer modContainer)
{
this.keyBinding=keyHandler;
this.shouldRepeat=allowRepeat;
this.modContainer=modContainer;
}
@Override
public Object getKeyBinding()
{
return this.keyBinding;
}
/**
* @return the modContainer
*/
public ModContainer getOwningContainer()
{
return modContainer;
}
@Override
public void onEndTick()
{
int keyCode = keyBinding.field_1370_b;
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state && (!lastState || (lastState && shouldRepeat)))
{
modContainer.keyBindEvent(keyBinding);
}
lastState = state;
}
}
@@ -1,69 +0,0 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.client;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import cpw.mods.fml.common.FMLModContainer;
import cpw.mods.fml.common.IConsoleHandler;
import cpw.mods.fml.common.ICraftingHandler;
import cpw.mods.fml.common.IDispenseHandler;
import cpw.mods.fml.common.IKeyHandler;
import cpw.mods.fml.common.INetworkHandler;
import cpw.mods.fml.common.IPickupNotifier;
import cpw.mods.fml.common.IPlayerTracker;
import cpw.mods.fml.common.IWorldGenerator;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
/**
* @author cpw
*
*/
public class OptifineModContainer extends FMLModContainer
{
private String optifineVersion;
private ModMetadata metadata;
/**
* @param optifineConfig
*/
public OptifineModContainer(Class<?> optifineConfig)
{
super("Optifine");
try
{
optifineVersion = (String) optifineConfig.getField("VERSION").get(null);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
@Override
public String getName()
{
return "Optifine";
}
@Override
public String getVersion()
{
return optifineVersion;
}
}
+26 -31
View File
@@ -16,11 +16,10 @@ package cpw.mods.fml.client;
import java.util.BitSet;
import java.util.HashMap;
import java.util.logging.Level;
import net.minecraft.src.ModLoader;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.FMLLog;
/**
* @author cpw
@@ -31,9 +30,12 @@ public class SpriteHelper
private static HashMap<String, BitSet> spriteInfo = new HashMap<String, BitSet>();
private static void initMCSpriteMaps() {
BitSet slots =
BitSet slots =
SpriteHelper.toBitSet(
"0000000000000000" +
"0000000000110000" +
"0000000000100000" +
"0000000001100000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
@@ -41,16 +43,13 @@ public class SpriteHelper
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000011111" +
"0000000000000000" +
"0000000000000000" +
"0000000011111100" +
"0000000011111111" +
"0000000011111000" +
"0000000111111100" +
"0000000111111000" +
"0000000001111100" +
"0000000001111000" +
"0000000000000000");
spriteInfo.put("/terrain.png", slots);
slots = SpriteHelper.toBitSet(
"0000000000000000" +
"0000000000000000" +
@@ -58,23 +57,23 @@ public class SpriteHelper
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000001000000000" +
"0000001110000000" +
"0000001000000000" +
"1111111010000000" +
"1111111010100000" +
"1111111111111100" +
"1111111111111111" +
"1111111111111111" +
"1111111111111111" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0111100000000000" +
"1111100010000000" +
"0000101110000000" +
"0111000000000000" +
"1100001100001111" +
"0000000000001111" +
"0000000000000000");
spriteInfo.put("/gui/items.png", slots);
}
/**
* Register a sprite map for ModTextureStatic, to allow for other mods to override
* your sprite page.
*
*
*
*
*/
public static void registerSpriteMapForFile(String file, String spriteMap) {
if (spriteInfo.size() == 0) {
@@ -86,20 +85,20 @@ public class SpriteHelper
}
spriteInfo.put(file, toBitSet(spriteMap));
}
public static int getUniqueSpriteIndex(String path)
{
if (!spriteInfo.containsKey("/terrain.png"))
{
initMCSpriteMaps();
}
BitSet slots = spriteInfo.get(path);
if (slots == null)
{
Exception ex = new Exception(String.format("Invalid getUniqueSpriteIndex call for texture: %s", path));
Loader.log.throwing("ModLoader", "getUniqueSpriteIndex", ex);
FMLLog.log(Level.SEVERE, ex, "A critical error has been detected with sprite overrides");
FMLCommonHandler.instance().raiseException(ex,"Invalid request to getUniqueSpriteIndex",true);
}
@@ -108,7 +107,7 @@ public class SpriteHelper
if (ret == -1)
{
Exception ex = new Exception(String.format("No more sprite indicies left for: %s", path));
Loader.log.throwing("ModLoader", "getUniqueSpriteIndex", ex);
FMLLog.log(Level.SEVERE, ex, "There are no sprite indicies left for %s", path);
FMLCommonHandler.instance().raiseException(ex,"No more sprite indicies left", true);
}
return ret;
@@ -131,10 +130,6 @@ public class SpriteHelper
return next;
}
/**
* @param textureToOverride
* @return
*/
public static int freeSlotCount(String textureToOverride)
{
return spriteInfo.get(textureToOverride).cardinality();
@@ -0,0 +1,323 @@
package cpw.mods.fml.client;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_BINDING_2D;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.src.ModTextureStatic;
import net.minecraft.src.RenderEngine;
import net.minecraft.src.TextureFX;
import net.minecraft.src.ITexturePack;
import org.lwjgl.opengl.GL11;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.ModContainer;
public class TextureFXManager
{
private static final TextureFXManager INSTANCE = new TextureFXManager();
private class TextureProperties
{
private int textureId;
private Dimension dim;
}
private Map<Integer,TextureProperties> textureProperties = Maps.newHashMap();
private Multimap<String, OverrideInfo> overrideInfo = ArrayListMultimap.create();
private HashSet<OverrideInfo> animationSet = new HashSet<OverrideInfo>();
private List<TextureFX> addedTextureFX = new ArrayList<TextureFX>();
private Minecraft client;
void setClient(Minecraft client)
{
this.client = client;
}
public boolean onUpdateTextureEffect(TextureFX effect)
{
ITextureFX ifx = (effect instanceof ITextureFX ? ((ITextureFX)effect) : null);
if (ifx != null && ifx.getErrored())
{
return false;
}
String name = effect.getClass().getSimpleName();
client.field_71424_I.func_76320_a(name);
try
{
if (!FMLClientHandler.instance().hasOptifine())
{
effect.func_76846_a();
}
}
catch (Exception e)
{
FMLLog.warning("Texture FX %s has failed to animate. Likely caused by a texture pack change that they did not respond correctly to", name);
if (ifx != null)
{
ifx.setErrored(true);
}
client.field_71424_I.func_76319_b();
return false;
}
client.field_71424_I.func_76319_b();
if (ifx != null)
{
Dimension dim = getTextureDimensions(effect);
int target = ((dim.width >> 4) * (dim.height >> 4)) << 2;
if (effect.field_76852_a.length != target)
{
FMLLog.warning("Detected a texture FX sizing discrepancy in %s (%d, %d)", name, effect.field_76852_a.length, target);
ifx.setErrored(true);
return false;
}
}
return true;
}
//Quick and dirty image scaling, no smoothing or fanciness, meant for speed as it will be called every tick.
public void scaleTextureFXData(byte[] data, ByteBuffer buf, int target, int length)
{
int sWidth = (int)Math.sqrt(data.length / 4);
int factor = target / sWidth;
byte[] tmp = new byte[4];
buf.clear();
if (factor > 1)
{
for (int y = 0; y < sWidth; y++)
{
int sRowOff = sWidth * y;
int tRowOff = target * y * factor;
for (int x = 0; x < sWidth; x++)
{
int sPos = (x + sRowOff) * 4;
tmp[0] = data[sPos + 0];
tmp[1] = data[sPos + 1];
tmp[2] = data[sPos + 2];
tmp[3] = data[sPos + 3];
int tPosTop = (x * factor) + tRowOff;
for (int y2 = 0; y2 < factor; y2++)
{
buf.position((tPosTop + (y2 * target)) * 4);
for (int x2 = 0; x2 < factor; x2++)
{
buf.put(tmp);
}
}
}
}
}
buf.position(0).limit(length);
}
public void onPreRegisterEffect(TextureFX effect)
{
Dimension dim = getTextureDimensions(effect);
if (effect instanceof ITextureFX)
{
((ITextureFX)effect).onTextureDimensionsUpdate(dim.width, dim.height);
}
}
public int getEffectTexture(TextureFX effect)
{
Integer id = effectTextures.get(effect);
if (id != null)
{
return id;
}
int old = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
effect.func_76845_a(client.field_71446_o);
id = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
GL11.glBindTexture(GL_TEXTURE_2D, old);
effectTextures.put(effect, id);
return id;
}
public void onTexturePackChange(RenderEngine engine, ITexturePack texturepack, List<TextureFX> effects)
{
pruneOldTextureFX(texturepack, effects);
for (TextureFX tex : effects)
{
if (tex instanceof ITextureFX)
{
((ITextureFX)tex).onTexturePackChanged(engine, texturepack, getTextureDimensions(tex));
}
}
loadTextures(texturepack);
}
private HashMap<Integer, Dimension> textureDims = new HashMap<Integer, Dimension>();
private IdentityHashMap<TextureFX, Integer> effectTextures = new IdentityHashMap<TextureFX, Integer>();
private ITexturePack earlyTexturePack;
public void setTextureDimensions(int id, int width, int height, List<TextureFX> effects)
{
Dimension dim = new Dimension(width, height);
textureDims.put(id, dim);
for (TextureFX tex : effects)
{
if (getEffectTexture(tex) == id && tex instanceof ITextureFX)
{
((ITextureFX)tex).onTextureDimensionsUpdate(width, height);
}
}
}
public Dimension getTextureDimensions(TextureFX effect)
{
return getTextureDimensions(getEffectTexture(effect));
}
public Dimension getTextureDimensions(int id)
{
return textureDims.get(id);
}
public void addAnimation(TextureFX anim)
{
OverrideInfo info=new OverrideInfo();
info.index=anim.field_76850_b;
info.imageIndex=anim.field_76847_f;
info.textureFX=anim;
if (animationSet.contains(info)) {
animationSet.remove(info);
}
animationSet.add(info);
}
public void loadTextures(ITexturePack texturePack)
{
registerTextureOverrides(client.field_71446_o);
}
public void registerTextureOverrides(RenderEngine renderer) {
for (OverrideInfo animationOverride : animationSet) {
renderer.func_78355_a(animationOverride.textureFX);
addedTextureFX.add(animationOverride.textureFX);
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Registered texture override %d (%d) on %s (%d)", animationOverride.index, animationOverride.textureFX.field_76850_b, animationOverride.textureFX.getClass().getSimpleName(), animationOverride.textureFX.field_76847_f));
}
for (String fileToOverride : overrideInfo.keySet()) {
for (OverrideInfo override : overrideInfo.get(fileToOverride)) {
try
{
BufferedImage image=loadImageFromTexturePack(renderer, override.override);
ModTextureStatic mts=new ModTextureStatic(override.index, 1, override.texture, image);
renderer.func_78355_a(mts);
addedTextureFX.add(mts);
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Registered texture override %d (%d) on %s (%d)", override.index, mts.field_76850_b, override.texture, mts.field_76847_f));
}
catch (IOException e)
{
FMLCommonHandler.instance().getFMLLogger().throwing("FMLClientHandler", "registerTextureOverrides", e);
}
}
}
}
protected void registerAnimatedTexturesFor(ModContainer mod)
{
}
public void onEarlyTexturePackLoad(ITexturePack fallback)
{
if (client==null) {
// We're far too early- let's wait
this.earlyTexturePack = fallback;
} else {
loadTextures(fallback);
}
}
public void pruneOldTextureFX(ITexturePack var1, List<TextureFX> effects)
{
ListIterator<TextureFX> li = addedTextureFX.listIterator();
while (li.hasNext())
{
TextureFX tex = li.next();
if (tex instanceof FMLTextureFX)
{
if (((FMLTextureFX)tex).unregister(client.field_71446_o, effects))
{
li.remove();
}
}
else
{
effects.remove(tex);
li.remove();
}
}
}
public void addNewTextureOverride(String textureToOverride, String overridingTexturePath, int location) {
OverrideInfo info = new OverrideInfo();
info.index = location;
info.override = overridingTexturePath;
info.texture = textureToOverride;
overrideInfo.put(textureToOverride, info);
FMLLog.fine("Overriding %s @ %d with %s. %d slots remaining",textureToOverride, location, overridingTexturePath, SpriteHelper.freeSlotCount(textureToOverride));
}
public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
{
InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
if (image==null) {
throw new RuntimeException(String.format("The requested image path %s is not found",path));
}
BufferedImage result=ImageIO.read(image);
if (result==null)
{
throw new RuntimeException(String.format("The requested image path %s appears to be corrupted",path));
}
return result;
}
public static TextureFXManager instance()
{
return INSTANCE;
}
}
@@ -12,41 +12,42 @@
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.client;
package cpw.mods.fml.client.modloader;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Block;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.RenderBlocks;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
/**
* @author cpw
*
*/
public class BlockRenderInfo
public class ModLoaderBlockRendererHandler implements ISimpleBlockRenderingHandler
{
private int renderId;
private boolean render3dInInventory;
private ModContainer modContainer;
private BaseMod mod;
/**
* @param modContainer
*
* @param mod
*
*/
public BlockRenderInfo(int renderId, boolean render3dInInventory, ModContainer modContainer)
public ModLoaderBlockRendererHandler(int renderId, boolean render3dInInventory, BaseMod mod)
{
this.renderId=renderId;
this.render3dInInventory=render3dInInventory;
this.modContainer=modContainer;
this.mod=mod;
}
@Override
public int getRenderId()
{
return renderId;
}
@Override
public boolean shouldRender3DInInventory()
{
return render3dInInventory;
@@ -61,9 +62,10 @@ public class BlockRenderInfo
* @param modelId
* @param renderer
*/
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
{
return ((BaseMod)modContainer.getMod()).renderWorldBlock(renderer, world, x, y, z, block, modelId);
return mod.renderWorldBlock(renderer, world, x, y, z, block, modelId);
}
/**
@@ -72,9 +74,10 @@ public class BlockRenderInfo
* @param modelID
* @param renderer
*/
@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer)
{
((BaseMod)modContainer.getMod()).renderInvBlock(renderer, block, metadata, modelID);
mod.renderInvBlock(renderer, block, metadata, modelID);
}
}
@@ -0,0 +1,177 @@
package cpw.mods.fml.client.modloader;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import net.minecraft.client.Minecraft;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityClientPlayerMP;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.KeyBinding;
import net.minecraft.src.NetClientHandler;
import net.minecraft.src.NetHandler;
import net.minecraft.src.INetworkManager;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.Render;
import net.minecraft.src.RenderManager;
import com.google.common.base.Equivalences;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.modloader.BaseModProxy;
import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
import cpw.mods.fml.common.modloader.ModLoaderHelper;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
public class ModLoaderClientHelper implements IModLoaderSidedHelper
{
public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
{
int renderId=RenderingRegistry.getNextAvailableRenderId();
ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
RenderingRegistry.registerBlockHandler(bri);
return renderId;
}
public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
{
FMLLog.finer("Handling post startup activities for ModLoader mod %s", mc.getModId());
BaseMod mod = (BaseMod) mc.getMod();
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.field_78727_a.field_78729_o);
try
{
FMLLog.finest("Requesting renderers from basemod %s", mc.getModId());
mod.addRenderer(renderers);
FMLLog.finest("Received %d renderers from basemod %s", renderers.size(), mc.getModId());
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the addRenderer call. Continuing, but expect odd results", mc.getModId());
}
MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.field_78727_a.field_78729_o, renderers, Equivalences.identity());
for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
{
FMLLog.warning("The mod %s attempted to remove an entity renderer %s from the entity map. This will be ignored.", mc.getModId(), e.getKey().getName());
}
for (Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnRight().entrySet())
{
FMLLog.finest("Registering ModLoader entity renderer %s as instance of %s", e.getKey().getName(), e.getValue().getClass().getName());
RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue());
}
for (Entry<Class<? extends Entity>, ValueDifference<Render>> e : difference.entriesDiffering().entrySet())
{
FMLLog.finest("Registering ModLoader entity rendering override for %s as instance of %s", e.getKey().getName(), e.getValue().rightValue().getClass().getName());
RenderingRegistry.registerEntityRenderingHandler(e.getKey(), e.getValue().rightValue());
}
try
{
mod.registerAnimation(game);
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "A severe problem was detected with the mod %s during the registerAnimation call. Continuing, but expect odd results", mc.getModId());
}
}
public ModLoaderClientHelper(Minecraft client)
{
this.client = client;
ModLoaderHelper.sidedHelper = this;
keyBindingContainers = Multimaps.newMultimap(Maps.<ModLoaderModContainer, Collection<ModLoaderKeyBindingHandler>>newHashMap(), new Supplier<Collection<ModLoaderKeyBindingHandler>>()
{
@Override
public Collection<ModLoaderKeyBindingHandler> get()
{
return Collections.singleton(new ModLoaderKeyBindingHandler());
}
});
}
private Minecraft client;
private static Multimap<ModLoaderModContainer, ModLoaderKeyBindingHandler> keyBindingContainers;
@Override
public void finishModLoading(ModLoaderModContainer mc)
{
handleFinishLoadingFor(mc, client);
}
public static void registerKeyBinding(BaseModProxy mod, KeyBinding keyHandler, boolean allowRepeat)
{
ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
ModLoaderKeyBindingHandler handler = Iterables.getOnlyElement(keyBindingContainers.get(mlmc));
handler.setModContainer(mlmc);
handler.addKeyBinding(keyHandler, allowRepeat);
KeyBindingRegistry.registerKeyBinding(handler);
}
@Override
public Object getClientGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
{
return ((net.minecraft.src.BaseMod)mod).getContainerGUI((EntityClientPlayerMP) player, ID, x, y, z);
}
@Override
public Entity spawnEntity(BaseModProxy mod, EntitySpawnPacket input, EntityRegistration er)
{
return ((net.minecraft.src.BaseMod)mod).spawnEntity(er.getModEntityId(), client.field_71441_e, input.scaledX, input.scaledY, input.scaledZ);
}
@Override
public void sendClientPacket(BaseModProxy mod, Packet250CustomPayload packet)
{
((net.minecraft.src.BaseMod)mod).clientCustomPayload(client.field_71439_g.field_71174_a, packet);
}
private Map<INetworkManager,NetHandler> managerLookups = new MapMaker().weakKeys().weakValues().makeMap();
@Override
public void clientConnectionOpened(NetHandler netClientHandler, INetworkManager manager, BaseModProxy mod)
{
managerLookups.put(manager, netClientHandler);
((BaseMod)mod).clientConnect((NetClientHandler)netClientHandler);
}
@Override
public boolean clientConnectionClosed(INetworkManager manager, BaseModProxy mod)
{
if (managerLookups.containsKey(manager))
{
((BaseMod)mod).clientDisconnect((NetClientHandler) managerLookups.get(manager));
return true;
}
return false;
}
}
@@ -0,0 +1,112 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.client.modloader;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import org.lwjgl.input.Mouse;
import com.google.common.collect.ObjectArrays;
import com.google.common.primitives.Booleans;
import net.minecraft.src.KeyBinding;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
/**
* @author cpw
*
*/
public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
{
private ModLoaderModContainer modContainer;
private List<KeyBinding> helper;
private boolean[] active = new boolean[0];
private boolean[] mlRepeats = new boolean[0];
private boolean[] armed = new boolean[0];
public ModLoaderKeyBindingHandler()
{
super(new KeyBinding[0], new boolean[0]);
}
void setModContainer(ModLoaderModContainer modContainer)
{
this.modContainer = modContainer;
}
public void fireKeyEvent(KeyBinding kb)
{
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(kb);
}
@Override
public void keyDown(EnumSet<TickType> type, KeyBinding kb, boolean end, boolean repeats)
{
if (!end)
{
return;
}
int idx = helper.indexOf(kb);
if (type.contains(TickType.CLIENT))
{
armed[idx] = true;
}
if (armed[idx] && type.contains(TickType.RENDER) && (!active[idx] || mlRepeats[idx]))
{
fireKeyEvent(kb);
active[idx] = true;
armed[idx] = false;
}
}
@Override
public void keyUp(EnumSet<TickType> type, KeyBinding kb, boolean end)
{
if (!end)
{
return;
}
int idx = helper.indexOf(kb);
active[idx] = false;
}
@Override
public EnumSet<TickType> ticks()
{
return EnumSet.of(TickType.CLIENT, TickType.RENDER);
}
@Override
public String getLabel()
{
return modContainer.getModId() +" KB "+keyBindings[0].field_74512_d;
}
void addKeyBinding(KeyBinding binding, boolean repeats)
{
this.keyBindings = ObjectArrays.concat(this.keyBindings, binding);
this.repeatings = new boolean[this.keyBindings.length];
Arrays.fill(this.repeatings, true);
this.active = new boolean[this.keyBindings.length];
this.armed = new boolean[this.keyBindings.length];
this.mlRepeats = Booleans.concat(this.mlRepeats, new boolean[] { repeats });
this.keyDown = new boolean[this.keyBindings.length];
this.helper = Arrays.asList(this.keyBindings);
}
}
@@ -0,0 +1,29 @@
package cpw.mods.fml.client.registry;
import net.minecraft.src.TileEntity;
import net.minecraft.src.TileEntityRenderer;
import net.minecraft.src.TileEntitySpecialRenderer;
import cpw.mods.fml.common.registry.GameRegistry;
public class ClientRegistry
{
/**
*
* Utility method for registering a tile entity and it's renderer at once - generally you should register them separately
*
* @param tileEntityClass
* @param id
* @param specialRenderer
*/
public static void registerTileEntity(Class <? extends TileEntity > tileEntityClass, String id, TileEntitySpecialRenderer specialRenderer)
{
GameRegistry.registerTileEntity(tileEntityClass, id);
bindTileEntitySpecialRenderer(tileEntityClass, specialRenderer);
}
public static void bindTileEntitySpecialRenderer(Class <? extends TileEntity> tileEntityClass, TileEntitySpecialRenderer specialRenderer)
{
TileEntityRenderer.field_76963_a.field_76966_m.put(tileEntityClass, specialRenderer);
specialRenderer.func_76893_a(TileEntityRenderer.field_76963_a);
}
}
@@ -0,0 +1,16 @@
package cpw.mods.fml.client.registry;
import net.minecraft.src.Block;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.RenderBlocks;
public interface ISimpleBlockRenderingHandler
{
public abstract void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer);
public abstract boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer);
public abstract boolean shouldRender3DInInventory();
public abstract int getRenderId();
}
@@ -0,0 +1,187 @@
package cpw.mods.fml.client.registry;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Set;
import net.minecraft.src.GameSettings;
import net.minecraft.src.KeyBinding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.registry.TickRegistry;
public class KeyBindingRegistry
{
/**
* Register a KeyHandler to the game. This handler will be called on certain tick events
* if any of its key is inactive or has recently changed state
*
* @param handler
*/
public static void registerKeyBinding(KeyHandler handler) {
instance().keyHandlers.add(handler);
if (!handler.isDummy)
{
TickRegistry.registerTickHandler(handler, Side.CLIENT);
}
}
/**
* Extend this class to register a KeyBinding and recieve callback
* when the key binding is triggered
*
* @author cpw
*
*/
public static abstract class KeyHandler implements ITickHandler
{
protected KeyBinding[] keyBindings;
protected boolean[] keyDown;
protected boolean[] repeatings;
private boolean isDummy;
/**
* Pass an array of keybindings and a repeat flag for each one
*
* @param keyBindings
* @param repeatings
*/
public KeyHandler(KeyBinding[] keyBindings, boolean[] repeatings)
{
assert keyBindings.length == repeatings.length : "You need to pass two arrays of identical length";
this.keyBindings = keyBindings;
this.repeatings = repeatings;
this.keyDown = new boolean[keyBindings.length];
}
/**
* Register the keys into the system. You will do your own keyboard management elsewhere. No events will fire
* if you use this method
*
* @param keyBindings
*/
public KeyHandler(KeyBinding[] keyBindings)
{
this.keyBindings = keyBindings;
this.isDummy = true;
}
public KeyBinding[] getKeyBindings()
{
return this.keyBindings;
}
/**
* Not to be overridden - KeyBindings are tickhandlers under the covers
*/
@Override
public final void tickStart(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, false);
}
/**
* Not to be overridden - KeyBindings are tickhandlers under the covers
*/
@Override
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, true);
}
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
{
for (int i = 0; i < keyBindings.length; i++)
{
KeyBinding keyBinding = keyBindings[i];
int keyCode = keyBinding.field_74512_d;
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state != keyDown[i] || (state && repeatings[i]))
{
if (state)
{
keyDown(type, keyBinding, tickEnd, state!=keyDown[i]);
}
else
{
keyUp(type, keyBinding, tickEnd);
}
if (tickEnd)
{
keyDown[i] = state;
}
}
}
}
/**
* Called when the key is first in the down position on any tick from the {@link #ticks()}
* set. Will be called subsequently with isRepeat set to true
*
* @see #keyUp(EnumSet, KeyBinding, boolean)
*
* @param types the type(s) of tick that fired when this key was first down
* @param tickEnd was it an end or start tick which fired the key
* @param isRepeat is it a repeat key event
*/
public abstract void keyDown(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd, boolean isRepeat);
/**
* Fired once when the key changes state from down to up
*
* @see #keyDown(EnumSet, KeyBinding, boolean, boolean)
*
* @param types the type(s) of tick that fired when this key was first down
* @param tickEnd was it an end or start tick which fired the key
*/
public abstract void keyUp(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd);
/**
* This is the list of ticks for which the key binding should trigger. The only
* valid ticks are client side ticks, obviously.
*
* @see cpw.mods.fml.common.ITickHandler#ticks()
*/
public abstract EnumSet<TickType> ticks();
}
private static final KeyBindingRegistry INSTANCE = new KeyBindingRegistry();
private Set<KeyHandler> keyHandlers = Sets.newLinkedHashSet();
@Deprecated
public static KeyBindingRegistry instance()
{
return INSTANCE;
}
public void uploadKeyBindingsToGame(GameSettings settings)
{
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
for (KeyHandler key : keyHandlers)
{
for (KeyBinding kb : key.keyBindings)
{
harvestedBindings.add(kb);
}
}
KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]);
KeyBinding[] allKeys = new KeyBinding[settings.field_74324_K.length + modKeyBindings.length];
System.arraycopy(settings.field_74324_K, 0, allKeys, 0, settings.field_74324_K.length);
System.arraycopy(modKeyBindings, 0, allKeys, settings.field_74324_K.length, modKeyBindings.length);
settings.field_74324_K = allKeys;
settings.func_74300_a();
}
}
@@ -0,0 +1,169 @@
package cpw.mods.fml.client.registry;
import java.util.List;
import java.util.Map;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.Render;
import net.minecraft.src.RenderBiped;
import net.minecraft.src.RenderBlocks;
import net.minecraft.src.RenderManager;
import net.minecraft.src.RenderPlayer;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.ObjectArrays;
import cpw.mods.fml.client.SpriteHelper;
import cpw.mods.fml.client.TextureFXManager;
/**
* @author cpw
*
*/
public class RenderingRegistry
{
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
private int nextRenderId = 36;
private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
/**
* Add a new armour prefix to the RenderPlayer
*
* @param armor
*/
public static int addNewArmourRendererPrefix(String armor)
{
RenderPlayer.field_77110_j = ObjectArrays.concat(RenderPlayer.field_77110_j, armor);
RenderBiped.field_82424_k = RenderPlayer.field_77110_j;
return RenderPlayer.field_77110_j.length - 1;
}
/**
* Register an entity rendering handler. This will, after mod initialization, be inserted into the main
* render map for entities
*
* @param entityClass
* @param renderer
*/
public static void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
{
instance().entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
}
/**
* Register a simple block rendering handler
*
* @param handler
*/
public static void registerBlockHandler(ISimpleBlockRenderingHandler handler)
{
instance().blockRenderers.put(handler.getRenderId(), handler);
}
/**
* Register the simple block rendering handler
* This version will not call getRenderId on the passed in handler, instead using the supplied ID, so you
* can easily re-use the same rendering handler for multiple IDs
*
* @param renderId
* @param handler
*/
public static void registerBlockHandler(int renderId, ISimpleBlockRenderingHandler handler)
{
instance().blockRenderers.put(renderId, handler);
}
/**
* Get the next available renderId from the block render ID list
*/
public static int getNextAvailableRenderId()
{
return instance().nextRenderId++;
}
/**
* Add a texture override for the given path and return the used index
*
* @param fileToOverride
* @param fileToAdd
*/
public static int addTextureOverride(String fileToOverride, String fileToAdd)
{
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
addTextureOverride(fileToOverride, fileToAdd, idx);
return idx;
}
/**
* Add a texture override for the given path and index
*
* @param path
* @param overlayPath
* @param index
*/
public static void addTextureOverride(String path, String overlayPath, int index)
{
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
}
/**
* Get and reserve a unique texture index for the supplied path
*
* @param path
*/
public static int getUniqueTextureIndex(String path)
{
return SpriteHelper.getUniqueSpriteIndex(path);
}
@Deprecated public static RenderingRegistry instance()
{
return INSTANCE;
}
private static class EntityRendererInfo
{
public EntityRendererInfo(Class<? extends Entity> target, Render renderer)
{
this.target = target;
this.renderer = renderer;
}
private Class<? extends Entity> target;
private Render renderer;
}
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
{
if (!blockRenderers.containsKey(modelId)) { return false; }
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
return bri.renderWorldBlock(world, x, y, z, block, modelId, renderer);
}
public void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
if (!blockRenderers.containsKey(modelID)) { return; }
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelID);
bri.renderInventoryBlock(block, metadata, modelID, renderer);
}
public boolean renderItemAsFull3DBlock(int modelId)
{
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
return bri != null && bri.shouldRender3DInInventory();
}
public void loadEntityRenderers(Map<Class<? extends Entity>, Render> rendererMap)
{
for (EntityRendererInfo info : entityRenderers)
{
rendererMap.put(info.target, info.renderer);
info.renderer.func_76976_a(RenderManager.field_78727_a);
}
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

+116 -118
View File
@@ -12,58 +12,51 @@
*/
package net.minecraft.src;
import static cpw.mods.fml.common.Side.CLIENT;
import java.util.Map;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.IConsoleHandler;
import cpw.mods.fml.common.ICraftingHandler;
import cpw.mods.fml.common.IDispenseHandler;
import cpw.mods.fml.common.INetworkHandler;
import cpw.mods.fml.common.IPickupNotifier;
import cpw.mods.fml.common.IPlayerTracker;
import cpw.mods.fml.common.IWorldGenerator;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.asm.SideOnly;
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModProxy
{
// CALLBACK MECHANISMS
public void keyBindingEvent(Object keybinding)
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object... data)
{
this.keyboardEvent((KeyBinding)keybinding);
}
/**
* @param minecraftInstance
* @return
*/
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object minecraftInstance, Object... data)
{
Minecraft mc = (Minecraft) minecraftInstance;
boolean hasWorld = mc.field_6324_e != null;
Minecraft mc = FMLClientHandler.instance().getClient();
boolean hasWorld = mc.field_71441_e != null;
// World and render ticks
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.GAME ) && hasWorld) {
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT ) && hasWorld) {
return onTickInGame((Float) data[0], mc);
} else if (tickEnd && (tick==TickType.WORLDGUI || tick==TickType.GUI) && data[1]!=null) {
return onTickInGUI((Float) data[0], mc, (GuiScreen)data[1]);
}
return true;
}
/**
* @param renderers
*/
public final boolean doTickInGUI(TickType tick, boolean tickEnd, Object... data)
{
Minecraft mc = FMLClientHandler.instance().getClient();
boolean hasWorld = mc.field_71441_e != null;
if (tickEnd && ( tick==TickType.RENDER || ( tick==TickType.CLIENT && hasWorld))) {
return onTickInGUI((Float) data[0], mc, mc.field_71462_r);
}
return true;
}
/*
public final void onRenderHarvest(Map renderers)
{
addRenderer((Map<Class<? extends Entity>,Render>)renderers);
}
/**
*
*/
public final void onRegisterAnimations()
{
registerAnimation(FMLClientHandler.instance().getClient());
@@ -82,7 +75,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
}
@Override
public final boolean dispense(double x, double y, double z, byte xVelocity, byte zVelocity, Object... data)
public final boolean dispense(double x, double y, double z, int xVelocity, int zVelocity, Object... data)
{
return dispenseEntity((World)data[0], x, y, z, xVelocity, zVelocity, (ItemStack)data[1]);
}
@@ -90,7 +83,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
@Override
public final boolean onChat(Object... data)
{
receiveChatPacket(((Packet3Chat)data[0]).field_517_a);
receiveChatPacket(((Packet3Chat)data[0]).field_73476_b);
return true;
}
@@ -99,11 +92,11 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
public final void onServerLogin(Object handler) {
serverConnect((NetClientHandler) handler);
}
public final void onServerLogout() {
serverDisconnect();
}
@Override
public final void onPlayerLogin(Object player)
{
@@ -133,7 +126,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
{
EntityItem item = (EntityItem) pickupData[0];
EntityPlayer player = (EntityPlayer) pickupData[1];
onItemPickup(player, item.field_801_a);
onItemPickup(player, item.field_70294_a);
}
@Override
@@ -152,52 +145,33 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
}
}
/**
* NO-OP on client side
*/
@Override
public final boolean handleCommand(String command, Object... data)
{
return false;
}
*/
// BASEMOD API
/**
* Override if you wish to provide a fuel item for the furnace and return the fuel value of the item
*
*
* @param id
* @param metadata
* @return
*/
public int addFuel(int id, int metadata)
{
return 0;
}
@SideOnly(CLIENT)
public void addRenderer(Map<Class<? extends Entity>, Render> renderers)
{
}
/**
* Override if you wish to perform some action other than just dispensing the item from the dispenser
*
* @param world
* @param x
* @param y
* @param z
* @param xVel
* @param zVel
* @param item
* @return
*/
public boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
{
return false;
}
/**
* Override if you wish to generate Nether (Hell biome) blocks
*
*
* @param world
* @param random
* @param chunkX
@@ -209,7 +183,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Override if you wish to generate Overworld (not hell or the end) blocks
*
*
* @param world
* @param random
* @param chunkX
@@ -219,10 +193,22 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
{
}
/**
* Callback to return a gui screen to display
* @param player
* @param containerID
* @param x
* @param y
* @param z
*/
@SideOnly(CLIENT)
public GuiContainer getContainerGUI(EntityClientPlayerMP player, int containerID, int x, int y, int z)
{
return null;
}
/**
* Return the name of your mod. Defaults to the class name
*
* @return
*/
public String getName()
{
@@ -231,8 +217,6 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Get your mod priorities
*
* @return
*/
public String getPriorities()
{
@@ -241,11 +225,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Return the version of your mod
*
* @return
*/
public abstract String getVersion();
@SideOnly(CLIENT)
public void keyboardEvent(KeyBinding event)
{
@@ -265,7 +248,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Handle item pickup
*
*
* @param player
* @param item
*/
@@ -275,16 +258,23 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Ticked every game tick if you have subscribed to tick events through {@link ModLoader#setInGameHook(BaseMod, boolean, boolean)}
*
*
* @param time the rendering subtick time (0.0-1.0)
* @param minecraftInstance the client
* @return true to continue receiving ticks
*/
@SideOnly(CLIENT)
public boolean onTickInGame(float time, Minecraft minecraftInstance)
{
return false;
}
public boolean onTickInGame(MinecraftServer minecraftServer)
{
return false;
}
@SideOnly(CLIENT)
public boolean onTickInGUI(float tick, Minecraft game, GuiScreen gui)
{
return false;
@@ -292,52 +282,81 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
/**
* Only implemented on the client side
* {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)}
*
* {@link #serverChat(NetServerHandler, String)}
*
* @param text
*/
public void receiveChatPacket(String text)
@Override
public void clientChat(String text)
{
// TODO
}
/**
* Only called on the client side
* {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)}
*
* @param packet
* Called when a client connects
* @param handler
*/
public void receiveCustomPacket(Packet250CustomPayload packet)
@SideOnly(CLIENT)
public void clientConnect(NetClientHandler handler)
{
// TODO
}
/**
* Called when the client disconnects
* @param handler
*/
@SideOnly(CLIENT)
public void clientDisconnect(NetClientHandler handler)
{
}
/**
* Called client side to receive a custom payload for this mod
*
* @param packet
*/
@Override
public void receiveCustomPacket(Packet250CustomPayload packet)
{
}
@SideOnly(CLIENT)
public void registerAnimation(Minecraft game)
{
}
@SideOnly(CLIENT)
public void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
}
@SideOnly(CLIENT)
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
{
return false;
}
public void serverConnect(NetClientHandler handler) {
@Override
public void serverConnect(NetHandler handler) {
}
@Override
public void serverCustomPayload(NetServerHandler handler, Packet250CustomPayload packet)
{
}
@Override
public void serverDisconnect() {
}
/**
* Called when someone crafts an item from a crafting table
*
*
* @param player
* @param item
* @param matrix
@@ -365,63 +384,42 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseMod
return getName() + " " + getVersion();
}
/**
* Called when a 250 packet is received on a channel registered to this mod
*
* @param source
* @param payload
*/
public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload)
{
}
/**
* Called when a chat message is received. Return true to stop further processing
*
* @param source
* @param chat
* @return true if you want to consume the message so it is not available for further processing
*/
public boolean onChatMessageReceived(EntityPlayer source, Packet3Chat chat)
@Override
public void serverChat(NetServerHandler source, String message)
{
return false;
}
/**
* Called when a server command is received
* @param command
* @return true if you want to consume the message so it is not available for further processing
*/
public boolean onServerCommand(String command, String sender, Object listener)
{
return false;
}
/**
* Called when a new client logs in.
*
*
* @param player
*/
@Override
public void onClientLogin(EntityPlayer player)
{
}
/**
* Called when a client logs out of the server.
*
* @param player
*/
public void onClientLogout(EntityPlayer player)
@Override
public void onClientLogout(INetworkManager mgr)
{
}
/**
*
* Called when a client changes dimensions on the server.
*
* @param player
* Spawn the entity of the supplied type, if it is your mod's
*/
public void onClientDimensionChanged(EntityPlayer player)
@SideOnly(CLIENT)
public Entity spawnEntity(int entityId, World world, double scaledX, double scaledY, double scaledZ)
{
return null;
}
public void clientCustomPayload(NetClientHandler handler, Packet250CustomPayload packet)
{
}
@@ -1,166 +0,0 @@
package net.minecraft.src;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.registry.FMLRegistry;
import cpw.mods.fml.common.registry.IMinecraftRegistry;
public class ClientRegistry implements IMinecraftRegistry
{
public static ClientRegistry instance() {
return (ClientRegistry) FMLRegistry.instance();
}
@Override
public void addRecipe(ItemStack output, Object... params)
{
CraftingManager.func_1120_a().func_1121_a(output, params);
}
@Override
public void addShapelessRecipe(ItemStack output, Object... params)
{
CraftingManager.func_1120_a().func_21187_b(output, params);
}
@Override
public void addRecipe(IRecipe recipe)
{
CraftingManager.func_1120_a().func_25193_b().add(recipe);
}
@Override
public void addSmelting(int input, ItemStack output)
{
FurnaceRecipes.func_21200_a().func_21199_a(input, output);
}
@Override
public void registerBlock(Block block)
{
registerBlock(block, ItemBlock.class);
}
@Override
public void registerBlock(Block block, Class <? extends ItemBlock > itemclass)
{
try
{
assert block != null : "registerBlock: block cannot be null";
assert itemclass != null : "registerBlock: itemclass cannot be null";
int blockItemId = block.field_376_bc - 256;
itemclass.getConstructor(int.class).newInstance(blockItemId);
}
catch (Exception e)
{
//HMMM
}
}
@Override
public void registerEntityID(Class <? extends Entity > entityClass, String entityName, int id)
{
EntityList.addNewEntityListMapping(entityClass, entityName, id);
}
@Override
public void registerEntityID(Class <? extends Entity > entityClass, String entityName, int id, int backgroundEggColour, int foregroundEggColour)
{
EntityList.addNewEntityListMapping(entityClass, entityName, id, backgroundEggColour, foregroundEggColour);
}
@Override
public void registerTileEntity(Class <? extends TileEntity > tileEntityClass, String id)
{
TileEntity.addNewTileEntityMapping(tileEntityClass, id);
}
public void registerTileEntity(Class <? extends TileEntity > tileEntityClass, String id, TileEntitySpecialRenderer specialRenderer)
{
registerTileEntity(tileEntityClass, id);
TileEntityRenderer.setTileEntityRenderer(tileEntityClass, specialRenderer);
}
@Override
public void addBiome(BiomeGenBase biome)
{
FMLClientHandler.instance().addBiomeToDefaultWorldGenerator(biome);
}
@Override
public void addSpawn(Class <? extends EntityLiving > entityClass, int weightedProb, int min, int max, EnumCreatureType typeOfCreature, BiomeGenBase... biomes)
{
for (BiomeGenBase biome : biomes)
{
@SuppressWarnings("unchecked")
List<SpawnListEntry> spawns = biome.func_25063_a(typeOfCreature);
for (SpawnListEntry entry : spawns)
{
//Adjusting an existing spawn entry
if (entry.field_25212_a == entityClass)
{
entry.field_35590_d = weightedProb;
entry.field_35591_b = min;
entry.field_35592_c = max;
break;
}
}
spawns.add(new SpawnListEntry(entityClass, weightedProb, min, max));
}
}
@Override
@SuppressWarnings("unchecked")
public void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
{
Class <? extends Entity > entityClazz = EntityList.getEntityToClassMapping().get(entityName);
if (EntityLiving.class.isAssignableFrom(entityClazz))
{
addSpawn((Class <? extends EntityLiving >) entityClazz, weightedProb, min, max, spawnList, biomes);
}
}
@Override
public void removeBiome(BiomeGenBase biome)
{
FMLClientHandler.instance().removeBiomeFromDefaultWorldGenerator(biome);
}
@Override
public void removeSpawn(Class <? extends EntityLiving > entityClass, EnumCreatureType typeOfCreature, BiomeGenBase... biomes)
{
for (BiomeGenBase biome : biomes)
{
@SuppressWarnings("unchecked")
Iterator<SpawnListEntry> spawns = biome.func_25063_a(typeOfCreature).iterator();
while (spawns.hasNext())
{
SpawnListEntry entry = spawns.next();
if (entry.field_25212_a == entityClass)
{
spawns.remove();
}
}
}
}
@Override
@SuppressWarnings("unchecked")
public void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
{
Class <? extends Entity > entityClazz = EntityList.getEntityToClassMapping().get(entityName);
if (EntityLiving.class.isAssignableFrom(entityClazz))
{
removeSpawn((Class <? extends EntityLiving >) entityClazz, spawnList, biomes);
}
}
}
@@ -1,36 +1,36 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
import net.minecraft.client.Minecraft;
public class EntityRendererProxy extends EntityRenderer
{
private Minecraft game;
public EntityRendererProxy(Minecraft minecraft)
{
super(minecraft);
game = minecraft;
}
@Override
public void func_4136_b(float tick)
{
super.func_4136_b(tick);
//This is where ModLoader does all of it's ticking
}
}
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
import net.minecraft.client.Minecraft;
public class EntityRendererProxy extends EntityRenderer
{
public static final String fmlMarker = "This is an FML marker";
private Minecraft game;
public EntityRendererProxy(Minecraft minecraft)
{
super(minecraft);
game = minecraft;
}
@Override
public void func_78480_b(float tick)
{
super.func_78480_b(tick);
//This is where ModLoader does all of it's ticking
}
}
@@ -19,13 +19,14 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.client.TextureFXManager;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLLog;
/**
*
*
* A static hook library for optifine and other basemod editing code to access FML functions
*
*
* @author cpw
*
*/
@@ -33,56 +34,59 @@ public class FMLRenderAccessLibrary
{
public static Logger getLogger()
{
return FMLCommonHandler.instance().getFMLLogger();
return FMLLog.getLogger();
}
public static void log(Level level, String message)
{
getLogger().log(level, message);
FMLLog.log(level, message);
}
public static void log(Level level, String message, Throwable throwable)
{
getLogger().log(level, message, throwable);
FMLLog.log(level, throwable, message);
}
public static void setTextureDimensions(int textureId, int width, int height, List<TextureFX> textureFXList)
{
FMLClientHandler.instance().setTextureDimensions(textureId, width, height, textureFXList);
TextureFXManager.instance().setTextureDimensions(textureId, width, height, textureFXList);
}
public static void preRegisterEffect(TextureFX textureFX)
{
FMLClientHandler.instance().onPreRegisterEffect(textureFX);
TextureFXManager.instance().onPreRegisterEffect(textureFX);
}
public static boolean onUpdateTextureEffect(TextureFX textureFX)
{
return FMLClientHandler.instance().onUpdateTextureEffect(textureFX);
return TextureFXManager.instance().onUpdateTextureEffect(textureFX);
}
public static Dimension getTextureDimensions(TextureFX textureFX)
{
return FMLClientHandler.instance().getTextureDimensions(textureFX);
return TextureFXManager.instance().getTextureDimensions(textureFX);
}
public static void onTexturePackChange(RenderEngine engine, TexturePackBase texturePack, List<TextureFX> textureFXList)
public static void onTexturePackChange(RenderEngine engine, ITexturePack texturePack, List<TextureFX> textureFXList)
{
FMLClientHandler.instance().onTexturePackChange(engine, texturePack, textureFXList);
TextureFXManager.instance().onTexturePackChange(engine, texturePack, textureFXList);
}
@SuppressWarnings("deprecation")
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
{
return FMLClientHandler.instance().renderWorldBlock(renderer, world, x, y, z, block, modelId);
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelId);
}
@SuppressWarnings("deprecation")
public static void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
FMLClientHandler.instance().renderInventoryBlock(renderer, block, metadata, modelID);
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
}
@SuppressWarnings("deprecation")
public static boolean renderItemAsFull3DBlock(int modelId)
{
return FMLClientHandler.instance().renderItemAsFull3DBlock(modelId);
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelId);
}
}
+3 -2
View File
@@ -12,10 +12,11 @@
*/
package net.minecraft.src;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.*;
import static java.lang.annotation.ElementType.*;
/**
* @author cpw
+212 -114
View File
@@ -12,40 +12,56 @@
*/
package net.minecraft.src;
import static cpw.mods.fml.common.Side.CLIENT;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.SpriteHelper;
import cpw.mods.fml.client.TextureFXManager;
import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
import cpw.mods.fml.client.modloader.ModLoaderKeyBindingHandler;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ReflectionHelper;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.common.asm.SideOnly;
import cpw.mods.fml.common.modloader.ModLoaderHelper;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.registry.FMLRegistry;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.server.FMLServerHandler;
public class ModLoader
{
public static final String fmlMarker = "This is an FML marker";
// TODO dirty workaround for millinaire
@Deprecated
public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap();
/**
* Not used on the server.
* Adds localization info for an achievement, Not used on the server.
*
* @param achievement
* @param name
* @param description
* @param achievement The achievement to name
* @param name The name
* @param description The description
*/
public static void addAchievementDesc(Achievement achievement, String name, String description)
{
String achName=achievement.func_44020_i();
String achName=achievement.func_75970_i();
addLocalization(achName, name);
addLocalization(achName+".desc", description);
}
@@ -53,11 +69,11 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
*
* {@link FMLCommonHandler#fuelLookup(int, int)}
* {@link GameRegistry#getFuelValue(ItemStack)}
*
* @param id
* @param metadata
* @return
* @param id The Item ID
* @param metadata The Item Metadata
* @return The fuel strength, in ticks, 0 if unhandled
*/
@Deprecated
public static int addAllFuel(int id, int metadata)
@@ -66,41 +82,66 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers)
{
}
@SideOnly(CLIENT)
public static void addAnimation(TextureFX anim)
{
FMLClientHandler.instance().addAnimation(anim);
TextureFXManager.instance().addAnimation(anim);
}
/**
* This method is unimplemented in server versions to date.
* Adds a new prefix to the armor texture list
*
* @param armor
* @return
* {@link RenderingRegistry#addNewArmourRendererPrefix(String)}
*
* @param armor The new armor prefix
* @return The new armor index
*/
@SideOnly(CLIENT)
public static int addArmor(String armor)
{
return FMLClientHandler.instance().addNewArmourRendererPrefix(armor);
return RenderingRegistry.addNewArmourRendererPrefix(armor);
}
/**
* This method adds the supplied biome to the set of candidate biomes for the default world generator type.
*
* @param biome
* @param biome The biome to add
*/
public static void addBiome(BiomeGenBase biome)
{
FMLClientHandler.instance().addBiomeToDefaultWorldGenerator(biome);
GameRegistry.addBiome(biome);
}
public static void addEntityTracker(BaseMod mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval, boolean sendVelocityInfo)
{
ModLoaderHelper.buildEntityTracker(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
}
public static void addCommand(ICommand command)
{
ModLoaderHelper.addCommand(command);
}
/**
* Add a behaviour to the dispenser
*
* @param item
* @param behavior
*/
public static void addDispenserBehavior(Item item, IBehaviorDispenseItem behavior)
{
BlockDispenser.field_82527_a.func_82595_a(item, behavior);
}
/**
* Add localization for the specified string
*
* @param key
* @param value
* @param key Key
* @param value Value
*/
public static void addLocalization(String key, String value)
{
@@ -110,20 +151,20 @@ public class ModLoader
/**
* Add localization for the specified string
*
* @param key
* @param lang
* @param value
* @param key Key
* @param lang Language identifier
* @param value Value
*/
public static void addLocalization(String key, String lang, String value)
{
FMLCommonHandler.instance().addStringLocalization(key, lang, value);
LanguageRegistry.instance().addStringLocalization(key, lang, value);
}
/**
* Name the specified minecraft object with the supplied name
*
* @param instance
* @param name
* @param instance Item to name
* @param name The name to give it
*/
public static void addName(Object instance, String name)
{
@@ -133,61 +174,73 @@ public class ModLoader
/**
* Unimplemented on the server as it does not generate names
*
* @param instance
* @param lang
* @param name
* @param instance Item to name
* @param lang Languge identifier
* @param name Name to give it
*/
public static void addName(Object instance, String lang, String name)
{
FMLCommonHandler.instance().addNameForObject(instance, lang, name);
LanguageRegistry.instance().addNameForObject(instance, lang, name);
}
/**
* Attempts to register a small image to be applied to a larger texture image,
* typically how old ModLoader mods add custom Item/Block textures.
*
* Forge mods should use setTextureFile in Item/Block
*
* Will return the icon index it was applied to.
*
* Unimplemented on the server as it does not render textures
*
* @param fileToOverride
* @param fileToAdd
* @return
* @param fileToOverride The texture to apply the new image to
* @param fileToAdd The new image
* @return The 'icon index' in the main image that the new image will be applied to
*/
@SideOnly(CLIENT)
public static int addOverride(String fileToOverride, String fileToAdd)
{
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
addOverride(fileToOverride, fileToAdd, idx);
return idx;
return RenderingRegistry.addTextureOverride(fileToOverride, fileToAdd);
}
/**
* Attempts to register a small image to be applied to a larger texture image,
* typically how old ModLoader mods add custom Item/Block textures.
*
* Forge mods should use setTextureFile in Item/Block
*
* Unimplemented on the server as it does not render textures
*
* @param path
* @param overlayPath
* @param index
* @param path The texture to apply the new image to
* @param overlayPath The new image
* @param index Where on the texture to apply it
*/
@SideOnly(CLIENT)
public static void addOverride(String path, String overlayPath, int index)
{
FMLClientHandler.instance().addNewTextureOverride(path, overlayPath, index);
RenderingRegistry.addTextureOverride(path, overlayPath, index);
}
/**
* Add a Shaped Recipe
*
* @param output
* @param params
* @param output The result
* @param params The input
*/
public static void addRecipe(ItemStack output, Object... params)
{
FMLRegistry.addRecipe(output, params);
GameRegistry.addRecipe(output, params);
}
/**
* Add a shapeless recipe
*
* @param output
* @param params
* @param output The result
* @param params The input
*/
public static void addShapelessRecipe(ItemStack output, Object... params)
{
FMLRegistry.addShapelessRecipe(output, params);
GameRegistry.addShapelessRecipe(output, params);
}
/**
@@ -198,9 +251,19 @@ public class ModLoader
*/
public static void addSmelting(int input, ItemStack output)
{
FMLRegistry.addSmelting(input, output);
GameRegistry.addSmelting(input, output, 1.0f);
}
/**
* Add a new product to be smelted
*
* @param input
* @param output
*/
public static void addSmelting(int input, ItemStack output, float experience)
{
GameRegistry.addSmelting(input, output, experience);
}
/**
* Add a mob to the spawn list
*
@@ -212,7 +275,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 +290,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 +304,7 @@ public class ModLoader
*/
public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList)
{
FMLRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, FMLClientHandler.instance().getDefaultOverworldBiomes());
EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, WorldType.base12Biomes);
}
/**
@@ -256,12 +319,24 @@ public class ModLoader
*/
public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeGenBase... biomes)
{
FMLRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
}
public static void addTrade(int profession, TradeEntry entry)
{
ModLoaderHelper.registerTrade(profession, entry);
}
/**
* Send a packet from the client
* @param packet
*/
public static void clientSendPacket(Packet packet)
{
PacketDispatcher.sendPacketToServer(packet);
}
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLClientHandler#tryDispensingEntity(World, double, double, double, byte, byte, ItemStack)}
*
* @param world
* @param x
@@ -270,7 +345,7 @@ public class ModLoader
* @param xVel
* @param zVel
* @param item
* @return
* @return Always false, not implemented here
*/
@Deprecated
public static boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
@@ -288,7 +363,7 @@ public class ModLoader
*/
public static void genericContainerRemoval(World world, int x, int y, int z)
{
TileEntity te = world.func_603_b(x, y, z);
/* TileEntity te = world.func_603_b(x, y, z);
if (!(te instanceof IInventory))
{
@@ -334,13 +409,13 @@ public class ModLoader
world.func_674_a(entityitem);
}
}
}
*/ }
/**
* Get a list of all BaseMod loaded into the system
* {@link ModLoaderModContainer#findAll}
*
* @return
* @return A list containing all loaded ModLoader mods
*/
public static List<BaseMod> getLoadedMods()
{
@@ -350,77 +425,74 @@ public class ModLoader
/**
* Get a logger instance {@link FMLCommonHandler#getFMLLogger()}
*
* @return
* @return The current logger
*/
public static Logger getLogger()
{
return FMLCommonHandler.instance().getFMLLogger();
return FMLLog.getLogger();
}
@SideOnly(CLIENT)
public static Minecraft getMinecraftInstance()
{
return FMLClientHandler.instance().getClient();
}
/**
* This is not the server
* {@link FMLClientHandler#getServer()}
*
* @return
*/
public static Object getMinecraftServerInstance()
public static MinecraftServer getMinecraftServerInstance()
{
return getMinecraftInstance();
return FMLCommonHandler.instance().getMinecraftServerInstance();
}
/**
* Get a value from a field using reflection
* {@link ReflectionHelper#getPrivateValue(Class, Object, int)}
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, int)}
*
* @param instanceclass
* @param instance
* @param fieldindex
* @return
* @return The value in the specified field.
*/
public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, int fieldindex)
{
return ReflectionHelper.getPrivateValue(instanceclass, instance, fieldindex);
return ObfuscationReflectionHelper.getPrivateValue(instanceclass, instance, fieldindex);
}
/**
* Get a value from a field using reflection
* {@link ReflectionHelper#getPrivateValue(Class, Object, String)}
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, String[])}
*
* @param instanceclass
* @param instance
* @param field
* @return
* @return The value in the specified field.
*/
public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, String field)
{
return ReflectionHelper.getPrivateValue(instanceclass, instance, field);
return ObfuscationReflectionHelper.getPrivateValue(instanceclass, instance, field);
}
/**
* Stubbed method on the server to return a unique model id
*
*/
@SideOnly(CLIENT)
public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
{
return FMLClientHandler.instance().obtainBlockModelIdFor(mod, inventoryRenderer);
return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
}
/**
* Get a new unique entity id
* {@link Entity#getNextId()}
* {@link EntityRegistry#findGlobalUniqueEntityId()}
*
* @return
* @return A unique entity ID
*/
public static int getUniqueEntityId()
{
return FMLCommonHandler.instance().nextUniqueEntityListId();
return EntityRegistry.findGlobalUniqueEntityId();
}
@SideOnly(CLIENT)
public static int getUniqueSpriteIndex(String path)
{
return SpriteHelper.getUniqueSpriteIndex(path);
@@ -432,16 +504,17 @@ public class ModLoader
*
* @param player
* @param channel
* @return
* @return If the channel is registered to the current connection.
*/
public static boolean isChannelActive(EntityPlayer player, String channel)
{
return FMLCommonHandler.instance().isChannelActive(channel, player);
return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
}
@SideOnly(CLIENT)
public static boolean isGUIOpen(Class<? extends GuiScreen> gui)
{
return FMLClientHandler.instance().getClient().field_6313_p!=null && FMLClientHandler.instance().getClient().field_6313_p.equals(gui);
return FMLClientHandler.instance().getClient().field_71462_r != null && FMLClientHandler.instance().getClient().field_71462_r.equals(gui);
}
/**
@@ -449,7 +522,7 @@ public class ModLoader
* {@link Loader#isModLoaded(String)}
*
* @param modname
* @return
* @return If the specified mod is loaded
*/
public static boolean isModLoaded(String modname)
{
@@ -464,9 +537,10 @@ public class ModLoader
{
}
@SideOnly(CLIENT)
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
{
return FMLClientHandler.instance().loadImageFromTexturePack(renderEngine, path);
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
}
/**
@@ -482,10 +556,12 @@ public class ModLoader
* Call in from elsewhere. Unimplemented here.
*/
@Deprecated
@SideOnly(CLIENT)
public static void onTick(float tick, Minecraft game)
{
}
@SideOnly(CLIENT)
public static void openGUI(EntityPlayer player, GuiScreen gui)
{
FMLClientHandler.instance().displayGuiScreen(player, gui);
@@ -498,7 +574,6 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLServerHandler#handlePacket250(Packet250CustomPayload, EntityPlayer)}
*
* @param packet
*/
@@ -508,12 +583,14 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
{
return keys;
}
@Deprecated
@SideOnly(CLIENT)
public static void registerAllTextureOverrides(RenderEngine cache)
{
}
@@ -525,7 +602,7 @@ public class ModLoader
*/
public static void registerBlock(Block block)
{
FMLRegistry.registerBlock(block);
GameRegistry.registerBlock(block);
}
/**
@@ -536,9 +613,13 @@ public class ModLoader
*/
public static void registerBlock(Block block, Class<? extends ItemBlock> itemclass)
{
FMLRegistry.registerBlock(block, itemclass);
GameRegistry.registerBlock(block, itemclass);
}
public static void registerContainerID(BaseMod mod, int id)
{
ModLoaderHelper.buildGuiHelper(mod, id);
}
/**
* Register a new entity ID
*
@@ -548,7 +629,7 @@ public class ModLoader
*/
public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id)
{
FMLRegistry.registerEntityID(entityClass, entityName, id);
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id);
}
/**
@@ -562,26 +643,25 @@ public class ModLoader
*/
public static void registerEntityID(Class<? extends Entity> entityClass, String entityName, int id, int background, int foreground)
{
FMLRegistry.registerEntityID(entityClass, entityName, id, background, foreground);
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
}
@SideOnly(CLIENT)
public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
{
FMLClientHandler.instance().registerKeyHandler(mod, keyHandler, allowRepeat);
ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
}
/**
* Register the mod for packets on this channel. This only registers the
* channel with Forge Mod Loader, not with clients connecting- use
* BaseMod.onClientLogin to tell them about your custom channel
* {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)}
* Register the mod for packets on this channel.
* {@link NetworkRegistry#registerChannel(IPacketHandler, String)}
*
* @param mod
* @param channel
*/
public static void registerPacketChannel(BaseMod mod, String channel)
{
FMLCommonHandler.instance().registerChannel(FMLCommonHandler.instance().findContainerFor(mod), channel);
NetworkRegistry.instance().registerChannel(ModLoaderHelper.buildPacketHandlerFor(mod), channel);
}
/**
@@ -592,12 +672,13 @@ public class ModLoader
*/
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id)
{
FMLRegistry.registerTileEntity(tileEntityClass, id);
GameRegistry.registerTileEntity(tileEntityClass, id);
}
@SideOnly(CLIENT)
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
{
ClientRegistry.instance().registerTileEntity(tileEntityClass, id, renderer);
ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
}
/**
@@ -607,7 +688,7 @@ public class ModLoader
*/
public static void removeBiome(BiomeGenBase biome)
{
FMLRegistry.removeBiome(biome);
GameRegistry.removeBiome(biome);
}
/**
@@ -618,7 +699,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 +711,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 +722,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 +734,28 @@ public class ModLoader
*/
public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeGenBase... biomes)
{
FMLRegistry.removeSpawn(entityName, spawnList, biomes);
EntityRegistry.removeSpawn(entityName, spawnList, biomes);
}
@Deprecated
@SideOnly(CLIENT)
public static boolean renderBlockIsItemFull3D(int modelID)
{
return FMLClientHandler.instance().renderItemAsFull3DBlock(modelID);
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
}
@Deprecated
@SideOnly(CLIENT)
public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
FMLClientHandler.instance().renderInventoryBlock(renderer, block, metadata, modelID);
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
}
@Deprecated
@SideOnly(CLIENT)
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
{
return FMLClientHandler.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
}
/**
@@ -683,12 +767,16 @@ public class ModLoader
{
}
/**
* Send a packet from client to server
*
* @param packet
*/
public static void sendPacket(Packet packet) {
FMLClientHandler.instance().sendPacket(packet);
PacketDispatcher.sendPacketToServer(packet);
}
/**
* Send a chat message to the server
* {@link FMLClientHandler#handleChatPacket(Packet3Chat, EntityPlayer)}
*
* @param text
*/
@@ -699,11 +787,24 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
{
//TODO
}
public static void serverSendPacket(NetServerHandler handler, Packet packet)
{
if (handler != null)
{
PacketDispatcher.sendPacketToPlayer(packet, (Player)handler.getPlayer());
}
}
public static void serverOpenWindow(EntityPlayerMP player, Container container, int ID, int x, int y, int z)
{
ModLoaderHelper.openGui(ID, player, container, x, y, z);
}
/**
* Indicate that you want to receive ticks
*
@@ -724,7 +825,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 +834,12 @@ public class ModLoader
*/
public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, int fieldindex, E value)
{
ReflectionHelper.setPrivateValue(instanceclass, instance, fieldindex, value);
ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, fieldindex);
}
/**
* Set a private field to a value using reflection
* {@link ReflectionHelper#setPrivateValue(Class, Object, String, Object)}
* {@link ObfuscationReflectionHelper#setPrivateValue(Class, Object, String, Object)}
*
* @param instanceclass
* @param instance
@@ -747,12 +848,11 @@ public class ModLoader
*/
public static <T, E> void setPrivateValue(Class<? super T> instanceclass, T instance, String field, E value)
{
ReflectionHelper.setPrivateValue(instanceclass, instance, field, value);
ObfuscationReflectionHelper.setPrivateValue(instanceclass, instance, value, field);
}
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLClientHandler#onItemCrafted(EntityPlayer, ItemStack, IInventory)}
*
* @param player
* @param item
@@ -765,7 +865,6 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLClientHandler#onItemSmelted(EntityPlayer, ItemStack)}
*
* @param player
* @param item
@@ -777,7 +876,6 @@ public class ModLoader
/**
* Throw the offered exception. Likely will stop the game.
* {@link FMLClientHandler#raiseException(Throwable, String, boolean)}
*
* @param message
* @param e
+139 -128
View File
@@ -1,128 +1,139 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLTextureFX;
import cpw.mods.fml.common.FMLCommonHandler;
import static org.lwjgl.opengl.GL11.*;
/**
* A texture override for animations, it takes a vertical image of
* texture frames and constantly rotates them in the texture.
*/
public class ModTextureAnimation extends FMLTextureFX
{
private final int tickRate;
private byte[][] images;
private int index = 0;
private int ticks = 0;
private String targetTex = null;
private BufferedImage imgData = null;
public ModTextureAnimation(int icon, int target, BufferedImage image, int tickCount)
{
this(icon, 1, target, image, tickCount);
}
public ModTextureAnimation(int icon, int size, int target, BufferedImage image, int tickCount)
{
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image, tickCount);
}
public ModTextureAnimation(int icon, int size, String target, BufferedImage image, int tickCount)
{
super(icon);
RenderEngine re = FMLClientHandler.instance().getClient().field_6315_n;
targetTex = target;
field_1129_e = size;
field_1128_f = re.func_1070_a(target);
tickRate = tickCount;
ticks = tickCount;
imgData = image;
}
@Override
public void setup()
{
super.setup();
int sWidth = imgData.getWidth();
int sHeight = imgData.getHeight();
int tWidth = tileSizeBase;
int tHeight = tileSizeBase;
int frames = (int)Math.floor((double)(sHeight / sWidth));
if (frames < 1)
{
throw new IllegalArgumentException(String.format("Attempted to create a TextureAnimation with no complete frames: %dx%d", sWidth, sHeight));
}
else
{
images = new byte[frames][];
BufferedImage image = imgData;
if (sWidth != tWidth)
{
BufferedImage b = new BufferedImage(tWidth, tHeight * frames, 6);
Graphics2D g = b.createGraphics();
g.drawImage(imgData, 0, 0, tWidth, tHeight * frames, 0, 0, sWidth, sHeight, (ImageObserver)null);
g.dispose();
image = b;
}
for (int frame = 0; frame < frames; frame++)
{
int[] pixels = new int[tileSizeSquare];
image.getRGB(0, tHeight * frame, tWidth, tHeight, pixels, 0, tWidth);
images[frame] = new byte[tileSizeSquare << 2];
for (int i = 0; i < pixels.length; i++)
{
int i4 = i * 4;
images[frame][i4 + 0] = (byte)(pixels[i] >> 16 & 255);
images[frame][i4 + 1] = (byte)(pixels[i] >> 8 & 255);
images[frame][i4 + 2] = (byte)(pixels[i] >> 0 & 255);
images[frame][i4 + 3] = (byte)(pixels[i] >> 24 & 255);
}
}
}
}
public void func_783_a()
{
if (++ticks >= tickRate)
{
if (++index >= images.length)
{
index = 0;
}
field_1127_a = images[index];
ticks = 0;
}
}
}
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLTextureFX;
/**
* A texture override for animations, it takes a vertical image of
* texture frames and constantly rotates them in the texture.
*/
public class ModTextureAnimation extends FMLTextureFX
{
private final int tickRate;
private byte[][] images;
private int index = 0;
private int ticks = 0;
private String targetTex = null;
private BufferedImage imgData = null;
public ModTextureAnimation(int icon, int target, BufferedImage image, int tickCount)
{
this(icon, 1, target, image, tickCount);
}
public ModTextureAnimation(int icon, int size, int target, BufferedImage image, int tickCount)
{
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image, tickCount);
}
public ModTextureAnimation(int icon, int size, String target, BufferedImage image, int tickCount)
{
super(icon);
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
targetTex = target;
field_76849_e = size;
field_76847_f = re.func_78341_b(target);
tickRate = tickCount;
ticks = tickCount;
imgData = image;
}
@Override
public void setup()
{
super.setup();
int sWidth = imgData.getWidth();
int sHeight = imgData.getHeight();
int tWidth = tileSizeBase;
int tHeight = tileSizeBase;
int frames = (int)Math.floor((double)(sHeight / sWidth));
if (frames < 1)
{
throw new IllegalArgumentException(String.format("Attempted to create a TextureAnimation with no complete frames: %dx%d", sWidth, sHeight));
}
else
{
images = new byte[frames][];
BufferedImage image = imgData;
if (sWidth != tWidth)
{
BufferedImage b = new BufferedImage(tWidth, tHeight * frames, 6);
Graphics2D g = b.createGraphics();
g.drawImage(imgData, 0, 0, tWidth, tHeight * frames, 0, 0, sWidth, sHeight, (ImageObserver)null);
g.dispose();
image = b;
}
for (int frame = 0; frame < frames; frame++)
{
int[] pixels = new int[tileSizeSquare];
image.getRGB(0, tHeight * frame, tWidth, tHeight, pixels, 0, tWidth);
images[frame] = new byte[tileSizeSquare << 2];
for (int i = 0; i < pixels.length; i++)
{
int i4 = i * 4;
images[frame][i4 + 0] = (byte)(pixels[i] >> 16 & 255);
images[frame][i4 + 1] = (byte)(pixels[i] >> 8 & 255);
images[frame][i4 + 2] = (byte)(pixels[i] >> 0 & 255);
images[frame][i4 + 3] = (byte)(pixels[i] >> 24 & 255);
}
}
}
}
public void func_76846_a()
{
if (++ticks >= tickRate)
{
if (++index >= images.length)
{
index = 0;
}
field_76852_a = images[index];
ticks = 0;
}
}
public void func_76845_a(RenderEngine renderEngine)
{
GL11.glBindTexture(GL11.GL_TEXTURE_2D, field_76847_f);
}
// TODO: REMOVE THIS - just for you dan200
@Deprecated
public void func_783_a()
{
func_76846_a();
}
}
+181 -179
View File
@@ -1,179 +1,181 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLTextureFX;
import cpw.mods.fml.common.FMLCommonHandler;
import static org.lwjgl.opengl.GL11.*;
public class ModTextureStatic extends FMLTextureFX
{
private boolean oldanaglyph = false;
private int[] pixels = null;
private String targetTex = null;
private int storedSize;
private BufferedImage overrideData = null;
private int needApply = 2;
public ModTextureStatic(int icon, int target, BufferedImage image)
{
this(icon, 1, target, image);
}
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
{
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image);
}
public ModTextureStatic(int icon, int size, String target, BufferedImage image)
{
super(icon);
RenderEngine re = FMLClientHandler.instance().getClient().field_6315_n;
targetTex = target;
storedSize = size;
field_1129_e = size;
field_1128_f = re.func_1070_a(target);
overrideData = image;
}
@Override
public void setup()
{
super.setup();
int sWidth = overrideData.getWidth();
int sHeight = overrideData.getHeight();
pixels = new int[tileSizeSquare];
if (tileSizeBase == sWidth && tileSizeBase == sHeight)
{
overrideData.getRGB(0, 0, sWidth, sHeight, pixels, 0, sWidth);
}
else
{
BufferedImage tmp = new BufferedImage(tileSizeBase, tileSizeBase, 6);
Graphics2D gfx = tmp.createGraphics();
gfx.drawImage(overrideData, 0, 0, tileSizeBase, tileSizeBase, 0, 0, sWidth, sHeight, (ImageObserver)null);
tmp.getRGB(0, 0, tileSizeBase, tileSizeBase, pixels, 0, tileSizeBase);
gfx.dispose();
}
update();
}
public void func_783_a()
{
if (oldanaglyph != field_1131_c)
{
update();
}
// This makes it so we only apply the texture to the target texture when we need to,
//due to the fact that update is called when the Effect is first registered, we actually
//need to wait for the next one.
field_1129_e = (needApply == 0 ? 0 : storedSize);
if (needApply > 0)
{
needApply--;
}
}
public void func_782_a(RenderEngine p_782_1_)
{
GL11.glBindTexture(GL_TEXTURE_2D, p_782_1_.func_1070_a(targetTex));
}
public void update()
{
needApply = 2;
for (int idx = 0; idx < pixels.length; idx++)
{
int i = idx * 4;
int a = pixels[idx] >> 24 & 255;
int r = pixels[idx] >> 16 & 255;
int g = pixels[idx] >> 8 & 255;
int b = pixels[idx] >> 0 & 255;
if (field_1131_c)
{
r = g = b = (r + g + b) / 3;
}
field_1127_a[i + 0] = (byte)r;
field_1127_a[i + 1] = (byte)g;
field_1127_a[i + 2] = (byte)b;
field_1127_a[i + 3] = (byte)a;
}
oldanaglyph = field_1131_c;
}
//Implementation of http://scale2x.sourceforge.net/algorithm.html
public static BufferedImage scale2x(BufferedImage image)
{
int w = image.getWidth();
int h = image.getHeight();
BufferedImage tmp = new BufferedImage(w * 2, h * 2, 2);
for (int x = 0; x < h; ++x)
{
int x2 = x * 2;
for (int y = 0; y < w; ++y)
{
int y2 = y * 2;
int E = image.getRGB(y, x);
int D = (x == 0 ? E : image.getRGB(y, x - 1));
int B = (y == 0 ? E : image.getRGB(y - 1, x ));
int H = (y >= w - 1 ? E : image.getRGB(y + 1, x ));
int F = (x >= h - 1 ? E : image.getRGB(y, x + 1));
int e0, e1, e2, e3;
if (B != H && D != F)
{
e0 = D == B ? D : E;
e1 = B == F ? F : E;
e2 = D == H ? D : E;
e3 = H == F ? F : E;
}
else
{
e0 = e1 = e2 = e3 = E;
}
tmp.setRGB(y2, x2, e0);
tmp.setRGB(y2 + 1, x2, e1);
tmp.setRGB(y2, x2 + 1, e2);
tmp.setRGB(y2 + 1, x2 + 1, e3);
}
}
return tmp;
}
@Override
public String toString()
{
return String.format("ModTextureStatic %s @ %d", targetTex, field_1126_b);
}
}
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLTextureFX;
public class ModTextureStatic extends FMLTextureFX
{
private boolean oldanaglyph = false;
private int[] pixels = null;
private String targetTex = null;
private int storedSize;
private BufferedImage overrideData = null;
private int needApply = 2;
public ModTextureStatic(int icon, int target, BufferedImage image)
{
this(icon, 1, target, image);
}
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
{
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image);
}
public ModTextureStatic(int icon, int size, String target, BufferedImage image)
{
super(icon);
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
targetTex = target;
storedSize = size;
field_76849_e = size;
field_76847_f = re.func_78341_b(target);
overrideData = image;
}
@Override
public void setup()
{
super.setup();
int sWidth = overrideData.getWidth();
int sHeight = overrideData.getHeight();
pixels = new int[tileSizeSquare];
if (tileSizeBase == sWidth && tileSizeBase == sHeight)
{
overrideData.getRGB(0, 0, sWidth, sHeight, pixels, 0, sWidth);
}
else
{
BufferedImage tmp = new BufferedImage(tileSizeBase, tileSizeBase, 6);
Graphics2D gfx = tmp.createGraphics();
gfx.drawImage(overrideData, 0, 0, tileSizeBase, tileSizeBase, 0, 0, sWidth, sHeight, (ImageObserver)null);
tmp.getRGB(0, 0, tileSizeBase, tileSizeBase, pixels, 0, tileSizeBase);
gfx.dispose();
}
update();
}
@Override
public void func_76846_a()
{
if (oldanaglyph != field_76851_c)
{
update();
}
// This makes it so we only apply the texture to the target texture when we need to,
//due to the fact that update is called when the Effect is first registered, we actually
//need to wait for the next one.
field_76849_e = (needApply == 0 ? 0 : storedSize);
if (needApply > 0)
{
needApply--;
}
}
@Override
public void func_76845_a(RenderEngine p_76845_1_)
{
GL11.glBindTexture(GL_TEXTURE_2D, p_76845_1_.func_78341_b(targetTex));
}
public void update()
{
needApply = 2;
for (int idx = 0; idx < pixels.length; idx++)
{
int i = idx * 4;
int a = pixels[idx] >> 24 & 255;
int r = pixels[idx] >> 16 & 255;
int g = pixels[idx] >> 8 & 255;
int b = pixels[idx] >> 0 & 255;
if (field_76851_c)
{
r = g = b = (r + g + b) / 3;
}
field_76852_a[i + 0] = (byte)r;
field_76852_a[i + 1] = (byte)g;
field_76852_a[i + 2] = (byte)b;
field_76852_a[i + 3] = (byte)a;
}
oldanaglyph = field_76851_c;
}
//Implementation of http://scale2x.sourceforge.net/algorithm.html
public static BufferedImage scale2x(BufferedImage image)
{
int w = image.getWidth();
int h = image.getHeight();
BufferedImage tmp = new BufferedImage(w * 2, h * 2, 2);
for (int x = 0; x < h; ++x)
{
int x2 = x * 2;
for (int y = 0; y < w; ++y)
{
int y2 = y * 2;
int E = image.getRGB(y, x);
int D = (x == 0 ? E : image.getRGB(y, x - 1));
int B = (y == 0 ? E : image.getRGB(y - 1, x ));
int H = (y >= w - 1 ? E : image.getRGB(y + 1, x ));
int F = (x >= h - 1 ? E : image.getRGB(y, x + 1));
int e0, e1, e2, e3;
if (B != H && D != F)
{
e0 = D == B ? D : E;
e1 = B == F ? F : E;
e2 = D == H ? D : E;
e3 = H == F ? F : E;
}
else
{
e0 = e1 = e2 = e3 = E;
}
tmp.setRGB(y2, x2, e0);
tmp.setRGB(y2 + 1, x2, e1);
tmp.setRGB(y2, x2 + 1, e2);
tmp.setRGB(y2 + 1, x2 + 1, e3);
}
}
return tmp;
}
@Override
public String toString()
{
return String.format("ModTextureStatic %s @ %d", targetTex, field_76850_b);
}
}
-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 "";
}
+30
View File
@@ -0,0 +1,30 @@
package net.minecraft.src;
/**
* Compatibility class for ModLoader -- do not use
*
* @author cpw
*
*/
public class TradeEntry
{
public final int id;
public float chance;
public boolean buying;
public int min = 0;
public int max = 0;
public TradeEntry(int id, float chance, boolean buying, int min, int max)
{
this.id = id;
this.chance = chance;
this.buying = buying;
this.min = min;
this.max = max;
}
public TradeEntry(int id, float chance, boolean buying)
{
this(id, chance, buying, 0, 0);
}
}
-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);
}
+235
View File
@@ -0,0 +1,235 @@
--- commands.py
+++ commands.py
@@ -58,6 +58,8 @@
def reallyrmtree(path):
+ if os.path.isfile(os.path.join(path, 'asm-all-4.0.jar')): #Check if asm exists, indicating the libs folder, if so, don't delete it
+ return
if not sys.platform.startswith('win'):
if os.path.exists(path):
shutil.rmtree(path)
@@ -584,6 +586,9 @@
self.has_astyle_cfg = False
if os.path.isfile(self.astyleconf):
self.has_astyle_cfg = True
+
+ #FML Entries
+ self.srcshared = os.path.normpath(os.path.join(self.dirsrc, 'common'))
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
"""Create the files necessary for RetroGuard"""
@@ -781,13 +786,16 @@
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):
binlk = {CLIENT: self.binclient, SERVER: self.binserver}
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
+ if side == SERVER:
+ return self.checkbins(CLIENT)
if not os.path.exists(os.path.join(binlk[side], os.path.normpath(testlk[side] + '.class'))):
return False
return True
@@ -1029,6 +1037,10 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
pathlog = {CLIENT: self.clientrecomplog, SERVER: self.serverrecomplog}
+ if side == SERVER: #Disable server because FML recombines it into client
+ self.logger.info('Server side recompiling skipped, this is normal')
+ return
+
if not os.path.exists(pathbinlk[side]):
os.makedirs(pathbinlk[side])
@@ -1041,6 +1053,7 @@
all_files = True
append_pattern = False
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=append_pattern, all_files=all_files) #FML, Add Common folder
dirs = ' '.join(pkglist)
classpath = os.pathsep.join(cplk[side])
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
@@ -1062,7 +1075,7 @@
raise
def startserver(self):
- classpath = [self.binserver] + self.cpathserver
+ classpath = [self.binclient, self.srcshared] + self.cpathserver
classpath = [os.path.join('..', p) for p in classpath]
classpath = os.pathsep.join(classpath)
os.chdir(self.dirjars)
@@ -1070,7 +1083,7 @@
self.runmc(forkcmd)
def startclient(self):
- classpath = [self.binclient] + self.cpathclient
+ classpath = [self.binclient, self.srcshared] + self.cpathclient
classpath = [os.path.join('..', p) for p in classpath]
classpath = os.pathsep.join(classpath)
natives = os.path.join('..', self.dirnatives)
@@ -1197,20 +1210,20 @@
with open(self.csvmethods, 'rb') as fh:
methodsreader = csv.DictReader(fh)
for row in methodsreader:
- if int(row['side']) == side:
+ if int(row['side']) == side or int(row['side']) == 2:
if row['name'] != row['searge']:
names['methods'][row['searge']] = row['name']
with open(self.csvfields, 'rb') as fh:
fieldsreader = csv.DictReader(fh)
for row in fieldsreader:
- if int(row['side']) == side:
+ if int(row['side']) == side or int(row['side']) == 2:
if row['name'] != row['searge']:
names['fields'][row['searge']] = row['name']
if self.has_param_csv:
with open(self.csvparams, 'rb') as fh:
paramsreader = csv.DictReader(fh)
for row in paramsreader:
- if int(row['side']) == side:
+ if int(row['side']) == side or int(row['side']) == 2:
names['params'][row['param']] = row['name']
regexps = {
@@ -1240,6 +1253,11 @@
# HINT: We pathwalk the sources
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
+ for cur_file in fnmatch.filter(filelist, '*.java'):
+ updatefile(os.path.normpath(os.path.join(path, cur_file)))
+
+ # FML, copy of the above, for the common folder
+ for path, _, filelist in os.walk(self.srcshared, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.java'):
updatefile(os.path.normpath(os.path.join(path, cur_file)))
return True
@@ -1322,12 +1340,14 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
strip_comments(pathsrclk[side])
+ strip_comments(self.srcshared)
def process_cleanup(self, side):
"""Do lots of random cleanups including stripping comments, trailing whitespace and extra blank lines"""
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
src_cleanup(pathsrclk[side], fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
+ src_cleanup(self.srcshared, fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
def process_javadoc(self, side):
"""Add CSV descriptions to methods and fields as javadoc"""
@@ -1336,6 +1356,21 @@
if not self.has_doc_csv:
self.logger.warning('!! javadoc disabled due to no csvs !!')
return False
+
+ #FML Recall this function on the common folder
+ #Potential bug: If this is called without a subsiquent rename call, will cause double comments
+ if pathsrclk[side] != self.srcshared:
+ if side == CLIENT:
+ tmp = self.srcclient
+ self.srcclient = self.srcshared
+ self.process_javadoc(side)
+ self.srcclient = tmp
+ else:
+ tmp = self.srcserver
+ self.srcserver = self.srcshared
+ self.process_javadoc(side)
+ self.srcserver = tmp
+
#HINT: We read the relevant CSVs
methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
@@ -1344,13 +1379,13 @@
methods = {}
for row in methodsreader:
#HINT: Only include methods that have a non-empty description
- if int(row['side']) == side and row['desc']:
+ if (int(row['side']) == side or int(row['side']) == 2) and row['desc']:
methods[row['searge']] = row['desc'].replace('*/', '* /')
fields = {}
for row in fieldsreader:
#HINT: Only include fields that have a non-empty description
- if int(row['side']) == side and row['desc']:
+ if (int(row['side']) == side or int(row['side']) == 2) and row['desc']:
fields[row['searge']] = row['desc'].replace('*/', '* /')
regexps = {
@@ -1422,12 +1457,13 @@
# HINT: We create the list of source directories based on the list of packages
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=True) #FML, Add Common folder
dirs = ' '.join(pkglist)
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
self.runcmd(forkcmd)
return True
- def gathermd5s(self, side, reobf=False):
+ def gathermd5s(self, side, reobf=False, skip_fml=False):
if not reobf:
md5lk = {CLIENT: self.md5client, SERVER: self.md5server}
else:
@@ -1442,6 +1478,9 @@
class_path = ''
else:
class_path += '/'
+ if skip_fml:
+ if class_path.startswith('cpw/'):
+ continue
for class_file in fnmatch.filter(filelist, '*.class'):
class_name = class_path + os.path.splitext(class_file)[0]
bin_file = os.path.normpath(os.path.join(path, class_file))
@@ -1594,6 +1633,9 @@
sys.exit(1)
for entry in newfiles:
+ if 'commands.py' in entry[0]: #FML, Disable updating of Commands.py
+ print 'Update to runtime/commands.py found, but disbled due to using fml'
+ continue
if entry[3] == 'U':
self.logger.info('Retrieving file from server : %s', entry[0])
cur_file = os.path.normpath(entry[0])
@@ -1614,6 +1656,9 @@
md5reoblk = {CLIENT: self.md5reobfclient, SERVER: self.md5reobfserver}
outpathlk = {CLIENT: self.srcmodclient, SERVER: self.srcmodserver}
src = {CLIENT: self.srcclient, SERVER: self.srcserver}
+
+ if side == SERVER: #Noop out server side stuff
+ return
# HINT: We need a table for the old md5 and the new ones
md5table = {}
@@ -1646,6 +1691,7 @@
# HINT: We extract the source files for the modified class files
for in_class in trgclasses:
src_file = os.path.normpath(os.path.join(src[side], in_class + '.java'))
+ cmn_file = os.path.normpath(os.path.join(self.srcshared, in_class + '.java'))
dest_file = os.path.normpath(os.path.join(outpathlk[side], in_class + '.java'))
if os.path.isfile(src_file):
if not os.path.exists(os.path.dirname(dest_file)):
@@ -1655,4 +1701,15 @@
self.logger.info('> Outputted %s to %s', in_class.ljust(35), outpathlk[side])
except IOError:
self.logger.error('* File %s copy failed', in_class)
-
+ elif os.path.isfile(cmn_file):
+ if not os.path.exists(os.path.dirname(dest_file)):
+ os.makedirs(os.path.dirname(dest_file))
+ try:
+ shutil.copyfile(cmn_file, dest_file)
+ self.logger.info('> Outputted %s to %s', in_class.ljust(35), outpathlk[side])
+ except IOError:
+ self.logger.error('* File %s copy failed', in_class)
+
+def commands_sanity_check():
+ print 'Commands patch applied successfully'
+
@@ -0,0 +1,29 @@
package cpw.mods.fml.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Declare a variable to be populated by a Bukkit Plugin proxy instance if the bukkit coremod
* is available. It can only be applied to field typed as {@link BukkitProxy}
* Generally it should be used in conjunction with {@link Mod#bukkitPlugin()} specifying the
* plugin to load.
*
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface BukkitPluginRef
{
/**
* A reference (possibly version specific) to a Bukkit Plugin by name, using the name@versionbound
* specification. If this is a bukkit enabled environment the field annotated by this
* will be populated with a {@link BukkitProxy} instance if possible. This proxy will be gotten by
* reflectively calling the "getModProxy" method on the bukkit plugin instance.
* @return The name of the plugin which we will inject into this field
*/
String value();
}
@@ -0,0 +1,12 @@
package cpw.mods.fml.common;
/**
* A marker interface for retrieving a proxy to a bukkit plugin.
* Fields associated with {@link BukkitPluginRef} annotations should be should probably
* declare this type and cast down if the target is available (not null)
* @author cpw
*
*/
public interface BukkitProxy
{
}
@@ -0,0 +1,141 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionRange;
public class DummyModContainer implements ModContainer
{
private ModMetadata md;
private ArtifactVersion processedVersion;
public DummyModContainer(ModMetadata md)
{
this.md = md;
}
public DummyModContainer()
{
}
@Override
public void bindMetadata(MetadataCollection mc)
{
}
@Override
public List<ArtifactVersion> getDependants()
{
return Collections.emptyList();
}
@Override
public List<ArtifactVersion> getDependencies()
{
return Collections.emptyList();
}
@Override
public Set<ArtifactVersion> getRequirements()
{
return Collections.emptySet();
}
@Override
public ModMetadata getMetadata()
{
return md;
}
@Override
public Object getMod()
{
return null;
}
@Override
public String getModId()
{
return md.modId;
}
@Override
public String getName()
{
return md.name;
}
@Override
public String getSortingRules()
{
return "";
}
@Override
public File getSource()
{
return null;
}
@Override
public String getVersion()
{
return md.version;
}
public boolean matches(Object mod)
{
return false;
}
@Override
public void setEnabledState(boolean enabled)
{
}
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
return false;
}
@Override
public ArtifactVersion getProcessedVersion()
{
if (processedVersion == null)
{
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
}
return processedVersion;
}
@Override
public boolean isImmutable()
{
return false;
}
@Override
public boolean isNetworkMod()
{
return false;
}
@Override
public String getDisplayVersion()
{
return md.version;
}
@Override
public VersionRange acceptableMinecraftVersionRange()
{
return Loader.instance().getMinecraftModContainer().getStaticVersionRange();
}
}
@@ -0,0 +1,16 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.List;
import com.google.common.collect.SetMultimap;
public class DuplicateModsFoundException extends LoaderException {
public SetMultimap<ModContainer,File> dupes;
public DuplicateModsFoundException(SetMultimap<ModContainer, File> dupes) {
this.dupes = dupes;
}
}
+254 -467
View File
@@ -13,32 +13,45 @@
*/
package cpw.mods.fml.common;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import cpw.mods.fml.common.ModContainer.SourceType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.CrashReport;
import net.minecraft.src.CrashReportCategory;
import net.minecraft.src.DedicatedServer;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.EntityPlayerMP;
import net.minecraft.src.NBTBase;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NetHandler;
import net.minecraft.src.Packet131MapData;
import net.minecraft.src.SaveHandler;
import net.minecraft.src.ServerListenThread;
import net.minecraft.src.ThreadMinecraftServer;
import net.minecraft.src.World;
import net.minecraft.src.WorldInfo;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.server.FMLServerHandler;
/**
* The main class for non-obfuscated hook handling code
@@ -59,148 +72,72 @@ public class FMLCommonHandler
* The singleton
*/
private static final FMLCommonHandler INSTANCE = new FMLCommonHandler();
private static final Pattern metadataFile = Pattern.compile("$/modinfo.json$");;
/**
* A map of mods to their network channels
*/
private Map<ModContainer, Set<String>> channelList = new HashMap<ModContainer, Set<String>>();
/**
* A map of channels to mods
*/
private Map<String, ModContainer> modChannels = new HashMap<String, ModContainer>();
/**
* A map of active channels per player
*/
private Map<Object, Set<String>> activeChannels = new HashMap<Object, Set<String>>();
/**
* The delegate for side specific data and functions
*/
private IFMLSidedHandler sidedDelegate;
private int uniqueEntityListId = 220;
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
private Class<?> forge;
private boolean noForge;
private List<String> brandings;
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
private List<ModContainer> auxilliaryContainers = new ArrayList<ModContainer>();
private Map<String,Properties> modLanguageData=new HashMap<String,Properties>();
private PriorityQueue<TickQueueElement> tickHandlers = new PriorityQueue<TickQueueElement>();
private List<IScheduledTickHandler> scheduledTicks = new ArrayList<IScheduledTickHandler>();
private Set<IWorldGenerator> worldGenerators = new HashSet<IWorldGenerator>();
/**
* We register our delegate here
* @param handler
*/
private static class TickQueueElement implements Comparable<TickQueueElement>
{
static long tickCounter = 0;
public TickQueueElement(IScheduledTickHandler ticker)
{
this.ticker = ticker;
update();
}
@Override
public int compareTo(TickQueueElement o)
{
return (int)(next - o.next);
}
public void update()
{
next = tickCounter + Math.max(ticker.nextTickSpacing(),1);
}
private long next;
private IScheduledTickHandler ticker;
public boolean scheduledNow()
{
return tickCounter >= next;
}
}
public void beginLoading(IFMLSidedHandler handler)
{
sidedDelegate = handler;
getFMLLogger().info("Attempting early MinecraftForge initialization");
FMLLog.info("Attempting early MinecraftForge initialization");
callForgeMethod("initialize");
getFMLLogger().info("Completed early MinecraftForge initialization");
callForgeMethod("registerCrashCallable");
FMLLog.info("Completed early MinecraftForge initialization");
}
public void rescheduleTicks()
public void rescheduleTicks(Side side)
{
sidedDelegate.profileStart("modTickScheduling");
TickQueueElement.tickCounter++;
scheduledTicks.clear();
while (true)
{
if (tickHandlers.size()==0 || !tickHandlers.peek().scheduledNow())
{
break;
}
TickQueueElement tickQueueElement = tickHandlers.poll();
tickQueueElement.update();
tickHandlers.offer(tickQueueElement);
scheduledTicks.add(tickQueueElement.ticker);
}
sidedDelegate.profileEnd();
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
}
public void tickStart(EnumSet<TickType> ticks, Object ... data)
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
{
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
if (scheduledTicks.size()==0)
{
return;
}
sidedDelegate.profileStart("modTickStart$"+ticks);
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
ticksToRun.removeAll(EnumSet.complementOf(ticks));
if (!ticksToRun.isEmpty())
{
sidedDelegate.profileStart(ticker.getLabel());
ticker.tickStart(ticksToRun, data);
sidedDelegate.profileEnd();
}
}
sidedDelegate.profileEnd();
}
public void tickEnd(EnumSet<TickType> ticks, Object ... data)
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
{
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
if (scheduledTicks.size()==0)
{
return;
}
sidedDelegate.profileStart("modTickEnd$"+ticks);
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
ticksToRun.removeAll(EnumSet.complementOf(ticks));
if (!ticksToRun.isEmpty())
{
sidedDelegate.profileStart(ticker.getLabel());
ticker.tickEnd(ticksToRun, data);
sidedDelegate.profileEnd();
}
}
sidedDelegate.profileEnd();
}
public List<IKeyHandler> gatherKeyBindings() {
List<IKeyHandler> allKeys=new ArrayList<IKeyHandler>();
for (ModContainer mod : Loader.getModList())
{
allKeys.addAll(mod.getKeys());
}
for (ModContainer mod : auxilliaryContainers)
{
allKeys.addAll(mod.getKeys());
}
return allKeys;
}
/**
* @return the instance
*/
@@ -211,229 +148,18 @@ public class FMLCommonHandler
/**
* Find the container that associates with the supplied mod object
* @param mod
* @return
*/
public ModContainer findContainerFor(Object mod)
{
for (ModContainer mc : Loader.getModList())
{
if (mc.matches(mod))
{
return mc;
}
}
return null;
return Loader.instance().getReversedModObjectList().get(mod);
}
/**
* Lookup the mod for a channel
* @param channel
* @return
*/
public ModContainer getModForChannel(String channel)
{
return modChannels.get(channel);
}
/**
* Get the channel list for a mod
* @param modLoaderModContainer
* @return
*/
public Set<String> getChannelListFor(ModContainer container)
{
return channelList.get(container);
}
/**
* register a channel to a mod
* @param container
* @param channelName
*/
public void registerChannel(ModContainer container, String channelName)
{
if (modChannels.containsKey(channelName))
{
// NOOP
}
Set<String> list = channelList.get(container);
if (list == null)
{
list = new HashSet<String>();
channelList.put(container, list);
}
list.add(channelName);
modChannels.put(channelName, container);
}
/**
* Activate the channel for the player
* @param player
*/
public void activateChannel(Object player, String channel)
{
Set<String> active = activeChannels.get(player);
if (active == null)
{
active = new HashSet<String>();
activeChannels.put(player, active);
}
active.add(channel);
}
/**
* Deactivate the channel for the player
* @param player
* @param channel
*/
public void deactivateChannel(Object player, String channel)
{
Set<String> active = activeChannels.get(player);
if (active == null)
{
active = new HashSet<String>();
activeChannels.put(player, active);
}
active.remove(channel);
}
/**
* Get the packet 250 channel registration string
* @return
*/
public byte[] getPacketRegistry()
{
StringBuffer sb = new StringBuffer();
for (String chan : modChannels.keySet())
{
sb.append(chan).append("\0");
}
try
{
return sb.toString().getBytes("UTF8");
}
catch (UnsupportedEncodingException e)
{
Loader.log.warning("Error building registration list");
Loader.log.throwing("FMLHooks", "getPacketRegistry", e);
return new byte[0];
}
}
/**
* Is the specified channel active for the player?
* @param channel
* @param player
* @return
*/
public boolean isChannelActive(String channel, Object player)
{
return activeChannels.get(player).contains(channel);
}
/**
* Get the forge mod loader logging instance (goes to the forgemodloader log file)
* @return
* @return The log instance for the FML log file
*/
public Logger getFMLLogger()
{
return Loader.log;
}
/**
* Get the minecraft logger (goes to the server log file)
* @return
*/
public Logger getMinecraftLogger()
{
if (sidedDelegate == null)
{
throw new RuntimeException("sidedDelegate null when attempting to getMinecraftLogger, this is generally caused by you not installing FML properly, " +
"or installing some other mod that edits Minecraft.class on top of FML such as ModLoader, do not do this. Reinstall FML properly and try again.");
}
return sidedDelegate.getMinecraftLogger();
}
/**
* Is this a modloader mod?
* @param clazz
* @return
*/
public boolean isModLoaderMod(Class<?> clazz)
{
return sidedDelegate.isModLoaderMod(clazz);
}
/**
* Load the modloader mod
* @param clazz
* @param canonicalPath
* @return
*/
public ModContainer loadBaseModMod(Class<?> clazz, File canonicalFile)
{
return sidedDelegate.loadBaseModMod(clazz, canonicalFile);
}
public File getMinecraftRootDirectory() {
return sidedDelegate.getMinecraftRootDirectory();
}
/**
* @return
*/
public Object getMinecraftInstance()
{
return sidedDelegate.getMinecraftInstance();
}
/**
* @return
*/
public int nextUniqueEntityListId()
{
return uniqueEntityListId++;
}
/**
* @param key
* @param lang
* @param value
*/
public void addStringLocalization(String key, String lang, String value)
{
Properties langPack=modLanguageData.get(lang);
if (langPack==null) {
langPack=new Properties();
modLanguageData.put(lang, langPack);
}
langPack.put(key,value);
handleLanguageLoad(sidedDelegate.getCurrentLanguageTable(), lang);
}
/**
* @param languagePack
* @param lang
*/
public void handleLanguageLoad(Properties languagePack, String lang)
{
Properties usPack=modLanguageData.get("en_US");
if (usPack!=null) {
languagePack.putAll(usPack);
}
Properties langPack=modLanguageData.get(lang);
if (langPack==null) {
return;
}
languagePack.putAll(langPack);
return FMLLog.getLogger();
}
public Side getSide()
@@ -441,66 +167,42 @@ public class FMLCommonHandler
return sidedDelegate.getSide();
}
public void addAuxilliaryModContainer(ModContainer ticker)
{
auxilliaryContainers.add(ticker);
}
/**
* Called from the furnace to lookup fuel values
*
* @param itemId
* @param itemDamage
* @return
* Return the effective side for the context in the game. This is dependent
* on thread analysis to try and determine whether the code is running in the
* server or not. Use at your own risk
*/
public int fuelLookup(int itemId, int itemDamage)
public Side getEffectiveSide()
{
int fv = 0;
for (ModContainer mod : Loader.getModList())
Thread thr = Thread.currentThread();
if ((thr instanceof ThreadMinecraftServer) || (thr instanceof ServerListenThread))
{
fv = Math.max(fv, mod.lookupFuelValue(itemId, itemDamage));
return Side.SERVER;
}
return fv;
return Side.CLIENT;
}
public void addNameForObject(Object minecraftObject, String lang, String name) {
String label=sidedDelegate.getObjectName(minecraftObject);
addStringLocalization(label, lang, name);
}
/**
* Raise an exception
*
* @param exception
* @param message
* @param stopGame
*/
public void raiseException(Throwable exception, String message, boolean stopGame)
{
FMLCommonHandler.instance().getFMLLogger().throwing("FMLHandler", "raiseException", exception);
throw new RuntimeException(exception);
if (stopGame)
{
getSidedDelegate().haltGame(message,exception);
}
}
private Class<?> forge;
private boolean noForge;
private Class<?> findMinecraftForge()
{
if (forge==null && !noForge)
{
try {
forge = Class.forName("forge.MinecraftForge");
forge = Class.forName("net.minecraftforge.common.MinecraftForge");
} catch (Exception ex) {
try {
forge = Class.forName("net.minecraft.src.forge.MinecraftForge");
} catch (Exception ex2) {
// Ignore- forge isn't loaded
noForge = true;
}
noForge = true;
}
}
return forge;
@@ -520,138 +222,223 @@ public class FMLCommonHandler
return null;
}
}
/**
* @param string
* @return
*/
public String[] getBrandingStrings(String mcVersion)
public void computeBranding()
{
ArrayList<String> brandings=new ArrayList<String>();
brandings.add(mcVersion);
brandings.add(Loader.instance().getFMLVersionString());
String forgeVersion = (String)callForgeMethod("getVersionString");
if (forgeVersion != null)
if (brandings == null)
{
brandings.add(forgeVersion);
Builder brd = ImmutableList.<String>builder();
brd.add(Loader.instance().getMCVersionString());
brd.add(Loader.instance().getMCPVersionString());
brd.add("FML v"+Loader.instance().getFMLVersionString());
String forgeBranding = (String) callForgeMethod("getBrandingVersion");
if (!Strings.isNullOrEmpty(forgeBranding))
{
brd.add(forgeBranding);
}
if (sidedDelegate!=null)
{
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
}
try {
Properties props=new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
brd.add(props.getProperty("fmlbranding"));
} catch (Exception ex) {
// Ignore - no branding file found
}
int tModCount = Loader.instance().getModList().size();
int aModCount = Loader.instance().getActiveModList().size();
brd.add(String.format("%d mod%s loaded, %d mod%s active", tModCount, tModCount!=1 ? "s" :"", aModCount, aModCount!=1 ? "s" :"" ));
brandings = brd.build();
}
brandings.addAll(sidedDelegate.getAdditionalBrandingInformation());
try {
Properties props=new Properties();
props.load(FMLCommonHandler.class.getClassLoader().getResourceAsStream("fmlbranding.properties"));
brandings.add(props.getProperty("fmlbranding"));
} catch (Exception ex) {
// Ignore - no branding file found
}
brandings.add(String.format("%d mod%s loaded",Loader.getModList().size(), Loader.getModList().size()!=1?"s":""));
Collections.reverse(brandings);
return brandings.toArray(new String[brandings.size()]);
}
/**
* @param mod
*/
public void loadMetadataFor(ModContainer mod)
public List<String> getBrandings()
{
if (mod.getSourceType()==SourceType.JAR) {
ZipFile jar = null;
try
{
jar = new ZipFile(mod.getSource());
ZipEntry infoFile=jar.getEntry("mcmod.info");
if (infoFile!=null) {
InputStream input=jar.getInputStream(infoFile);
ModMetadata data=sidedDelegate.readMetadataFrom(input, mod);
mod.setMetadata(data);
} else {
getFMLLogger().fine(String.format("Failed to find mcmod.info file in %s for %s", mod.getSource().getName(), mod.getName()));
}
}
catch (Exception e)
{
// Something wrong but we don't care
getFMLLogger().fine(String.format("Failed to find mcmod.info file in %s for %s", mod.getSource().getName(), mod.getName()));
getFMLLogger().throwing("FMLCommonHandler", "loadMetadataFor", e);
}
finally
{
if (jar!=null)
{
try
{
jar.close();
}
catch (IOException e)
{
// GO AWAY
}
}
}
} else {
try
{
InputStream input=Loader.instance().getModClassLoader().getResourceAsStream(mod.getName()+".info");
if (input==null) {
input=Loader.instance().getModClassLoader().getResourceAsStream("net/minecraft/src/"+mod.getName()+".info");
}
if (input!=null) {
ModMetadata data=sidedDelegate.readMetadataFrom(input, mod);
mod.setMetadata(data);
}
}
catch (Exception e)
{
// Something wrong but we don't care
getFMLLogger().fine(String.format("Failed to find %s.info file in %s for %s", mod.getName(), mod.getSource().getName(), mod.getName()));
getFMLLogger().throwing("FMLCommonHandler", "loadMetadataFor", e);
}
if (brandings == null)
{
computeBranding();
}
return ImmutableList.copyOf(brandings);
}
/**
* @return
*/
public IFMLSidedHandler getSidedDelegate()
{
return sidedDelegate;
}
public void onPostServerTick()
{
tickEnd(EnumSet.of(TickType.SERVER), Side.SERVER);
}
/**
* @param mod
* Every tick just after world and other ticks occur
*/
public void injectSidedProxyDelegate(ModContainer mod)
public void onPostWorldTick(Object world)
{
ProxyInjector injector = mod.findSidedProxy();
if (injector != null)
tickEnd(EnumSet.of(TickType.WORLD), Side.SERVER, world);
}
public void onPreServerTick()
{
tickStart(EnumSet.of(TickType.SERVER), Side.SERVER);
}
/**
* Every tick just before world and other ticks occur
*/
public void onPreWorldTick(Object world)
{
tickStart(EnumSet.of(TickType.WORLD), Side.SERVER, world);
}
public void onWorldLoadTick(World[] worlds)
{
rescheduleTicks(Side.SERVER);
for (World w : worlds)
{
injector.inject(mod, sidedDelegate.getSide());
tickStart(EnumSet.of(TickType.WORLDLOAD), Side.SERVER, w);
}
}
public void handleWorldGeneration(int chunkX, int chunkZ, long worldSeed, Object... data)
public void handleServerStarting(MinecraftServer server)
{
Random fmlRandom = new Random(worldSeed);
long xSeed = fmlRandom.nextLong() >> 2 + 1L;
long zSeed = fmlRandom.nextLong() >> 2 + 1L;
fmlRandom.setSeed((xSeed * chunkX + zSeed * chunkZ) ^ worldSeed);
Loader.instance().serverStarting(server);
}
for (IWorldGenerator generator : worldGenerators)
public void handleServerStarted()
{
Loader.instance().serverStarted();
}
public void handleServerStopping()
{
Loader.instance().serverStopping();
}
public MinecraftServer getMinecraftServerInstance()
{
return sidedDelegate.getServer();
}
public void showGuiScreen(Object clientGuiElement)
{
sidedDelegate.showGuiScreen(clientGuiElement);
}
public Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket entitySpawnPacket)
{
return sidedDelegate.spawnEntityIntoClientWorld(registration, entitySpawnPacket);
}
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
{
sidedDelegate.adjustEntityLocationOnClient(entitySpawnAdjustmentPacket);
}
public void onServerStart(DedicatedServer dedicatedServer)
{
FMLServerHandler.instance();
sidedDelegate.beginServerLoading(dedicatedServer);
}
public void onServerStarted()
{
sidedDelegate.finishServerLoading();
}
public void onPreClientTick()
{
tickStart(EnumSet.of(TickType.CLIENT), Side.CLIENT);
}
public void onPostClientTick()
{
tickEnd(EnumSet.of(TickType.CLIENT), Side.CLIENT);
}
public void onRenderTickStart(float timer)
{
tickStart(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
}
public void onRenderTickEnd(float timer)
{
tickEnd(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
}
public void onPlayerPreTick(EntityPlayer player)
{
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
tickStart(EnumSet.of(TickType.PLAYER), side, player);
}
public void onPlayerPostTick(EntityPlayer player)
{
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
tickEnd(EnumSet.of(TickType.PLAYER), side, player);
}
public void registerCrashCallable(ICrashCallable callable)
{
crashCallables.add(callable);
}
public void enhanceCrashReport(CrashReport crashReport, CrashReportCategory category)
{
for (ICrashCallable call: crashCallables)
{
generator.generate(fmlRandom, chunkX, chunkZ, data);
category.func_71500_a(call.getLabel(), call);
}
}
public void registerTickHandler(ITickHandler handler)
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
{
registerScheduledTickHandler(new SingleIntervalHandler(handler));
sidedDelegate.handleTinyPacket(handler, mapData);
}
public void registerScheduledTickHandler(IScheduledTickHandler handler)
public void handleWorldDataSave(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
{
tickHandlers.add(new TickQueueElement(handler));
for (ModContainer mc : Loader.instance().getModList())
{
if (mc instanceof InjectedModContainer)
{
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
if (wac != null)
{
NBTTagCompound dataForWriting = wac.getDataForWriting(handler, worldInfo);
tagCompound.func_74766_a(mc.getModId(), dataForWriting);
}
}
}
}
public void registerWorldGenerator(IWorldGenerator generator)
public void handleWorldDataLoad(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
{
worldGenerators.add(generator);
if (getEffectiveSide()!=Side.SERVER)
{
return;
}
if (handlerSet.contains(handler))
{
return;
}
handlerSet.add(handler);
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
worldInfo.setAdditionalProperties(additionalProperties);
for (ModContainer mc : Loader.instance().getModList())
{
if (mc instanceof InjectedModContainer)
{
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
if (wac != null)
{
wac.readData(handler, worldInfo, additionalProperties, tagCompound.func_74775_l(mc.getModId()));
}
}
}
}
}
@@ -0,0 +1,105 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.common;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import net.minecraft.src.NBTBase;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import net.minecraft.src.NBTTagString;
import net.minecraft.src.SaveHandler;
import net.minecraft.src.WorldInfo;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
/**
* @author cpw
*
*/
public class FMLDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public FMLDummyContainer()
{
super(new ModMetadata());
ModMetadata meta = getMetadata();
meta.modId="FML";
meta.name="Forge Mod Loader";
meta.version=Loader.instance().getFMLVersionString();
meta.credits="Made possible with help from many people";
meta.authorList=Arrays.asList("cpw, LexManos");
meta.description="The Forge Mod Loader provides the ability for systems to load mods " +
"from the file system. It also provides key capabilities for mods to be able " +
"to cooperate and provide a good modding environment. " +
"The mod loading system is compatible with ModLoader, all your ModLoader " +
"mods should work.";
meta.url="https://github.com/cpw/FML/wiki";
meta.updateUrl="https://github.com/cpw/FML/wiki";
meta.screenshots=new String[0];
meta.logoFile="";
}
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
return true;
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
NBTTagCompound fmlData = new NBTTagCompound();
NBTTagList list = new NBTTagList();
for (ModContainer mc : Loader.instance().getActiveModList())
{
NBTTagCompound mod = new NBTTagCompound();
mod.func_74778_a("ModId", mc.getModId());
mod.func_74778_a("ModVersion", mc.getVersion());
list.func_74742_a(mod);
}
fmlData.func_74782_a("ModList", list);
return fmlData;
}
@Override
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
{
if (tag.func_74764_b("ModList"))
{
NBTTagList modList = tag.func_74761_m("ModList");
for (int i = 0; i < modList.func_74745_c(); i++)
{
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
String modId = mod.func_74779_i("ModId");
String modVersion = mod.func_74779_i("ModVersion");
ModContainer container = Loader.instance().getIndexedModList().get(modId);
if (container == null)
{
FMLLog.severe("This world was saved with mod %s which appears to be missing, things may not work well", modId);
continue;
}
if (!modVersion.equals(container.getVersion()))
{
FMLLog.info("This world was saved with mod %s version %s and it is now at version %s, things may not work well", modId, modVersion, container.getVersion());
}
}
}
}
}
+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, format, data);
}
public static void log(Level level, Throwable ex, String format, Object... data)
{
coreLog.log(level, ex, format, data);
}
public static void severe(String format, Object... data)
{
log(Level.SEVERE, format, data);
}
public static void warning(String format, Object... data)
{
log(Level.WARNING, format, data);
}
public static void info(String format, Object... data)
{
log(Level.INFO, format, data);
}
public static void fine(String format, Object... data)
{
log(Level.FINE, format, data);
}
public static void finer(String format, Object... data)
{
log(Level.FINER, format, data);
}
public static void finest(String format, Object... data)
{
log(Level.FINEST, format, data);
}
public static Logger getLogger()
{
return coreLog.getLogger();
}
}
+412 -322
View File
@@ -13,9 +13,53 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.ArrayList;
import java.io.FileInputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.Metadata;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.versioning.VersionRange;
public class FMLModContainer implements ModContainer
{
@@ -23,101 +67,54 @@ public class FMLModContainer implements ModContainer
private Object modInstance;
private File source;
private ModMetadata modMetadata;
private String className;
private Map<String, Object> descriptor;
private boolean enabled = true;
private String internalVersion;
private boolean overridesMetadata;
private EventBus eventBus;
private LoadController controller;
private Multimap<Class<? extends Annotation>, Object> annotations;
private DefaultArtifactVersion processedVersion;
private boolean isNetworkMod;
public FMLModContainer(String dummy)
private static final BiMap<Class<? extends FMLEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLEvent>, Class<? extends Annotation>>builder()
.put(FMLPreInitializationEvent.class, Mod.PreInit.class)
.put(FMLInitializationEvent.class, Mod.Init.class)
.put(FMLPostInitializationEvent.class, Mod.PostInit.class)
.put(FMLServerStartingEvent.class, Mod.ServerStarting.class)
.put(FMLServerStartedEvent.class, Mod.ServerStarted.class)
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
.put(IMCEvent.class,Mod.IMCCallback.class)
.build();
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
private String annotationDependencies;
private VersionRange minecraftAccepted;
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
{
this(new File(dummy));
}
public FMLModContainer(File source)
{
this.source = source;
}
public FMLModContainer(Class<?> clazz)
{
if (clazz == null)
{
return;
}
modDescriptor = clazz.getAnnotation(Mod.class);
try
{
modInstance = clazz.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
this.className = className;
this.source = modSource;
this.descriptor = modDescriptor;
}
@Override
public boolean wantsPreInit()
public String getModId()
{
return modDescriptor.wantsPreInit();
}
@Override
public boolean wantsPostInit()
{
return modDescriptor.wantsPostInit();
}
@Override
public void preInit()
{
}
@Override
public void init()
{
// TODO Auto-generated method stub
}
@Override
public void postInit()
{
// TODO Auto-generated method stub
}
public static ModContainer buildFor(Class<?> clazz)
{
return new FMLModContainer(clazz);
return (String) descriptor.get("modid");
}
@Override
public String getName()
{
// TODO Auto-generated method stub
return null;
return modMetadata.name;
}
@Override
public ModState getModState()
public String getVersion()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void nextState()
{
// TODO Auto-generated method stub
}
@Override
public String getSortingRules()
{
// TODO Auto-generated method stub
return null;
}
@Override
public boolean matches(Object mod)
{
// TODO Auto-generated method stub
return false;
return internalVersion;
}
@Override
@@ -126,267 +123,360 @@ public class FMLModContainer implements ModContainer
return source;
}
@Override
public Object getMod()
{
// TODO Auto-generated method stub
return null;
}
@Override
public int lookupFuelValue(int itemId, int itemDamage)
{
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean wantsPickupNotification()
{
// TODO Auto-generated method stub
return false;
}
@Override
public IPickupNotifier getPickupNotifier()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#wantsToDispense()
*/
@Override
public boolean wantsToDispense()
{
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getDispenseHandler()
*/
@Override
public IDispenseHandler getDispenseHandler()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#wantsCraftingNotification()
*/
@Override
public boolean wantsCraftingNotification()
{
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getCraftingHandler()
*/
@Override
public ICraftingHandler getCraftingHandler()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getDependencies()
*/
@Override
public List<String> getDependencies()
{
// TODO Auto-generated method stub
return new ArrayList<String>(0);
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getPreDepends()
*/
@Override
public List<String> getPreDepends()
{
// TODO Auto-generated method stub
return new ArrayList<String>(0);
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getPostDepends()
*/
@Override
public List<String> getPostDepends()
{
// TODO Auto-generated method stub
return new ArrayList<String>(0);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return getSource().getName();
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#wantsNetworkPackets()
*/
@Override
public boolean wantsNetworkPackets()
{
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getNetworkHandler()
*/
@Override
public INetworkHandler getNetworkHandler()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#ownsNetworkChannel(java.lang.String)
*/
@Override
public boolean ownsNetworkChannel(String channel)
{
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#wantsConsoleCommands()
*/
@Override
public boolean wantsConsoleCommands()
{
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getConsoleHandler()
*/
@Override
public IConsoleHandler getConsoleHandler()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#wantsPlayerTracking()
*/
@Override
public boolean wantsPlayerTracking()
{
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getPlayerTracker()
*/
@Override
public IPlayerTracker getPlayerTracker()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getKeys()
*/
@Override
public List<IKeyHandler> getKeys()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getSourceType()
*/
@Override
public SourceType getSourceType()
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#setSourceType(cpw.mods.fml.common.ModContainer.SourceType)
*/
@Override
public void setSourceType(SourceType type)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getMetadata()
*/
@Override
public ModMetadata getMetadata()
{
return modMetadata;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#setMetadata(cpw.mods.fml.common.ModMetadata)
*/
@Override
public void setMetadata(ModMetadata meta)
public void bindMetadata(MetadataCollection mc)
{
this.modMetadata=meta;
modMetadata = mc.getMetadataForId(getModId(), descriptor);
if (descriptor.containsKey("useMetadata"))
{
overridesMetadata = !((Boolean)descriptor.get("useMetadata")).booleanValue();
}
if (overridesMetadata || !modMetadata.useDependencyInformation)
{
Set<ArtifactVersion> requirements = Sets.newHashSet();
List<ArtifactVersion> dependencies = Lists.newArrayList();
List<ArtifactVersion> dependants = Lists.newArrayList();
annotationDependencies = (String) descriptor.get("dependencies");
Loader.instance().computeDependencies(annotationDependencies, requirements, dependencies, dependants);
modMetadata.requiredMods = requirements;
modMetadata.dependencies = dependencies;
modMetadata.dependants = dependants;
FMLLog.finest("Parsed dependency info : %s %s %s", requirements, dependencies, dependants);
}
else
{
FMLLog.finest("Using mcmod dependency info : %s %s %s", modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants);
}
if (Strings.isNullOrEmpty(modMetadata.name))
{
FMLLog.info("Mod %s is missing the required element 'name'. Substituting %s", getModId(), getModId());
modMetadata.name = getModId();
}
internalVersion = (String) descriptor.get("version");
if (Strings.isNullOrEmpty(internalVersion))
{
Properties versionProps = searchForVersionProperties();
if (versionProps != null)
{
internalVersion = versionProps.getProperty(getModId()+".version");
FMLLog.fine("Found version %s for mod %s in version.properties, using", internalVersion, getModId());
}
}
if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version))
{
FMLLog.warning("Mod %s is missing the required element 'version' and a version.properties file could not be found. Falling back to metadata version %s", getModId(), modMetadata.version);
internalVersion = modMetadata.version;
}
if (Strings.isNullOrEmpty(internalVersion))
{
FMLLog.warning("Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
modMetadata.version = internalVersion = "1.0";
}
String mcVersionString = (String) descriptor.get("acceptedMinecraftVersions");
if (!Strings.isNullOrEmpty(mcVersionString))
{
minecraftAccepted = VersionParser.parseRange(mcVersionString);
}
else
{
minecraftAccepted = Loader.instance().getMinecraftModContainer().getStaticVersionRange();
}
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#gatherRenderers(java.util.Map)
*/
@Override
public void gatherRenderers(Map renderers)
public Properties searchForVersionProperties()
{
// TODO Auto-generated method stub
try
{
FMLLog.fine("Attempting to load the file version.properties from %s to locate a version number for %s", getSource().getName(), getModId());
Properties version = null;
if (getSource().isFile())
{
ZipFile source = new ZipFile(getSource());
ZipEntry versionFile = source.getEntry("version.properties");
if (versionFile!=null)
{
version = new Properties();
version.load(source.getInputStream(versionFile));
}
source.close();
}
else if (getSource().isDirectory())
{
File propsFile = new File(getSource(),"version.properties");
if (propsFile.exists() && propsFile.isFile())
{
version = new Properties();
FileInputStream fis = new FileInputStream(propsFile);
version.load(fis);
fis.close();
}
}
return version;
}
catch (Exception e)
{
Throwables.propagateIfPossible(e);
FMLLog.fine("Failed to find a usable version.properties file");
return null;
}
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#requestAnimations()
*/
@Override
public void requestAnimations()
public void setEnabledState(boolean enabled)
{
// TODO Auto-generated method stub
this.enabled = enabled;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#getVersion()
*/
@Override
public String getVersion()
public Set<ArtifactVersion> getRequirements()
{
// TODO Auto-generated method stub
return null;
return modMetadata.requiredMods;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#findSidedProxy()
*/
@Override
public ProxyInjector findSidedProxy()
public List<ArtifactVersion> getDependencies()
{
// TODO Auto-generated method stub
return null;
return modMetadata.dependencies;
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.ModContainer#keyBindEvernt(java.lang.Object)
*/
@Override
public void keyBindEvent(Object keyBinding)
public List<ArtifactVersion> getDependants()
{
// TODO Auto-generated method stub
return modMetadata.dependants;
}
@Override
public String getSortingRules()
{
return ((overridesMetadata || !modMetadata.useDependencyInformation) ? Strings.nullToEmpty(annotationDependencies) : modMetadata.printableSortingRules());
}
@Override
public boolean matches(Object mod)
{
return mod == modInstance;
}
@Override
public Object getMod()
{
return modInstance;
}
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
if (this.enabled)
{
FMLLog.fine("Enabling mod %s", getModId());
this.eventBus = bus;
this.controller = controller;
eventBus.register(this);
return true;
}
else
{
return false;
}
}
private Multimap<Class<? extends Annotation>, Object> gatherAnnotations(Class<?> clazz) throws Exception
{
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
for (Method m : clazz.getDeclaredMethods())
{
for (Annotation a : m.getAnnotations())
{
if (modTypeAnnotations.containsKey(a.annotationType()))
{
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
if (Arrays.equals(m.getParameterTypes(), paramTypes))
{
m.setAccessible(true);
anns.put(a.annotationType(), m);
}
else
{
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
}
}
}
}
return anns;
}
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
{
SetMultimap<String, ASMData> annotations = asmDataTable.getAnnotationsFor(this);
parseSimpleFieldAnnotation(annotations, Instance.class.getName(), new Function<ModContainer, Object>()
{
public Object apply(ModContainer mc)
{
return mc.getMod();
}
});
parseSimpleFieldAnnotation(annotations, Metadata.class.getName(), new Function<ModContainer, Object>()
{
public Object apply(ModContainer mc)
{
return mc.getMetadata();
}
});
//TODO
// for (Object o : annotations.get(Block.class))
// {
// Field f = (Field) o;
// f.set(modInstance, GameRegistry.buildBlock(this, f.getType(), f.getAnnotation(Block.class)));
// }
}
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
{
String[] annName = annotationClassName.split("\\.");
String annotationName = annName[annName.length - 1];
for (ASMData targets : annotations.get(annotationClassName))
{
String targetMod = (String) targets.getAnnotationInfo().get("value");
Field f = null;
Object injectedMod = null;
ModContainer mc = this;
boolean isStatic = false;
Class<?> clz = modInstance.getClass();
if (!Strings.isNullOrEmpty(targetMod))
{
if (Loader.isModLoaded(targetMod))
{
mc = Loader.instance().getIndexedModList().get(targetMod);
}
else
{
mc = null;
}
}
if (mc != null)
{
try
{
clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader());
f = clz.getDeclaredField(targets.getObjectName());
f.setAccessible(true);
isStatic = Modifier.isStatic(f.getModifiers());
injectedMod = retreiver.apply(mc);
}
catch (Exception e)
{
Throwables.propagateIfPossible(e);
FMLLog.log(Level.WARNING, e, "Attempting to load @%s in class %s for %s and failing", annotationName, targets.getClassName(), mc.getModId());
}
}
if (f != null)
{
Object target = null;
if (!isStatic)
{
target = modInstance;
if (!modInstance.getClass().equals(clz))
{
FMLLog.warning("Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId());
continue;
}
}
f.set(target, injectedMod);
}
}
}
@Subscribe
public void constructMod(FMLConstructionEvent event)
{
try
{
ModClassLoader modClassLoader = event.getModClassLoader();
modClassLoader.addFile(source);
Class<?> clazz = Class.forName(className, true, modClassLoader);
ASMDataTable asmHarvestedAnnotations = event.getASMHarvestedData();
// TODO
asmHarvestedAnnotations.getAnnotationsFor(this);
annotations = gatherAnnotations(clazz);
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
modInstance = clazz.newInstance();
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
processFieldAnnotations(event.getASMHarvestedData());
}
catch (Throwable e)
{
controller.errorOccurred(this, e);
Throwables.propagateIfPossible(e);
}
}
@Subscribe
public void handleModStateEvent(FMLEvent event)
{
Class<? extends Annotation> annotation = modAnnotationTypes.get(event.getClass());
if (annotation == null)
{
return;
}
try
{
for (Object o : annotations.get(annotation))
{
Method m = (Method) o;
m.invoke(modInstance, event);
}
}
catch (Throwable t)
{
controller.errorOccurred(this, t);
Throwables.propagateIfPossible(t);
}
}
@Override
public ArtifactVersion getProcessedVersion()
{
if (processedVersion == null)
{
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
}
return processedVersion;
}
@Override
public boolean isImmutable()
{
return false;
}
@Override
public boolean isNetworkMod()
{
return isNetworkMod;
}
@Override
public String getDisplayVersion()
{
return modMetadata.version;
}
@Override
public VersionRange acceptableMinecraftVersionRange()
{
return minecraftAccepted;
}
}
@@ -1,77 +0,0 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.common;
import java.util.Arrays;
/**
* @author cpw
*
*/
public class FMLModLoaderContainer extends FMLModContainer
{
/**
* @param dummy
*/
public FMLModLoaderContainer()
{
super("Forge Mod Loader");
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.FMLModContainer#getMetadata()
*/
@Override
public ModMetadata getMetadata()
{
if (super.getMetadata()==null) {
ModMetadata md=new ModMetadata(this);
setMetadata(md);
md.name="Forge Mod Loader";
md.version=Loader.instance().getFMLVersionString();
md.credits="Made possible with help from many people";
md.authorList=Arrays.asList("cpw, LexManos");
md.description="The Forge Mod Loader provides the ability for systems to load mods " +
"from the file system. It also provides key capabilities for mods to be able " +
"to cooperate and provide a good modding environment. " +
"The mod loading system is compatible with ModLoader, all your ModLoader " +
"mods should work.";
md.url="https://github.com/cpw/FML/wiki";
md.updateUrl="https://github.com/cpw/FML/wiki";
md.screenshots=new String[0];
md.logoFile="";
}
return super.getMetadata();
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.FMLModContainer#getName()
*/
@Override
public String getName()
{
return "Forge Mod Loader";
}
/* (non-Javadoc)
* @see cpw.mods.fml.common.FMLModContainer#getVersion()
*/
@Override
public String getVersion()
{
return Loader.instance().getFMLVersionString();
}
}
@@ -13,28 +13,31 @@
*/
package cpw.mods.fml.common;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
/**
* Return a crafting handler for the mod container to call
*
*
* @author cpw
*
*/
public interface ICraftingHandler
{
/**
* The object array contains these three arguments
*
*
* @param player
* @param craftedItem
* @param craftingGrid
* @param item
* @param craftMatrix
*/
void onCrafting(Object... craftingParameters);
void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix);
/**
* The object array contains these two arguments
* @param player
* @param smeltedItem
* @param item
*/
void onSmelting(Object... smeltingParameters);
void onSmelting(EntityPlayer player, ItemStack item);
}
@@ -0,0 +1,8 @@
package cpw.mods.fml.common;
import java.util.concurrent.Callable;
public interface ICrashCallable extends Callable<String>
{
String getLabel();
}
@@ -12,9 +12,30 @@
*/
package cpw.mods.fml.common;
import java.util.Random;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
public interface IDispenseHandler
{
boolean dispense(double x, double y, double z, byte xVelocity, byte zVelocity, Object... data);
/**
* Return -1 if you don't want to dispense anything. the other values seem to have specific meanings
* to blockdispenser.
*
* @param x
* @param y
* @param z
* @param xVelocity
* @param zVelocity
* @param world
* @param item
* @param random
* @param entX
* @param entY
* @param entZ
*/
@Deprecated
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ);
}
@@ -0,0 +1,29 @@
package cpw.mods.fml.common;
import java.util.Random;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
/**
* @author cpw
*
*/
public interface IDispenserHandler
{
/**
* Called to dispense an entity
* @param x
* @param y
* @param z
* @param xVelocity
* @param zVelocity
* @param world
* @param item
* @param random
* @param entX
* @param entY
* @param entZ
*/
int dispense(int x, int y, int z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ);
}
@@ -0,0 +1,6 @@
package cpw.mods.fml.common;
public interface IFMLHandledException
{
}
@@ -1,30 +1,44 @@
package cpw.mods.fml.common;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import cpw.mods.fml.common.modloader.BaseMod;
import cpw.mods.fml.common.modloader.ModProperty;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.Entity;
import net.minecraft.src.NetHandler;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet131MapData;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
public interface IFMLSidedHandler
{
Logger getMinecraftLogger();
File getMinecraftRootDirectory();
boolean isModLoaderMod(Class<?> clazz);
ModContainer loadBaseModMod(Class<?> clazz, File canonicalFile);
Object getMinecraftInstance();
String getCurrentLanguage();
Properties getCurrentLanguageTable();
String getObjectName(Object minecraftObject);
ModMetadata readMetadataFrom(InputStream input, ModContainer mod) throws Exception;
void profileStart(String profileLabel);
void profileEnd();
ModProperty getModLoaderPropertyFor(Field f);
List<String> getAdditionalBrandingInformation();
Side getSide();
ProxyInjector findSidedProxyOn(BaseMod mod);
void haltGame(String message, Throwable exception);
void showGuiScreen(Object clientGuiElement);
Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket packet);
void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket);
void beginServerLoading(MinecraftServer server);
void finishServerLoading();
MinecraftServer getServer();
void sendPacket(Packet packet);
void displayMissingMods(ModMissingPacket modMissingPacket);
void handleTinyPacket(NetHandler handler, Packet131MapData mapData);
void setClientCompatibilityLevel(byte compatibilityLevel);
byte getClientCompatibilityLevel();
}
@@ -0,0 +1,8 @@
package cpw.mods.fml.common;
import net.minecraft.src.ItemStack;
public interface IFuelHandler
{
int getBurnTime(ItemStack fuel);
}
@@ -1,33 +0,0 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.common;
/**
* @author cpw
*
*/
public interface IKeyHandler
{
Object getKeyBinding();
/**
* @return
*/
ModContainer getOwningContainer();
void onEndTick();
}
@@ -13,7 +13,10 @@
*/
package cpw.mods.fml.common;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityPlayer;
public interface IPickupNotifier
{
void notifyPickup(Object... pickupData);
void notifyPickup(EntityItem item, EntityPlayer player);
}
@@ -14,13 +14,19 @@
package cpw.mods.fml.common;
import net.minecraft.src.EntityPlayer;
/**
* @author cpw
*
*/
public interface IPlayerTracker
{
void onPlayerLogin(Object player);
void onPlayerLogout(Object player);
void onPlayerChangedDimension(Object player);
void onPlayerLogin(EntityPlayer player);
void onPlayerLogout(EntityPlayer player);
void onPlayerChangedDimension(EntityPlayer player);
void onPlayerRespawn(EntityPlayer player);
}
@@ -6,8 +6,7 @@ public interface IScheduledTickHandler extends ITickHandler
* Return the number of actual ticks that will pass
* before your next tick will fire. This will be called
* just after your last tick fired to compute the next delay.
* @param tick
* @return
* @return Time until next tick
*/
public int nextTickSpacing();
}
@@ -51,14 +51,11 @@ public interface ITickHandler
/**
* Returns the list of ticks this tick handler is interested in receiving at the minute
*
* @return
*/
public EnumSet<TickType> ticks();
/**
* A profiling label for this tick handler
* @return
*/
public String getLabel();
}
@@ -15,10 +15,12 @@ package cpw.mods.fml.common;
import java.util.Random;
import net.minecraft.src.IChunkProvider;
import net.minecraft.src.World;
/**
* This is called back during world generation. The {@link #generate(Random, int, int, Object...)} method passes in some additional data that
* can be cast into minecraft objects.
*
* This is called back during world generation.
*
* @author cpw
*
*/
@@ -26,14 +28,14 @@ public interface IWorldGenerator
{
/**
* Generate some world
*
*
* @param random the chunk specific {@link Random}.
* @param chunkX the block X coordinate of this chunk.
* @param chunkZ the block Z coordinate of this chunk.
* @param chunkX the chunk X coordinate of this chunk.
* @param chunkZ the chunk Z coordinate of this chunk.
* @param world : additionalData[0] The minecraft {@link World} we're generating for.
* @param generator : additionalData[1] The {@link IChunkProvider} that is generating.
* @param chunkGenerator : additionalData[1] The {@link IChunkProvider} that is generating.
* @param chunkProvider : additionalData[2] {@link IChunkProvider} that is requesting the world generation.
*
*
*/
public void generate(Random random, int chunkX, int chunkZ, Object...additionalData);
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider);
}
@@ -0,0 +1,132 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.List;
import java.util.Set;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionRange;
public class InjectedModContainer implements ModContainer
{
private File source;
private ModContainer wrappedContainer;
public InjectedModContainer(ModContainer mc, File source)
{
this.source = source;
this.wrappedContainer = mc;
}
public String getModId()
{
return wrappedContainer.getModId();
}
public String getName()
{
return wrappedContainer.getName();
}
public String getVersion()
{
return wrappedContainer.getVersion();
}
public File getSource()
{
return source;
}
public ModMetadata getMetadata()
{
return wrappedContainer.getMetadata();
}
public void bindMetadata(MetadataCollection mc)
{
wrappedContainer.bindMetadata(mc);
}
public void setEnabledState(boolean enabled)
{
wrappedContainer.setEnabledState(enabled);
}
public Set<ArtifactVersion> getRequirements()
{
return wrappedContainer.getRequirements();
}
public List<ArtifactVersion> getDependencies()
{
return wrappedContainer.getDependencies();
}
public List<ArtifactVersion> getDependants()
{
return wrappedContainer.getDependants();
}
public String getSortingRules()
{
return wrappedContainer.getSortingRules();
}
public boolean registerBus(EventBus bus, LoadController controller)
{
return wrappedContainer.registerBus(bus, controller);
}
public boolean matches(Object mod)
{
return wrappedContainer.matches(mod);
}
public Object getMod()
{
return wrappedContainer.getMod();
}
public ArtifactVersion getProcessedVersion()
{
return wrappedContainer.getProcessedVersion();
}
@Override
public boolean isNetworkMod()
{
return wrappedContainer.isNetworkMod();
}
@Override
public boolean isImmutable()
{
return true;
}
@Override
public String getDisplayVersion()
{
return wrappedContainer.getDisplayVersion();
}
@Override
public VersionRange acceptableMinecraftVersionRange()
{
return wrappedContainer.acceptableMinecraftVersionRange();
}
public WorldAccessContainer getWrappedWorldAccessContainer()
{
if (wrappedContainer instanceof WorldAccessContainer)
{
return (WorldAccessContainer) wrappedContainer;
}
else
{
return null;
}
}
}
@@ -0,0 +1,240 @@
package cpw.mods.fml.common;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.event.FMLEvent;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
public class LoadController
{
private Loader loader;
private EventBus masterChannel;
private ImmutableMap<String,EventBus> eventChannels;
private LoaderState state;
private Multimap<String, ModState> modStates = ArrayListMultimap.create();
private Multimap<String, Throwable> errors = ArrayListMultimap.create();
private Map<String, ModContainer> modList;
private List<ModContainer> activeModList = Lists.newArrayList();
private ModContainer activeContainer;
private BiMap<ModContainer, Object> modObjectList;
public LoadController(Loader loader)
{
this.loader = loader;
this.masterChannel = new EventBus("FMLMainChannel");
this.masterChannel.register(this);
state = LoaderState.NOINIT;
}
@Subscribe
public void buildModList(FMLLoadEvent event)
{
this.modList = loader.getIndexedModList();
Builder<String, EventBus> eventBus = ImmutableMap.builder();
for (ModContainer mod : loader.getModList())
{
EventBus bus = new EventBus(mod.getModId());
boolean isActive = mod.registerBus(bus, this);
if (isActive)
{
FMLLog.fine("Activating mod %s", mod.getModId());
activeModList.add(mod);
modStates.put(mod.getModId(), ModState.UNLOADED);
eventBus.put(mod.getModId(), bus);
}
else
{
FMLLog.warning("Mod %s has been disabled through configuration", mod.getModId());
modStates.put(mod.getModId(), ModState.UNLOADED);
modStates.put(mod.getModId(), ModState.DISABLED);
}
}
eventChannels = eventBus.build();
}
public void distributeStateMessage(LoaderState state, Object... eventData)
{
if (state.hasEvent())
{
masterChannel.post(state.getEvent(eventData));
}
}
public void transition(LoaderState desiredState)
{
LoaderState oldState = state;
state = state.transition(!errors.isEmpty());
if (state != desiredState)
{
Throwable toThrow = null;
FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState);
StringBuilder sb = new StringBuilder();
printModStates(sb);
FMLLog.severe(sb.toString());
FMLLog.severe("The following problems were captured during this phase");
for (Entry<String, Throwable> error : errors.entries())
{
FMLLog.log(Level.SEVERE, error.getValue(), "Caught exception from %s", error.getKey());
if (error.getValue() instanceof IFMLHandledException)
{
toThrow = error.getValue();
}
else if (toThrow == null)
{
toThrow = error.getValue();
}
}
if (toThrow != null && toThrow instanceof RuntimeException)
{
throw (RuntimeException)toThrow;
}
else
{
throw new LoaderException(toThrow);
}
}
}
public ModContainer activeContainer()
{
return activeContainer;
}
@Subscribe
public void propogateStateMessage(FMLEvent stateEvent)
{
if (stateEvent instanceof FMLPreInitializationEvent)
{
modObjectList = buildModObjectList();
}
for (ModContainer mc : activeModList)
{
activeContainer = mc;
String modId = mc.getModId();
stateEvent.applyModContainer(activeContainer());
FMLLog.finer("Sending event %s to mod %s", stateEvent.getEventType(), modId);
eventChannels.get(modId).post(stateEvent);
FMLLog.finer("Sent event %s to mod %s", stateEvent.getEventType(), modId);
activeContainer = null;
if (stateEvent instanceof FMLStateEvent)
{
if (!errors.containsKey(modId))
{
modStates.put(modId, ((FMLStateEvent)stateEvent).getModState());
}
else
{
modStates.put(modId, ModState.ERRORED);
}
}
}
}
public ImmutableBiMap<ModContainer, Object> buildModObjectList()
{
ImmutableBiMap.Builder<ModContainer, Object> builder = ImmutableBiMap.<ModContainer, Object>builder();
for (ModContainer mc : activeModList)
{
if (!mc.isImmutable() && mc.getMod()!=null)
{
builder.put(mc, mc.getMod());
}
if (mc.getMod()==null && !mc.isImmutable() && state!=LoaderState.CONSTRUCTING)
{
FMLLog.severe("There is a severe problem with %s - it appears not to have constructed correctly", mc.getModId());
if (state != LoaderState.CONSTRUCTING)
{
this.errorOccurred(mc, new RuntimeException());
}
}
}
return builder.build();
}
public void errorOccurred(ModContainer modContainer, Throwable exception)
{
if (exception instanceof InvocationTargetException)
{
errors.put(modContainer.getModId(), ((InvocationTargetException)exception).getCause());
}
else
{
errors.put(modContainer.getModId(), exception);
}
}
public void printModStates(StringBuilder ret)
{
for (ModContainer mc : loader.getModList())
{
ret.append("\n\t").append(mc.getModId()).append(" [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
Joiner.on("->"). appendTo(ret, modStates.get(mc.getModId()));
}
}
public List<ModContainer> getActiveModList()
{
return activeModList;
}
public ModState getModState(ModContainer selectedMod)
{
return Iterables.getLast(modStates.get(selectedMod.getModId()), ModState.AVAILABLE);
}
public void distributeStateMessage(Class<?> customEvent)
{
try
{
masterChannel.post(customEvent.newInstance());
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "An unexpected exception");
throw new LoaderException(e);
}
}
public BiMap<ModContainer, Object> getModObjectList()
{
if (modObjectList == null)
{
FMLLog.severe("Detected an attempt by a mod %s to perform game activity during mod construction. This is a serious programming error.", activeContainer);
return buildModObjectList();
}
return ImmutableBiMap.copyOf(modObjectList);
}
public boolean isInState(LoaderState state)
{
return this.state == state;
}
boolean hasReachedState(LoaderState state) {
return this.state.ordinal()>=state.ordinal() && this.state!=LoaderState.ERRORED;
}
}
File diff suppressed because it is too large. Load diff
+104
View File
@@ -0,0 +1,104 @@
package cpw.mods.fml.common;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
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,14 @@
package cpw.mods.fml.common;
import com.google.common.eventbus.EventBus;
public class MCPDummyContainer extends DummyModContainer {
public MCPDummyContainer(ModMetadata metadata) {
super(metadata);
}
@Override
public boolean registerBus(EventBus bus, LoadController controller) {
return true;
}
}
@@ -0,0 +1,91 @@
package cpw.mods.fml.common;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.logging.Level;
import argo.jdom.JdomParser;
import argo.jdom.JsonNode;
import argo.jdom.JsonRootNode;
import argo.saj.InvalidSyntaxException;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
public class MetadataCollection
{
private static JdomParser parser = new JdomParser();
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
private int metadataVersion = 1;
public static MetadataCollection from(InputStream inputStream, String sourceName)
{
if (inputStream == null)
{
return new MetadataCollection();
}
InputStreamReader reader = new InputStreamReader(inputStream);
try
{
JsonRootNode root = parser.parse(reader);
if (root.hasElements())
{
return parse10ModInfo(root);
}
else
{
return parseModInfo(root);
}
}
catch (InvalidSyntaxException e)
{
FMLLog.log(Level.SEVERE, e, "The mcmod.info file in %s cannot be parsed as valid JSON. It will be ignored", sourceName);
return new MetadataCollection();
}
catch (Exception e)
{
throw Throwables.propagate(e);
}
}
private static MetadataCollection parseModInfo(JsonRootNode root)
{
MetadataCollection mc = new MetadataCollection();
mc.metadataVersion = Integer.parseInt(root.getNumberValue("modinfoversion"));
mc.parseModMetadataList(root.getNode("modlist"));
return mc;
}
private static MetadataCollection parse10ModInfo(JsonRootNode root)
{
MetadataCollection mc = new MetadataCollection();
mc.parseModMetadataList(root);
return mc;
}
private void parseModMetadataList(JsonNode metadataList)
{
for (JsonNode node : metadataList.getElements())
{
ModMetadata mmd = new ModMetadata(node);
metadatas.put(mmd.modId, mmd);
}
}
public ModMetadata getMetadataForId(String modId, Map<String, Object> extraData)
{
if (!metadatas.containsKey(modId))
{
ModMetadata dummy = new ModMetadata();
dummy.modId = modId;
dummy.name = (String) extraData.get("name");
dummy.version = (String) extraData.get("version");
dummy.autogenerated = true;
metadatas.put(modId, dummy);
}
return metadatas.get(modId);
}
}
@@ -0,0 +1,26 @@
package cpw.mods.fml.common;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.versioning.VersionRange;
public class MinecraftDummyContainer extends DummyModContainer
{
private VersionRange staticRange;
public MinecraftDummyContainer(String actualMCVersion)
{
super(new ModMetadata());
getMetadata().modId = "Minecraft";
getMetadata().name = "Minecraft";
getMetadata().version = actualMCVersion;
staticRange = VersionParser.parseRange("["+actualMCVersion+"]");
}
public VersionRange getStaticVersionRange()
{
return staticRange;
}
}
@@ -0,0 +1,18 @@
package cpw.mods.fml.common;
import java.util.Set;
import com.google.common.collect.Sets.SetView;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class MissingModsException extends RuntimeException
{
public Set<ArtifactVersion> missingMods;
public MissingModsException(Set<ArtifactVersion> missingMods)
{
this.missingMods = missingMods;
}
}
+191 -6
View File
@@ -13,23 +13,208 @@
*/
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.FMLInterModComms;
import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage;
import net.minecraft.src.ItemBlock;
/**
* A possible future way to indicate mods to the system is to use an annotation style
*
* The new mod style in FML 1.3
*
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Mod
{
String name() default "";
String version() default "";
boolean wantsPreInit() default false;
boolean wantsPostInit() default false;
/**
* The unique mod identifier for this mod
*/
String modid();
/**
* A user friendly name for the mod
*/
String name() default "";
/**
* A version string for this mod
*/
String version() default "";
/**
* A simple dependency string for this mod (see modloader's "priorities" string specification)
*/
String dependencies() default "";
/**
* Whether to use the mcmod.info metadata by default for this mod.
* If true, settings in the mcmod.info file will override settings in these annotations.
*/
boolean useMetadata() default false;
/**
* The acceptable range of minecraft versions that this mod will load and run in
* The default ("empty string") indicates that only the current minecraft version is acceptable.
* FML will refuse to run with an error if the minecraft version is not in this range across all mods.
* @return A version range as specified by the maven version range specification or the empty string
*/
String acceptedMinecraftVersions() default "";
/**
* An optional bukkit plugin that will be injected into the bukkit plugin framework if
* this mod is loaded into the FML framework and the bukkit coremod is present.
* Instances of the bukkit plugin can be obtained via the {@link BukkitPluginRef} annotation on fields.
* @return The name of the plugin to load for this mod
*/
String bukkitPlugin() default "";
/**
* Mods that this mod will <strong>not</strong> load with.
* An optional comma separated string of (+|-)(*|modid[@value]) which specify mods that
* this mod will refuse to load with, resulting in the game failing to start.
* Entries can be prefixed with a + for a positive exclusion assertion, or - for a negative exclusion
* assertion. Asterisk is the wildcard and represents <strong>all</strong> mods.
*
* The <strong>only</strong> mods that cannot be excluded are FML and MCP, trivially.
* Other special values:
* <ul>
* <li>+f indicates that the mod will accept a minecraft forge environment.</li>
* <li>-* indicates that the mod will not accept any other mods.</li>
* </ul>
*
* Some examples:
* <ul>
* <li><em>-*,+f,+IronChest</em>: Will run only in a minecraft forge environment with the mod IronChests.
* The -* forces all mods to be excluded, then the +f and +IronChest add into the "allowed list".</li>
* <li><em>+f,-IC2</em>: Will run in a minecraft forge environment but will <strong>not</strong> run if
* IndustrialCraft 2 (IC2) is loaded alongside.</li>
* <li><em>-*</em>: Will not run if <strong>any</strong> othe mod is loaded except MCP/FML itself.</li>
* </ul>
*
* If a mod is present on the excluded list, the game will stop and show an error screen. If the
* class containing the {@link Mod} annotation has a "getCustomErrorException" method, it will be
* called to retrieve a custom error message for display in this case. If two mods have a declared
* exclusion which is matched, the screen that is shown is indeterminate.
*
* @return A string listing modids to exclude from loading with this mod.
*/
String modExclusionList() default "";
/**
* 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 "server-started" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServerStarted {}
/**
* Mark the designated method as being called at the "server-stopping" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServerStopping {}
/**
* Mark the designated method as the receiver for {@link FMLInterModComms} messages
* Called between {@link Init} and {@link PostInit}
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface IMCCallback {}
/**
* Populate the annotated field with the mod instance.
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Instance {
/**
* The mod object to inject into this field
*/
String value() default "";
}
/**
* Populate the annotated field with the mod's metadata.
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Metadata {
/**
* The mod id specifying the metadata to load here
*/
String value() default "";
}
/**
* Populate the annotated field with an instance of the Block as specified
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Block {
/**
* The block's name
*/
String name();
/**
* The associated ItemBlock subtype for the item (can be null for an ItemBlock)
*/
Class<?> itemTypeClass() default ItemBlock.class;
}
/**
* Populate the annotated field with an Item
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Item {
/**
* The name of the item
*/
String name();
/**
* The type of the item
*/
String typeClass();
}
}
+49 -39
View File
@@ -14,66 +14,76 @@
package cpw.mods.fml.common;
import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import java.util.logging.Level;
import com.google.common.collect.ImmutableList;
import cpw.mods.fml.common.asm.ASMTransformer;
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.common.modloader.BaseModProxy;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
/**
* A simple delegating class loader used to load mods into the system
*
*
*
*
* @author cpw
*
*/
public class ModClassLoader extends URLClassLoader
{
public ModClassLoader()
{
super(new URL[0], ModClassLoader.class.getClassLoader());
}
private static final List<String> STANDARD_LIBRARIES = ImmutableList.of("jinput.jar", "lwjgl.jar", "lwjgl_util.jar");
private RelaunchClassLoader mainClassLoader;
public ModClassLoader(ClassLoader parent) {
super(new URL[0], null);
this.mainClassLoader = (RelaunchClassLoader)parent;
}
public void addFile(File modFile) throws MalformedURLException
{
ClassLoader cl=getParent();
if (cl instanceof URLClassLoader) {
URLClassLoader ucl=(URLClassLoader) cl;
URL url = modFile.toURI().toURL();
try {
Method addUrl=URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addUrl.setAccessible(true);
addUrl.invoke(ucl, url);
} catch (Exception e) {
Loader.log.severe("A fatal error occured attempting to load a file into the classloader");
throw new LoaderException(e);
mainClassLoader.addURL(url);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException
{
return mainClassLoader.loadClass(name);
}
public File[] getParentSources() {
List<URL> urls=mainClassLoader.getSources();
File[] sources=new File[urls.size()];
try
{
for (int i = 0; i<urls.size(); i++)
{
sources[i]=new File(urls.get(i).toURI());
}
return sources;
}
catch (URISyntaxException e)
{
FMLLog.log(Level.SEVERE, "Unable to process our input to locate the minecraft code", e);
throw new LoaderException(e);
}
}
public File[] getParentSources() {
ClassLoader cl=getParent();
if (cl instanceof URLClassLoader) {
URLClassLoader ucl=(URLClassLoader) cl;
URL[] pUrl=ucl.getURLs();
File[] sources=new File[pUrl.length];
try
{
for (int i=0; i<pUrl.length; i++) {
sources[i]=new File(pUrl[i].toURI());
}
return sources;
}
catch (URISyntaxException e)
{
Loader.log.throwing("ModClassLoader", "getParentSources", e);
}
}
Loader.log.severe("Unable to process our input to locate the minecraft code");
throw new LoaderException();
public List<String> getDefaultLibraries()
{
return STANDARD_LIBRARIES;
}
public Class<? extends BaseModProxy> loadBaseModClass(String modClazzName) throws Exception
{
AccessTransformer transformer = (AccessTransformer)mainClassLoader.getTransformers().get(0);
transformer.ensurePublicAccessFor(modClazzName);
return (Class<? extends BaseModProxy>) Class.forName(modClazzName, true, this);
}
}
+93 -174
View File
@@ -15,15 +15,21 @@ package cpw.mods.fml.common;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import cpw.mods.fml.common.ModContainer.SourceType;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionRange;
/**
* The container that wraps around mods in the system.
* <p>The philosophy is that individual mod implementation technologies should not impact the actual loading and management
* of mod code. This interface provides a mechanism by which we can wrap actual mod code so that the loader and other
* facilities can treat mods at arms length.</p>
* <p>
* The philosophy is that individual mod implementation technologies should not
* impact the actual loading and management of mod code. This interface provides
* a mechanism by which we can wrap actual mod code so that the loader and other
* facilities can treat mods at arms length.
* </p>
*
* @author cpw
*
@@ -31,183 +37,96 @@ import cpw.mods.fml.common.ModContainer.SourceType;
public interface ModContainer
{
public enum ModState {
UNLOADED("Unloaded"), LOADED("Loaded"), PREINITIALIZED("Pre-initialized"), INITIALIZED("Initialized"), POSTINITIALIZED("Post-initialized"), AVAILABLE("Available");
private String label;
/**
* The globally unique modid for this mod
*/
String getModId();
private ModState(String label) {
this.label=label;
}
public String toString() {
return this.label;
}
}
public enum SourceType {
JAR, CLASSPATH, DIR;
}
/**
* The enclosed mod wants to be called during pre-initialization.
* @return
*/
boolean wantsPreInit();
/**
* The enclosed mod wants to be called during post-initialization.
* @return
*/
boolean wantsPostInit();
/**
* Called when pre-initialization occurs.
*/
void preInit();
/**
* Called when main initialization occurs.
*/
void init();
/**
* Called when post-initialization occurs.
*/
void postInit();
/**
* The name of the mod
* @return
* A human readable name
*/
String getName();
/**
* The state of the mod
* @return
*/
ModState getModState();
/**
* Move to the next mod state
*/
void nextState();
/**
* Does this mod match the supplied mod?
* @param mod
* @return
*/
boolean matches(Object mod);
/**
* The source of this mod: the file on the file system
* @return
*/
File getSource();
/**
* Returns the sorting rules as a string for printing
* @return
*/
String getSortingRules();
/**
* The actual mod object itself
* @return
*/
Object getMod();
/**
* Lookup the fuel value for the supplied item/damage with this mod.
* @param itemId
* @param itemDamage
* @return
*/
int lookupFuelValue(int itemId, int itemDamage);
/**
* This mod wants to be notified when an object is picked up.
* @return
*/
boolean wantsPickupNotification();
/**
* The pickup notifier for this mod.
* @return
*/
IPickupNotifier getPickupNotifier();
/**
* This mod wants to have special dispenser handling.
* @return
*/
boolean wantsToDispense();
/**
* The dispensing handler.
* @return
*/
IDispenseHandler getDispenseHandler();
/**
* This mod wants notification of crafting and/or smelting events.
* @return
*/
boolean wantsCraftingNotification();
/**
* The crafting and smelting handler for this mod.
* @return
*/
ICraftingHandler getCraftingHandler();
/**
* The strong dependencies of this mod. If the named mods in this list are not present, the game will abort.
* @return
*/
List<String> getDependencies();
/**
* Get a list of mods to load before this one. The special value "*" indicates to load <i>after</i> all other mods (except other "*" mods).
* @return
*/
List<String> getPreDepends();
/**
* Get a list of mods to load after this one. The special value "*" indicates to load <i>before</i> all other mods (except other "*" mods).
* @return
*/
List<String> getPostDepends();
/**
* This mod wants packets from the client, and wants them handled by FML.
* @return
*/
boolean wantsNetworkPackets();
/**
* The network handler for this mod.
* @return
*/
INetworkHandler getNetworkHandler();
/**
* Does this mod own this channel?
* @param channel
* @return
*/
boolean ownsNetworkChannel(String channel);
/**
* Does this mod want commands from the console?
* @return
*/
boolean wantsConsoleCommands();
IConsoleHandler getConsoleHandler();
boolean wantsPlayerTracking();
IPlayerTracker getPlayerTracker();
List<IKeyHandler> getKeys();
SourceType getSourceType();
void setSourceType(SourceType type);
ModMetadata getMetadata();
void setMetadata(ModMetadata meta);
/**
*
*/
void gatherRenderers(Map renderers);
/**
*
*/
void requestAnimations();
/**
* @return
* A human readable version identifier
*/
String getVersion();
/**
* @return
* The location on the file system which this mod came from
*/
ProxyInjector findSidedProxy();
void keyBindEvent(Object keyBinding);
File getSource();
/**
* The metadata for this mod
*/
ModMetadata getMetadata();
/**
* Attach this mod to it's metadata from the supplied metadata collection
*/
void bindMetadata(MetadataCollection mc);
/**
* Set the enabled/disabled state of this mod
*/
void setEnabledState(boolean enabled);
/**
* A list of the modids that this mod requires loaded prior to loading
*/
Set<ArtifactVersion> getRequirements();
/**
* A list of modids that should be loaded prior to this one. The special
* value <strong>*</strong> indicates to load <em>before</em> any other mod.
*/
List<ArtifactVersion> getDependencies();
/**
* A list of modids that should be loaded <em>after</em> this one. The
* special value <strong>*</strong> indicates to load <em>after</em> any
* other mod.
*/
List<ArtifactVersion> getDependants();
/**
* A representative string encapsulating the sorting preferences for this
* mod
*/
String getSortingRules();
/**
* Register the event bus for the mod and the controller for error handling
* Returns if this bus was successfully registered - disabled mods and other
* mods that don't need real events should return false and avoid further
* processing
*
* @param bus
* @param controller
*/
boolean registerBus(EventBus bus, LoadController controller);
/**
* Does this mod match the supplied mod
*
* @param mod
*/
boolean matches(Object mod);
/**
* Get the actual mod object
*/
Object getMod();
ArtifactVersion getProcessedVersion();
boolean isImmutable();
boolean isNetworkMod();
String getDisplayVersion();
VersionRange acceptableMinecraftVersionRange();
}
@@ -0,0 +1,58 @@
package cpw.mods.fml.common;
import java.io.File;
import java.util.regex.Pattern;
import org.objectweb.asm.Type;
import cpw.mods.fml.common.discovery.ModCandidate;
import cpw.mods.fml.common.discovery.asm.ASMModParser;
import cpw.mods.fml.common.discovery.asm.ModAnnotation;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
public class ModContainerFactory
{
private static Pattern modClass = Pattern.compile(".*(\\.|)(mod\\_[^\\s$]+)$");
private static ModContainerFactory INSTANCE = new ModContainerFactory();
public static ModContainerFactory instance() {
return INSTANCE;
}
public ModContainer build(ASMModParser modParser, File modSource, ModCandidate container)
{
String className = modParser.getASMType().getClassName();
if (modParser.isBaseMod(container.getRememberedBaseMods()) && modClass.matcher(className).find())
{
FMLLog.fine("Identified a BaseMod type mod %s", className);
return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties());
}
else if (modClass.matcher(className).find())
{
FMLLog.fine("Identified a class %s following modloader naming convention but not directly a BaseMod or currently seen subclass", className);
container.rememberModCandidateType(modParser);
}
else if (modParser.isBaseMod(container.getRememberedBaseMods()))
{
FMLLog.fine("Found a basemod %s of non-standard naming format", className);
container.rememberBaseModType(className);
}
// We warn if it's not a basemod instance -- compatibility requires it to be in net.minecraft.src *sigh*
if (className.startsWith("net.minecraft.src.") && container.isClasspath() && !container.isMinecraftJar())
{
FMLLog.severe("FML has detected a mod that is using a package name based on 'net.minecraft.src' : %s. This is generally a severe programming error. "
+ " There should be no mod code in the minecraft namespace. MOVE YOUR MOD! If you're in eclipse, select your source code and 'refactor' it into "
+ "a new package. Go on. DO IT NOW!",className);
}
for (ModAnnotation ann : modParser.getAnnotations())
{
if (ann.getASMType().equals(Type.getType(Mod.class)))
{
FMLLog.fine("Identified an FMLMod type mod %s", className);
return new FMLModContainer(className, modSource, ann.getValues());
}
}
return null;
}
}
+120 -60
View File
@@ -14,91 +14,151 @@
package cpw.mods.fml.common;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import static argo.jdom.JsonNodeBuilders.aStringBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
import java.util.Set;
import java.util.logging.Level;
import argo.jdom.JsonNode;
import argo.jdom.JsonStringNode;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.functions.ModNameFunction;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
/**
* @author cpw
*
*/
public class ModMetadata
{
public enum ModType { MODLOADER, FML };
public ModContainer mod;
public ModType type;
private static final class JsonStringConverter implements Function<JsonNode, Object>
{
public Object apply(JsonNode arg0)
{
if (arg0.hasElements())
{
return Lists.transform(arg0.getElements(), new JsonArrayConverter());
}
else
{
return arg0.getText();
}
}
}
private static final class JsonArrayConverter implements Function<JsonNode, String>
{
public String apply(JsonNode arg0)
{
return arg0.getText();
}
}
public String modId;
public String name;
public String description;
public String url="";
public String updateUrl="";
public String logoFile="";
public String version="";
public List<String> authorList=new ArrayList<String>(1);
public String credits="";
public String parent="";
public String url = "";
public String updateUrl = "";
public String logoFile = "";
public String version = "";
public List<String> authorList = Lists.newArrayList();
public String credits = "";
public String parent = "";
public String[] screenshots;
public ModContainer parentMod;
public List<ModContainer> childMods = new ArrayList<ModContainer>(1);
public List<ModContainer> childMods = Lists.newArrayList();
/**
* @param mod2
* @param type2
*/
public ModMetadata(ModContainer mod)
public boolean useDependencyInformation;
public Set<ArtifactVersion> requiredMods;
public List<ArtifactVersion> dependencies;
public List<ArtifactVersion> dependants;
public boolean autogenerated;
public ModMetadata(JsonNode node)
{
this.mod=mod;
this.type=(mod instanceof FMLModContainer ? ModType.FML : ModType.MODLOADER);
}
public void associate(Map<String, ModContainer> mods) {
if (parent!=null && parent.length() > 0) {
ModContainer mc=mods.get(parent);
if (mc!=null && mc.getMetadata()!=null) {
mc.getMetadata().childMods.add(mod);
parentMod = mc;
}
Map<JsonStringNode, Object> processedFields = Maps.transformValues(node.getFields(), new JsonStringConverter());
modId = (String)processedFields.get(aStringBuilder("modid"));
if (Strings.isNullOrEmpty(modId))
{
FMLLog.log(Level.SEVERE, "Found an invalid mod metadata file - missing modid");
throw new LoaderException();
}
name = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("name")));
description = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("description")));
url = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("url")));
updateUrl = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("updateUrl")));
logoFile = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("logoFile")));
version = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("version")));
credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
parent = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), HashSet.class);
dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), ArrayList.class);
dependants = processReferences(processedFields.get(aStringBuilder("dependants")), ArrayList.class);
useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
}
public ModMetadata()
{
}
private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
{
T res = null;
try
{
res = retType.newInstance();
}
catch (Exception e)
{
// unpossible
}
if (refs == null)
{
return res;
}
for (String ref : ((List<String>)refs))
{
res.add(VersionParser.parseVersionReference(ref));
}
return res;
}
/**
* @return
*/
public String getChildModCountString()
{
return String.format("%d child mod%s", childMods.size(), childMods.size()!=1 ? "s" : "");
return String.format("%d child mod%s", childMods.size(), childMods.size() != 1 ? "s" : "");
}
public String getAuthorList() {
StringBuilder sb=new StringBuilder();
for (int i=0; i<authorList.size(); i++) {
sb.append(authorList.get(i));
if (i<authorList.size()-1) {
sb.append(", ");
}
}
return sb.toString();
public String getAuthorList()
{
return Joiner.on(", ").join(authorList);
}
/**
* @return
*/
public String getChildModList()
{
StringBuilder sb=new StringBuilder();
for (int i=0; i<childMods.size(); i++) {
sb.append(childMods.get(i).getMetadata().name);
if (i<childMods.size()-1) {
sb.append(", ");
}
}
return sb.toString();
return Joiner.on(", ").join(Lists.transform(childMods, new ModNameFunction()));
}
public String printableSortingRules()
{
return "";
}
}
@@ -0,0 +1,116 @@
/*
* The FML Forge Mod Loader suite. Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.common;
import java.util.Arrays;
import java.util.logging.Level;
import cpw.mods.fml.relauncher.ReflectionHelper;
import cpw.mods.fml.relauncher.ReflectionHelper.UnableToAccessFieldException;
import cpw.mods.fml.relauncher.ReflectionHelper.UnableToFindFieldException;
/**
* Some reflection helper code.
*
* @author cpw
*
*/
public class ObfuscationReflectionHelper
{
public static boolean obfuscation;
@SuppressWarnings("unchecked")
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, int fieldIndex)
{
try
{
return ReflectionHelper.getPrivateValue(classToAccess, instance, fieldIndex);
}
catch (UnableToAccessFieldException e)
{
FMLLog.log(Level.SEVERE, e, "There was a problem getting field index %d from %s", fieldIndex, classToAccess.getName());
throw e;
}
}
@SuppressWarnings("unchecked")
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, String... fieldNames)
{
try
{
return ReflectionHelper.getPrivateValue(classToAccess, instance, fieldNames);
}
catch (UnableToFindFieldException e)
{
FMLLog.log(Level.SEVERE,e,"Unable to locate any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
throw e;
}
catch (UnableToAccessFieldException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to access any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
throw e;
}
}
@Deprecated
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, int fieldIndex, E value)
{
setPrivateValue(classToAccess, instance, value, fieldIndex);
}
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, E value, int fieldIndex)
{
try
{
ReflectionHelper.setPrivateValue(classToAccess, instance, value, fieldIndex);
}
catch (UnableToAccessFieldException e)
{
FMLLog.log(Level.SEVERE, e, "There was a problem setting field index %d on type %s", fieldIndex, classToAccess.getName());
throw e;
}
}
@Deprecated
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, String fieldName, E value)
{
setPrivateValue(classToAccess, instance, value, fieldName);
}
public static <T, E> void setPrivateValue(Class<? super T> classToAccess, T instance, E value, String... fieldNames)
{
try
{
ReflectionHelper.setPrivateValue(classToAccess, instance, value, fieldNames);
}
catch (UnableToFindFieldException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to locate any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
throw e;
}
catch (UnableToAccessFieldException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to set any field %s on type %s", Arrays.toString(fieldNames), classToAccess.getName());
throw e;
}
}
/**
*
*/
public static void detectObfuscation(Class<?> clazz)
{
obfuscation = !clazz.getSimpleName().equals("World");
}
}
+41 -45
View File
@@ -15,6 +15,12 @@
package cpw.mods.fml.common;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Set;
import java.util.logging.Level;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
/**
* @author cpw
@@ -22,55 +28,45 @@ import java.lang.reflect.Field;
*/
public class ProxyInjector
{
private String clientName;
private String serverName;
private String bukkitName;
private Field target;
public static void inject(ModContainer mod, ASMDataTable data, Side side)
{
FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId());
Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName());
ClassLoader mcl = Loader.instance().getModClassLoader();
public ProxyInjector(String clientName, String serverName, String bukkitName, Field target)
{
this.clientName = clientName;
this.serverName = serverName;
this.bukkitName = bukkitName;
this.target = target;
}
public boolean isValidFor(Side type)
{
if (type == Side.CLIENT)
for (ASMData targ : targets)
{
return !this.clientName.isEmpty();
}
else if (type == Side.SERVER)
{
return !this.serverName.isEmpty();
}
else if (type == Side.BUKKIT)
{
return this.bukkitName.isEmpty();
}
return false;
}
public void inject(ModContainer mod, Side side)
{
String targetType = side == Side.CLIENT ? clientName : serverName;
try
{
Object proxy=Class.forName(targetType, false, Loader.instance().getModClassLoader()).newInstance();
if (target.getType().isAssignableFrom(proxy.getClass()))
try
{
target.set(mod.getMod(), proxy);
} else {
FMLCommonHandler.instance().getFMLLogger().severe(String.format("Attempted to load a proxy type %s into %s, but the types don't match", targetType, target.getName()));
throw new LoaderException();
Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl);
Field target = proxyTarget.getDeclaredField(targ.getObjectName());
if (target == null)
{
// Impossible?
FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName());
throw new LoaderException();
}
String targetType = side.isClient() ? target.getAnnotation(SidedProxy.class).clientSide() : target.getAnnotation(SidedProxy.class).serverSide();
Object proxy=Class.forName(targetType, true, mcl).newInstance();
if ((target.getModifiers() & Modifier.STATIC) == 0 )
{
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName());
throw new LoaderException();
}
if (!target.getType().isAssignableFrom(proxy.getClass()))
{
FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName());
throw new LoaderException();
}
target.set(null, proxy);
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName());
throw new LoaderException(e);
}
}
catch (Exception e)
{
FMLCommonHandler.instance().getFMLLogger().severe(String.format("An error occured trying to load a proxy type %s into %s", targetType, target.getName()));
FMLCommonHandler.instance().getFMLLogger().throwing("ProxyInjector", "inject", e);
throw new LoaderException(e);
}
}
}
@@ -1,105 +0,0 @@
/*
* The FML Forge Mod Loader suite. Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package cpw.mods.fml.common;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Some reflection helper code.
*
* @author cpw
*
*/
public class ReflectionHelper
{
public static boolean obfuscation;
@SuppressWarnings("unchecked")
public static <T, E> T getPrivateValue(Class <? super E > classToAccess, E instance, int fieldIndex)
{
try
{
Field f = classToAccess.getDeclaredFields()[fieldIndex];
f.setAccessible(true);
return (T) f.get(instance);
}
catch (Exception e)
{
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem getting field %d from %s", fieldIndex, classToAccess.getName()));
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public static <T, E> T getPrivateValue(Class <? super E > classToAccess, E instance, String fieldName)
{
try
{
Field f = classToAccess.getDeclaredField(fieldName);
f.setAccessible(true);
return (T) f.get(instance);
}
catch (Exception e)
{
if ((fieldName.length() > 3 && !obfuscation) || (fieldName.length() <= 3 && obfuscation)) {
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem getting field %s from %s", fieldName, classToAccess.getName()));
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
}
throw new RuntimeException(e);
}
}
public static <T, E> void setPrivateValue(Class <? super T > classToAccess, T instance, int fieldIndex, E value)
{
try
{
Field f = classToAccess.getDeclaredFields()[fieldIndex];
f.setAccessible(true);
f.set(instance, value);
}
catch (Exception e)
{
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem setting field %d from %s", fieldIndex, classToAccess.getName()));
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
throw new RuntimeException(e);
}
}
public static <T, E> void setPrivateValue(Class <? super T > classToAccess, T instance, String fieldName, E value)
{
try
{
Field f = classToAccess.getDeclaredField(fieldName);
f.setAccessible(true);
f.set(instance, value);
}
catch (Exception e)
{
if ((fieldName.length() > 3 && !obfuscation) || (fieldName.length() <= 3 && obfuscation)) {
FMLCommonHandler.instance().getFMLLogger().severe(String.format("There was a problem setting field %s from %s", fieldName, classToAccess.getName()));
FMLCommonHandler.instance().getFMLLogger().throwing("ReflectionHelper", "getPrivateValue", e);
}
throw new RuntimeException(e);
}
}
/**
*
*/
public static void detectObfuscation(Class<?> clazz)
{
obfuscation=!clazz.getSimpleName().equals("World");
}
}
+2 -2
View File
@@ -18,7 +18,7 @@ public enum Side {
CLIENT, SERVER, BUKKIT;
/**
* @return
* @return If this is the server environment
*/
public boolean isServer()
{
@@ -26,7 +26,7 @@ public enum Side {
}
/**
* @return
* @return if this is the Client environment
*/
public boolean isClient()
{
@@ -12,7 +12,7 @@
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraft.src;
package cpw.mods.fml.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -29,18 +29,16 @@ public @interface SidedProxy
{
/**
* The name of the client side class to load and populate
* @return
*/
String clientSide() default "";
/**
* The name of the server side class to load and populate
* @return
*/
String serverSide() default "";
/**
* The name of the a special bukkit plugin class to load and populate
* The name of a special bukkit plugin class to load and populate
*/
String bukkitSide() default "";
}
+16 -25
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,24 +61,21 @@ public enum TickType {
*/
PLAYER,
/**
* This is a special internal tick type that is
* not sent to mods. It resets the scheduler for
* the next tick pass.
* server side only.
* This is the server game tick.
* Fired once per tick loop on the server.
*/
RESETMARKER;
SERVER;
/**
* Partner ticks that are also cancelled by returning false from onTickInGame
*
* @return
*/
public EnumSet<TickType> partnerTicks()
{
if (this==GAME) return EnumSet.of(RENDER);
if (this==RENDER) return EnumSet.of(GAME);
if (this==GUI) return EnumSet.of(WORLDGUI, GUILOAD);
if (this==WORLDGUI) return EnumSet.of(GUI, GUILOAD);
if (this==GUILOAD) return EnumSet.of(GUI, WORLDGUI);
if (this==CLIENT) return EnumSet.of(RENDER);
if (this==RENDER) return EnumSet.of(CLIENT);
if (this==GUI) return EnumSet.of(CLIENTGUI);
if (this==CLIENTGUI) return EnumSet.of(GUI);
return EnumSet.noneOf(TickType.class);
}
}
@@ -0,0 +1,14 @@
package cpw.mods.fml.common;
import java.util.Map;
import net.minecraft.src.NBTBase;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.SaveHandler;
import net.minecraft.src.WorldInfo;
public interface WorldAccessContainer
{
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info);
public void readData(SaveHandler handler, WorldInfo info, Map<String,NBTBase> propertyMap, NBTTagCompound tag);
}
@@ -0,0 +1,13 @@
package cpw.mods.fml.common;
public class WrongMinecraftVersionException extends RuntimeException
{
public ModContainer mod;
public WrongMinecraftVersionException(ModContainer mod)
{
this.mod = mod;
}
}
@@ -0,0 +1,31 @@
package cpw.mods.fml.common.asm;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import cpw.mods.fml.common.registry.BlockProxy;
import cpw.mods.fml.relauncher.IClassTransformer;
public class ASMTransformer implements IClassTransformer
{
@Override
public byte[] transform(String name, byte[] bytes)
{
if ("net.minecraft.src.Block".equals(name))
{
ClassReader cr = new ClassReader(bytes);
ClassNode cn = new ClassNode(Opcodes.ASM4);
cr.accept(cn, ClassReader.EXPAND_FRAMES);
cn.interfaces.add(Type.getInternalName(BlockProxy.class));
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
return cw.toByteArray();
}
return bytes;
}
}
@@ -0,0 +1,72 @@
package cpw.mods.fml.common.asm;
import java.util.Map;
import javax.swing.JOptionPane;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
public class FMLSanityChecker implements IFMLCallHook
{
static class MLDetectorClassVisitor extends ClassVisitor
{
private boolean foundMarker = false;
private MLDetectorClassVisitor()
{
super(Opcodes.ASM4);
}
@Override
public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4)
{
if ("fmlMarker".equals(arg1))
{
foundMarker = true;
}
return null;
}
}
private RelaunchClassLoader cl;
@Override
public Void call() throws Exception
{
byte[] mlClass = cl.getClassBytes("ModLoader");
// Only care in obfuscated env
if (mlClass == null)
{
return null;
}
MLDetectorClassVisitor mlTester = new MLDetectorClassVisitor();
ClassReader cr = new ClassReader(mlClass);
cr.accept(mlTester, ClassReader.SKIP_CODE);
if (!mlTester.foundMarker)
{
JOptionPane.showMessageDialog(null, "<html>CRITICAL ERROR<br/>" +
"ModLoader was detected in this environment<br/>" +
"ForgeModLoader cannot be installed alongside ModLoader<br/>" +
"All mods should work without ModLoader being installed<br/>" +
"Because ForgeModLoader is 100% compatible with ModLoader<br/>" +
"Re-install Minecraft Forge or Forge ModLoader into a clean<br/>" +
"jar and try again.",
"ForgeModLoader critical error",
JOptionPane.ERROR_MESSAGE);
throw new RuntimeException("Invalid ModLoader class detected");
}
return null;
}
@Override
public void injectData(Map<String, Object> data)
{
cl = (RelaunchClassLoader) data.get("classLoader");
}
}
@@ -0,0 +1,15 @@
package cpw.mods.fml.common.asm;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cpw.mods.fml.common.Side;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface SideOnly
{
public Side value();
}
@@ -0,0 +1,419 @@
package cpw.mods.fml.common.asm.transformers;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
import cpw.mods.fml.relauncher.IClassTransformer;
public class AccessTransformer implements IClassTransformer
{
private static final boolean DEBUG = false;
private class Modifier
{
public String name = "";
public String desc = "";
public int oldAccess = 0;
public int newAccess = 0;
public int targetAccess = 0;
public boolean changeFinal = false;
public boolean markFinal = false;
protected boolean modifyClassVisibility;
private void setTargetAccess(String name)
{
if (name.startsWith("public")) targetAccess = ACC_PUBLIC;
else if (name.startsWith("private")) targetAccess = ACC_PRIVATE;
else if (name.startsWith("protected")) targetAccess = ACC_PROTECTED;
if (name.endsWith("-f"))
{
changeFinal = true;
markFinal = false;
}
else if (name.endsWith("+f"))
{
changeFinal = true;
markFinal = true;
}
}
}
private Multimap<String, Modifier> modifiers = ArrayListMultimap.create();
public AccessTransformer() throws IOException
{
this("fml_at.cfg");
}
protected AccessTransformer(String rulesFile) throws IOException
{
readMapFile(rulesFile);
}
private void readMapFile(String rulesFile) throws IOException
{
File file = new File(rulesFile);
URL rulesResource;
if (file.exists())
{
rulesResource = file.toURI().toURL();
}
else
{
rulesResource = Resources.getResource(rulesFile);
}
Resources.readLines(rulesResource, Charsets.UTF_8, new LineProcessor<Void>()
{
@Override
public Void getResult()
{
return null;
}
@Override
public boolean processLine(String input) throws IOException
{
String line = Iterables.getFirst(Splitter.on('#').limit(2).split(input), "").trim();
if (line.length()==0)
{
return true;
}
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
if (parts.size()>2)
{
throw new RuntimeException("Invalid config file line "+ input);
}
Modifier m = new Modifier();
m.setTargetAccess(parts.get(0));
List<String> descriptor = Lists.newArrayList(Splitter.on(".").trimResults().split(parts.get(1)));
if (descriptor.size() == 1)
{
m.modifyClassVisibility = true;
}
else
{
String nameReference = descriptor.get(1);
int parenIdx = nameReference.indexOf('(');
if (parenIdx>0)
{
m.desc = nameReference.substring(parenIdx);
m.name = nameReference.substring(0,parenIdx);
}
else
{
m.name = nameReference;
}
}
modifiers.put(descriptor.get(0).replace('/', '.'), m);
return true;
}
});
}
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
{
if (bytes == null) { return null; }
if (!modifiers.containsKey(name)) { return bytes; }
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
Collection<Modifier> mods = modifiers.get(name);
for (Modifier m : mods)
{
if (m.modifyClassVisibility)
{
classNode.access = getFixedAccess(classNode.access, m);
if (DEBUG)
{
System.out.println(String.format("Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess)));
}
continue;
}
if (m.desc.isEmpty())
{
for (FieldNode n : (List<FieldNode>) classNode.fields)
{
if (n.name.equals(m.name) || m.name.equals("*"))
{
n.access = getFixedAccess(n.access, m);
if (DEBUG)
{
System.out.println(String.format("Field: %s.%s %s -> %s", name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess)));
}
if (!m.name.equals("*"))
{
break;
}
}
}
}
else
{
for (MethodNode n : (List<MethodNode>) classNode.methods)
{
if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*"))
{
n.access = getFixedAccess(n.access, m);
if (DEBUG)
{
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
}
if (!m.name.equals("*"))
{
break;
}
}
}
}
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
private String toBinary(int num)
{
return String.format("%16s", Integer.toBinaryString(num)).replace(' ', '0');
}
private int getFixedAccess(int access, Modifier target)
{
target.oldAccess = access;
int t = target.targetAccess;
int ret = (access & ~7);
switch (access & 7)
{
case ACC_PRIVATE:
ret |= t;
break;
case 0: // default
ret |= (t != ACC_PRIVATE ? t : 0 /* default */);
break;
case ACC_PROTECTED:
ret |= (t != ACC_PRIVATE && t != 0 /* default */? t : ACC_PROTECTED);
break;
case ACC_PUBLIC:
ret |= (t != ACC_PRIVATE && t != 0 /* default */&& t != ACC_PROTECTED ? t : ACC_PUBLIC);
break;
default:
throw new RuntimeException("The fuck?");
}
// Clear the "final" marker on fields only if specified in control field
if (target.changeFinal && target.desc == "")
{
if (target.markFinal)
{
ret |= ACC_FINAL;
}
else
{
ret &= ~ACC_FINAL;
}
}
target.newAccess = ret;
return ret;
}
public static void main(String[] args)
{
if (args.length < 2)
{
System.out.println("Usage: AccessTransformer <JarPath> <MapFile> [MapFile2]... ");
System.exit(1);
}
boolean hasTransformer = false;
AccessTransformer[] trans = new AccessTransformer[args.length - 1];
for (int x = 1; x < args.length; x++)
{
try
{
trans[x - 1] = new AccessTransformer(args[x]);
hasTransformer = true;
}
catch (IOException e)
{
System.out.println("Could not read Transformer Map: " + args[x]);
e.printStackTrace();
}
}
if (!hasTransformer)
{
System.out.println("Culd not find a valid transformer to perform");
System.exit(1);
}
File orig = new File(args[0]);
File temp = new File(args[0] + ".ATBack");
if (!orig.exists() && !temp.exists())
{
System.out.println("Could not find target jar: " + orig);
System.exit(1);
}
if (!orig.renameTo(temp))
{
System.out.println("Could not rename file: " + orig + " -> " + temp);
System.exit(1);
}
try
{
processJar(temp, orig, trans);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
if (!temp.delete())
{
System.out.println("Could not delete temp file: " + temp);
}
}
private static void processJar(File inFile, File outFile, AccessTransformer[] transformers) throws IOException
{
ZipInputStream inJar = null;
ZipOutputStream outJar = null;
try
{
try
{
inJar = new ZipInputStream(new BufferedInputStream(new FileInputStream(inFile)));
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
}
try
{
outJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
}
ZipEntry entry;
while ((entry = inJar.getNextEntry()) != null)
{
if (entry.isDirectory())
{
outJar.putNextEntry(entry);
continue;
}
byte[] data = new byte[4096];
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
int len;
do
{
len = inJar.read(data);
if (len > 0)
{
entryBuffer.write(data, 0, len);
}
}
while (len != -1);
byte[] entryData = entryBuffer.toByteArray();
String entryName = entry.getName();
if (entryName.endsWith(".class") && !entryName.startsWith("."))
{
ClassNode cls = new ClassNode();
ClassReader rdr = new ClassReader(entryData);
rdr.accept(cls, 0);
String name = cls.name.replace('/', '.').replace('\\', '.');
for (AccessTransformer trans : transformers)
{
entryData = trans.transform(name, entryData);
}
}
ZipEntry newEntry = new ZipEntry(entryName);
outJar.putNextEntry(newEntry);
outJar.write(entryData);
}
}
finally
{
if (outJar != null)
{
try
{
outJar.close();
}
catch (IOException e)
{
}
}
if (inJar != null)
{
try
{
inJar.close();
}
catch (IOException e)
{
}
}
}
}
public void ensurePublicAccessFor(String modClazzName)
{
Modifier m = new Modifier();
m.setTargetAccess("public");
m.modifyClassVisibility = true;
modifiers.put(modClazzName, m);
}
}
@@ -0,0 +1,637 @@
package cpw.mods.fml.common.asm.transformers;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
public class MCPMerger
{
private static Hashtable<String, ClassInfo> clients = new Hashtable<String, ClassInfo>();
private static Hashtable<String, ClassInfo> shared = new Hashtable<String, ClassInfo>();
private static Hashtable<String, ClassInfo> servers = new Hashtable<String, ClassInfo>();
private static HashSet<String> copyToServer = new HashSet<String>();
private static HashSet<String> copyToClient = new HashSet<String>();
private static final boolean DEBUG = false;
public static void main(String[] args)
{
if (args.length != 3)
{
System.out.println("Usage: MCPMerger <MapFile> <minecraft.jar> <minecraft_server.jar>");
System.exit(1);
}
File map_file = new File(args[0]);
File client_jar = new File(args[1]);
File server_jar = new File(args[2]);
File client_jar_tmp = new File(args[1] + ".MergeBack");
File server_jar_tmp = new File(args[2] + ".MergeBack");
if (client_jar_tmp.exists() && !client_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + client_jar_tmp);
}
if (server_jar_tmp.exists() && !server_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + server_jar_tmp);
}
if (!client_jar.exists())
{
System.out.println("Could not find minecraft.jar: " + client_jar);
System.exit(1);
}
if (!server_jar.exists())
{
System.out.println("Could not find minecraft_server.jar: " + server_jar);
System.exit(1);
}
if (!client_jar.renameTo(client_jar_tmp))
{
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
System.exit(1);
}
if (!server_jar.renameTo(server_jar_tmp))
{
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
System.exit(1);
}
if (!readMapFile(map_file))
{
System.out.println("Could not read map file: " + map_file);
System.exit(1);
}
try
{
processJar(client_jar_tmp, server_jar_tmp, client_jar, server_jar);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
if (!client_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + client_jar_tmp);
}
if (!server_jar_tmp.delete())
{
System.out.println("Could not delete temp file: " + server_jar_tmp);
}
}
private static boolean readMapFile(File mapFile)
{
try
{
FileInputStream fstream = new FileInputStream(mapFile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null)
{
line = line.split("#")[0];
boolean toClient = line.charAt(0) == '<';
line = line.substring(1).trim();
if (toClient) copyToClient.add(line);
else copyToServer.add(line);
}
in.close();
return true;
}
catch (Exception e)
{
System.err.println("Error: " + e.getMessage());
return false;
}
}
public static void processJar(File clientInFile, File serverInFile, File clientOutFile, File serverOutFile) throws IOException
{
ZipFile cInJar = null;
ZipFile sInJar = null;
ZipOutputStream cOutJar = null;
ZipOutputStream sOutJar = null;
try
{
try
{
cInJar = new ZipFile(clientInFile);
sInJar = new ZipFile(serverInFile);
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
}
try
{
cOutJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(clientOutFile)));
sOutJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(serverOutFile)));
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
}
Hashtable<String, ZipEntry> cClasses = getClassEntries(cInJar, cOutJar);
Hashtable<String, ZipEntry> sClasses = getClassEntries(sInJar, sOutJar);
HashSet<String> cAdded = new HashSet<String>();
HashSet<String> sAdded = new HashSet<String>();
for (Entry<String, ZipEntry> entry : cClasses.entrySet())
{
String name = entry.getKey();
ZipEntry cEntry = entry.getValue();
ZipEntry sEntry = sClasses.get(name);
if (sEntry == null)
{
if (!copyToServer.contains(name))
{
copyClass(cInJar, cEntry, cOutJar, null, true);
cAdded.add(name);
}
else
{
if (DEBUG)
{
System.out.println("Copy class c->s : " + name);
}
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
cAdded.add(name);
sAdded.add(name);
}
continue;
}
sClasses.remove(name);
ClassInfo info = new ClassInfo(name);
shared.put(name, info);
byte[] cData = readEntry(cInJar, entry.getValue());
byte[] sData = readEntry(sInJar, sEntry);
byte[] data = processClass(cData, sData, info);
ZipEntry newEntry = new ZipEntry(cEntry.getName());
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
cAdded.add(name);
sAdded.add(name);
}
for (Entry<String, ZipEntry> entry : sClasses.entrySet())
{
if (!copyToClient.contains(entry.getKey()))
{
copyClass(sInJar, entry.getValue(), null, sOutJar, false);
}
else
{
if (DEBUG)
{
System.out.println("Copy class s->c : " + entry.getKey());
}
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
}
}
for (String name : new String[]{SideOnly.class.getName(), Side.class.getName()})
{
String eName = name.replace(".", "/");
byte[] data = getClassBytes(name);
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
if (!cAdded.contains(eName))
{
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
}
if (!sAdded.contains(eName))
{
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
}
}
}
finally
{
if (cInJar != null)
{
try { cInJar.close(); } catch (IOException e){}
}
if (sInJar != null)
{
try { sInJar.close(); } catch (IOException e) {}
}
if (cOutJar != null)
{
try { cOutJar.close(); } catch (IOException e){}
}
if (sOutJar != null)
{
try { sOutJar.close(); } catch (IOException e) {}
}
}
}
private static void copyClass(ZipFile inJar, ZipEntry entry, ZipOutputStream outJar, ZipOutputStream outJar2, boolean isClientOnly) throws IOException
{
ClassReader reader = new ClassReader(readEntry(inJar, entry));
ClassNode classNode = new ClassNode();
reader.accept(classNode, 0);
if (!classNode.name.equals("bdz")) //Special case CodecMus so I dont have to make a new patch, anyone who uses this in production code is.. bad.
{
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
byte[] data = writer.toByteArray();
ZipEntry newEntry = new ZipEntry(entry.getName());
if (outJar != null)
{
outJar.putNextEntry(newEntry);
outJar.write(data);
}
if (outJar2 != null)
{
outJar2.putNextEntry(newEntry);
outJar2.write(data);
}
}
private static AnnotationNode getSideAnn(boolean isClientOnly)
{
AnnotationNode ann = new AnnotationNode(Type.getDescriptor(SideOnly.class));
ann.values = new ArrayList<Object>();
ann.values.add("value");
ann.values.add(new String[]{ Type.getDescriptor(Side.class), (isClientOnly ? "CLIENT" : "SERVER")});
return ann;
}
@SuppressWarnings("unchecked")
private static Hashtable<String, ZipEntry> getClassEntries(ZipFile inFile, ZipOutputStream outFile) throws IOException
{
Hashtable<String, ZipEntry> ret = new Hashtable<String, ZipEntry>();
for (ZipEntry entry : Collections.list((Enumeration<ZipEntry>)inFile.entries()))
{
if (entry.isDirectory())
{
outFile.putNextEntry(entry);
continue;
}
String entryName = entry.getName();
if (!entryName.endsWith(".class") || entryName.startsWith("."))
{
ZipEntry newEntry = new ZipEntry(entry.getName());
outFile.putNextEntry(newEntry);
outFile.write(readEntry(inFile, entry));
}
else
{
ret.put(entryName.replace(".class", ""), entry);
}
}
return ret;
}
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
{
return readFully(inFile.getInputStream(entry));
}
private static byte[] readFully(InputStream stream) throws IOException
{
byte[] data = new byte[4096];
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
int len;
do
{
len = stream.read(data);
if (len > 0)
{
entryBuffer.write(data, 0, len);
}
} while (len != -1);
return entryBuffer.toByteArray();
}
private static class ClassInfo
{
public String name;
public ArrayList<FieldNode> cField = new ArrayList<FieldNode>();
public ArrayList<FieldNode> sField = new ArrayList<FieldNode>();
public ArrayList<MethodNode> cMethods = new ArrayList<MethodNode>();
public ArrayList<MethodNode> sMethods = new ArrayList<MethodNode>();
public ClassInfo(String name){ this.name = name; }
public boolean isSame() { return (cField.size() == 0 && sField.size() == 0 && cMethods.size() == 0 && sMethods.size() == 0); }
}
public static byte[] processClass(byte[] cIn, byte[] sIn, ClassInfo info)
{
ClassNode cClassNode = getClassNode(cIn);
ClassNode sClassNode = getClassNode(sIn);
processFields(cClassNode, sClassNode, info);
processMethods(cClassNode, sClassNode, info);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cClassNode.accept(writer);
return writer.toByteArray();
}
private static ClassNode getClassNode(byte[] data)
{
ClassReader reader = new ClassReader(data);
ClassNode classNode = new ClassNode();
reader.accept(classNode, 0);
return classNode;
}
@SuppressWarnings("unchecked")
private static void processFields(ClassNode cClass, ClassNode sClass, ClassInfo info)
{
List<FieldNode> cFields = cClass.fields;
List<FieldNode> sFields = sClass.fields;
int sI = 0;
for (int x = 0; x < cFields.size(); x++)
{
FieldNode cF = cFields.get(x);
if (sI < sFields.size())
{
if (!cF.name.equals(sFields.get(sI).name))
{
boolean serverHas = false;
for (int y = sI + 1; y < sFields.size(); y++)
{
if (cF.name.equals(sFields.get(y).name))
{
serverHas = true;
break;
}
}
if (serverHas)
{
boolean clientHas = false;
FieldNode sF = sFields.get(sI);
for (int y = x + 1; y < cFields.size(); y++)
{
if (sF.name.equals(cFields.get(y).name))
{
clientHas = true;
break;
}
}
if (!clientHas)
{
if (sF.visibleAnnotations == null) sF.visibleAnnotations = new ArrayList<AnnotationNode>();
sF.visibleAnnotations.add(getSideAnn(false));
cFields.add(x++, sF);
info.sField.add(sF);
}
}
else
{
if (cF.visibleAnnotations == null) cF.visibleAnnotations = new ArrayList<AnnotationNode>();
cF.visibleAnnotations.add(getSideAnn(true));
sFields.add(sI, cF);
info.cField.add(cF);
}
}
}
else
{
if (cF.visibleAnnotations == null) cF.visibleAnnotations = new ArrayList<AnnotationNode>();
cF.visibleAnnotations.add(getSideAnn(true));
sFields.add(sI, cF);
info.cField.add(cF);
}
sI++;
}
if (sFields.size() != cFields.size())
{
for (int x = cFields.size(); x < sFields.size(); x++)
{
FieldNode sF = sFields.get(x);
if (sF.visibleAnnotations == null) sF.visibleAnnotations = new ArrayList<AnnotationNode>();
sF.visibleAnnotations.add(getSideAnn(true));
cFields.add(x++, sF);
info.sField.add(sF);
}
}
}
private static class MethodWrapper
{
private MethodNode node;
public boolean client;
public boolean server;
public MethodWrapper(MethodNode node)
{
this.node = node;
}
@Override
public boolean equals(Object obj)
{
if (obj == null || !(obj instanceof MethodWrapper)) return false;
MethodWrapper mw = (MethodWrapper) obj;
boolean eq = Objects.equal(node.name, mw.node.name) && Objects.equal(node.desc, mw.node.desc);
if (eq)
{
mw.client = this.client | mw.client;
mw.server = this.server | mw.server;
this.client = this.client | mw.client;
this.server = this.server | mw.server;
if (DEBUG)
{
System.out.printf(" eq: %s %s\n", this, mw);
}
}
return eq;
}
@Override
public int hashCode()
{
return Objects.hashCode(node.name, node.desc);
}
@Override
public String toString()
{
return Objects.toStringHelper(this).add("name", node.name).add("desc",node.desc).add("server",server).add("client",client).toString();
}
}
@SuppressWarnings("unchecked")
private static void processMethods(ClassNode cClass, ClassNode sClass, ClassInfo info)
{
List<MethodNode> cMethods = (List<MethodNode>)cClass.methods;
List<MethodNode> sMethods = (List<MethodNode>)sClass.methods;
LinkedHashSet<MethodWrapper> allMethods = Sets.newLinkedHashSet();
int cPos = 0;
int sPos = 0;
int cLen = cMethods.size();
int sLen = sMethods.size();
String clientName = "";
String lastName = clientName;
String serverName = "";
while (cPos < cLen || sPos < sLen)
{
do
{
if (sPos>=sLen)
{
break;
}
MethodNode sM = sMethods.get(sPos);
serverName = sM.name;
if (!serverName.equals(lastName) && cPos != cLen)
{
if (DEBUG)
{
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
break;
}
MethodWrapper mw = new MethodWrapper(sM);
mw.server = true;
allMethods.add(mw);
if (DEBUG)
{
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
sPos++;
}
while (sPos < sLen);
do
{
if (cPos>=cLen)
{
break;
}
MethodNode cM = cMethods.get(cPos);
lastName = clientName;
clientName = cM.name;
if (!clientName.equals(lastName) && sPos != sLen)
{
if (DEBUG)
{
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
break;
}
MethodWrapper mw = new MethodWrapper(cM);
mw.client = true;
allMethods.add(mw);
if (DEBUG)
{
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
cPos++;
}
while (cPos < cLen);
}
cMethods.clear();
sMethods.clear();
for (MethodWrapper mw : allMethods)
{
if (DEBUG)
{
System.out.println(mw);
}
cMethods.add(mw.node);
sMethods.add(mw.node);
if (mw.server && mw.client)
{
// no op
}
else
{
if (mw.node.visibleAnnotations == null) mw.node.visibleAnnotations = Lists.newArrayListWithExpectedSize(1);
mw.node.visibleAnnotations.add(getSideAnn(mw.client));
if (mw.client)
{
info.sMethods.add(mw.node);
}
else
{
info.cMethods.add(mw.node);
}
}
}
}
public static byte[] getClassBytes(String name) throws IOException
{
InputStream classStream = null;
try
{
classStream = MCPMerger.class.getResourceAsStream("/" + name.replace('.', '/').concat(".class"));
return readFully(classStream);
}
finally
{
if (classStream != null)
{
try
{
classStream.close();
}
catch (IOException e){}
}
}
}
}
@@ -0,0 +1,277 @@
package cpw.mods.fml.common.asm.transformers;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
import cpw.mods.fml.relauncher.IClassTransformer;
public class MarkerTransformer implements IClassTransformer
{
private ListMultimap<String, String> markers = ArrayListMultimap.create();
public MarkerTransformer() throws IOException
{
this("fml_marker.cfg");
}
protected MarkerTransformer(String rulesFile) throws IOException
{
readMapFile(rulesFile);
}
private void readMapFile(String rulesFile) throws IOException
{
File file = new File(rulesFile);
URL rulesResource;
if (file.exists())
{
rulesResource = file.toURI().toURL();
}
else
{
rulesResource = Resources.getResource(rulesFile);
}
Resources.readLines(rulesResource, Charsets.UTF_8, new LineProcessor<Void>()
{
@Override
public Void getResult()
{
return null;
}
@Override
public boolean processLine(String input) throws IOException
{
String line = Iterables.getFirst(Splitter.on('#').limit(2).split(input), "").trim();
if (line.length()==0)
{
return true;
}
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
if (parts.size()!=2)
{
throw new RuntimeException("Invalid config file line "+ input);
}
List<String> markerInterfaces = Lists.newArrayList(Splitter.on(",").trimResults().split(parts.get(1)));
for (String marker : markerInterfaces)
{
markers.put(parts.get(0), marker);
}
return true;
}
});
}
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
{
if (bytes == null) { return null; }
if (!markers.containsKey(name)) { return bytes; }
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
for (String marker : markers.get(name))
{
classNode.interfaces.add(marker);
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
return writer.toByteArray();
}
public static void main(String[] args)
{
if (args.length < 2)
{
System.out.println("Usage: MarkerTransformer <JarPath> <MapFile> [MapFile2]... ");
return;
}
boolean hasTransformer = false;
MarkerTransformer[] trans = new MarkerTransformer[args.length - 1];
for (int x = 1; x < args.length; x++)
{
try
{
trans[x - 1] = new MarkerTransformer(args[x]);
hasTransformer = true;
}
catch (IOException e)
{
System.out.println("Could not read Transformer Map: " + args[x]);
e.printStackTrace();
}
}
if (!hasTransformer)
{
System.out.println("Culd not find a valid transformer to perform");
return;
}
File orig = new File(args[0]);
File temp = new File(args[0] + ".ATBack");
if (!orig.exists() && !temp.exists())
{
System.out.println("Could not find target jar: " + orig);
return;
}
/*
if (temp.exists())
{
if (orig.exists() && !orig.renameTo(new File(args[0] + (new SimpleDateFormat(".yyyy.MM.dd.HHmmss")).format(new Date()))))
{
System.out.println("Could not backup existing file: " + orig);
return;
}
if (!temp.renameTo(orig))
{
System.out.println("Could not restore backup from previous run: " + temp);
return;
}
}
*/
if (!orig.renameTo(temp))
{
System.out.println("Could not rename file: " + orig + " -> " + temp);
return;
}
try
{
processJar(temp, orig, trans);
}
catch (IOException e)
{
e.printStackTrace();
}
if (!temp.delete())
{
System.out.println("Could not delete temp file: " + temp);
}
}
private static void processJar(File inFile, File outFile, MarkerTransformer[] transformers) throws IOException
{
ZipInputStream inJar = null;
ZipOutputStream outJar = null;
try
{
try
{
inJar = new ZipInputStream(new BufferedInputStream(new FileInputStream(inFile)));
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
}
try
{
outJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
}
ZipEntry entry;
while ((entry = inJar.getNextEntry()) != null)
{
if (entry.isDirectory())
{
outJar.putNextEntry(entry);
continue;
}
byte[] data = new byte[4096];
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
int len;
do
{
len = inJar.read(data);
if (len > 0)
{
entryBuffer.write(data, 0, len);
}
}
while (len != -1);
byte[] entryData = entryBuffer.toByteArray();
String entryName = entry.getName();
if (entryName.endsWith(".class") && !entryName.startsWith("."))
{
ClassNode cls = new ClassNode();
ClassReader rdr = new ClassReader(entryData);
rdr.accept(cls, 0);
String name = cls.name.replace('/', '.').replace('\\', '.');
for (MarkerTransformer trans : transformers)
{
entryData = trans.transform(name, entryData);
}
}
ZipEntry newEntry = new ZipEntry(entryName);
outJar.putNextEntry(newEntry);
outJar.write(entryData);
}
}
finally
{
if (outJar != null)
{
try
{
outJar.close();
}
catch (IOException e)
{
}
}
if (inJar != null)
{
try
{
inJar.close();
}
catch (IOException e)
{
}
}
}
}
}
Loaded 100 of 401 files, more files were not shown because too many files have changed in this diff. Show more