Compare commits

...
577 Commits
Author SHA1 Message Date
Christian 012a755bb9 Fix up patch properly. Also, fix md5s for the jars. 2013-03-22 01:48:21 -04:00
cpw 748eece456 Merge pull request #206 from mDiyo/patch-1
Fix missing block world rendering
2013-03-21 07:41:35 -07:00
mDiyo f709ce7579 Fix missing block world rendering 2013-03-21 07:10:55 -07:00
LexManos 33efc35b60 Merge MC 1.5.1 branch to master. 2013-03-21 04:10:30 -07:00
LexManos 687d3c059d Merge pull request #204 from agaricusb/fix-mcpdir
Fix install.py --mcp-dir option
2013-03-20 10:24:27 -07:00
LexManos aaf02ea2ac Updated for new PR client jar. 2013-03-20 08:59:25 -07:00
Agaricus 625da6492d Fix install.py --mcp-dir option. Fixes #204. 2013-03-19 21:42:04 -07:00
LexManos a573faf92d Someone derped up this function bad, revert name. 2013-03-19 17:54:06 -07:00
LexManos 9565529baf Updated to latest MCP and Minecraft 1.5.1 Pre-release. 2013-03-19 15:48:42 -07:00
LexManos 3c346247e1 Fix NPE with CoreMods who do not have the new MCVersion annotation. 2013-03-19 13:48:18 -07:00
Christian ce949e6099 Support simple mc version test in coremods, only effective through
jar loading.
Also, log some more data about the environment.
2013-03-17 23:40:12 -04:00
Christian 5e3af8ac0e Use the relaunch log, for class circularity safety. 2013-03-17 23:19:39 -04:00
Christian 5cc90f060c Fix the logger to treat newlines better, hopefully. Closes #199 2013-03-17 23:15:18 -04:00
LexManos 577b19c1cf Fix potential NPE in class loading and add extra debug information. 2013-03-17 11:54:26 -07:00
cpw 8905237306 Merge pull request #200 from bspkrs/patch-2
Added comments to note FML-only methods
2013-03-14 18:37:08 -07:00
Christian c5d5f4e516 Fix AllPublic access transformer not affecting methods. Should fix modloader
compatibility
2013-03-14 15:53:19 -04:00
bspkrs 24022ab6ba Added comments to note FML-only methods 2013-03-14 01:29:36 -03:00
LexManos 6370c242f0 OS X's python 2.6.1 has a bug in zipfile.extractall that makes it unzip directories as regular files. So switch to extract 2013-03-13 13:11:43 -07:00
LexManos 4762d4d8ef Allocate more ram {typically 256 is defailt} to fermflower, should fix decomplication issues on OSX 2013-03-13 13:11:10 -07:00
Christian 8f2dbf7046 Fix up stupid derp in IMC code: actually reset the IMC list after
each delivery. Fixes a bunch of mods. Sorry everyone.
2013-03-13 15:09:50 -04:00
Christian 23ea835fa7 Pass obfuscation status to coremods 2013-03-12 21:06:37 -04:00
Christian d88db6c0cf Fix up deep tree deobfuscation 2013-03-12 20:33:19 -04:00
LexManos c6dab815f4 Missed joined.exc, must fix scripts. 2013-03-12 15:12:49 -07:00
LexManos 7b722bfcd6 Update MCP for latest PR silent update. 2013-03-12 15:02:58 -07:00
LexManos a90504315e Readjust size of mods button when Minecraft Realms button is enabled. 2013-03-11 16:20:56 -07:00
Christian 3765ceb02d Update MCP, fixes the "broken texture packs" problem. 2013-03-11 16:31:26 -04:00
Christian dab22f5b74 Fix "0 mods" display when installed in forge. 2013-03-10 12:12:22 -04:00
Christian b301e8e4c1 Change type of connection queue to a concurrent linked queue. Much more efficient, hopefully. Closes #189 2013-03-10 01:25:36 -05:00
Christian f647929993 Merge branch 'master' of github.com:Uristqwerty/FML 2013-03-10 01:22:24 -05:00
Christian 984291cee9 Fix supertype parsing to handle null superclass (Hi Object!). Closes #160 2013-03-10 01:20:08 -05:00
Christian ac16845fc4 Fix demo mode crash. Closes #187 2013-03-10 01:15:16 -05:00
Christian 29edd242cd Fix coremods without a manifest crashing the game. Closes #181 2013-03-10 01:05:31 -05:00
Christian ca2d8bd834 Fix reflection helper: it needs to unmap the classname to find the field maps. 2013-03-09 17:58:18 -05:00
Christian 2a779ec328 Try a different way of remapping the fields. Should work because it's userspace, not relauncher space 2013-03-09 17:36:31 -05:00
Christian 591e65fa1a Revert "Use the reobfuscation maps in the reflection helper for field lookups: should help some reflection cases with the deobf."
This reverts commit 485db6be2e.
2013-03-09 17:32:11 -05:00
Christian 485db6be2e Use the reobfuscation maps in the reflection helper for field lookups: should help some reflection cases with the deobf. 2013-03-09 17:19:48 -05:00
Christian 25f3fcad46 Fix up some relauncher stuff: the vanilla applet works now, as do other applets. Deobf data is resolveable for them too. 2013-03-09 15:25:58 -05:00
LexManos 6bf7c9878c Fixed srg name of minecraftDir for runtime deobf. 2013-03-09 11:52:40 -08:00
Christian 95d0ff18cd Fix runtime deobfuscation for remapped inner classes 2013-03-09 14:06:39 -05:00
LexManos 1642bad402 Fix Multi-part entity children ID issue, mobs with custom spawning must deal with child ids themselves. 2013-03-09 10:07:41 -08:00
Christian 450dd8313c Fix up some small things, merging into mainline 2013-03-09 12:39:36 -05:00
Christian ebdb166ec8 Merge branch 'snapshot15' 2013-03-09 12:26:14 -05:00
Christian 1eba1dfdc0 Fix accidental commands.patch overwrite 2013-03-09 12:25:24 -05:00
Christian 368a2245ef Merge branch 'snapshot15' 2013-03-09 12:19:37 -05:00
Christian 58ee06ea8e Some fixes for the snapshot 2013-03-09 12:10:13 -05:00
Christian 62f5adf8e2 Revert "Fix modlist to use the new texture binding functions, i think"
This reverts commit 48544db690.

Conflicts:
	client/cpw/mods/fml/client/GuiModList.java
2013-03-09 11:12:12 -05:00
cpw fe1623a36a Merge pull request #195 from RainWarrior/snapshot15
Fixes GameRegistry.registerBlock
2013-03-09 07:07:48 -08:00
RainWarrior 889efc1c0a Fixes GameRegistry.registerBlock 2013-03-09 14:06:12 +04:00
Christian 0419b9d975 Update MCP info for latest 2013-03-08 23:14:30 -05:00
Christian f1c6bdd57d Support the MCP format of partial reobfuscation for portability. Ensure modloader-like compatibility 2013-03-08 23:13:39 -05:00
LexManos b3e854a15d Update for new MCP with srg reobf. 2013-03-08 18:11:44 -08:00
Christian 80a40c03e6 Update to MCP 1.5 and minecraft 1.5. 2013-03-08 20:36:05 -05:00
Christian 5bfaf7c170 Global object registry, also, support the new itemblockwithmetadata constructor 2013-03-08 13:17:12 -05:00
Christian 2d98835db8 Scala support!
It's still primitive, I hope that people will like it. I do :)
2013-03-07 20:22:24 -05:00
Christian 81c6421f84 Tweak license text- any osi licensed project can use the asm transformer code 2013-03-07 19:41:52 -05:00
Christian 6eeae8c49f Fix up state transition derp when the server crashes with an error- it shouldn't double-derp 2013-03-07 19:37:52 -05:00
Christian c42a210140 Strip deprecated code 2013-03-07 19:33:34 -05:00
Christian a723aa6860 Refresh copyright notices on everything 2013-03-07 19:25:48 -05:00
Christian e9ff699c2d Refresh the renderengine after modloading is complete. Should fix issues with out-of-place texture registration by mods. 2013-03-07 19:02:26 -05:00
Christian abe4f73a9a FIX massive performance issue with FML. Thanks to @sfPlayer1 for finding
this epic derp on my part!
2013-03-06 14:00:28 -05:00
Christian 74fffc6fdc Update next render to 40 2013-03-04 22:52:24 -05:00
Christian debbdc00be Capture Minecraft logs into FML logging 2013-03-04 22:45:58 -05:00
LexManos aed2cc446a Force file name encoding to UTF-8, caused different zips on different systems. 2013-03-04 18:19:06 -08:00
LexManos e74087ee43 Ignore again, testing submodule. 2013-03-03 11:54:53 -08:00
LexManos f329084f1f Ignore this commit. 2013-03-03 11:52:47 -08:00
Christian 33cd9ad0fe Ignore deobf data 2013-03-03 14:04:41 -05:00
Christian ce819ac143 Force the joined.srg timestamp to zero- avoids annoying sha1 differences 2013-03-02 15:06:13 -05:00
Christian f0495a8abc Don't enforce signatures on minecraft classes 2013-03-02 14:48:08 -05:00
Christian a696db5a21 Update MCP URL for snapshot 2013-03-02 10:56:25 -05:00
Christian fcdbb4f5b3 Fix up runtime deobfuscation. Working well now. 2013-03-02 10:46:32 -05:00
Christian e105337ff4 Build, and use, MC versioned deobfuscation data 2013-03-02 10:30:45 -05:00
Christian f52e2112dd Merge branch 'runtimedeobf' into snapshot15 2013-03-02 10:04:06 -05:00
Christian 945d927fa0 Add in build for deobf data zip file, update for official mcp 7.39 2013-03-02 10:02:02 -05:00
LexManos 2ee6946824 Fix exc for renamed Behavior classes. 2013-03-02 00:48:44 -08:00
LexManos e08c43366a Actually remove classes from the csv when removed, and moved All EntityMinecart entities to net.minecraft.entity.item 2013-03-02 00:12:31 -08:00
LexManos c508004429 Delete unneeded patch 2013-03-02 00:11:48 -08:00
LexManos 21af85323a Readd ignore for argo and bouncycastle, needed for our replacement to work properly. 2013-03-02 00:11:33 -08:00
Christian 3410242f03 Update FML to 1.5 snapshot 13w09c 2013-03-02 02:06:32 -05:00
Christian 9b9c46d93b Tweaks to runtime deobf 2013-03-02 01:49:45 -05:00
LexManos de8e76c7fd Update distribuited eclipse's classpath for updated libraries. 2013-02-28 04:22:34 -08:00
LexManos 47b5e99b6f Fix crash in GuiModList for mod logo files, logo is not rendering for unknow reason. 2013-02-27 22:41:00 -08:00
LexManos 1a465b33f5 Fix bug in rename_vars where certian items would fail to be renamed. 2013-02-27 22:40:15 -08:00
LexManos 8e7956397d Just enable server side compile, and warn not to cmplain to us. 2013-02-26 14:54:18 -08:00
LexManos 86a9c7d359 Fixup reobfusication of server code if present. 2013-02-26 14:34:51 -08:00
Christian 6a581803a9 Tweak IASM hook api. You can return multiple classes now. 2013-02-26 15:04:45 -05:00
Christian b4e0c709c5 Merge branch 'runtimedeobf' into snapshot15 2013-02-26 10:24:03 -05:00
Christian f3458456a2 Change readFully to actually read a bunch of bytes at once now. Thanks to nallar and aartbluestoke for the suggestion to
revisit this..
2013-02-26 01:07:14 -05:00
Christian dcb15a587c Clean up more junk 2013-02-26 00:28:12 -05:00
Christian 937e9a0169 Update libs for 1.5. Lots of new libs. 2013-02-26 00:16:57 -05:00
Christian decd230ac1 Fix renderengine patch *sigh* 2013-02-25 22:06:20 -05:00
Christian 5347caa1c4 Merge branch 'master' into snapshot15
Conflicts:
	patches/minecraft/net/minecraft/client/renderer/RenderEngine.java.patch
2013-02-25 21:53:56 -05:00
Christian 52f6a674ea Merge branch 'master' into snapshot15
Conflicts:
	client/cpw/mods/fml/client/TextureFXManager.java
2013-02-25 21:18:08 -05:00
cpw a16c61f7ba Merge pull request #188 from immibis/master
Console log thread should be a daemon thread.
2013-02-22 22:35:14 -08:00
immibis 67f12d6dec Console log thread should be a daemon thread. 2013-02-23 19:27:16 +13:00
LexManos bad55cacfa Fix sprite map issue. 2013-02-22 14:45:25 -08:00
Christian a6e979b311 Merge branch 'master' into runtimedeobf 2013-02-17 16:29:13 -05:00
Christian ce68456f97 Fix Language Registry, closes #163 2013-02-17 16:28:54 -05:00
Christian 29e59438c5 Fix Language Registry, closes #163 2013-02-17 16:22:58 -05:00
Christian 10d4acfad2 Merge branch 'master' into runtimedeobf 2013-02-16 14:28:29 -05:00
LexManos 1c3dc132cb Option to disable renaming for srgnames. 2013-02-08 14:50:17 -08:00
Christian cd96718339 Fix HD mob skins, FINALLY!!!
Stupid eyes are stupid.
2013-02-06 01:25:46 -05:00
Christian 22dbe411d9 Fix up mistake that broke all modloading. Nice. 2013-02-04 10:58:48 -05:00
Christian a99d110fff Fix some class naming and packaging issues, pending an MCP update
for the same
2013-02-02 10:54:48 -05:00
Christian f21929b7d1 Update for MCP 7.34 and MC 13w05b 2013-02-01 23:05:23 -05:00
Christian 5d78b310da MCP compilation works 2013-02-01 22:42:28 -05:00
Christian 549b6fd535 IMC tweaks: runtimeMessages now work (thanks for all that testing for this much requested feature!)
and IMCEvent will no longer remove messages if no one gets them, so you can do
just manual runtime polling, if you wish.
2013-01-31 13:39:53 -05:00
Christian 9fafdc1695 More logging tweaks. You can probably configure individual mod log files if you wish now 2013-01-30 20:55:12 -05:00
Christian f169f7c92f A log of logging cleanup. FML will now read logging.properties to configure logging channels a couple of times during startup.
You should be able to filter a lot of messages based on things like modid and certain FML related features that can be noisy
like item tracking.
Should close #175
2013-01-30 18:57:21 -05:00
Christian b9ccadb2f1 Final part of the deobfuscation data setup- fields are now deobfuscated as well.
All that remains, is to figure out what and how to distribute the deobfuscation data itself.
2013-01-28 17:48:44 -05:00
Christian f00650481b Read the joined.srg file directly from lib/deobfuscation_data.zip now. Still debating distribution method. 2013-01-28 17:39:22 -05:00
Christian 5d4c2fed88 Now actually works for mods, somewhat. It currently generates access violations for
ModLoader mods that presume access to fields that are not actually accessible from
a different package.
2013-01-27 22:42:36 -05:00
Christian 66a81e7dbe Method deobfuscation now works 2013-01-27 21:50:08 -05:00
Christian 6b5a433f65 Working to read class names and remap them at runtime. 2013-01-27 17:09:00 -05:00
Christian b5d5c95b33 First draft runtime deobf 2013-01-27 15:55:37 -05:00
Christian 3ac891fa5a Try and handle "death on startup" a bit cleaner 2013-01-27 15:54:36 -05:00
Christian 2dc0189179 Deprecate the old GUI ticktype. They're dead and have been for some time. 2013-01-24 17:29:46 -05:00
Christian dd98784262 Tweak a method signature 2013-01-24 10:23:36 -05:00
LexManos 1c9a51098b Add parameters to FML install to enable/disable certian aspects. Applying patches, running transformer/merger, and decompiling server. 2013-01-24 03:08:19 -08:00
Christian d075daf00e Merge branch 'master' into snapshot15
Fix up compilation and patching errors

Conflicts:
	common/cpw/mods/fml/common/registry/GameRegistry.java
	conf/joined.srg
	conf/params.csv
	conf/version.cfg
	patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch
2013-01-22 15:21:22 -05:00
Christian 1bd6847bc8 Fix up packages.csv ordering for easier diffing 2013-01-22 14:43:27 -05:00
Christian dd832f2a88 Update for MCP7.30c - fixes redstone rendering issues 2013-01-22 14:40:09 -05:00
Christian aebf6eb168 Add in a registry method to allow for alternative TileEntity names- they will be used to support
loading maps containing the older definitions.
2013-01-22 13:11:32 -05:00
Christian 8921cfe061 Remember to add the new patches! 2013-01-22 09:32:53 -05:00
Christian cd67596d57 The "ServerStarting" event should now properly crash the server if it fails,
so the client will properly exit. Also, added in a "pre-server-start" event
that fires before the worlds are loaded for a save, just for you immibis.
2013-01-22 09:17:04 -05:00
Christian e1c6630569 Javadoc cleanup 2013-01-21 21:37:29 -05:00
Christian 5ce4e31855 Fix breaking change 2013-01-20 17:54:56 -05:00
Christian a99c488d49 Merge branch 'patch-1' of https://github.com/bspkrs/FML into gh-updates 2013-01-20 11:31:47 -05:00
Christian 94282c5575 Merge branch 'FMLLogFormatter' of https://github.com/donington/FML into gh-updates 2013-01-20 11:31:24 -05:00
Christian 7ad8529390 Update MCP to MCP7.26a and refresh MCP names 2013-01-20 10:30:36 -05:00
Christian 15534edce4 Update address of the FML repository to the new location in all the files 2013-01-18 21:26:43 -05:00
bspkrs aa822e32af Fix logical error in comment text 2013-01-16 23:49:09 -05:00
Christian a14ab913a9 Update license text to make clear that FML is not a way to sidestep
MCP licensing.
2013-01-15 16:54:26 -05:00
Christian 0165742a30 Fix mcp conf md5 signatures for the snapshot 2013-01-12 14:25:03 -05:00
donington 26a5b316de FMLLogFormatter: dynamic log level name
FMLLogFormatter now uses getLocalizedName or getName for log level name

Changes to be committed:
	modified:   common/cpw/mods/fml/relauncher/FMLLogFormatter.java
2013-01-12 00:42:36 -05:00
Christian 2140cd8cb6 Temporary hosting 2013-01-12 00:38:42 -05:00
Christian 4a6245a215 Another packaging update. I think we're done now. 2013-01-12 00:33:32 -05:00
Christian 48544db690 Fix modlist to use the new texture binding functions, i think 2013-01-12 00:27:11 -05:00
Christian 2c89b3def3 A couple of packaging tweaks, clean up more junk. It may come back but for now it's gone 2013-01-12 00:17:35 -05:00
Christian 5689182088 Delete old patches not needed anymore 2013-01-11 23:53:14 -05:00
Christian 4a1f4b90fd Initial patch update for snapshot 2013-01-11 23:47:05 -05:00
Christian f2d42d1134 Initial setup for snapshot- the client compiles, but patches fail to apply. 2013-01-11 22:49:09 -05:00
LexManos 51e7606e74 Updated patches for new JAD style names. 2013-01-11 13:16:40 -08:00
LexManos 723c2d98eb FML will now rename local variables to have JAD-style names instead of FernFlower var## names. New script to do this, to allow for modders to run it over there own code: python rename_vars.py -mcp [folders to rename]... 2013-01-11 13:16:23 -08:00
Christian 7dee072e1a Fix incorrect end length calculation. Closes #161 Thanks BStramke! 2013-01-11 09:41:47 -05:00
Christian 3e18c4160f Fix LanguageRegistry loading files in UTF-8 format. loadLocalization should work for non-xml in
all languages now (assumes UTF-8)
2013-01-08 08:46:50 -05:00
cpw 513ad19187 Merge pull request #158 from CovertJaguar/patch-2
Added an accessor for villagers
2013-01-08 05:36:45 -08:00
CovertJaguar eabede2203 Added an accessor for villagers 2013-01-07 14:55:17 -08:00
LexManos b22dbc12a2 New python script to update java files for new package names. Usage: paython update_packages.py --mcp-dir <mcp folder> [Folders To Repackage] 2013-01-06 22:10:19 -08:00
LexManos 708e86adfb New python script for signing partial jar files. See comments inside for details. 2013-01-06 22:09:12 -08:00
Christian 6f1b762c9d Move server stopped *after* the server has actually stopped. *sigh* 2012-12-31 01:20:35 -05:00
Christian d9bfb29d6c Add in a "server stopped" event 2012-12-30 23:52:38 -05:00
Christian 6fc7bc4941 Add in some classloader debugging information: use fml.debugClassLoading=true as a system property
to track down problems with classes not being found or loading erratically.
2012-12-30 21:32:37 -05:00
Christian fb701cdc5e Revert MCP name change for canConnectRedstone - it conflicts with a forge method of the same name and breaks 1.4.6 to 1.4.7 compatibility 2012-12-29 00:00:24 -05:00
Christian f7cc50b521 Update for MC 1.4.7 2012-12-28 10:07:53 -05:00
Christian 1a232cf766 Fix multiple GUI containers for ML containers. Sorry ultimatechest that
this fix took so long, a bug report at github.com/cpw/FML would help,
next time ;)
2012-12-27 23:00:52 -05:00
Christian 853f54bcc2 Log if there's a problem reading the class bytes 2012-12-27 23:00:37 -05:00
LexManos 127be2237d Fix NPE in fingerprint loading, and pass expectged fingerprint to FMLFingerprintViolationEvent 2012-12-25 15:59:30 -08:00
Christian 7e6456d7cd Fix a message delivery issue in IMC 2012-12-24 09:41:22 -05:00
Christian 664ebda599 Some tweaks for signing and ID matching 2012-12-23 22:27:26 -05:00
LexManos 9b4a225ad2 Remove unneeded file 2012-12-20 14:30:59 -08:00
LexManos 6c59fa2d2c Fixed placement of onConnectionClosed callback. 2012-12-20 14:30:41 -08:00
LexManos 5736d850f0 MCP will reobf classes with reserved names in windows to a legal file name. And FML will try to read these classes over the default ones. 2012-12-19 19:10:00 -08:00
LexManos 127d6ee8ac Output obfed files with reserved windows names to _NAME.class 2012-12-19 18:12:11 -08:00
LexManos 2055543042 Add quotes around javac command. 2012-12-19 02:58:09 -08:00
Christian 40e57a26a9 Update MCP to newer version
Fix fingerprint fire
2012-12-18 16:43:48 -05:00
Christian d604e44195 InterModComms now supports a runtime polling based model for inter-mod comms at
runtime.
Deprecate method that shouldn't be used. COPY it's content to your mod. Don't CALL it.
2012-12-18 13:58:57 -05:00
Christian 8b7778ccb6 Don't be as alarming about item overwrites. 2012-12-18 08:33:46 -05:00
Christian 7e30814ecb Added configuration file which allows modids to ignore ID validation checking. IT WILL CRASH YOUR GAME in 99.999% of cases.
Immibis is a whingy ass. And TinyTimRob too. Now STFU and GTFO. closes #510 for ever.
2012-12-18 08:15:46 -05:00
LexManos e5b1dfb74c Dixed ev eclipse worksapce, now references BC. 2012-12-18 05:10:32 -08:00
LexManos 27bc77363e Added client src folder to classpath for startclient/startserver. 2012-12-18 05:06:20 -08:00
LexManos 506b73d0a0 Removed hardcoded additions 2012-12-18 05:05:25 -08:00
Christian 20337b6e8a Update to MC 1.4.6 2012-12-17 21:48:29 -05:00
Christian 33ff87d8d9 Fix build script 2012-12-17 17:56:00 -05:00
Christian af06bbd373 more 1.4.6 tweaks 2012-12-17 17:00:54 -05:00
Christian 92a47ace8b More work 2012-12-17 14:30:51 -05:00
Christian f285ac369a Merge branch 'securityupdate' 2012-12-17 11:46:47 -05:00
Christian 68e76c273a Merge branch 'master' into securityupdate 2012-12-17 11:46:27 -05:00
Christian e98c311a2c Fix up handling null names. *sigh* 2012-12-17 10:29:54 -05:00
Christian 293edb316e Some tweaks to item identification. The GameRegistry methods are deprecated
to encourage you to use the new named ones instead. These will force a
name on the item/block, allowing for stronger matching than "sequential guessing"
2012-12-16 22:57:11 -05:00
Christian 2d4465eaf7 More fixes 2012-12-16 21:22:55 -05:00
LexManos 9266ff394a Updated MCP download mirriors upon Searge's request. 2012-12-16 05:35:46 -08:00
Christian bbfd85ed1e Move Side and SideOnly to relauncher package 2012-12-15 23:21:26 -05:00
Christian 6ecc2303f4 Fix newline fun 2012-12-15 22:37:32 -05:00
Christian d35cfda798 More stuff for the thingy 2012-12-15 22:30:16 -05:00
Christian cffa2a92a6 Remove old NEI/CCC compatibility code and other classloading tweaks 2012-12-15 20:40:08 -05:00
Uristqwerty 179c504746 Simplify logic in tick start/end
Change the EnumSet equivalent of "A &= ~ new(~B)" to "A &= B".
This eliminates the need for one temporary object in a frequently called loop, and reduces the number of methods that need to be invoked.
2012-12-14 04:14:17 -05:00
LexManos 31695d5ec1 Fix var name messup 2012-12-13 00:22:30 -08:00
LexManos bfb3020505 Update released eclipse project to link BouncyCastle 2012-12-12 23:44:28 -08:00
Christian 22a88ea2e4 Change ID management slightly. IDs are tracked by block type for itemblock items now. This means servers will need to update.
Also, ordinal rearrangements within a mod will no longer trigger server disconnection, though a warning will still be logged.
2012-12-12 19:31:05 -05:00
Christian 0423fa5885 Fix possible escape leakage.. 2012-12-12 19:31:05 -05:00
LexManos d17fbb527f More robust eclipse workspace replacement 2012-12-12 14:31:07 -08:00
LexManos d40bb0fe32 Kill decompile if astyle is not found and set execution bits on mcp .sh files and astyle-osx 2012-12-11 21:47:45 -08:00
Christian a513060a81 Change to download bouncy castle as well. We also finally properly use the downloaded libs
even in vanilla code!
2012-12-11 22:37:07 -05:00
Christian 8e594a347c Remove extraneous patch file 2012-12-11 20:37:12 -05:00
Christian 9af365edcc Merge branch 'repackage'
Conflicts:
	build.xml
	client/cpw/mods/fml/client/FMLClientHandler.java
	client/cpw/mods/fml/client/GuiIdMismatchScreen.java
	common/cpw/mods/fml/common/FMLCommonHandler.java
	common/cpw/mods/fml/common/IFMLSidedHandler.java
	common/cpw/mods/fml/common/network/ModIdMapPacket.java
	common/cpw/mods/fml/common/network/ModListResponsePacket.java
	common/cpw/mods/fml/common/registry/GameData.java
	common/cpw/mods/fml/common/registry/GameRegistry.java
	common/cpw/mods/fml/common/registry/ItemData.java
	common/cpw/mods/fml/common/registry/LanguageRegistry.java
	common/cpw/mods/fml/server/FMLServerHandler.java
	install/fml.py
	patches/minecraft/net/minecraft/client/Minecraft.java.patch
	patches/minecraft/net/minecraft/server/MinecraftServer.java.patch
	patches/minecraft/net/minecraft/world/storage/SaveHandler.java.patch
2012-12-11 14:58:38 -05:00
Christian 70554d6a2b Merge branch 'repackage' of github.com:cpw/FML into repackage
Conflicts:
	common/cpw/mods/fml/common/registry/GameData.java
2012-12-11 14:49:23 -05:00
cpw eb84f52493 Merge pull request #145 from pahimar/master
More logging of loading files in LanguageRegistry
2012-12-11 08:28:39 -08:00
pahimar d074830d95 Update common/cpw/mods/fml/common/registry/LanguageRegistry.java
Add in logging of what file failed to be loaded
2012-12-11 11:27:05 -05:00
LexManos f7fe9ebeb2 Fix patches, rebased with HEAD 2012-12-10 15:37:48 -08:00
LexManos b2c8f37aec Remade python dist as 32-bit. 2012-12-10 15:26:15 -08:00
Christian a5bcccab59 Fixing id map generation - should validate correctly now 2012-12-10 15:26:13 -08:00
LexManos a11f368b62 Reenabled replacement of the eclipse folder. 2012-12-10 14:56:23 -08:00
LexManos 59656b004b Remade python dist as 32-bit. 2012-12-10 14:56:05 -08:00
Christian ff8cb67a99 Fixing id map generation - should validate correctly now 2012-12-09 22:24:16 -05:00
Christian fa5256c8a7 Fix up idmap code 2012-12-09 22:01:13 -05:00
LexManos 4b19987ee6 Some derp protection in the workspace copy. 2012-12-09 02:20:21 -08:00
LexManos 9f43303073 Removed remaining references to src/common
Fixed eclipse workspace replacemnt on source dist
Cleanup some outputs
2012-12-09 02:10:28 -08:00
LexManos a20958fb56 Updated build script to not use the mcp common directory as it doesn't exist anymore. 2012-12-08 21:41:51 -08:00
LexManos 8c71098081 Fished moving out the rest of the default packaged classes to aproperiate packages. Updated patches and code to reflect. 2012-12-08 21:41:16 -08:00
LexManos a3a5b44acb Updated the update_packages script to support different mcp locations 2012-12-08 21:40:39 -08:00
LexManos 0473273709 Update fml_marker.cfg, Minecraft is now runnable! 2012-12-08 20:25:29 -08:00
LexManos bf492f32f9 Update all imports for repackaging. Branch is compileable. 2012-12-08 20:21:03 -08:00
LexManos 4744677646 Some stragler patches 2012-12-08 19:34:35 -08:00
LexManos f0af2e4ef5 Updated patches to new packages. 2012-12-08 19:33:29 -08:00
LexManos c7f763d6f0 Give new classes a distinct package to be moved from. 2012-12-08 17:50:14 -08:00
LexManos 563b8d1215 Fixed 0.tree to actually refresh the workspace. 2012-12-08 17:35:11 -08:00
LexManos 221493453f Remerged branch, and updated dev eclipse workspace. 2012-12-08 17:08:51 -08:00
Christian 86c928430a Add in storage, detection and validation of the ItemID array between client and server
and also for world saves. May help with item configuration issues.
2012-12-08 17:05:18 -08:00
Christian cd0a0e51d5 Add a modid on the mods list, should make it easier to do things like forge chunkloading config 2012-12-08 16:46:47 -08:00
Christian 66ff95f9d7 Fix build eclipse extractor task 2012-12-08 16:46:46 -08:00
Christian 8ad172295f Add in storage, detection and validation of the ItemID array between client and server
and also for world saves. May help with item configuration issues.
2012-12-07 01:52:16 -05:00
Christian 26a2ef5995 Add a modid on the mods list, should make it easier to do things like forge chunkloading config 2012-12-04 18:08:27 -05:00
Christian b4e3490fa1 Fix build eclipse extractor task 2012-12-04 18:04:45 -05:00
Christian 828341f987 Fix typo 2012-12-04 01:30:38 -05:00
Christian bc03fbb3be Merge branch 'master' into repackage
Conflicts:
	eclipse/Clean/.classpath
	eclipse/Clean/.project
	eclipse/FML/.classpath
	eclipse/FML/.project
	install/fml.py
2012-12-04 01:24:50 -05:00
Christian 7a8dae5e35 Try and make branch non-derpy 2012-12-03 23:47:23 -05:00
Christian d3c0e1f589 Try defaulting branch differently 2012-12-03 22:26:12 -05:00
Christian 9c77d3f25b Remove old eclipse workspace and ship/extract as a zip file (use ant setupenvironment)
Fix up install.py for forge multibranch changes
2012-12-03 19:55:37 -05:00
LexManos 6371e9b71e Assume Forge is the parent directory when checking for AT configs. 2012-12-03 16:53:03 -08:00
Christian 578ef5cfeb Merge branch 'master' into repackage
Conflicts:
	patches/minecraft/net/minecraft/client/EntityFX.java.patch
2012-12-03 17:31:29 -05:00
Christian 516954e6f9 Name both zips the same format 2012-12-03 08:38:20 -05:00
Christian 1151d5c3e3 Last part of branch name only please 2012-12-03 08:30:44 -05:00
Christian 25f1ddac30 Try and get a valid branch name on jenkins 2012-12-03 08:23:21 -05:00
Christian 39a146f8e6 Clean up build.xml script- support outputting a branched jar file 2012-12-03 08:13:20 -05:00
LexManos 037dcaefea Small derp in install.py 2012-12-02 20:26:36 -08:00
LexManos 01d6da3a90 Try marking python as binary. 2012-12-02 20:19:55 -08:00
LexManos 8b2665980d FML will now attempt to download MCP as part of the install process
Now shipping a py2exe version of python for windows.
Linux/Macs should come with python pre-installed so they do not have a distrabution here.
2012-12-02 19:59:22 -08:00
LexManos 42b3e6ad56 Windows Python distrabution created using py2exe, thanks Fesh0r for the script. 2012-12-02 19:56:17 -08:00
LexManos e709ab8a70 Marked more spots in gui/items bitmask as being free. 2012-11-21 15:58:04 -08:00
LexManos 501409d1fb Delete duplicate file 2012-11-20 18:07:39 -08:00
LexManos 0fb3a34235 Finished repackaging net.minecraft.* net.minecraft.client is left 2012-11-20 17:58:22 -08:00
LexManos e4ba1f863e More re-packaging, got most classes out of the default package. 2012-11-20 17:22:55 -08:00
Christian 1f5c58b723 Fix up MCP version 2012-11-20 08:47:14 -05:00
Christian 61e4db2c3b Merge joined.exc add update howto 2012-11-20 08:38:33 -05:00
Christian 5efc1eb34c Revert "Fix MC-2497 - derpy torch flames. Moved from forge. Everyone should benefit."
This reverts commit fa567014a5.
2012-11-20 08:27:13 -05:00
LexManos 96c6f91201 Remove common folder from projects 2012-11-20 03:15:45 -08:00
LexManos 62e69a2804 Move IBossDisplayData to shared 2012-11-20 03:15:16 -08:00
LexManos e9352d2675 First half of new patches 2012-11-20 03:15:01 -08:00
LexManos ee6abdf28d Update FML imports 2012-11-20 03:14:36 -08:00
LexManos 968ee7ab09 Inital script side commit for MC source repackaging done. 2012-11-20 01:55:41 -08:00
LexManos 3b3600d44f Modified merger to just consider all server classes as common. And moved the defnition of CodecMus to the config. 2012-11-19 17:45:53 -08:00
LexManos edcc5ca554 Forgot mcp.cfg 2012-11-19 15:47:18 -08:00
LexManos ca79dfe298 Updated to 1.4.5b 2012-11-19 15:35:08 -08:00
LexManos 5945279b8b Fix python error 2012-11-19 15:03:13 -08:00
LexManos 57bf64318b Modified decompile so that we do not have to decompile the server, saves time. 2012-11-19 15:01:04 -08:00
LexManos d9d0a46809 Cleaned up some tabs 2012-11-19 15:00:11 -08:00
LexManos 2fac644914 Change usage of ZipFile, fixes issues with Mac's default instation of python. Also cleaned the python a little bit. 2012-11-19 13:33:22 -08:00
Christian 570592b24b Attempt to fix a possible comodification risk 2012-11-18 20:40:48 -05:00
Christian fde94144ec Change texturebinding to use the textureId directly rather than iconIndex
to determine if it needs to rebind the texture sheet
2012-11-18 08:45:25 -05:00
Christian f348496c10 Fix mod display list. Shouldn't be derpy anymore. 2012-11-17 23:51:14 -05:00
Christian a5c31b5365 Fix World patch- workaround no longer required and leftovers are bad. 2012-11-17 23:44:53 -05:00
LexManos 2dc3f0ddef Cleaned up the AT config updater, should work for any setup of the MCP workspace now. 2012-11-17 19:08:47 -08:00
Christian fa567014a5 Fix MC-2497 - derpy torch flames. Moved from forge. Everyone should benefit. 2012-11-16 22:50:21 -05:00
Christian 96935bb122 Fix an NPE in TileEntity trying to generate a crash report. Make suspicious classes just return the obvious.
Fix NPE for FML crash report on server. Clean up dead patches.
2012-11-16 22:50:00 -05:00
Christian 43d3042dff Clean up a patch 2012-11-16 16:49:44 -05:00
Christian fec221f8a6 Update FML for MC 1.4.5 2012-11-16 16:31:06 -05:00
LexManos b0f0635eb3 Fix for ModLoader static overrides not displaying. 2012-11-15 14:08:41 -08:00
Christian 23a25131b0 Fix up derpy file name handling: closes #127
Fix up duping childmods: closes #126
FMLPreinitializationEvent now offers a getLogger() that'll return your mod a personalized logger instance
2012-11-12 17:54:21 -05:00
LexManos a6eaa2bebc Fix spelling issue. 2012-11-08 21:01:31 -08:00
LexManos c6a0741379 FML setup should now download and verify all the minecraft files needed to run MCP. 2012-11-08 17:54:05 -08:00
Christian 5a1930e2d6 Small fix to some MCP metadata for pre2 2012-11-08 20:34:45 -05:00
Christian 418deba5bf Update to MC 1.4.4 2012-11-08 17:55:20 -05:00
Christian 4ff2cff3c0 Fix bug when a modloader mod is run on a dedicated server and has a
connection handler assigned to it. Hi SmartMoving! Perhaps you should try
@Mod instead of BaseMod?
2012-11-04 10:57:49 -05:00
Christian bd2123cf9d Clean up some patch fuzz 2012-11-02 17:32:39 -04:00
Christian c2a603c910 Update joined.exc file from latest conf 2012-11-02 17:23:54 -04:00
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
395 changed files with 40384 additions and 23200 deletions

No files matched your search

+10 -1
View File
@@ -1 +1,10 @@
* text=auto
* text eol=lf
*.bat text eol=crlf
*.patch text eol=lf
*.png binary
*.exe binary
*.dll binary
*.zip binary
*.pyd binary
*.cfg text eol=lf
*.py text eol=lf
+4 -2
View File
@@ -4,9 +4,11 @@
/fmlbuild.properties
/fmlversion.properties
/difflist.txt
/.metadata/
/eclipse/.metadata/
/target
fmlbranding.properties
/fernflower.zip
/commands.py.bck
/mcp*.zip
/mcp
/eclipse
/deobfuscation_data*.zip
+13 -3
View File
@@ -1,7 +1,7 @@
This minecraft mod, Forge Mod Loader, including all parts herein, is licensed
under the GNU LGPL v2.1 or later.
This minecraft mod, Forge Mod Loader, including all parts herein except as noted below,
is licensed under the GNU LGPL v2.1 or later.
Homepage: https://github.com/cpw/FML
Homepage: https://github.com/MinecraftForge/FML
This software includes portions from the Apache Maven project at
http://maven.apache.org/ specifically the ComparableVersion.java code. It is
@@ -9,6 +9,16 @@ 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.
=== MCP Data ===
This software includes data from the Minecraft Coder Pack (MCP), with kind permission
from them. The license to MCP data is not transitive - distribution of this data by
third parties requires independent licensing from the MCP team. This data is not
redistributable without permission from the MCP team.
=== Sharing ===
License is granted to redistribute the ASM transformer code (common/cpw/mods/fml/common/asm/ and subdirectories)
under any alternative open source license as classified by the OSI (http://opensource.org/licenses)
========
GNU LESSER GENERAL PUBLIC LICENSE
+110 -136
View File
@@ -9,20 +9,6 @@
====================================================================== -->
<project name="FML" default="jenkinsbuild">
<description>The Forge Mod Loader</description>
<macrodef name="side">
<attribute name="prop" />
<attribute name="src" />
<attribute name="side" />
<sequential>
<property name="@{prop}" value="${@{side}.@{src}}" />
<condition property="is.client">
<equals arg1="@{side}" arg2="client" />
</condition>
<condition property="is.server">
<equals arg1="@{side}" arg2="server" />
</condition>
</sequential>
</macrodef>
<target name="writeversion" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${basedir}" failonerror="true">
<arg value="${basedir}/getversion.py" />
@@ -30,6 +16,7 @@
</exec>
<propertyfile file="fmlversion.properties">
<entry key="fmlbuild.build.number" type="int" value="${version.build}"/>
<entry key="fmlbuild.deobfuscation.hash" type="string" value="${deobf.checksum}"/>
</propertyfile>
</target>
@@ -38,36 +25,36 @@
<format pattern="yyMMddHHmmss" property="timestamp" />
</tstamp>
<property environment="env" />
<property file="fmlbuild.properties" />
<property name="modname" value="fml" />
<condition property="dev.home" value="${env.WORKSPACE}" else="${default.dev.home}">
<condition property="mcp.home" value="${env.WORKSPACE}/mcp" else="${basedir}/mcp">
<isset property="env.WORKSPACE" />
</condition>
<condition property="mcp.home" value="${env.WORKSPACE}/mcpworkspace" else="${default.mcp.home}">
<isset property="env.WORKSPACE" />
</condition>
<condition property="python.exe" value="${mcp.home}/runtime/bin/python/python_mcp" else="python">
<property name="fml.python.dir" location="${basedir}/python" />
<condition property="python.exe" value="${fml.python.dir}/python_fml" else="python">
<os family="Windows" />
</condition>
<condition property="mcp.exists">
<available file="${mcp.home}/runtime/commands.py"/>
</condition>
<condition property="signature.exists">
<available file="${env.JENKINS_HOME}/fmlsigned.properties"/>
</condition>
<property name="mcp.obfoutput" location="${mcp.home}/reobf" />
<property name="client.mcp.obfoutput" location="${mcp.obfoutput}/minecraft" />
<property name="server.mcp.obfoutput" location="${mcp.obfoutput}/minecraft_server" />
<property name="mcp.srcdir" location="${mcp.home}/src" />
<property name="common.mcp.srcdir" location="${mcp.srcdir}/common" />
<property name="client.mcp.srcdir" location="${mcp.srcdir}/minecraft" />
<property name="server.mcp.srcdir" location="${mcp.srcdir}/minecraft_server" />
<property name="clean.mcp.srcdir" location="${mcp.home}/src-base" />
<property name="patch.mcp.srcdir" location="${mcp.home}/src-work" />
<property name="tmp.mcp.srcdir" location="${mcp.home}/src-tmp" />
<property name="renamed.mcp.srcdir" location="${mcp.home}/src-renamed" />
<property name="common.src.dir" location="${basedir}/common" />
<property name="client.src.dir" location="${basedir}/client" />
<property name="server.src.dir" location="${basedir}/server" />
<property name="patch.src.dir" location="${basedir}/patches" />
<property name="fml.conf.dir" location="${basedir}/conf" />
<condition property="version.build" value="${env.BUILD_NUMBER}" else="1">
<isset property="env.BUILD_NUMBER" />
</condition>
<available file="eclipse" property="eclipse.exists"/>
</target>
<target name="makeversion" depends="buildenvsetup">
@@ -77,58 +64,58 @@
<property name="version.major" value="${fmlbuild.major.number}" />
<property name="version.minor" value="${fmlbuild.minor.number}" />
<property name="version.rev" value="${fmlbuild.revision.number}" />
<property name="version.minecraft" value="${fmlbuild.mcversion}" />
<property name="version.branch" value="${fmlbuild.branch}" />
<property name="version" value="${version.major}.${version.minor}.${version.rev}.${version.build}" />
</target>
<target name="clean" depends="buildenvsetup">
<target name="makeclean" depends="buildenvsetup" if="mcp.exists">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/cleanup.py" />
<arg value="-f" />
</exec>
</target>
<target name="clean" depends="buildenvsetup,makeclean" if="mcp.exists">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/decompile.py" />
<arg value="-d" />
<arg value="-n" />
<arg value="${basedir}/decompile.py" />
<arg value="${mcp.home}" />
<arg value="${basedir}" />
</exec>
</target>
<target name="buildandreobfmcp" depends="buildenvsetup,recompile">
<target name="reobfuscate" depends="buildenvsetup,recompile">
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
<arg value="${mcp.home}/runtime/reobfuscate.py" />
</exec>
<fail message="Reobfuscation failed">
<condition>
<not>
<and>
<available file="${mcp.home}/temp/server.md5"/>
<available file="${mcp.home}/temp/server_reobf.md5"/>
<available file="${mcp.home}/temp/client.md5"/>
<fail message="Reobfuscation failed">
<condition>
<not>
<and>
<available file="${mcp.home}/temp/client.md5"/>
<available file="${mcp.home}/temp/client_reobf.md5"/>
</and>
</not>
</condition>
</fail>
</and>
</not>
</condition>
</fail>
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${basedir}/generatechangedfilelist.py"/>
<arg value="${mcp.home}"/>
<arg value="${basedir}/difflist.txt"/>
</exec>
</target>
<target name="recompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}" failonerror="true">
<arg value="${mcp.home}/runtime/recompile.py" />
</exec>
<fail message="Compilation failed">
<condition>
<not>
<and>
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
<available file="${mcp.home}/bin/minecraft_server/net/minecraft/server/MinecraftServer.class"/>
</and>
</not>
</condition>
</fail>
<fail message="Compilation failed">
<condition>
<not>
<available file="${mcp.home}/bin/minecraft/net/minecraft/client/Minecraft.class"/>
</not>
</condition>
</fail>
</target>
<target name="merge-client" depends="buildenvsetup">
@@ -137,40 +124,34 @@
</copy>
</target>
<target name="merge-server" depends="buildenvsetup">
<copy todir="${server.mcp.srcdir}" overwrite="true" verbose="true">
<fileset dir="${server.src.dir}" includes="**/*.java" />
</copy>
</target>
<target name="merge-common">
<copy todir="${common.mcp.srcdir}" overwrite="true" verbose="true">
<copy todir="${client.mcp.srcdir}" overwrite="true" verbose="true">
<fileset dir="${common.src.dir}" includes="**/*.java" />
</copy>
</target>
<target name="merge-source" depends="buildenvsetup,merge-client,merge-server,merge-common" />
<target name="build-client" depends="buildenvsetup,merge-client,merge-common,buildandreobfmcp,makeversion">
<antcall target="extract-built-jar">
<param name="side" value="client" />
</antcall>
</target>
<target name="merge-source" depends="buildenvsetup,merge-client,merge-common" />
<target name="build-server" depends="buildenvsetup,merge-server,merge-common,buildandreobfmcp,makeversion">
<antcall target="extract-built-jar">
<param name="side" value="server" />
</antcall>
</target>
<target name="build-universal" depends="buildenvsetup,merge-client,merge-common,reobfuscate,makeversion">
<condition property="universal.jarname" value="${modname}-universal-${version.minecraft}-${version}" else="${modname}-universal-${version.minecraft}-${version}-${version.branch}">
<equals arg1="${version.branch}" arg2="master" />
</condition>
<target name="extract-built-jar">
<side prop="output" src="mcp.obfoutput" side="${side}" />
<property name="jarname" value="${modname}-${side}-${version}" />
<mkdir dir="${basedir}/target" />
<zip destfile="${basedir}/target/${jarname}.zip">
<fileset dir="${output}" includes="**/*.class" />
<jar destfile="${basedir}/target/${universal.jarname}.zip" duplicate="preserve">
<manifest>
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
<attribute name="Class-Path" value="minecraft_server.jar"/>
</manifest>
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" excludes="*.class"/>
</jar>
<antcall target="signjar"/>
<zip update="true" destfile="${basedir}/target/${universal.jarname}.zip" >
<fileset dir="${client.mcp.obfoutput}" includes="*.class"/>
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" />
<zipfileset dir="${client.src.dir}" includes="mcp.png" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
<mappedresources>
@@ -191,48 +172,19 @@
</zip>
</target>
<target name="build-universal">
<property name="universal.jarname" value="${modname}-universal-${version}" />
<mkdir dir="${basedir}/target" />
<jar destfile="${basedir}/target/${universal.jarname}.zip">
<manifest>
<attribute name="Main-Class" value="net.minecraft.server.MinecraftServer"/>
</manifest>
<fileset dir="${server.mcp.obfoutput}" includes="**/*.class" />
<fileset dir="${client.mcp.obfoutput}" includes="**/*.class" />
<zipfileset dir="${basedir}" includes="fmlversion.properties"/>
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt" />
<zipfileset dir="${basedir}" includes="install/CREDITS-fml.txt" fullpath="CREDITS-fml.txt"/>
<zipfileset dir="${common.src.dir}" includes="*.cfg" />
<mappedresources>
<concat>
<fileset dir="${basedir}/install" includes="README.txt" />
<filterchain>
<replacetokens>
<token key="MAJOR" value="${version.major}" />
<token key="MINOR" value="${version.minor}" />
<token key="REV" value="${version.rev}" />
<token key="BUILD" value="${version.build}" />
<token key="MCVERSION" value="${version.minecraft}" />
</replacetokens>
</filterchain>
</concat>
<mergemapper to="README-fml.txt" />
</mappedresources>
</jar>
</target>
<target name="build-source-pack" depends="makeversion">
<property name="srcpack.jarname" value="${modname}-src-${version}" />
<property name="srcpack.jarname" value="${modname}-src-${version.minecraft}-${version}-${version.branch}" />
<zip destfile="${basedir}/target/${srcpack.jarname}.zip">
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt,commands.patch,mcp_merge.cfg" prefix="fml" />
<zipfileset dir="${basedir}" includes="LICENSE-fml.txt,difflist.txt,commands.patch,mcp_merge.cfg,mc_versions.cfg" prefix="fml" />
<zipfileset dir="${common.src.dir}" includes="**/*.java" prefix="fml/common" />
<zipfileset dir="${client.src.dir}" includes="**/*.java" prefix="fml/client" />
<zipfileset dir="${server.src.dir}" includes="**/*.java" prefix="fml/server" />
<zipfileset dir="${client.src.dir}" includes="mcp.png" prefix="fml/client" />
<zipfileset dir="${basedir}" includes="fmlversion.properties" prefix="fml/common" />
<zipfileset dir="${common.src.dir}" includes="*.cfg" prefix="fml/common" />
<zipfileset dir="${common.src.dir}" includes="mcpmod.info" prefix="fml/common" />
<zipfileset dir="${patch.src.dir}" includes="**/*.patch" prefix="fml/patches" />
<zipfileset dir="${fml.conf.dir}" prefix="fml/conf" />
<zipfileset dir="${fml.python.dir}" prefix="fml/python" />
<mappedresources>
<concat>
<fileset dir="${basedir}/install" includes="README.txt" />
@@ -252,7 +204,24 @@
</zip>
</target>
<target name="build" depends="buildenvsetup,merge-server,merge-client,merge-common,build-server,build-client,build-universal,build-source-pack" />
<target name="build-deobf-data" depends="makeversion">
<mkdir dir="build-tmp-deobf"/>
<copy todir="build-tmp-deobf">
<mappedresources>
<fileset dir="${mcp.home}/conf" includes="packaged.srg"/>
<globmapper from="packaged.srg" to="joined.srg"/>
</mappedresources>
</copy>
<touch millis="0" file="build-tmp-deobf/joined.srg"/>
<zip file="deobfuscation_data_${version.minecraft}.zip" encoding="UTF-8">
<fileset dir="build-tmp-deobf" includes="joined.srg"/>
</zip>
<checksum algorithm="SHA1" property="deobf.checksum" file="deobfuscation_data_${version.minecraft}.zip"/>
<antcall target="writeversion"/>
<delete dir="build-tmp-deobf" />
</target>
<target name="build" depends="buildenvsetup,merge-client,merge-common,build-deobf-data,build-universal,build-source-pack" />
<target name="jenkinsbuild" depends="buildenvsetup,jenkinsfmldecompile,patch,build"/>
@@ -273,11 +242,7 @@
</condition>
<fail if="do.not.continue">You have decided not to continue. This script will stop now.</fail>
<echo>Preparing the MCP environment at ${mcp.home}</echo>
<!--<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/download_fernflower.py" />
<arg value="${mcp.home}"/>
</exec>-->
<antcall target="fmldecompile"/>
<antcall target="fmldecompile"/>
<echo>Moving old patched sources at ${patch.mcp.srcdir} out of the way</echo>
<move todir="${mcp.home}/src-work${timestamp}" failonerror="false" verbose="true">
<fileset dir="${patch.mcp.srcdir}"/>
@@ -295,26 +260,19 @@
<fileset dir="${mcp.srcdir}"/>
</copy>
<antcall target="writeversion"/>
<echo>Setup complete! You should now be able to open ${basedir}/eclipse as a workspace in eclipse and import/refresh the FML-Server and FML-Client projects</echo>
<antcall target="makeeclipse"/>
<echo>Setup complete! You should now be able to open ${basedir}/eclipse as a workspace in eclipse and import/refresh the FML project</echo>
</target>
<target name="fmldecompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/cleanup.py" />
<arg value="-f" />
</exec>
<target name="fmldecompile" depends="buildenvsetup,makeclean">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/decompile.py" />
<arg value="${mcp.home}" />
<arg value="${basedir}" />
</exec>
</target>
<target name="jenkinsfmldecompile" depends="buildenvsetup">
<exec executable="${python.exe}" dir="${mcp.home}">
<arg value="${mcp.home}/runtime/cleanup.py" />
<arg value="-f" />
</exec>
<target name="jenkinsfmldecompile" depends="buildenvsetup,makeclean">
<exec executable="${python.exe}" dir="${basedir}">
<arg value="${basedir}/decompile.py" />
<arg value="${mcp.home}" />
@@ -340,7 +298,7 @@
<fileset dir="${mcp.srcdir}"/>
</copy>
</target>
<target name="repatchclean" depends="buildenvsetup">
<delete dir="${mcp.srcdir}"/>
<copy todir="${mcp.srcdir}">
@@ -354,20 +312,21 @@
<target name="cleanargo" depends="buildenvsetup">
<delete dir="${client.mcp.srcdir}/argo"/>
<delete dir="${client.mcp.srcdir}/org"/>
</target>
<target name="checkpatches" depends="buildenvsetup">
<uptodate property="checkUptodate.uptodate">
<srcfiles dir="${patch.mcp.srcdir}" includes="**/*.java">
<present targetdir="${patch.src.dir}">
<globmapper from="*.java" to="*.java.patch"/>
</present>
<present targetdir="${patch.src.dir}">
<globmapper from="*.java" to="*.java.patch"/>
</present>
</srcfiles>
<globmapper from="*.java" to="${patch.src.dir}/*.java.patch"/>
</uptodate>
<fail unless="checkUptodate.uptodate">
A patch is out of date. Update your patches!
</fail>
<fail unless="checkUptodate.uptodate">
A patch is out of date. Update your patches!
</fail>
</target>
<target name="updatepatches" depends="buildenvsetup">
@@ -378,7 +337,14 @@
</exec>
</target>
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-server,buildandreobfmcp">
<target name="makeeclipse" depends="buildenvsetup" unless="eclipse.exists">
<echo>
Extracting fresh eclipse workspace to ${basedir}/eclipse
</echo>
<unzip src="${basedir}/eclipse-workspace-dev.zip" dest="${basedir}"/>
</target>
<target name="makerenamedsource" depends="buildenvsetup,repatch,merge-client,merge-common,reobfuscate">
<copy todir="${tmp.mcp.srcdir}">
<fileset dir="${mcp.srcdir}"/>
</copy>
@@ -393,4 +359,12 @@
<fileset dir="${tmp.mcp.srcdir}"/>
</move>
</target>
<target name="signjar" depends="buildenvsetup,makeversion" if="signature.exists">
<condition property="universal.jarname" value="${modname}-universal-${version.minecraft}-${version}" else="${modname}-universal-${version.minecraft}-${version}-${version.branch}">
<equals arg1="${version.branch}" arg2="master" />
</condition>
<property file="${env.JENKINS_HOME}/fmlsigned.properties" prefix="sign"/>
<echo>${env.JENKINS_HOME} ${universal.jarname} ${sign.KEYPASS}</echo>
<signjar alias="FML" jar="${basedir}/target/${universal.jarname}.zip" keypass="${sign.KEYPASS}" keystore="${env.JENKINS_HOME}/${sign.KEYSTORE}" storepass="${sign.STOREPASS}" verbose="true"/>
</target>
</project>
@@ -0,0 +1,55 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiErrorScreen;
import cpw.mods.fml.common.IFMLHandledException;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* If a mod throws this exception during loading, it will be called back to render
* the error screen through the methods below. This error will not be cleared, and will
* not allow the game to carry on, but might be useful if your mod wishes to report
* a fatal configuration error in a pretty way.
*
* Throw this through a proxy. It won't work on the dedicated server environment.
* @author cpw
*
*/
@SideOnly(Side.CLIENT)
public abstract class CustomModLoadingErrorDisplayException extends RuntimeException implements IFMLHandledException
{
/**
* Called after the GUI is inited by the parent code. You can do extra stuff here, maybe?
*
* @param errorScreen The error screen we're painting
* @param fontRenderer A font renderer for you
*/
public abstract void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer);
/**
* Draw your error to the screen.
*
* <br/><em>Warning: Minecraft is in a deep error state.</em> <strong>All</strong> it can do is stop.
* Do not try and do anything involving complex user interaction here.
*
* @param errorScreen The error screen to draw to
* @param fontRenderer A font renderer for you
* @param mouseRelX Mouse X
* @param mouseRelY Mouse Y
* @param tickTime tick time
*/
public abstract void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime);
}
+253 -127
View File
@@ -12,114 +12,73 @@
*/
package cpw.mods.fml.client;
import static org.lwjgl.opengl.GL11.*;
import java.awt.image.BufferedImage;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.multiplayer.GuiConnecting;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.crash.CrashReport;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet131MapData;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.BaseMod;
import net.minecraft.src.BiomeGenBase;
import net.minecraft.src.Block;
import net.minecraft.src.CrashReport;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityLiving;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.GameSettings;
import net.minecraft.src.GuiScreen;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.IChunkProvider;
import net.minecraft.src.IInventory;
import net.minecraft.src.Item;
import net.minecraft.src.ItemStack;
import net.minecraft.src.KeyBinding;
import net.minecraft.src.MLProp;
import net.minecraft.src.ModTextureStatic;
import net.minecraft.src.NetClientHandler;
import net.minecraft.src.NetworkManager;
import net.minecraft.src.Packet;
import net.minecraft.src.Packet1Login;
import net.minecraft.src.Packet250CustomPayload;
import net.minecraft.src.Packet3Chat;
import net.minecraft.src.Profiler;
import net.minecraft.src.Render;
import net.minecraft.src.RenderBlocks;
import net.minecraft.src.RenderEngine;
import net.minecraft.src.RenderManager;
import net.minecraft.src.RenderPlayer;
import net.minecraft.src.StringTranslate;
import net.minecraft.src.TextureFX;
import net.minecraft.src.TexturePackBase;
import net.minecraft.src.World;
import net.minecraft.src.WorldClient;
import net.minecraft.src.WorldType;
import argo.jdom.JdomParser;
import argo.jdom.JsonNode;
import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.DuplicateModsFoundException;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLDummyContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.IFMLSidedHandler;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.MetadataCollection;
import cpw.mods.fml.common.MissingModsException;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.ProxyInjector;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.modloader.ModLoaderHelper;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.modloader.ModProperty;
import cpw.mods.fml.common.WrongMinecraftVersionException;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.common.registry.IThrowableEntity;
import cpw.mods.fml.common.registry.ItemData;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.relauncher.Side;
/**
* Handles primary communication from hooked code into the system
*
* The FML entry point is {@link #beginMinecraftLoading(MinecraftServer)} called from
* {@link MinecraftServer}
* The FML entry point is {@link #beginMinecraftLoading(Minecraft)} called from
* {@link Minecraft}
*
* Obfuscated code should focus on this class and other members of the "server"
* (or "client") code
@@ -146,23 +105,32 @@ public class FMLClientHandler implements IFMLSidedHandler
*/
private Minecraft client;
private boolean firstTick;
/**
* Called to start the whole game off from
* {@link MinecraftServer#startServer}
*
* @param minecraftServer
*/
private DummyModContainer optifineContainer;
private boolean guiLoaded;
private boolean serverIsRunning;
private MissingModsException modsMissing;
private boolean loading;
private WrongMinecraftVersionException wrongMC;
private CustomModLoadingErrorDisplayException customError;
private DuplicateModsFoundException dupesFound;
private boolean serverShouldBeKilledQuietly;
/**
* Called to start the whole game off
*
* @param minecraft The minecraft instance being launched
*/
public void beginMinecraftLoading(Minecraft minecraft)
{
client = minecraft;
if (minecraft.func_71355_q())
{
FMLLog.severe("DEMO MODE DETECTED, FML will not work. Finishing now.");
@@ -170,9 +138,8 @@ public class FMLClientHandler implements IFMLSidedHandler
return;
}
client = minecraft;
ObfuscationReflectionHelper.detectObfuscation(World.class);
TextureFXManager.instance().setClient(client);
loading = true;
// TextureFXManager.instance().setClient(client);
FMLCommonHandler.instance().beginLoading(this);
new ModLoaderClientHelper(client);
try
@@ -180,7 +147,7 @@ public class FMLClientHandler implements IFMLSidedHandler
Class<?> optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader());
String optifineVersion = (String) optifineConfig.getField("VERSION").get(null);
Map<String,Object> dummyOptifineMeta = ImmutableMap.<String,Object>builder().put("name", "Optifine").put("version", optifineVersion).build();
ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info")).getMetadataForId("optifine", dummyOptifineMeta);
ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info"),"optifine").getMetadataForId("optifine", dummyOptifineMeta);
optifineContainer = new DummyModContainer(optifineMetadata);
FMLLog.info("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion());
}
@@ -192,6 +159,23 @@ public class FMLClientHandler implements IFMLSidedHandler
{
Loader.instance().loadMods();
}
catch (WrongMinecraftVersionException wrong)
{
wrongMC = wrong;
}
catch (DuplicateModsFoundException dupes)
{
dupesFound = dupes;
}
catch (MissingModsException missing)
{
modsMissing = missing;
}
catch (CustomModLoadingErrorDisplayException custom)
{
FMLLog.log(Level.SEVERE, custom, "A custom exception was thrown by a mod, the game will now halt");
customError = custom;
}
catch (LoaderException le)
{
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
@@ -210,28 +194,62 @@ public class FMLClientHandler implements IFMLSidedHandler
* Also initializes key bindings
*
*/
@SuppressWarnings("deprecation")
public void finishMinecraftLoading()
{
if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null)
{
return;
}
try
{
Loader.instance().initializeMods();
}
catch (CustomModLoadingErrorDisplayException custom)
{
FMLLog.log(Level.SEVERE, custom, "A custom exception was thrown by a mod, the game will now halt");
customError = custom;
return;
}
catch (LoaderException le)
{
haltGame("There was a severe problem during mod loading that has caused the game to fail", le);
return;
}
LanguageRegistry.reloadLanguageTable();
RenderingRegistry.instance().loadEntityRenderers((Map<Class<? extends Entity>, Render>)RenderManager.field_78727_a.field_78729_o);
KeyBindingRegistry.uploadKeyBindingsToGame(client.field_71474_y);
loading = false;
KeyBindingRegistry.instance().uploadKeyBindingsToGame(client.field_71474_y);
}
// Mark this as a "first tick"
firstTick = true;
public void onInitializationComplete()
{
if (wrongMC != null)
{
client.func_71373_a(new GuiWrongMinecraft(wrongMC));
}
else if (modsMissing != null)
{
client.func_71373_a(new GuiModsMissing(modsMissing));
}
else if (dupesFound != null)
{
client.func_71373_a(new GuiDupesFound(dupesFound));
}
else if (customError != null)
{
client.func_71373_a(new GuiCustomModLoadingErrorScreen(customError));
}
else
{
// Force renderengine to reload and re-initialize all textures
client.field_71446_o.func_78352_b();
// TextureFXManager.instance().loadTextures(client.field_71418_C.func_77292_e());
}
}
/**
* Get the server instance
*
* @return
*/
public Minecraft getClient()
{
@@ -266,16 +284,6 @@ public class FMLClientHandler implements IFMLSidedHandler
}
}
@Override
public void profileStart(String profileLabel) {
client.field_71424_I.func_76320_a(profileLabel);
}
@Override
public void profileEnd() {
client.field_71424_I.func_76319_b();
}
/**
* @param mods
*/
@@ -293,7 +301,7 @@ public class FMLClientHandler implements IFMLSidedHandler
{
return Arrays.asList(String.format("Optifine %s",optifineContainer.getVersion()));
} else {
return Collections.emptyList();
return ImmutableList.<String>of();
}
}
@@ -316,39 +324,48 @@ public class FMLClientHandler implements IFMLSidedHandler
}
@Override
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket packet)
public Entity spawnEntityIntoClientWorld(EntityRegistration er, EntitySpawnPacket packet)
{
WorldClient wc = client.field_71441_e;
Class<? extends Entity> cls = er.getEntityClass();
try
{
Entity entity = (Entity)(cls.getConstructor(World.class).newInstance(wc));
if (entity instanceof IThrowableEntity)
Entity entity;
if (er.hasCustomSpawning())
{
Entity thrower = client.field_71439_g.field_70157_k == packet.throwerId ? client.field_71439_g : wc.func_73024_a(packet.throwerId);
((IThrowableEntity)entity).setThrower(thrower);
entity = er.doCustomSpawning(packet);
}
else
{
entity = (Entity)(cls.getConstructor(World.class).newInstance(wc));
int offset = packet.entityId - entity.field_70157_k;
entity.field_70157_k = packet.entityId;
entity.func_70012_b(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch);
if (entity instanceof EntityLiving)
{
((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw;
}
Entity parts[] = entity.func_70021_al();
if (parts != null)
{
for (int j = 0; j < parts.length; j++)
{
parts[j].field_70157_k += offset;
}
}
}
entity.field_70118_ct = packet.rawX;
entity.field_70117_cu = packet.rawY;
entity.field_70116_cv = packet.rawZ;
Entity parts[] = entity.func_70021_al();
if (parts != null)
if (entity instanceof IThrowableEntity)
{
int i = packet.entityId - entity.field_70157_k;
for (int j = 0; j < parts.length; j++)
{
parts[j].field_70157_k += i;
}
}
entity.field_70157_k = packet.entityId;
entity.func_70056_a(packet.scaledX, packet.scaledY, packet.scaledZ, packet.scaledYaw, packet.scaledPitch, 1);
if (entity instanceof EntityLiving)
{
((EntityLiving)entity).field_70759_as = packet.scaledHeadYaw;
Entity thrower = client.field_71439_g.field_70157_k == packet.throwerId ? client.field_71439_g : wc.func_73045_a(packet.throwerId);
((IThrowableEntity)entity).setThrower(thrower);
}
if (packet.metadata != null)
@@ -379,15 +396,23 @@ public class FMLClientHandler implements IFMLSidedHandler
@Override
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket packet)
{
Entity ent = client.field_71441_e.func_73024_a(packet.entityId);
ent.field_70118_ct = packet.serverX;
ent.field_70117_cu = packet.serverY;
ent.field_70116_cv = packet.serverZ;
Entity ent = client.field_71441_e.func_73045_a(packet.entityId);
if (ent != null)
{
ent.field_70118_ct = packet.serverX;
ent.field_70117_cu = packet.serverY;
ent.field_70116_cv = packet.serverZ;
}
else
{
FMLLog.fine("Attempted to adjust the position of entity %d which is not present on the client", packet.entityId);
}
}
@Override
public void beginServerLoading(MinecraftServer server)
{
serverShouldBeKilledQuietly = false;
// NOOP
}
@@ -402,4 +427,105 @@ public class FMLClientHandler implements IFMLSidedHandler
{
return client.func_71401_C();
}
@Override
public void sendPacket(Packet packet)
{
if(client.field_71439_g != null)
{
client.field_71439_g.field_71174_a.func_72552_c(packet);
}
}
@Override
public void displayMissingMods(ModMissingPacket modMissingPacket)
{
client.func_71373_a(new GuiModsMissingForServer(modMissingPacket));
}
/**
* If the client is in the midst of loading, we disable saving so that custom settings aren't wiped out
*/
public boolean isLoading()
{
return loading;
}
@Override
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
{
((NetClientHandler)handler).fmlPacket131Callback(mapData);
}
@Override
public void setClientCompatibilityLevel(byte compatibilityLevel)
{
NetClientHandler.setConnectionCompatibilityLevel(compatibilityLevel);
}
@Override
public byte getClientCompatibilityLevel()
{
return NetClientHandler.getConnectionCompatibilityLevel();
}
public void warnIDMismatch(MapDifference<Integer, ItemData> idDifferences, boolean mayContinue)
{
GuiIdMismatchScreen mismatch = new GuiIdMismatchScreen(idDifferences, mayContinue);
client.func_71373_a(mismatch);
}
public void callbackIdDifferenceResponse(boolean response)
{
if (response)
{
serverShouldBeKilledQuietly = false;
GameData.releaseGate(true);
client.continueWorldLoading();
}
else
{
serverShouldBeKilledQuietly = true;
GameData.releaseGate(false);
// Reset and clear the client state
client.func_71403_a((WorldClient)null);
client.func_71373_a(null);
}
}
@Override
public boolean shouldServerShouldBeKilledQuietly()
{
return serverShouldBeKilledQuietly;
}
@Override
public void disconnectIDMismatch(MapDifference<Integer, ItemData> s, NetHandler toKill, INetworkManager mgr)
{
boolean criticalMismatch = !s.entriesOnlyOnLeft().isEmpty();
for (Entry<Integer, ValueDifference<ItemData>> mismatch : s.entriesDiffering().entrySet())
{
ValueDifference<ItemData> vd = mismatch.getValue();
if (!vd.leftValue().mayDifferByOrdinal(vd.rightValue()))
{
criticalMismatch = true;
}
}
if (!criticalMismatch)
{
// We'll carry on with this connection, and just log a message instead
return;
}
// Nuke the connection
((NetClientHandler)toKill).func_72553_e();
// Stop GuiConnecting
GuiConnecting.forceTermination((GuiConnecting)client.field_71462_r);
// pulse the network manager queue to clear cruft
mgr.func_74428_b();
// Nuke the world client
client.func_71403_a((WorldClient)null);
// Show error screen
warnIDMismatch(s, false);
}
}
@@ -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.awt.Dimension;
import java.util.List;
import java.util.logging.Logger;
import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraft.src.RenderEngine;
import net.minecraft.src.TextureFX;
import net.minecraft.src.TexturePackBase;
public class FMLTextureFX extends TextureFX implements ITextureFX
{
public int tileSizeBase = 16;
public int tileSizeSquare = 256;
public int tileSizeMask = 15;
public int tileSizeSquareMask = 255;
public boolean errored = false;
protected Logger log = FMLCommonHandler.instance().getFMLLogger();
public FMLTextureFX(int icon)
{
super(icon);
}
@Override public void setErrored(boolean err){ errored = err; }
@Override public boolean getErrored(){ return errored; }
@Override
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions)
{
onTextureDimensionsUpdate(dimensions.width, dimensions.height);
}
@Override
public void onTextureDimensionsUpdate(int width, int height)
{
tileSizeBase = width >> 4;
tileSizeSquare = tileSizeBase * tileSizeBase;
tileSizeMask = tileSizeBase - 1;
tileSizeSquareMask = tileSizeSquare - 1;
setErrored(false);
setup();
}
protected void setup()
{
field_76852_a = new byte[tileSizeSquare << 2];
}
public boolean unregister(RenderEngine engine, List<TextureFX> effects)
{
effects.remove(this);
return true;
}
}
@@ -0,0 +1,38 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import net.minecraft.client.gui.GuiErrorScreen;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.WrongMinecraftVersionException;
public class GuiCustomModLoadingErrorScreen extends GuiErrorScreen
{
private CustomModLoadingErrorDisplayException customException;
public GuiCustomModLoadingErrorScreen(CustomModLoadingErrorDisplayException customException)
{
this.customException = customException;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
this.customException.initGui(this, field_73886_k);
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
this.customException.drawScreen(this, field_73886_k, p_73863_1_, p_73863_2_, p_73863_3_);
}
}
@@ -0,0 +1,57 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import java.io.File;
import java.util.Map.Entry;
import net.minecraft.client.gui.GuiErrorScreen;
import cpw.mods.fml.common.DuplicateModsFoundException;
import cpw.mods.fml.common.MissingModsException;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class GuiDupesFound extends GuiErrorScreen
{
private DuplicateModsFoundException dupes;
public GuiDupesFound(DuplicateModsFoundException dupes)
{
this.dupes = dupes;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = Math.max(85 - dupes.dupes.size() * 10, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "You have mod sources that are duplicate within your system", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "Mod Id : File name", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
for (Entry<ModContainer, File> mc : dupes.dupes.entries())
{
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s : %s", mc.getKey().getModId(), mc.getValue().getName()), this.field_73880_f / 2, offset, 0xEEEEEE);
}
}
}
@@ -0,0 +1,100 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiYesNo;
import net.minecraft.util.StringTranslate;
import com.google.common.collect.Lists;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import cpw.mods.fml.common.registry.ItemData;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class GuiIdMismatchScreen extends GuiYesNo {
private List<String> missingIds = Lists.newArrayList();
private List<String> mismatchedIds = Lists.newArrayList();
private boolean allowContinue;
public GuiIdMismatchScreen(MapDifference<Integer, ItemData> idDifferences, boolean allowContinue)
{
super(null,"ID mismatch", "Should I continue?", 1);
field_73942_a = this;
for (Entry<Integer, ItemData> entry : idDifferences.entriesOnlyOnLeft().entrySet())
{
missingIds.add(String.format("ID %d (ModID: %s, type %s) is missing", entry.getValue().getItemId(), entry.getValue().getModId(), entry.getValue().getItemType()));
}
for (Entry<Integer, ValueDifference<ItemData>> entry : idDifferences.entriesDiffering().entrySet())
{
ItemData world = entry.getValue().leftValue();
ItemData game = entry.getValue().rightValue();
mismatchedIds.add(String.format("ID %d is mismatched. World: (ModID: %s, type %s, ordinal %d) Game (ModID: %s, type %s, ordinal %d)", world.getItemId(), world.getModId(), world.getItemType(), world.getOrdinal(), game.getModId(), game.getItemType(), game.getOrdinal()));
}
this.allowContinue = allowContinue;
}
@Override
public void func_73878_a(boolean choice, int p_73878_2_)
{
FMLClientHandler.instance().callbackIdDifferenceResponse(choice);
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
if (!allowContinue && field_73887_h.size() == 2)
{
field_73887_h.remove(0);
}
int offset = Math.max(85 - missingIds.size() * 10 + mismatchedIds.size() * 30, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found world ID mismatches", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
for (String s: missingIds) {
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
offset += 10;
}
for (String s: mismatchedIds) {
this.func_73732_a(this.field_73886_k, s, this.field_73880_f / 2, offset, 0xEEEEEE);
offset += 10;
}
offset += 10;
if (allowContinue)
{
this.func_73732_a(this.field_73886_k, "Do you wish to continue loading?", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
}
else
{
this.func_73732_a(this.field_73886_k, "You cannot connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
}
// super.super. Grrr
for (int var4 = 0; var4 < this.field_73887_h.size(); ++var4)
{
GuiButton var5 = (GuiButton)this.field_73887_h.get(var4);
var5.field_73743_d = Math.min(offset + 10, this.field_73881_g - 20);
if (!allowContinue)
{
var5.field_73746_c = this.field_73880_f / 2 - 75;
var5.field_73744_e = StringTranslate.func_74808_a().func_74805_b("gui.done");
}
var5.func_73737_a(this.field_73882_e, p_73863_1_, p_73863_2_);
}
}
}
+47 -26
View File
@@ -16,22 +16,21 @@ package cpw.mods.fml.client;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSmallButton;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.StringTranslate;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.common.FMLModContainer;
import cpw.mods.fml.common.FMLDummyContainer;
import com.google.common.base.Strings;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.client.Minecraft;
import net.minecraft.src.FontRenderer;
import net.minecraft.src.GuiButton;
import net.minecraft.src.GuiScreen;
import net.minecraft.src.GuiSmallButton;
import net.minecraft.src.StringTranslate;
import net.minecraft.src.Tessellator;
/**
* @author cpw
@@ -47,7 +46,7 @@ public class GuiModList extends GuiScreen
private ArrayList<ModContainer> mods;
/**
* @param guiMainMenu
* @param mainMenu
*/
public GuiModList(GuiScreen mainMenu)
{
@@ -55,8 +54,19 @@ public class GuiModList extends GuiScreen
this.mods=new ArrayList<ModContainer>();
FMLClientHandler.instance().addSpecialModEntries(mods);
for (ModContainer mod : Loader.instance().getModList()) {
if (mod.getMetadata()!=null && mod.getMetadata().parentMod != null) {
continue;
if (mod.getMetadata()!=null && mod.getMetadata().parentMod==null && !Strings.isNullOrEmpty(mod.getMetadata().parent)) {
String parentMod = mod.getMetadata().parent;
ModContainer parentContainer = Loader.instance().getIndexedModList().get(parentMod);
if (parentContainer != null)
{
mod.getMetadata().parentMod = parentContainer;
parentContainer.getMetadata().childMods.add(mod);
continue;
}
}
else if (mod.getMetadata()!=null && mod.getMetadata().parentMod!=null)
{
continue;
}
mods.add(mod);
}
@@ -92,7 +102,7 @@ public class GuiModList extends GuiScreen
public int drawLine(String line, int offset, int shifty)
{
this.field_73886_k.func_78276_b(line, offset, shifty, 0xd7edea);
int r = this.field_73886_k.func_78276_b(line, offset, shifty, 0xd7edea);
return shifty + 10;
}
@@ -103,14 +113,24 @@ public class GuiModList extends GuiScreen
this.func_73732_a(this.field_73886_k, "Mod List", this.field_73880_f / 2, 16, 0xFFFFFF);
int offset = this.listWidth + 20;
if (selectedMod != null) {
GL11.glEnable(GL11.GL_BLEND);
if (!selectedMod.getMetadata().autogenerated) {
int shifty = 35;
if (!selectedMod.getMetadata().logoFile.isEmpty())
String logoFile = selectedMod.getMetadata().logoFile;
if (!logoFile.isEmpty())
{
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_73882_e.field_71446_o.func_78342_b(texture);
Dimension dim = TextureFXManager.instance().getTextureDimensions(texture);
this.field_73882_e.field_71446_o.func_98187_b(logoFile);
Dimension dim = TextureFXManager.instance().getTextureDimensions(logoFile);
double scaleX = dim.width / 200.0;
double scaleY = dim.height / 65.0;
double scale = 1.0;
if (scaleX > 1 || scaleY > 1)
{
scale = 1.0 / Math.max(scaleX, scaleY);
}
dim.width *= scale;
dim.height *= scale;
int top = 32;
Tessellator tess = Tessellator.field_78398_a;
tess.func_78382_b();
@@ -125,15 +145,19 @@ public class GuiModList extends GuiScreen
this.field_73886_k.func_78261_a(selectedMod.getMetadata().name, offset, shifty, 0xFFFFFF);
shifty += 12;
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getMetadata().version, selectedMod.getVersion()), offset, shifty);
shifty = drawLine(String.format("Mod State: %s", Loader.instance().getModState(selectedMod)), offset, shifty);
shifty = drawLine(String.format("Version: %s (%s)", selectedMod.getDisplayVersion(), selectedMod.getVersion()), offset, shifty);
shifty = drawLine(String.format("Mod ID: '%s' Mod State: %s", selectedMod.getModId(), Loader.instance().getModState(selectedMod)), offset, shifty);
if (!selectedMod.getMetadata().credits.isEmpty()) {
shifty = drawLine(String.format("Credits: %s", selectedMod.getMetadata().credits), offset, shifty);
}
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_78279_b(selectedMod.getMetadata().description, offset, shifty + 10, this.field_73880_f - offset - 20, 0xDDDDDD);
int rightSide = this.field_73880_f - offset - 20;
if (rightSide > 20)
{
this.getFontRenderer().func_78279_b(selectedMod.getMetadata().description, offset, shifty + 10, rightSide, 0xDDDDDD);
}
} else {
offset = ( this.listWidth + this.field_73880_f ) / 2;
this.func_73732_a(this.field_73886_k, selectedMod.getName(), offset, 35, 0xFFFFFF);
@@ -142,6 +166,7 @@ public class GuiModList extends GuiScreen
this.func_73732_a(this.field_73886_k, "No mod information found", offset, 65, 0xDDDDDD);
this.func_73732_a(this.field_73886_k, "Ask your mod author to provide a mod mcmod.info file", offset, 75, 0xDDDDDD);
}
GL11.glDisable(GL11.GL_BLEND);
}
super.func_73863_a(p_571_1_, p_571_2_, p_571_3_);
}
@@ -167,10 +192,6 @@ public class GuiModList extends GuiScreen
}
}
/**
* @param var1
* @return
*/
public boolean modIndexSelected(int var1)
{
return var1==selected;
@@ -0,0 +1,51 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import net.minecraft.client.gui.GuiErrorScreen;
import cpw.mods.fml.common.MissingModsException;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class GuiModsMissing extends GuiErrorScreen
{
private MissingModsException modsMissing;
public GuiModsMissing(MissingModsException modsMissing)
{
this.modsMissing = modsMissing;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = Math.max(85 - modsMissing.missingMods.size() * 10, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
for (ArtifactVersion v : modsMissing.missingMods)
{
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
}
offset+=20;
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
}
}
@@ -0,0 +1,64 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSmallButton;
import net.minecraft.util.StringTranslate;
import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class GuiModsMissingForServer extends GuiScreen
{
private ModMissingPacket modsMissing;
public GuiModsMissingForServer(ModMissingPacket modsMissing)
{
this.modsMissing = modsMissing;
}
@Override
public void func_73866_w_()
{
StringTranslate translations = StringTranslate.func_74808_a();
this.field_73887_h.add(new GuiSmallButton(1, this.field_73880_f / 2 - 75, this.field_73881_g - 38, translations.func_74805_b("gui.done")));
}
@Override
protected void func_73875_a(GuiButton p_73875_1_)
{
if (p_73875_1_.field_73742_g && p_73875_1_.field_73741_f == 1)
{
FMLClientHandler.instance().getClient().func_71373_a(null);
}
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = Math.max(85 - modsMissing.getModList().size() * 10, 10);
this.func_73732_a(this.field_73886_k, "Forge Mod Loader could not connect to this server", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
this.func_73732_a(this.field_73886_k, "The mods and versions listed below could not be found", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 10;
this.func_73732_a(this.field_73886_k, "They are required to play on this server", this.field_73880_f / 2, offset, 0xFFFFFF);
offset += 5;
for (ArtifactVersion v : modsMissing.getModList())
{
offset += 10;
this.func_73732_a(this.field_73886_k, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.field_73880_f / 2, offset, 0xEEEEEE);
}
super.func_73863_a(p_73863_1_, p_73863_2_, p_73863_3_);
}
}
@@ -1,9 +1,22 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.src.GuiButton;
import net.minecraft.src.Tessellator;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.Tessellator;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
@@ -81,9 +94,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;
@@ -250,7 +264,7 @@ public abstract class GuiScrollingList
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_FOG);
Tessellator var18 = Tessellator.field_78398_a;
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_71446_o.func_78341_b("/gui/background.png"));
this.client.field_71446_o.func_98187_b("/gui/background.png");
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
float var17 = 32.0F;
var18.func_78382_b();
@@ -383,7 +397,7 @@ public abstract class GuiScrollingList
private void overlayBackground(int p_22239_1_, int p_22239_2_, int p_22239_3_, int p_22239_4_)
{
Tessellator var5 = Tessellator.field_78398_a;
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.field_71446_o.func_78341_b("/gui/background.png"));
this.client.field_71446_o.func_98187_b("/gui/background.png");
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
float var6 = 32.0F;
var5.func_78382_b();
+17 -23
View File
@@ -1,30 +1,24 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import java.util.ArrayList;
import net.minecraft.client.renderer.Tessellator;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
import net.minecraft.client.Minecraft;
import net.minecraft.src.GuiLanguage;
import net.minecraft.src.GuiSlot;
import net.minecraft.src.StringTranslate;
import net.minecraft.src.Tessellator;
/**
* @author cpw
@@ -78,15 +72,15 @@ public class GuiSlotModList extends GuiScrollingList
ModContainer mc=mods.get(listIndex);
if (Loader.instance().getModState(mc)==ModState.DISABLED)
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 11), this.left + 3 , var3 + 22, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xFF2222);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a("DISABLED", listWidth - 10), this.left + 3 , var3 + 22, 0xFF2222);
}
else
{
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 11), this.left + 3 , var3 + 2, 0xFFFFFF);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getVersion(), listWidth - 11), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 9), this.left + 3 , var3 + 22, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getName(), listWidth - 10), this.left + 3 , var3 + 2, 0xFFFFFF);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getDisplayVersion(), listWidth - 10), this.left + 3 , var3 + 12, 0xCCCCCC);
this.parent.getFontRenderer().func_78276_b(this.parent.getFontRenderer().func_78269_a(mc.getMetadata() !=null ? mc.getMetadata().getChildModCountString() : "Metadata not found", listWidth - 10), this.left + 3 , var3 + 22, 0xCCCCCC);
}
}
@@ -0,0 +1,46 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import net.minecraft.client.gui.GuiErrorScreen;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.WrongMinecraftVersionException;
import cpw.mods.fml.common.versioning.ArtifactVersion;
public class GuiWrongMinecraft extends GuiErrorScreen
{
private WrongMinecraftVersionException wrongMC;
public GuiWrongMinecraft(WrongMinecraftVersionException wrongMC)
{
this.wrongMC = wrongMC;
}
@Override
public void func_73866_w_()
{
super.func_73866_w_();
}
@Override
public void func_73863_a(int p_73863_1_, int p_73863_2_, float p_73863_3_)
{
this.func_73873_v_();
int offset = 75;
this.func_73732_a(this.field_73886_k, "Forge Mod Loader has found a problem with your minecraft installation", this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("The mod listed below does not want to run in Minecraft version %s", Loader.instance().getMinecraftModContainer().getVersion()), this.field_73880_f / 2, offset, 0xFFFFFF);
offset+=5;
offset+=10;
this.func_73732_a(this.field_73886_k, String.format("%s (%s) wants Minecraft %s", wrongMC.mod.getName(), wrongMC.mod.getModId(), wrongMC.mod.acceptableMinecraftVersionRange()), this.field_73880_f / 2, offset, 0xEEEEEE);
offset+=20;
this.func_73732_a(this.field_73886_k, "The file 'ForgeModLoader-client-0.log' contains more information", this.field_73880_f / 2, offset, 0xFFFFFF);
}
}
+12 -13
View File
@@ -1,26 +1,25 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client;
import java.awt.Dimension;
import net.minecraft.src.*;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.texturepacks.ITexturePack;
public interface ITextureFX
{
public void onTexturePackChanged(RenderEngine engine, TexturePackBase texturepack, Dimension dimensions);
public void onTexturePackChanged(RenderEngine engine, ITexturePack texturepack, Dimension dimensions);
public void onTextureDimensionsUpdate(int width, int height);
@@ -1,44 +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 net.minecraft.src.TextureFX;
class OverrideInfo
{
public String texture;
public String override;
public int index;
public int imageIndex;
public TextureFX textureFX;
public boolean added;
@Override
public boolean equals(Object obj)
{
try {
OverrideInfo inf=(OverrideInfo) obj;
return index==inf.index && imageIndex==inf.imageIndex;
} catch (Exception e) {
return false;
}
}
@Override
public int hashCode()
{
return index+imageIndex;
}
}
@@ -1,144 +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.util.BitSet;
import java.util.HashMap;
import java.util.logging.Level;
import net.minecraft.src.ModLoader;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
/**
* @author cpw
*
*/
public class SpriteHelper
{
private static HashMap<String, BitSet> spriteInfo = new HashMap<String, BitSet>();
private static void initMCSpriteMaps() {
BitSet slots =
SpriteHelper.toBitSet(
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000011111100" +
"0000000011111111" +
"0000000011111000" +
"0000000111111100" +
"0000000111111000" +
"0000000000000000");
spriteInfo.put("/terrain.png", slots);
slots = SpriteHelper.toBitSet(
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000000000000000" +
"0000001000000000" +
"0000001110000000" +
"0000001000000000" +
"1111111010000000" +
"1111111010100000" +
"1111111111111100" +
"1111111111111111" +
"1111111111111111" +
"1111111111111111" +
"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) {
initMCSpriteMaps();
}
if (spriteInfo.containsKey(file)) {
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Duplicate attempt to register a sprite file %s for overriding -- ignoring",file));
return;
}
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));
FMLLog.log(Level.SEVERE, ex, "A critical error has been detected with sprite overrides");
FMLCommonHandler.instance().raiseException(ex,"Invalid request to getUniqueSpriteIndex",true);
}
int ret = getFreeSlot(slots);
if (ret == -1)
{
Exception ex = new Exception(String.format("No more sprite indicies left for: %s", path));
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;
}
public static BitSet toBitSet(String data)
{
BitSet ret = new BitSet(data.length());
for (int x = 0; x < data.length(); x++)
{
ret.set(x, data.charAt(x) == '1');
}
return ret;
}
public static int getFreeSlot(BitSet slots)
{
int next=slots.nextSetBit(0);
slots.clear(next);
return next;
}
/**
* @param textureToOverride
* @return
*/
public static int freeSlotCount(String textureToOverride)
{
return spriteInfo.get(textureToOverride).cardinality();
}
}
+62 -304
View File
@@ -1,330 +1,43 @@
package cpw.mods.fml.client;
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_BINDING_2D;
package cpw.mods.fml.client;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import net.minecraft.client.Minecraft;
import net.minecraft.src.KeyBinding;
import net.minecraft.src.ModTextureStatic;
import net.minecraft.src.Profiler;
import net.minecraft.src.RenderEngine;
import net.minecraft.src.TextureFX;
import net.minecraft.src.TexturePackBase;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.client.renderer.RenderEngine;
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;
private Map<Integer,TextureHolder> texturesById = Maps.newHashMap();
private Map<String, TextureHolder> texturesByName = Maps.newHashMap();
void setClient(Minecraft client)
{
this.client = client;
}
public boolean onUpdateTextureEffect(TextureFX effect)
{
ITextureFX ifx = (effect instanceof ITextureFX ? ((ITextureFX)effect) : null);
if (ifx != null && ifx.getErrored())
{
return false;
}
String name = effect.getClass().getSimpleName();
FMLClientHandler.instance().profileStart(name);
try
{
if (!FMLClientHandler.instance().hasOptifine())
{
effect.func_76846_a();
}
}
catch (Exception e)
{
FMLLog.warning("Texture FX %s has failed to animate. Likely caused by a texture pack change that they did not respond correctly to", name);
if (ifx != null)
{
ifx.setErrored(true);
}
FMLClientHandler.instance().profileEnd();
return false;
}
FMLClientHandler.instance().profileEnd();
if (ifx != null)
{
Dimension dim = getTextureDimensions(effect);
int target = ((dim.width >> 4) * (dim.height >> 4)) << 2;
if (effect.field_76852_a.length != target)
{
FMLLog.warning("Detected a texture FX sizing discrepancy in %s (%d, %d)", name, effect.field_76852_a.length, target);
ifx.setErrored(true);
return false;
}
}
return true;
}
//Quick and dirty image scaling, no smoothing or fanciness, meant for speed as it will be called every tick.
public void scaleTextureFXData(byte[] data, ByteBuffer buf, int target, int length)
{
int sWidth = (int)Math.sqrt(data.length / 4);
int factor = target / sWidth;
byte[] tmp = new byte[4];
buf.clear();
if (factor > 1)
{
for (int y = 0; y < sWidth; y++)
{
int sRowOff = sWidth * y;
int tRowOff = target * y * factor;
for (int x = 0; x < sWidth; x++)
{
int sPos = (x + sRowOff) * 4;
tmp[0] = data[sPos + 0];
tmp[1] = data[sPos + 1];
tmp[2] = data[sPos + 2];
tmp[3] = data[sPos + 3];
int tPosTop = (x * factor) + tRowOff;
for (int y2 = 0; y2 < factor; y2++)
{
buf.position((tPosTop + (y2 * target)) * 4);
for (int x2 = 0; x2 < factor; x2++)
{
buf.put(tmp);
}
}
}
}
}
buf.position(0).limit(length);
}
public void onPreRegisterEffect(TextureFX effect)
{
Dimension dim = getTextureDimensions(effect);
if (effect instanceof ITextureFX)
{
((ITextureFX)effect).onTextureDimensionsUpdate(dim.width, dim.height);
}
}
public int getEffectTexture(TextureFX effect)
{
Integer id = effectTextures.get(effect);
if (id != null)
{
return id;
}
int old = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
effect.func_76845_a(client.field_71446_o);
id = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
GL11.glBindTexture(GL_TEXTURE_2D, old);
effectTextures.put(effect, id);
return id;
}
public void onTexturePackChange(RenderEngine engine, TexturePackBase texturepack, List<TextureFX> effects)
{
pruneOldTextureFX(texturepack, effects);
for (TextureFX tex : effects)
{
if (tex instanceof ITextureFX)
{
((ITextureFX)tex).onTexturePackChanged(engine, texturepack, getTextureDimensions(tex));
}
}
loadTextures(texturepack);
}
private HashMap<Integer, Dimension> textureDims = new HashMap<Integer, Dimension>();
private IdentityHashMap<TextureFX, Integer> effectTextures = new IdentityHashMap<TextureFX, Integer>();
private TexturePackBase earlyTexturePack;
public void setTextureDimensions(int id, int width, int height, List<TextureFX> effects)
{
Dimension dim = new Dimension(width, height);
textureDims.put(id, dim);
for (TextureFX tex : effects)
{
if (getEffectTexture(tex) == id && tex instanceof ITextureFX)
{
((ITextureFX)tex).onTextureDimensionsUpdate(width, height);
}
}
}
public Dimension getTextureDimensions(TextureFX effect)
{
return getTextureDimensions(getEffectTexture(effect));
}
public Dimension getTextureDimensions(int id)
{
return textureDims.get(id);
}
/**
* @param anim
*/
public void addAnimation(TextureFX anim)
{
OverrideInfo info=new OverrideInfo();
info.index=anim.field_76850_b;
info.imageIndex=anim.field_76847_f;
info.textureFX=anim;
if (animationSet.contains(info)) {
animationSet.remove(info);
}
animationSet.add(info);
}
/**
* @param p_6531_1_
*/
public void loadTextures(TexturePackBase texturePack)
{
registerTextureOverrides(client.field_71446_o);
}
public void registerTextureOverrides(RenderEngine renderer) {
for (ModContainer mod : Loader.instance().getActiveModList()) {
registerAnimatedTexturesFor(mod);
}
for (OverrideInfo animationOverride : animationSet) {
renderer.func_78355_a(animationOverride.textureFX);
addedTextureFX.add(animationOverride.textureFX);
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Registered texture override %d (%d) on %s (%d)", animationOverride.index, animationOverride.textureFX.field_76850_b, animationOverride.textureFX.getClass().getSimpleName(), animationOverride.textureFX.field_76847_f));
}
for (String fileToOverride : overrideInfo.keySet()) {
for (OverrideInfo override : overrideInfo.get(fileToOverride)) {
try
{
BufferedImage image=loadImageFromTexturePack(renderer, override.override);
ModTextureStatic mts=new ModTextureStatic(override.index, 1, override.texture, image);
renderer.func_78355_a(mts);
addedTextureFX.add(mts);
FMLCommonHandler.instance().getFMLLogger().finer(String.format("Registered texture override %d (%d) on %s (%d)", override.index, mts.field_76850_b, override.texture, mts.field_76847_f));
}
catch (IOException e)
{
FMLCommonHandler.instance().getFMLLogger().throwing("FMLClientHandler", "registerTextureOverrides", e);
}
}
}
}
/**
* @param mod
*/
private void registerAnimatedTexturesFor(ModContainer mod)
{
}
/**
* @param field_6539_c
*/
public void onEarlyTexturePackLoad(TexturePackBase fallback)
{
if (client==null) {
// We're far too early- let's wait
this.earlyTexturePack = fallback;
} else {
loadTextures(fallback);
}
}
public void pruneOldTextureFX(TexturePackBase var1, List<TextureFX> effects)
{
ListIterator<TextureFX> li = addedTextureFX.listIterator();
while (li.hasNext())
{
TextureFX tex = li.next();
if (tex instanceof FMLTextureFX)
{
if (((FMLTextureFX)tex).unregister(client.field_71446_o, effects))
{
li.remove();
}
}
else
{
effects.remove(tex);
li.remove();
}
}
}
public void addNewTextureOverride(String textureToOverride, String overridingTexturePath, int location) {
OverrideInfo info = new OverrideInfo();
info.index = location;
info.override = overridingTexturePath;
info.texture = textureToOverride;
overrideInfo.put(textureToOverride, info);
FMLLog.fine("Overriding %s @ %d with %s. %d slots remaining",textureToOverride, location, overridingTexturePath, SpriteHelper.freeSlotCount(textureToOverride));
}
/**
* @param renderEngine
* @param path
* @return
*/
public BufferedImage loadImageFromTexturePack(RenderEngine renderEngine, String path) throws IOException
{
InputStream image=client.field_71418_C.func_77292_e().func_77532_a(path);
@@ -344,4 +57,49 @@ public class TextureFXManager
return INSTANCE;
}
public void fixTransparency(BufferedImage loadedImage, String textureName)
{
if (textureName.matches("^/mob/.*_eyes.*.png$"))
{
for (int x = 0; x < loadedImage.getWidth(); x++) {
for (int y = 0; y < loadedImage.getHeight(); y++) {
int argb = loadedImage.getRGB(x, y);
if ((argb & 0xff000000) == 0 && argb != 0) {
loadedImage.setRGB(x, y, 0);
}
}
}
}
}
public void bindTextureToName(String name, int index)
{
TextureHolder holder = new TextureHolder();
holder.textureId = index;
holder.textureName = name;
texturesById.put(index,holder);
texturesByName.put(name,holder);
}
public void setTextureDimensions(int index, int j, int k)
{
TextureHolder holder = texturesById.get(index);
if (holder == null)
{
return;
}
holder.x = j;
holder.y = k;
}
private class TextureHolder {
private int textureId;
private String textureName;
private int x;
private int y;
}
public Dimension getTextureDimensions(String texture)
{
return texturesByName.containsKey(texture) ? new Dimension(texturesByName.get(texture).x, texturesByName.get(texture).y) : new Dimension(1,1);
}
}
@@ -1,26 +1,22 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.modloader;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Block;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.RenderBlocks;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
/**
* @author cpw
@@ -1,63 +1,190 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.modloader;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.Maps;
import java.util.logging.Level;
import net.minecraft.client.Minecraft;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.src.BaseMod;
import net.minecraft.src.Entity;
import net.minecraft.src.Render;
import net.minecraft.client.*;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import com.google.common.base.Equivalence;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.modloader.BaseModProxy;
import cpw.mods.fml.common.modloader.IModLoaderSidedHelper;
import cpw.mods.fml.common.modloader.ModLoaderHelper;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
public class ModLoaderClientHelper implements IModLoaderSidedHelper
{
/**
* @param mod
* @param inventoryRenderer
* @return
*/
public static int obtainBlockModelIdFor(BaseMod mod, boolean inventoryRenderer)
{
int renderId=RenderingRegistry.instance().getNextAvailableRenderId();
int renderId=RenderingRegistry.getNextAvailableRenderId();
ModLoaderBlockRendererHandler bri=new ModLoaderBlockRendererHandler(renderId, inventoryRenderer, mod);
RenderingRegistry.instance().registerBlockHandler(bri);
RenderingRegistry.registerBlockHandler(bri);
return renderId;
}
public static void handleFinishLoadingFor(ModLoaderModContainer mc, Minecraft game)
{
FMLLog.log(mc.getModId(), Level.FINE, "Handling post startup activities for ModLoader mod %s", mc.getModId());
BaseMod mod = (BaseMod) mc.getMod();
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap();
Map<Class<? extends Entity>, Render> renderers = Maps.newHashMap(RenderManager.field_78727_a.field_78729_o);
mod.addRenderer(renderers);
for (Entry<Class<? extends Entity>, Render> e : renderers.entrySet())
try
{
RenderingRegistry.instance().registerEntityRenderingHandler(e.getKey(), e.getValue());
FMLLog.log(mc.getModId(), Level.FINEST, "Requesting renderers from basemod %s", mc.getModId());
mod.addRenderer(renderers);
FMLLog.log(mc.getModId(), Level.FINEST, "Received %d renderers from basemod %s", renderers.size(), mc.getModId());
}
catch (Exception e)
{
FMLLog.log(mc.getModId(), Level.SEVERE, e, "A severe problem was detected with the mod %s during the addRenderer call. Continuing, but expect odd results", mc.getModId());
}
mod.registerAnimation(game);
MapDifference<Class<? extends Entity>, Render> difference = Maps.difference(RenderManager.field_78727_a.field_78729_o, renderers, Equivalence.identity());
for ( Entry<Class<? extends Entity>, Render> e : difference.entriesOnlyOnLeft().entrySet())
{
FMLLog.log(mc.getModId(), Level.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.log(mc.getModId(), Level.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.log(mc.getModId(), Level.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(mc.getModId(), 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;
}
}
@@ -1,30 +1,30 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.modloader;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.src.KeyBinding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.google.common.collect.ObjectArrays;
import com.google.common.primitives.Booleans;
import net.minecraft.client.settings.KeyBinding;
import cpw.mods.fml.client.registry.KeyBindingRegistry;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.registry.TickRegistry;
/**
* @author cpw
@@ -33,61 +33,55 @@ import cpw.mods.fml.common.registry.TickRegistry;
public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
{
private ModLoaderModContainer modContainer;
private boolean downArmed;
private boolean upArmed;
private List<KeyBinding> helper;
private boolean[] active = new boolean[0];
private boolean[] mlRepeats = new boolean[0];
private boolean[] armed = new boolean[0];
/**
* @param keyHandler
* @param allowRepeat
* @param modContainer
*/
public ModLoaderKeyBindingHandler(KeyBinding keyBinding, boolean allowRepeat, ModLoaderModContainer modContainer)
public ModLoaderKeyBindingHandler()
{
super(keyBinding, allowRepeat);
this.modContainer=modContainer;
super(new KeyBinding[0], new boolean[0]);
}
public void onRenderEndTick()
void setModContainer(ModLoaderModContainer modContainer)
{
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(keyBinding);
this.modContainer = modContainer;
}
public void fireKeyEvent(KeyBinding kb)
{
((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(kb);
}
@Override
public void keyDown(EnumSet<TickType> type, boolean end, boolean repeats)
public void keyDown(EnumSet<TickType> type, KeyBinding kb, boolean end, boolean repeats)
{
if (!end)
{
return;
}
upArmed = false;
int idx = helper.indexOf(kb);
if (type.contains(TickType.CLIENT))
{
downArmed = true;
armed[idx] = true;
}
if (type.contains(TickType.RENDER) && downArmed)
if (armed[idx] && type.contains(TickType.RENDER) && (!active[idx] || mlRepeats[idx]))
{
onRenderEndTick();
downArmed = false;
fireKeyEvent(kb);
active[idx] = true;
armed[idx] = false;
}
}
@Override
public void keyUp(EnumSet<TickType> type, boolean end)
public void keyUp(EnumSet<TickType> type, KeyBinding kb, boolean end)
{
if (!end)
{
return;
}
downArmed = false;
if (type.contains(TickType.CLIENT))
{
upArmed = true;
}
if (type.contains(TickType.RENDER) && upArmed)
{
onRenderEndTick();
upArmed = false;
}
int idx = helper.indexOf(kb);
active[idx] = false;
}
@Override
@@ -99,6 +93,18 @@ public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler
@Override
public String getLabel()
{
return modContainer.getModId() +" KB "+keyBinding.field_74512_d;
return modContainer.getModId() +" KB "+keyBindings[0].field_74512_d;
}
void addKeyBinding(KeyBinding binding, boolean repeats)
{
this.keyBindings = ObjectArrays.concat(this.keyBindings, binding);
this.repeatings = new boolean[this.keyBindings.length];
Arrays.fill(this.repeatings, true);
this.active = new boolean[this.keyBindings.length];
this.armed = new boolean[this.keyBindings.length];
this.mlRepeats = Booleans.concat(this.mlRepeats, new boolean[] { repeats });
this.keyDown = new boolean[this.keyBindings.length];
this.helper = Arrays.asList(this.keyBindings);
}
}
@@ -1,15 +1,21 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.registry;
import java.util.Collections;
import net.minecraft.src.BiomeGenBase;
import net.minecraft.src.TileEntity;
import net.minecraft.src.TileEntityRenderer;
import net.minecraft.src.TileEntitySpecialRenderer;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
public class ClientRegistry
{
@@ -1,8 +1,20 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.registry;
import net.minecraft.src.Block;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.RenderBlocks;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.world.IBlockAccess;
public interface ISimpleBlockRenderingHandler
{
@@ -1,47 +1,110 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.registry;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import com.google.common.collect.Lists;
import net.minecraft.src.GameSettings;
import net.minecraft.src.KeyBinding;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.relauncher.Side;
public class KeyBindingRegistry
{
/**
* Register a KeyHandler to the game. This handler will be called on certain tick events
* if any of its key is inactive or has recently changed state
*
* @param handler
*/
public static void registerKeyBinding(KeyHandler handler) {
instance().keyHandlers.add(handler);
if (!handler.isDummy)
{
TickRegistry.registerTickHandler(handler, Side.CLIENT);
}
}
/**
* Extend this class to register a KeyBinding and recieve callback
* when the key binding is triggered
*
* @author cpw
*
*/
public static abstract class KeyHandler implements ITickHandler
{
protected KeyBinding keyBinding;
protected boolean keyDown;
protected boolean repeating;
protected KeyBinding[] keyBindings;
protected boolean[] keyDown;
protected boolean[] repeatings;
private boolean isDummy;
public KeyHandler(KeyBinding keyBinding, boolean repeating)
/**
* Pass an array of keybindings and a repeat flag for each one
*
* @param keyBindings
* @param repeatings
*/
public KeyHandler(KeyBinding[] keyBindings, boolean[] repeatings)
{
this.keyBinding = keyBinding;
this.repeating = repeating;
assert keyBindings.length == repeatings.length : "You need to pass two arrays of identical length";
this.keyBindings = keyBindings;
this.repeatings = repeatings;
this.keyDown = new boolean[keyBindings.length];
}
public KeyBinding getKeyBinding()
/**
* Register the keys into the system. You will do your own keyboard management elsewhere. No events will fire
* if you use this method
*
* @param keyBindings
*/
public KeyHandler(KeyBinding[] keyBindings)
{
return this.keyBinding;
this.keyBindings = keyBindings;
this.isDummy = true;
}
public KeyBinding[] getKeyBindings()
{
return this.keyBindings;
}
/**
* Not to be overridden - KeyBindings are tickhandlers under the covers
*/
@Override
public final void tickStart(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, false);
}
/**
* Not to be overridden - KeyBindings are tickhandlers under the covers
*/
@Override
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
{
@@ -50,39 +113,81 @@ public class KeyBindingRegistry
private void keyTick(EnumSet<TickType> type, boolean tickEnd)
{
int keyCode = keyBinding.field_74512_d;
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state != keyDown || (state && repeating))
for (int i = 0; i < keyBindings.length; i++)
{
if (state)
KeyBinding keyBinding = keyBindings[i];
int keyCode = keyBinding.field_74512_d;
boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode));
if (state != keyDown[i] || (state && repeatings[i]))
{
keyDown(type, tickEnd, state!=keyDown);
if (state)
{
keyDown(type, keyBinding, tickEnd, state!=keyDown[i]);
}
else
{
keyUp(type, keyBinding, tickEnd);
}
if (tickEnd)
{
keyDown[i] = state;
}
}
else
{
keyUp(type, tickEnd);
}
keyDown = state;
}
}
public abstract void keyDown(EnumSet<TickType> types, boolean tickEnd, boolean isRepeat);
public abstract void keyUp(EnumSet<TickType> types, boolean tickEnd);
/**
* Called when the key is first in the down position on any tick from the {@link #ticks()}
* set. Will be called subsequently with isRepeat set to true
*
* @see #keyUp(EnumSet, KeyBinding, boolean)
*
* @param types the type(s) of tick that fired when this key was first down
* @param tickEnd was it an end or start tick which fired the key
* @param isRepeat is it a repeat key event
*/
public abstract void keyDown(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd, boolean isRepeat);
/**
* Fired once when the key changes state from down to up
*
* @see #keyDown(EnumSet, KeyBinding, boolean, boolean)
*
* @param types the type(s) of tick that fired when this key was first down
* @param tickEnd was it an end or start tick which fired the key
*/
public abstract void keyUp(EnumSet<TickType> types, KeyBinding kb, boolean tickEnd);
/**
* This is the list of ticks for which the key binding should trigger. The only
* valid ticks are client side ticks, obviously.
*
* @see cpw.mods.fml.common.ITickHandler#ticks()
*/
public abstract EnumSet<TickType> ticks();
}
private static List<KeyHandler> keyHandlers = Lists.newArrayList();
private static final KeyBindingRegistry INSTANCE = new KeyBindingRegistry();
public static void registerKeyBinding(KeyHandler handler) {
keyHandlers.add(handler);
TickRegistry.registerTickHandler(handler, Side.CLIENT);
private Set<KeyHandler> keyHandlers = Sets.newLinkedHashSet();
@Deprecated
public static KeyBindingRegistry instance()
{
return INSTANCE;
}
public static void uploadKeyBindingsToGame(GameSettings settings)
public void uploadKeyBindingsToGame(GameSettings settings)
{
ArrayList<KeyBinding> harvestedBindings = Lists.newArrayList();
for (KeyHandler key : keyHandlers)
{
harvestedBindings.add(key.keyBinding);
for (KeyBinding kb : key.keyBindings)
{
harvestedBindings.add(kb);
}
}
KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]);
KeyBinding[] allKeys = new KeyBinding[settings.field_74324_K.length + modKeyBindings.length];
@@ -1,44 +1,141 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.client.registry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.entity.*;
import net.minecraft.entity.Entity;
import net.minecraft.world.IBlockAccess;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.ObjectArrays;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.Render;
import net.minecraft.src.RenderBlocks;
import net.minecraft.src.RenderPlayer;
import cpw.mods.fml.client.modloader.ModLoaderBlockRendererHandler;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.client.TextureFXManager;
/**
* @author cpw
*
*/
public class RenderingRegistry
{
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
private int nextRenderId = 30;
private int nextRenderId = 40;
private Map<Integer, ISimpleBlockRenderingHandler> blockRenderers = Maps.newHashMap();
private List<EntityRendererInfo> entityRenderers = Lists.newArrayList();
public int addNewArmourRendererPrefix(String armor)
/**
* Add a new armour prefix to the RenderPlayer
*
* @param armor
*/
public static int addNewArmourRendererPrefix(String armor)
{
RenderPlayer.field_77110_j = ObjectArrays.concat(RenderPlayer.field_77110_j, armor);
RenderBiped.field_82424_k = RenderPlayer.field_77110_j;
return RenderPlayer.field_77110_j.length - 1;
}
public static RenderingRegistry instance()
/**
* Register an entity rendering handler. This will, after mod initialization, be inserted into the main
* render map for entities
*
* @param entityClass
* @param renderer
*/
public static void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
{
instance().entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
}
/**
* Register a simple block rendering handler
*
* @param handler
*/
public static void registerBlockHandler(ISimpleBlockRenderingHandler handler)
{
instance().blockRenderers.put(handler.getRenderId(), handler);
}
/**
* Register the simple block rendering handler
* This version will not call getRenderId on the passed in handler, instead using the supplied ID, so you
* can easily re-use the same rendering handler for multiple IDs
*
* @param renderId
* @param handler
*/
public static void registerBlockHandler(int renderId, ISimpleBlockRenderingHandler handler)
{
instance().blockRenderers.put(renderId, handler);
}
/**
* Get the next available renderId from the block render ID list
*/
public static int getNextAvailableRenderId()
{
return instance().nextRenderId++;
}
/**
* Add a texture override for the given path and return the used index
*
* @param fileToOverride
* @param fileToAdd
*/
@Deprecated
public static int addTextureOverride(String fileToOverride, String fileToAdd)
{
return -1;
}
/**
* 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
*/
@Deprecated
public static int getUniqueTextureIndex(String path)
{
return -1;
}
@Deprecated public static RenderingRegistry instance()
{
return INSTANCE;
}
private class EntityRendererInfo
private static class EntityRendererInfo
{
public EntityRendererInfo(Class<? extends Entity> target, Render renderer)
{
@@ -49,30 +146,6 @@ public class RenderingRegistry
private Render renderer;
}
public void registerEntityRenderingHandler(Class<? extends Entity> entityClass, Render renderer)
{
entityRenderers.add(new EntityRendererInfo(entityClass, renderer));
}
public void registerBlockHandler(ISimpleBlockRenderingHandler handler)
{
blockRenderers.put(handler.getRenderId(), handler);
}
public int getNextAvailableRenderId()
{
return nextRenderId++;
}
/**
* @param renderer
* @param world
* @param x
* @param y
* @param z
* @param block
* @param modelId
* @return
*/
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
{
if (!blockRenderers.containsKey(modelId)) { return false; }
@@ -80,12 +153,6 @@ public class RenderingRegistry
return bri.renderWorldBlock(world, x, y, z, block, modelId, renderer);
}
/**
* @param renderer
* @param block
* @param metadata
* @param modelID
*/
public void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
if (!blockRenderers.containsKey(modelID)) { return; }
@@ -93,10 +160,6 @@ public class RenderingRegistry
bri.renderInventoryBlock(block, metadata, modelID, renderer);
}
/**
* @param p_1219_0_
* @return
*/
public boolean renderItemAsFull3DBlock(int modelId)
{
ISimpleBlockRenderingHandler bri = blockRenderers.get(modelId);
@@ -108,6 +171,7 @@ public class RenderingRegistry
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

+109 -93
View File
@@ -12,19 +12,35 @@
*/
package net.minecraft.src;
import static cpw.mods.fml.relauncher.Side.CLIENT;
import java.util.Map;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.block.Block;
import net.minecraft.client.*;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetServerHandler;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.IConsoleHandler;
import cpw.mods.fml.common.ICraftingHandler;
import cpw.mods.fml.common.IDispenseHandler;
import cpw.mods.fml.common.INetworkHandler;
import cpw.mods.fml.common.IPickupNotifier;
import cpw.mods.fml.common.IPlayerTracker;
import cpw.mods.fml.common.IWorldGenerator;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.TickType;
import cpw.mods.fml.relauncher.SideOnly;
public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModProxy
{
@@ -33,7 +49,7 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
public final boolean doTickInGame(TickType tick, boolean tickEnd, Object... data)
{
Minecraft mc = FMLClientHandler.instance().getClient();
boolean hasWorld = true;
boolean hasWorld = mc.field_71441_e != null;
// World and render ticks
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT ) && hasWorld) {
return onTickInGame((Float) data[0], mc);
@@ -44,29 +60,21 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
public final boolean doTickInGUI(TickType tick, boolean tickEnd, Object... data)
{
Minecraft mc = FMLClientHandler.instance().getClient();
if (tickEnd && ( tick==TickType.RENDER || tick==TickType.CLIENT)) {
boolean hasWorld = mc.field_71441_e != null;
if (tickEnd && ( tick==TickType.RENDER || ( tick==TickType.CLIENT && hasWorld))) {
return onTickInGUI((Float) data[0], mc, mc.field_71462_r);
}
return true;
}
/**
* @param minecraftInstance
* @return
*//*
*//**
* @param renderers
*//*
/*
public final void onRenderHarvest(Map renderers)
{
addRenderer((Map<Class<? extends Entity>,Render>)renderers);
}
*//**
*
*//*
public final void onRegisterAnimations()
{
registerAnimation(FMLClientHandler.instance().getClient());
@@ -155,48 +163,28 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
}
}
*//**
* NO-OP on client side
*//*
@Override
public final boolean handleCommand(String command, Object... data)
{
return false;
}
*/ // BASEMOD API
*/
// BASEMOD API
/**
* Override if you wish to provide a fuel item for the furnace and return the fuel value of the item
*
* @param id
* @param metadata
* @return
*/
public int addFuel(int id, int metadata)
{
return 0;
}
@SideOnly(CLIENT)
public void addRenderer(Map<Class<? extends Entity>, Render> renderers)
{
}
/**
* Override if you wish to perform some action other than just dispensing the item from the dispenser
*
* @param world
* @param x
* @param y
* @param z
* @param xVel
* @param zVel
* @param item
* @return
*/
public boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
{
return false;
}
/**
@@ -223,10 +211,22 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
{
}
/**
* Callback to return a gui screen to display
* @param player
* @param containerID
* @param x
* @param y
* @param z
*/
@SideOnly(CLIENT)
public GuiContainer getContainerGUI(EntityClientPlayerMP player, int containerID, int x, int y, int z)
{
return null;
}
/**
* Return the name of your mod. Defaults to the class name
*
* @return
*/
public String getName()
{
@@ -235,8 +235,6 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
/**
* Get your mod priorities
*
* @return
*/
public String getPriorities()
{
@@ -245,11 +243,10 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
/**
* Return the version of your mod
*
* @return
*/
public abstract String getVersion();
@SideOnly(CLIENT)
public void keyboardEvent(KeyBinding event)
{
@@ -284,11 +281,18 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
* @param minecraftInstance the client
* @return true to continue receiving ticks
*/
@SideOnly(CLIENT)
public boolean onTickInGame(float time, Minecraft minecraftInstance)
{
return false;
}
public boolean onTickInGame(MinecraftServer minecraftServer)
{
return false;
}
@SideOnly(CLIENT)
public boolean onTickInGUI(float tick, Minecraft game, GuiScreen gui)
{
return false;
@@ -296,49 +300,81 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
/**
* Only implemented on the client side
* {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)}
* {@link #serverChat(NetServerHandler, String)}
*
* @param text
*/
@Override
public void receiveChatPacket(String text)
public void clientChat(String text)
{
// TODO
}
/**
* Only called on the client side
* {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)}
* Called when a client connects
* @param handler
*/
@SideOnly(CLIENT)
public void clientConnect(NetClientHandler handler)
{
}
/**
* Called when the client disconnects
* @param handler
*/
@SideOnly(CLIENT)
public void clientDisconnect(NetClientHandler handler)
{
}
/**
* Called client side to receive a custom payload for this mod
*
* NOTE: this method is not provided in Risugami's implementation of BaseMod!
*
* @param packet
*/
@Override
public void receiveCustomPacket(Packet250CustomPayload packet)
{
// TODO
}
@SideOnly(CLIENT)
public void registerAnimation(Minecraft game)
{
}
@SideOnly(CLIENT)
public void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
}
@SideOnly(CLIENT)
public boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
{
return false;
}
/*
* NOTE: this method is not provided in Risugami's implementation of BaseMod!
*/
@Override
public void serverConnect(NetHandler handler) {
}
@Override
public void serverCustomPayload(NetServerHandler handler, Packet250CustomPayload packet)
{
}
/*
* NOTE: this method is not provided in Risugami's implementation of BaseMod!
*/
@Override
public void serverDisconnect() {
@@ -374,39 +410,16 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
}
/**
* Called when a 250 packet is received on a channel registered to this mod
*
* @param source
* @param payload
* Called when a chat message is received. Return true to stop further processing
*/
@Override
public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload)
public void serverChat(NetServerHandler source, String message)
{
}
/**
* Called when a chat message is received. Return true to stop further processing
*
* @param source
* @param chat
* @return true if you want to consume the message so it is not available for further processing
*/
public boolean onChatMessageReceived(EntityPlayer source, Packet3Chat chat)
{
return false;
}
/**
* Called when a server command is received
* @param command
* @return true if you want to consume the message so it is not available for further processing
*/
public boolean onServerCommand(String command, String sender, Object listener)
{
return false;
}
/**
* Called when a new client logs in.
*
* NOTE: this method is not provided in Risugami's implementation of BaseMod!
*
* @param player
*/
@@ -417,22 +430,25 @@ public abstract class BaseMod implements cpw.mods.fml.common.modloader.BaseModPr
/**
* Called when a client logs out of the server.
*
* @param player
*
* NOTE: this method is not provided in Risugami's implementation of BaseMod!
*/
@Override
public void onClientLogout(NetworkManager mgr)
public void onClientLogout(INetworkManager mgr)
{
}
/**
*
* Called when a client changes dimensions on the server.
*
* @param player
* Spawn the entity of the supplied type, if it is your mod's
*/
public void onClientDimensionChanged(EntityPlayer player)
@SideOnly(CLIENT)
public Entity spawnEntity(int entityId, World world, double scaledX, double scaledY, double scaledZ)
{
return null;
}
public void clientCustomPayload(NetClientHandler handler, Packet250CustomPayload packet)
{
}
@@ -1,20 +1,19 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package net.minecraft.src;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
public class EntityRendererProxy extends EntityRenderer
{
@@ -1,15 +1,13 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package net.minecraft.src;
@@ -19,10 +17,14 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import cpw.mods.fml.client.FMLClientHandler;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.texturepacks.ITexturePack;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.TextureFXManager;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
/**
@@ -36,12 +38,14 @@ public class FMLRenderAccessLibrary
{
public static Logger getLogger()
{
return FMLLog.getLogger();
Logger l = Logger.getLogger("FMLRenderAccessLibrary");
l.setParent(FMLLog.getLogger());
return l;
}
public static void log(Level level, String message)
{
FMLLog.log(level, message);
FMLLog.log("FMLRenderAccessLibrary", level, message);
}
public static void log(Level level, String message, Throwable throwable)
@@ -49,41 +53,19 @@ public class FMLRenderAccessLibrary
FMLLog.log(level, throwable, message);
}
public static void setTextureDimensions(int textureId, int width, int height, List<TextureFX> textureFXList)
{
TextureFXManager.instance().setTextureDimensions(textureId, width, height, textureFXList);
}
public static void preRegisterEffect(TextureFX textureFX)
{
TextureFXManager.instance().onPreRegisterEffect(textureFX);
}
public static boolean onUpdateTextureEffect(TextureFX textureFX)
{
return TextureFXManager.instance().onUpdateTextureEffect(textureFX);
}
public static Dimension getTextureDimensions(TextureFX textureFX)
{
return TextureFXManager.instance().getTextureDimensions(textureFX);
}
public static void onTexturePackChange(RenderEngine engine, TexturePackBase texturePack, List<TextureFX> textureFXList)
{
TextureFXManager.instance().onTexturePackChange(engine, texturePack, textureFXList);
}
@SuppressWarnings("deprecation")
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelId)
{
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelId);
}
@SuppressWarnings("deprecation")
public static void renderInventoryBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
}
@SuppressWarnings("deprecation")
public static boolean renderItemAsFull3DBlock(int modelId)
{
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelId);
+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
+189 -77
View File
@@ -12,19 +12,49 @@
*/
package net.minecraft.src;
import static cpw.mods.fml.relauncher.Side.CLIENT;
import java.awt.image.BufferedImage;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDispenser;
import net.minecraft.client.*;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderEngine;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.command.ICommand;
import net.minecraft.dispenser.IBehaviorDispenseItem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.network.NetServerHandler;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet1Login;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.*;
import net.minecraft.stats.Achievement;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.chunk.IChunkProvider;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.SpriteHelper;
import cpw.mods.fml.client.TextureFXManager;
import cpw.mods.fml.client.modloader.ModLoaderClientHelper;
import cpw.mods.fml.client.modloader.ModLoaderKeyBindingHandler;
@@ -34,14 +64,17 @@ import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.common.modloader.ModLoaderHelper;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import cpw.mods.fml.relauncher.SideOnly;
import cpw.mods.fml.server.FMLServerHandler;
public class ModLoader
{
@@ -49,12 +82,13 @@ public class ModLoader
// TODO dirty workaround for millinaire
@Deprecated
public static final Map<String,Map<String,String>> localizedStrings=Collections.emptyMap();
/**
* Not used on the server.
* Adds localization info for an achievement, Not used on the server.
*
* @param achievement
* @param name
* @param description
* @param achievement The achievement to name
* @param name The name
* @param description The description
*/
public static void addAchievementDesc(Achievement achievement, String name, String description)
{
@@ -66,11 +100,11 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
*
* {@link FMLCommonHandler#fuelLookup(int, int)}
* {@link GameRegistry#getFuelValue(ItemStack)}
*
* @param id
* @param metadata
* @return
* @param id The Item ID
* @param metadata The Item Metadata
* @return The fuel strength, in ticks, 0 if unhandled
*/
@Deprecated
public static int addAllFuel(int id, int metadata)
@@ -79,41 +113,60 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static void addAllRenderers(Map<Class<? extends Entity>, Render> renderers)
{
}
public static void addAnimation(TextureFX anim)
{
TextureFXManager.instance().addAnimation(anim);
}
/**
* This method is unimplemented in server versions to date.
* Adds a new prefix to the armor texture list
*
* @param armor
* @return
* {@link RenderingRegistry#addNewArmourRendererPrefix(String)}
*
* @param armor The new armor prefix
* @return The new armor index
*/
@SideOnly(CLIENT)
public static int addArmor(String armor)
{
return RenderingRegistry.instance().addNewArmourRendererPrefix(armor);
return RenderingRegistry.addNewArmourRendererPrefix(armor);
}
/**
* This method adds the supplied biome to the set of candidate biomes for the default world generator type.
*
* @param biome
* @param biome The biome to add
*/
public static void addBiome(BiomeGenBase biome)
{
GameRegistry.addBiome(biome);
}
public static void addEntityTracker(BaseMod mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval, boolean sendVelocityInfo)
{
ModLoaderHelper.buildEntityTracker(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
}
public static void addCommand(ICommand command)
{
ModLoaderHelper.addCommand(command);
}
/**
* Add a behaviour to the dispenser
*
* @param item
* @param behavior
*/
public static void addDispenserBehavior(Item item, IBehaviorDispenseItem behavior)
{
BlockDispenser.field_82527_a.func_82595_a(item, behavior);
}
/**
* Add localization for the specified string
*
* @param key
* @param value
* @param key Key
* @param value Value
*/
public static void addLocalization(String key, String value)
{
@@ -123,9 +176,9 @@ public class ModLoader
/**
* Add localization for the specified string
*
* @param key
* @param lang
* @param value
* @param key Key
* @param lang Language identifier
* @param value Value
*/
public static void addLocalization(String key, String lang, String value)
{
@@ -135,8 +188,8 @@ public class ModLoader
/**
* Name the specified minecraft object with the supplied name
*
* @param instance
* @param name
* @param instance Item to name
* @param name The name to give it
*/
public static void addName(Object instance, String name)
{
@@ -146,9 +199,9 @@ public class ModLoader
/**
* Unimplemented on the server as it does not generate names
*
* @param instance
* @param lang
* @param name
* @param instance Item to name
* @param lang Languge identifier
* @param name Name to give it
*/
public static void addName(Object instance, String lang, String name)
{
@@ -156,36 +209,49 @@ public class ModLoader
}
/**
* Attempts to register a small image to be applied to a larger texture image,
* typically how old ModLoader mods add custom Item/Block textures.
*
* Forge mods should use setTextureFile in Item/Block
*
* Will return the icon index it was applied to.
*
* Unimplemented on the server as it does not render textures
*
* @param fileToOverride
* @param fileToAdd
* @return
* @param fileToOverride The texture to apply the new image to
* @param fileToAdd The new image
* @return The 'icon index' in the main image that the new image will be applied to
*/
@Deprecated
@SideOnly(CLIENT)
public static int addOverride(String fileToOverride, String fileToAdd)
{
int idx = SpriteHelper.getUniqueSpriteIndex(fileToOverride);
addOverride(fileToOverride, fileToAdd, idx);
return idx;
return RenderingRegistry.addTextureOverride(fileToOverride, fileToAdd);
}
/**
* Attempts to register a small image to be applied to a larger texture image,
* typically how old ModLoader mods add custom Item/Block textures.
*
* Forge mods should use setTextureFile in Item/Block
*
* Unimplemented on the server as it does not render textures
*
* @param path
* @param overlayPath
* @param index
* @param path The texture to apply the new image to
* @param overlayPath The new image
* @param index Where on the texture to apply it
*/
@SideOnly(CLIENT)
public static void addOverride(String path, String overlayPath, int index)
{
TextureFXManager.instance().addNewTextureOverride(path, overlayPath, index);
RenderingRegistry.addTextureOverride(path, overlayPath, index);
}
/**
* Add a Shaped Recipe
*
* @param output
* @param params
* @param output The result
* @param params The input
*/
public static void addRecipe(ItemStack output, Object... params)
{
@@ -195,8 +261,8 @@ public class ModLoader
/**
* Add a shapeless recipe
*
* @param output
* @param params
* @param output The result
* @param params The input
*/
public static void addShapelessRecipe(ItemStack output, Object... params)
{
@@ -214,6 +280,16 @@ public class ModLoader
GameRegistry.addSmelting(input, output, 1.0f);
}
/**
* Add a new product to be smelted
*
* @param input
* @param output
*/
public static void addSmelting(int input, ItemStack output, float experience)
{
GameRegistry.addSmelting(input, output, experience);
}
/**
* Add a mob to the spawn list
*
@@ -272,9 +348,21 @@ public class ModLoader
EntityRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes);
}
public static void addTrade(int profession, TradeEntry entry)
{
ModLoaderHelper.registerTrade(profession, entry);
}
/**
* Send a packet from the client
* @param packet
*/
public static void clientSendPacket(Packet packet)
{
PacketDispatcher.sendPacketToServer(packet);
}
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLClientHandler#tryDispensingEntity(World, double, double, double, byte, byte, ItemStack)}
*
* @param world
* @param x
@@ -283,7 +371,7 @@ public class ModLoader
* @param xVel
* @param zVel
* @param item
* @return
* @return Always false, not implemented here
*/
@Deprecated
public static boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item)
@@ -353,7 +441,7 @@ public class ModLoader
* Get a list of all BaseMod loaded into the system
* {@link ModLoaderModContainer#findAll}
*
* @return
* @return A list containing all loaded ModLoader mods
*/
public static List<BaseMod> getLoadedMods()
{
@@ -363,24 +451,19 @@ public class ModLoader
/**
* Get a logger instance {@link FMLCommonHandler#getFMLLogger()}
*
* @return
* @return The current logger
*/
public static Logger getLogger()
{
return FMLLog.getLogger();
}
@SideOnly(CLIENT)
public static Minecraft getMinecraftInstance()
{
return FMLClientHandler.instance().getClient();
}
/**
* This is not the server
* {@link FMLClientHandler#getServer()}
*
* @return
*/
public static MinecraftServer getMinecraftServerInstance()
{
return FMLCommonHandler.instance().getMinecraftServerInstance();
@@ -393,7 +476,7 @@ public class ModLoader
* @param instanceclass
* @param instance
* @param fieldindex
* @return
* @return The value in the specified field.
*/
public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, int fieldindex)
{
@@ -402,12 +485,12 @@ public class ModLoader
/**
* Get a value from a field using reflection
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, String)}
* {@link ObfuscationReflectionHelper#getPrivateValue(Class, Object, String[])}
*
* @param instanceclass
* @param instance
* @param field
* @return
* @return The value in the specified field.
*/
public static <T, E> T getPrivateValue(Class<? super E> instanceclass, E instance, String field)
{
@@ -418,6 +501,7 @@ public class ModLoader
* Stubbed method on the server to return a unique model id
*
*/
@SideOnly(CLIENT)
public static int getUniqueBlockModelID(BaseMod mod, boolean inventoryRenderer)
{
return ModLoaderClientHelper.obtainBlockModelIdFor(mod, inventoryRenderer);
@@ -425,18 +509,20 @@ public class ModLoader
/**
* Get a new unique entity id
* {@link Entity#getNextId()}
* {@link EntityRegistry#findGlobalUniqueEntityId()}
*
* @return
* @return A unique entity ID
*/
public static int getUniqueEntityId()
{
return EntityRegistry.findGlobalUniqueEntityId();
}
@Deprecated
@SideOnly(CLIENT)
public static int getUniqueSpriteIndex(String path)
{
return SpriteHelper.getUniqueSpriteIndex(path);
return -1;
}
/**
@@ -445,13 +531,14 @@ public class ModLoader
*
* @param player
* @param channel
* @return
* @return If the channel is registered to the current connection.
*/
public static boolean isChannelActive(EntityPlayer player, String channel)
{
return NetworkRegistry.instance().isChannelActive(channel, (Player)player);
}
@SideOnly(CLIENT)
public static boolean isGUIOpen(Class<? extends GuiScreen> gui)
{
return FMLClientHandler.instance().getClient().field_71462_r != null && FMLClientHandler.instance().getClient().field_71462_r.equals(gui);
@@ -462,7 +549,7 @@ public class ModLoader
* {@link Loader#isModLoaded(String)}
*
* @param modname
* @return
* @return If the specified mod is loaded
*/
public static boolean isModLoaded(String modname)
{
@@ -477,6 +564,7 @@ public class ModLoader
{
}
@SideOnly(CLIENT)
public static BufferedImage loadImage(RenderEngine renderEngine, String path) throws Exception
{
return TextureFXManager.instance().loadImageFromTexturePack(renderEngine, path);
@@ -495,10 +583,12 @@ public class ModLoader
* Call in from elsewhere. Unimplemented here.
*/
@Deprecated
@SideOnly(CLIENT)
public static void onTick(float tick, Minecraft game)
{
}
@SideOnly(CLIENT)
public static void openGUI(EntityPlayer player, GuiScreen gui)
{
FMLClientHandler.instance().displayGuiScreen(player, gui);
@@ -511,7 +601,6 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLServerHandler#handlePacket250(Packet250CustomPayload, EntityPlayer)}
*
* @param packet
*/
@@ -521,12 +610,14 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static KeyBinding[] registerAllKeys(KeyBinding[] keys)
{
return keys;
}
@Deprecated
@SideOnly(CLIENT)
public static void registerAllTextureOverrides(RenderEngine cache)
{
}
@@ -552,6 +643,10 @@ public class ModLoader
GameRegistry.registerBlock(block, itemclass);
}
public static void registerContainerID(BaseMod mod, int id)
{
ModLoaderHelper.buildGuiHelper(mod, id);
}
/**
* Register a new entity ID
*
@@ -578,15 +673,15 @@ public class ModLoader
EntityRegistry.registerGlobalEntityID(entityClass, entityName, id, background, foreground);
}
@SideOnly(CLIENT)
public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat)
{
ModLoaderModContainer mlmc=ModLoaderHelper.registerKeyHelper(mod);
KeyBindingRegistry.registerKeyBinding(new ModLoaderKeyBindingHandler(keyHandler, allowRepeat, mlmc));
ModLoaderClientHelper.registerKeyBinding(mod, keyHandler, allowRepeat);
}
/**
* Register the mod for packets on this channel.
* {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)}
* {@link NetworkRegistry#registerChannel(IPacketHandler, String)}
*
* @param mod
* @param channel
@@ -607,6 +702,7 @@ public class ModLoader
GameRegistry.registerTileEntity(tileEntityClass, id);
}
@SideOnly(CLIENT)
public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id, TileEntitySpecialRenderer renderer)
{
ClientRegistry.registerTileEntity(tileEntityClass, id, renderer);
@@ -669,18 +765,21 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static boolean renderBlockIsItemFull3D(int modelID)
{
return RenderingRegistry.instance().renderItemAsFull3DBlock(modelID);
}
@Deprecated
@SideOnly(CLIENT)
public static void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID)
{
RenderingRegistry.instance().renderInventoryBlock(renderer, block, metadata, modelID);
}
@Deprecated
@SideOnly(CLIENT)
public static boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID)
{
return RenderingRegistry.instance().renderWorldBlock(renderer, world, x, y, z, block, modelID);
@@ -695,13 +794,16 @@ public class ModLoader
{
}
/**
* Send a packet from client to server
*
* @param packet
*/
public static void sendPacket(Packet packet) {
// TODO
// FMLClientHandler.instance().sendPacket(packet);
PacketDispatcher.sendPacketToServer(packet);
}
/**
* Send a chat message to the server
* {@link FMLClientHandler#handleChatPacket(Packet3Chat, EntityPlayer)}
*
* @param text
*/
@@ -712,11 +814,24 @@ public class ModLoader
}
@Deprecated
@SideOnly(CLIENT)
public static void serverLogin(NetClientHandler handler, Packet1Login loginPacket)
{
//TODO
}
public static void serverSendPacket(NetServerHandler handler, Packet packet)
{
if (handler != null)
{
PacketDispatcher.sendPacketToPlayer(packet, (Player)handler.getPlayer());
}
}
public static void serverOpenWindow(EntityPlayerMP player, Container container, int ID, int x, int y, int z)
{
ModLoaderHelper.openGui(ID, player, container, x, y, z);
}
/**
* Indicate that you want to receive ticks
*
@@ -765,7 +880,6 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLClientHandler#onItemCrafted(EntityPlayer, ItemStack, IInventory)}
*
* @param player
* @param item
@@ -778,7 +892,6 @@ public class ModLoader
/**
* This method is a call in hook from modified external code. Implemented elsewhere.
* {@link FMLClientHandler#onItemSmelted(EntityPlayer, ItemStack)}
*
* @param player
* @param item
@@ -790,7 +903,6 @@ public class ModLoader
/**
* Throw the offered exception. Likely will stop the game.
* {@link FMLClientHandler#raiseException(Throwable, String, boolean)}
*
* @param message
* @param e
@@ -1,128 +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.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLTextureFX;
import cpw.mods.fml.common.FMLCommonHandler;
import static org.lwjgl.opengl.GL11.*;
/**
* A texture override for animations, it takes a vertical image of
* texture frames and constantly rotates them in the texture.
*/
public class ModTextureAnimation extends FMLTextureFX
{
private final int tickRate;
private byte[][] images;
private int index = 0;
private int ticks = 0;
private String targetTex = null;
private BufferedImage imgData = null;
public ModTextureAnimation(int icon, int target, BufferedImage image, int tickCount)
{
this(icon, 1, target, image, tickCount);
}
public ModTextureAnimation(int icon, int size, int target, BufferedImage image, int tickCount)
{
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image, tickCount);
}
public ModTextureAnimation(int icon, int size, String target, BufferedImage image, int tickCount)
{
super(icon);
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
targetTex = target;
field_76849_e = size;
field_76847_f = re.func_78341_b(target);
tickRate = tickCount;
ticks = tickCount;
imgData = image;
}
@Override
public void setup()
{
super.setup();
int sWidth = imgData.getWidth();
int sHeight = imgData.getHeight();
int tWidth = tileSizeBase;
int tHeight = tileSizeBase;
int frames = (int)Math.floor((double)(sHeight / sWidth));
if (frames < 1)
{
throw new IllegalArgumentException(String.format("Attempted to create a TextureAnimation with no complete frames: %dx%d", sWidth, sHeight));
}
else
{
images = new byte[frames][];
BufferedImage image = imgData;
if (sWidth != tWidth)
{
BufferedImage b = new BufferedImage(tWidth, tHeight * frames, 6);
Graphics2D g = b.createGraphics();
g.drawImage(imgData, 0, 0, tWidth, tHeight * frames, 0, 0, sWidth, sHeight, (ImageObserver)null);
g.dispose();
image = b;
}
for (int frame = 0; frame < frames; frame++)
{
int[] pixels = new int[tileSizeSquare];
image.getRGB(0, tHeight * frame, tWidth, tHeight, pixels, 0, tWidth);
images[frame] = new byte[tileSizeSquare << 2];
for (int i = 0; i < pixels.length; i++)
{
int i4 = i * 4;
images[frame][i4 + 0] = (byte)(pixels[i] >> 16 & 255);
images[frame][i4 + 1] = (byte)(pixels[i] >> 8 & 255);
images[frame][i4 + 2] = (byte)(pixels[i] >> 0 & 255);
images[frame][i4 + 3] = (byte)(pixels[i] >> 24 & 255);
}
}
}
}
public void func_783_a()
{
if (++ticks >= tickRate)
{
if (++index >= images.length)
{
index = 0;
}
field_76852_a = images[index];
ticks = 0;
}
}
}
@@ -1,179 +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.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLTextureFX;
import cpw.mods.fml.common.FMLCommonHandler;
import static org.lwjgl.opengl.GL11.*;
public class ModTextureStatic extends FMLTextureFX
{
private boolean oldanaglyph = false;
private int[] pixels = null;
private String targetTex = null;
private int storedSize;
private BufferedImage overrideData = null;
private int needApply = 2;
public ModTextureStatic(int icon, int target, BufferedImage image)
{
this(icon, 1, target, image);
}
public ModTextureStatic(int icon, int size, int target, BufferedImage image)
{
this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image);
}
public ModTextureStatic(int icon, int size, String target, BufferedImage image)
{
super(icon);
RenderEngine re = FMLClientHandler.instance().getClient().field_71446_o;
targetTex = target;
storedSize = size;
field_76849_e = size;
field_76847_f = re.func_78341_b(target);
overrideData = image;
}
@Override
public void setup()
{
super.setup();
int sWidth = overrideData.getWidth();
int sHeight = overrideData.getHeight();
pixels = new int[tileSizeSquare];
if (tileSizeBase == sWidth && tileSizeBase == sHeight)
{
overrideData.getRGB(0, 0, sWidth, sHeight, pixels, 0, sWidth);
}
else
{
BufferedImage tmp = new BufferedImage(tileSizeBase, tileSizeBase, 6);
Graphics2D gfx = tmp.createGraphics();
gfx.drawImage(overrideData, 0, 0, tileSizeBase, tileSizeBase, 0, 0, sWidth, sHeight, (ImageObserver)null);
tmp.getRGB(0, 0, tileSizeBase, tileSizeBase, pixels, 0, tileSizeBase);
gfx.dispose();
}
update();
}
public void func_783_a()
{
if (oldanaglyph != field_76851_c)
{
update();
}
// This makes it so we only apply the texture to the target texture when we need to,
//due to the fact that update is called when the Effect is first registered, we actually
//need to wait for the next one.
field_76849_e = (needApply == 0 ? 0 : storedSize);
if (needApply > 0)
{
needApply--;
}
}
public void func_782_a(RenderEngine p_782_1_)
{
GL11.glBindTexture(GL_TEXTURE_2D, p_782_1_.func_78341_b(targetTex));
}
public void update()
{
needApply = 2;
for (int idx = 0; idx < pixels.length; idx++)
{
int i = idx * 4;
int a = pixels[idx] >> 24 & 255;
int r = pixels[idx] >> 16 & 255;
int g = pixels[idx] >> 8 & 255;
int b = pixels[idx] >> 0 & 255;
if (field_76851_c)
{
r = g = b = (r + g + b) / 3;
}
field_76852_a[i + 0] = (byte)r;
field_76852_a[i + 1] = (byte)g;
field_76852_a[i + 2] = (byte)b;
field_76852_a[i + 3] = (byte)a;
}
oldanaglyph = field_76851_c;
}
//Implementation of http://scale2x.sourceforge.net/algorithm.html
public static BufferedImage scale2x(BufferedImage image)
{
int w = image.getWidth();
int h = image.getHeight();
BufferedImage tmp = new BufferedImage(w * 2, h * 2, 2);
for (int x = 0; x < h; ++x)
{
int x2 = x * 2;
for (int y = 0; y < w; ++y)
{
int y2 = y * 2;
int E = image.getRGB(y, x);
int D = (x == 0 ? E : image.getRGB(y, x - 1));
int B = (y == 0 ? E : image.getRGB(y - 1, x ));
int H = (y >= w - 1 ? E : image.getRGB(y + 1, x ));
int F = (x >= h - 1 ? E : image.getRGB(y, x + 1));
int e0, e1, e2, e3;
if (B != H && D != F)
{
e0 = D == B ? D : E;
e1 = B == F ? F : E;
e2 = D == H ? D : E;
e3 = H == F ? F : E;
}
else
{
e0 = e1 = e2 = e3 = E;
}
tmp.setRGB(y2, x2, e0);
tmp.setRGB(y2 + 1, x2, e1);
tmp.setRGB(y2, x2 + 1, e2);
tmp.setRGB(y2 + 1, x2 + 1, e3);
}
}
return tmp;
}
@Override
public String toString()
{
return String.format("ModTextureStatic %s @ %d", targetTex, field_76850_b);
}
}
+42
View File
@@ -0,0 +1,42 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package 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);
}
}
+92 -87
View File
@@ -4,58 +4,58 @@
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
+ if os.path.isfile(os.path.join(path, 'asm-4.1.tar.gz')): #Check if asm exists, indicating the libs folder, if so, don't delete it
+ return
if not sys.platform.startswith('win'):
if os.path.exists(path):
shutil.rmtree(path)
@@ -582,6 +584,9 @@
self.has_astyle_cfg = False
if os.path.isfile(self.astyleconf):
self.has_astyle_cfg = True
+
+ #FML Entries
+ self.srcshared = os.path.normpath(os.path.join(self.dirsrc, 'common'))
@@ -139,6 +141,8 @@
fieldnames = csvreader.fieldnames
return set(fieldnames)
def creatergcfg(self, reobf=False, keep_lvt=False, keep_generics=False, rg_update=False):
"""Create the files necessary for RetroGuard"""
@@ -779,7 +784,8 @@
+def commands_sanity_check():
+ print 'Commands patch applied successfully'
class Commands(object):
"""Contains the commands and initialisation for a full mcp run"""
@@ -796,6 +800,8 @@
binlk = {CLIENT: self.binclient, SERVER: self.binserver}
testlk = {CLIENT: self.testclient, SERVER: self.testserver}
if not os.path.exists(os.path.join(srclk[side], os.path.normpath(testlk[side] + '.java'))):
- return False
+ if not os.path.exists(os.path.join(self.srcshared, os.path.normpath(testlk[side] + '.java'))):
+ return False
+ if side == SERVER and not os.path.exists(os.path.join(binlk[side], os.path.normpath(testlk[side] + '.class'))):
+ return self.checkbins(CLIENT)
if not os.path.exists(os.path.join(binlk[side], os.path.normpath(testlk[side] + '.class'))):
return False
return True
@@ -1037,6 +1043,9 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
pathlog = {CLIENT: self.clientrecomplog, SERVER: self.serverrecomplog}
def checkbins(self, side):
@@ -1039,6 +1045,7 @@
all_files = True
append_pattern = False
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=append_pattern, all_files=all_files)
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=append_pattern, all_files=all_files) #FML, Add Common folder
dirs = ' '.join(pkglist)
classpath = os.pathsep.join(cplk[side])
forkcmd = self.cmdrecomp.format(classpath=classpath, sourcepath=pathsrclk[side], outpath=pathbinlk[side],
@@ -1060,7 +1067,7 @@
+ if side == SERVER: #Warn about server because FML recombines it into client
+ self.logger.info('Server side recompiling might be skipped, this is normal, do not complain to FML/Forge team about server side.')
+
if not os.path.exists(pathbinlk[side]):
os.makedirs(pathbinlk[side])
@@ -1070,7 +1079,7 @@
raise
def startserver(self):
- classpath = [self.binserver] + self.cpathserver
+ classpath = [self.binserver, self.srcshared] + self.cpathserver
+ classpath = [self.binclient, self.srcclient] + self.cpathserver
classpath = [os.path.join('..', p) for p in classpath]
classpath = os.pathsep.join(classpath)
os.chdir(self.dirjars)
@@ -1068,7 +1075,7 @@
@@ -1078,7 +1087,7 @@
self.runmc(forkcmd)
def startclient(self):
- classpath = [self.binclient] + self.cpathclient
+ classpath = [self.binclient, self.srcshared] + self.cpathclient
+ classpath = [self.binclient, self.srcclient] + self.cpathclient
classpath = [os.path.join('..', p) for p in classpath]
classpath = os.pathsep.join(classpath)
natives = os.path.join('..', self.dirnatives)
@@ -1195,20 +1202,20 @@
@@ -1205,20 +1214,20 @@
with open(self.csvmethods, 'rb') as fh:
methodsreader = csv.DictReader(fh)
for row in methodsreader:
@@ -79,56 +79,7 @@
names['params'][row['param']] = row['name']
regexps = {
@@ -1238,6 +1245,11 @@
# HINT: We pathwalk the sources
for path, _, filelist in os.walk(pathsrclk[side], followlinks=True):
+ for cur_file in fnmatch.filter(filelist, '*.java'):
+ updatefile(os.path.normpath(os.path.join(path, cur_file)))
+
+ # FML, copy of the above, for the common folder
+ for path, _, filelist in os.walk(self.srcshared, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.java'):
updatefile(os.path.normpath(os.path.join(path, cur_file)))
return True
@@ -1320,12 +1332,14 @@
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
strip_comments(pathsrclk[side])
+ strip_comments(self.srcshared)
def process_cleanup(self, side):
"""Do lots of random cleanups including stripping comments, trailing whitespace and extra blank lines"""
pathsrclk = {CLIENT: self.srcclient, SERVER: self.srcserver}
src_cleanup(pathsrclk[side], fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
+ src_cleanup(self.srcshared, fix_imports=True, fix_unicode=True, fix_charval=True, fix_pi=True, fix_round=False)
def process_javadoc(self, side):
"""Add CSV descriptions to methods and fields as javadoc"""
@@ -1334,6 +1348,21 @@
if not self.has_doc_csv:
self.logger.warning('!! javadoc disabled due to no csvs !!')
return False
+
+ #FML Recall this function on the common folder
+ #Potential bug: If this is called without a subsiquent rename call, will cause double comments
+ if pathsrclk[side] != self.srcshared:
+ if side == CLIENT:
+ tmp = self.srcclient
+ self.srcclient = self.srcshared
+ self.process_javadoc(side)
+ self.srcclient = tmp
+ else:
+ tmp = self.srcserver
+ self.srcserver = self.srcshared
+ self.process_javadoc(side)
+ self.srcserver = tmp
+
#HINT: We read the relevant CSVs
methodsreader = csv.DictReader(open(self.csvmethods, 'r'))
@@ -1342,13 +1371,13 @@
@@ -1352,13 +1361,13 @@
methods = {}
for row in methodsreader:
#HINT: Only include methods that have a non-empty description
@@ -144,15 +95,59 @@
fields[row['searge']] = row['desc'].replace('*/', '* /')
regexps = {
@@ -1420,6 +1449,7 @@
# HINT: We create the list of source directories based on the list of packages
pkglist = filterdirs(pathsrclk[side], '*.java', append_pattern=True)
+ pkglist = pkglist + filterdirs(self.srcshared, '*.java', append_pattern=True) #FML, Add Common folder
dirs = ' '.join(pkglist)
forkcmd = self.cmdastyle.format(classes=dirs, conffile=self.astyleconf)
@@ -1435,7 +1444,7 @@
self.runcmd(forkcmd)
@@ -1592,6 +1622,9 @@
return True
- def gathermd5s(self, side, reobf=False):
+ def gathermd5s(self, side, reobf=False, skip_fml=False):
if not reobf:
md5lk = {CLIENT: self.md5client, SERVER: self.md5server}
else:
@@ -1450,6 +1459,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))
@@ -1546,6 +1558,8 @@
if not os.path.exists(outpathlk[side]):
os.makedirs(outpathlk[side])
+ reserved = ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9']
+
# HINT: We extract the modified class files
with closing(zipfile.ZipFile(jarlk[side])) as zipjar:
for in_class in trgclasses:
@@ -1559,6 +1573,23 @@
out_class = out_class.replace(self.nullpkg, '')
if out_class[0] == '/':
out_class = out_class[1:]
+
+ rename = False
+ for res in reserved:
+ if out_class.upper().startswith(res):
+ rename = True
+ break
+
+ if rename:
+ try:
+ f = open(os.path.join(outpathlk[side], '_' + out_class), 'wb')
+ f.write(zipjar.read(out_class))
+ f.close()
+ self.logger.info('> Outputted %s to %s as %s', in_class.ljust(35), outpathlk[side], '_' + out_class)
+ except IOError:
+ self.logger.error('* File %s failed extracting for %s', out_class, in_class)
+ continue
+
try:
zipjar.extract(out_class, outpathlk[side])
self.logger.info('> Outputted %s to %s as %s', in_class.ljust(35), outpathlk[side], out_class)
@@ -1605,6 +1636,9 @@
sys.exit(1)
for entry in newfiles:
@@ -162,3 +157,13 @@
if entry[3] == 'U':
self.logger.info('Retrieving file from server : %s', entry[0])
cur_file = os.path.normpath(entry[0])
@@ -1625,6 +1659,9 @@
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 = {}
@@ -0,0 +1,41 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.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,24 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
/**
* A marker interface for retrieving a proxy to a bukkit plugin.
* Fields associated with {@link BukkitPluginRef} annotations should
* declare this type and cast down if the target is available (not null)
* @author cpw
*
*/
public interface BukkitProxy
{
}
@@ -0,0 +1,68 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.cert.Certificate;
public class CertificateHelper {
private static final String HEXES = "0123456789abcdef";
public static String getFingerprint(Certificate certificate)
{
if (certificate == null)
{
return "NO VALID CERTIFICATE FOUND";
}
try
{
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] der = certificate.getEncoded();
md.update(der);
byte[] digest = md.digest();
return hexify(digest);
}
catch (Exception e)
{
return null;
}
}
public static String getFingerprint(ByteBuffer buffer)
{
try
{
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(buffer);
byte[] chksum = digest.digest();
return hexify(chksum);
}
catch (Exception e)
{
return null;
}
}
private static String hexify(byte[] chksum)
{
final StringBuilder hex = new StringBuilder( 2 * chksum.length );
for ( final byte b : chksum ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
}
@@ -1,19 +1,33 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.security.cert.Certificate;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionRange;
public class DummyModContainer implements ModContainer
{
private ModMetadata md;
private ArtifactVersion processedVersion;
public DummyModContainer(ModMetadata md)
{
@@ -42,9 +56,9 @@ public class DummyModContainer implements ModContainer
}
@Override
public List<ArtifactVersion> getRequirements()
public Set<ArtifactVersion> getRequirements()
{
return Collections.emptyList();
return Collections.emptySet();
}
@Override
@@ -108,7 +122,11 @@ public class DummyModContainer implements ModContainer
@Override
public ArtifactVersion getProcessedVersion()
{
return null;
if (processedVersion == null)
{
processedVersion = new DefaultArtifactVersion(getModId(), getVersion());
}
return processedVersion;
}
@Override
@@ -122,4 +140,21 @@ public class DummyModContainer implements ModContainer
{
return false;
}
@Override
public String getDisplayVersion()
{
return md.version;
}
@Override
public VersionRange acceptableMinecraftVersionRange()
{
return Loader.instance().getMinecraftModContainer().getStaticVersionRange();
}
@Override
public Certificate getSigningCertificate()
{
return null;
}
}
@@ -0,0 +1,28 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.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;
}
}
+172 -94
View File
@@ -1,57 +1,60 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet131MapData;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.DedicatedServer;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.World;
import net.minecraft.server.ServerListenThread;
import net.minecraft.server.ThreadMinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.world.World;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
import cpw.mods.fml.common.registry.ItemData;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.server.FMLServerHandler;
/**
@@ -80,20 +83,26 @@ public class FMLCommonHandler
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
private Class<?> forge;
private boolean noForge;
private List<String> brandings;
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
public void beginLoading(IFMLSidedHandler handler)
{
sidedDelegate = handler;
FMLLog.info("Attempting early MinecraftForge initialization");
FMLLog.log("MinecraftForge", Level.INFO, "Attempting early MinecraftForge initialization");
callForgeMethod("initialize");
FMLLog.info("Completed early MinecraftForge initialization");
callForgeMethod("registerCrashCallable");
FMLLog.log("MinecraftForge", Level.INFO, "Completed early MinecraftForge initialization");
}
public void rescheduleTicks(Side side)
{
sidedDelegate.profileStart("modTickScheduling");
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
sidedDelegate.profileEnd();
}
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
{
@@ -103,19 +112,15 @@ public class FMLCommonHandler
{
return;
}
sidedDelegate.profileStart("modTickStart$"+ticks);
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
ticksToRun.removeAll(EnumSet.complementOf(ticks));
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
ticksToRun.retainAll(ticks);
if (!ticksToRun.isEmpty())
{
sidedDelegate.profileStart(ticker.getLabel());
ticker.tickStart(ticksToRun, data);
sidedDelegate.profileEnd();
}
}
sidedDelegate.profileEnd();
}
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
@@ -126,19 +131,15 @@ public class FMLCommonHandler
{
return;
}
sidedDelegate.profileStart("modTickEnd$"+ticks);
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
ticksToRun.removeAll(EnumSet.complementOf(ticks));
EnumSet<TickType> ticksToRun = EnumSet.copyOf(Objects.firstNonNull(ticker.ticks(), EnumSet.noneOf(TickType.class)));
ticksToRun.retainAll(ticks);
if (!ticksToRun.isEmpty())
{
sidedDelegate.profileStart(ticker.getLabel());
ticker.tickEnd(ticksToRun, data);
sidedDelegate.profileEnd();
}
}
sidedDelegate.profileEnd();
}
/**
@@ -151,7 +152,6 @@ public class FMLCommonHandler
/**
* Find the container that associates with the supplied mod object
* @param mod
* @return
*/
public ModContainer findContainerFor(Object mod)
{
@@ -159,38 +159,39 @@ public class FMLCommonHandler
}
/**
* Get the forge mod loader logging instance (goes to the forgemodloader log file)
* @return
* @return The log instance for the FML log file
*/
public Logger getFMLLogger()
{
return FMLLog.getLogger();
}
/**
* @param key
* @param lang
* @param value
*/
/**
* @param languagePack
* @param lang
*/
public Side getSide()
{
return sidedDelegate.getSide();
}
/**
* Return the effective side for the context in the game. This is dependent
* on thread analysis to try and determine whether the code is running in the
* server or not. Use at your own risk
*/
public Side getEffectiveSide()
{
Thread thr = Thread.currentThread();
if ((thr instanceof ThreadMinecraftServer) || (thr instanceof ServerListenThread))
{
return Side.SERVER;
}
return Side.CLIENT;
}
/**
* Raise an exception
*
* @param exception
* @param message
* @param stopGame
*/
public void raiseException(Throwable exception, String message, boolean stopGame)
{
FMLCommonHandler.instance().getFMLLogger().throwing("FMLHandler", "raiseException", exception);
FMLLog.log(Level.SEVERE, exception, "Something raised an exception. The message was '%s'. 'stopGame' is %b", message, stopGame);
if (stopGame)
{
getSidedDelegate().haltGame(message,exception);
@@ -198,9 +199,6 @@ public class FMLCommonHandler
}
private Class<?> forge;
private boolean noForge;
private List<String> brandings;
private Class<?> findMinecraftForge()
{
if (forge==null && !noForge)
@@ -228,18 +226,24 @@ public class FMLCommonHandler
return null;
}
}
/**
* @param string
* @return
*/
public void computeBranding()
{
if (brandings == null)
{
Builder brd = ImmutableList.<String>builder();
brd.add(Loader.instance().getMCVersionString());
brd.add(Loader.instance().getFMLVersionString());
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
brd.add(Loader.instance().getMCPVersionString());
brd.add("FML v"+Loader.instance().getFMLVersionString());
String forgeBranding = (String) callForgeMethod("getBrandingVersion");
if (!Strings.isNullOrEmpty(forgeBranding))
{
brd.add(forgeBranding);
}
if (sidedDelegate!=null)
{
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
}
try {
Properties props=new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
@@ -262,9 +266,6 @@ public class FMLCommonHandler
return ImmutableList.copyOf(brandings);
}
/**
* @return
*/
public IFMLSidedHandler getSidedDelegate()
{
return sidedDelegate;
@@ -305,9 +306,14 @@ public class FMLCommonHandler
}
}
public void handleServerStarting(MinecraftServer server)
public boolean handleServerAboutToStart(MinecraftServer server)
{
Loader.instance().serverStarting(server);
return Loader.instance().serverAboutToStart(server);
}
public boolean handleServerStarting(MinecraftServer server)
{
return Loader.instance().serverStarting(server);
}
public void handleServerStarted()
@@ -330,9 +336,9 @@ public class FMLCommonHandler
sidedDelegate.showGuiScreen(clientGuiElement);
}
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket entitySpawnPacket)
public Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket entitySpawnPacket)
{
return sidedDelegate.spawnEntityIntoClientWorld(cls, entitySpawnPacket);
return sidedDelegate.spawnEntityIntoClientWorld(registration, entitySpawnPacket);
}
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
@@ -342,16 +348,7 @@ public class FMLCommonHandler
public void onServerStart(DedicatedServer dedicatedServer)
{
try
{
// Done this way so that the client doesn't depend on server side handler
Class<?> cls = Class.forName("cpw.mods.fml.server.FMLServerHandler", true, getClass().getClassLoader());
}
catch (ClassNotFoundException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to load the FML server handler");
throw Throwables.propagate(e);
}
FMLServerHandler.instance();
sidedDelegate.beginServerLoading(dedicatedServer);
}
@@ -384,11 +381,92 @@ public class FMLCommonHandler
public void onPlayerPreTick(EntityPlayer player)
{
tickStart(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
tickStart(EnumSet.of(TickType.PLAYER), side, player);
}
public void onPlayerPostTick(EntityPlayer player)
{
tickEnd(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
Side side = player instanceof EntityPlayerMP ? Side.SERVER : Side.CLIENT;
tickEnd(EnumSet.of(TickType.PLAYER), side, player);
}
public void registerCrashCallable(ICrashCallable callable)
{
crashCallables.add(callable);
}
public void enhanceCrashReport(CrashReport crashReport, CrashReportCategory category)
{
for (ICrashCallable call: crashCallables)
{
category.func_71500_a(call.getLabel(), call);
}
}
public void handleTinyPacket(NetHandler handler, Packet131MapData mapData)
{
sidedDelegate.handleTinyPacket(handler, mapData);
}
public void handleWorldDataSave(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
{
for (ModContainer mc : Loader.instance().getModList())
{
if (mc instanceof InjectedModContainer)
{
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
if (wac != null)
{
NBTTagCompound dataForWriting = wac.getDataForWriting(handler, worldInfo);
tagCompound.func_74766_a(mc.getModId(), dataForWriting);
}
}
}
}
public void handleWorldDataLoad(SaveHandler handler, WorldInfo worldInfo, NBTTagCompound tagCompound)
{
if (getEffectiveSide()!=Side.SERVER)
{
return;
}
if (handlerSet.contains(handler))
{
return;
}
handlerSet.add(handler);
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
worldInfo.setAdditionalProperties(additionalProperties);
for (ModContainer mc : Loader.instance().getModList())
{
if (mc instanceof InjectedModContainer)
{
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
if (wac != null)
{
wac.readData(handler, worldInfo, additionalProperties, tagCompound.func_74775_l(mc.getModId()));
}
}
}
}
public boolean shouldServerBeKilledQuietly()
{
if (sidedDelegate == null)
{
return false;
}
return sidedDelegate.shouldServerShouldBeKilledQuietly();
}
public void disconnectIDMismatch(MapDifference<Integer, ItemData> serverDifference, NetHandler toKill, INetworkManager network)
{
sidedDelegate.disconnectIDMismatch(serverDifference, toKill, network);
}
public void handleServerStopped()
{
Loader.instance().serverStopped();
}
}
@@ -1,28 +1,40 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.security.cert.Certificate;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.ItemData;
/**
* @author cpw
*
*/
public class FMLDummyContainer extends DummyModContainer
public class FMLDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public FMLDummyContainer()
{
@@ -38,8 +50,8 @@ public class FMLDummyContainer extends DummyModContainer
"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.url="https://github.com/MinecraftForge/FML/wiki";
meta.updateUrl="https://github.com/MinecraftForge/FML/wiki";
meta.screenshots=new String[0];
meta.logoFile="";
}
@@ -49,4 +61,66 @@ public class FMLDummyContainer extends DummyModContainer
{
return true;
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
NBTTagCompound fmlData = new NBTTagCompound();
NBTTagList list = new NBTTagList();
for (ModContainer mc : Loader.instance().getActiveModList())
{
NBTTagCompound mod = new NBTTagCompound();
mod.func_74778_a("ModId", mc.getModId());
mod.func_74778_a("ModVersion", mc.getVersion());
list.func_74742_a(mod);
}
fmlData.func_74782_a("ModList", list);
NBTTagList itemList = new NBTTagList();
GameData.writeItemData(itemList);
fmlData.func_74782_a("ModItemData", itemList);
return fmlData;
}
@Override
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
{
if (tag.func_74764_b("ModList"))
{
NBTTagList modList = tag.func_74761_m("ModList");
for (int i = 0; i < modList.func_74745_c(); i++)
{
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
String modId = mod.func_74779_i("ModId");
String modVersion = mod.func_74779_i("ModVersion");
ModContainer container = Loader.instance().getIndexedModList().get(modId);
if (container == null)
{
FMLLog.log("fml.ModTracker", Level.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.log("fml.ModTracker", Level.INFO, "This world was saved with mod %s version %s and it is now at version %s, things may not work well", modId, modVersion, container.getVersion());
}
}
}
if (tag.func_74764_b("ModItemData"))
{
NBTTagList modList = tag.func_74761_m("ModItemData");
Set<ItemData> worldSaveItems = GameData.buildWorldItemData(modList);
GameData.validateWorldSave(worldSaveItems);
}
else
{
GameData.validateWorldSave(null);
}
}
@Override
public Certificate getSigningCertificate()
{
Certificate[] certificates = getClass().getProtectionDomain().getCodeSource().getCertificates();
return certificates != null ? certificates[0] : null;
}
}
+29 -2
View File
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.logging.Level;
@@ -7,14 +19,24 @@ public class FMLLog
{
private static cpw.mods.fml.relauncher.FMLRelaunchLog coreLog = cpw.mods.fml.relauncher.FMLRelaunchLog.log;
public static void log(String logChannel, Level level, String format, Object... data)
{
coreLog.log(logChannel, level, format, data);
}
public static void log(Level level, String format, Object... data)
{
coreLog.log(level, String.format(format, data));
coreLog.log(level, format, data);
}
public static void log(String logChannel, Level level, Throwable ex, String format, Object... data)
{
coreLog.log(logChannel, level, ex, format, data);
}
public static void log(Level level, Throwable ex, String format, Object... data)
{
coreLog.log(level, String.format(format, data), ex);
coreLog.log(level, ex, format, data);
}
public static void severe(String format, Object... data)
@@ -50,4 +72,9 @@ public class FMLLog
{
return coreLog.getLogger();
}
public static void makeLog(String logChannel)
{
coreLog.makeLog(logChannel);
}
}
+296 -61
View File
@@ -13,47 +13,62 @@
package cpw.mods.fml.common;
import java.io.File;
import java.io.FileInputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.lang.reflect.Modifier;
import java.security.cert.Certificate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.ImmutableBiMap.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.Mod.Block;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.Metadata;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent;
import cpw.mods.fml.common.event.FMLFingerprintViolationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerAboutToStartEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppedEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.versioning.VersionRange;
public class FMLModContainer implements ModContainer
{
@@ -64,9 +79,7 @@ public class FMLModContainer implements ModContainer
private String className;
private Map<String, Object> descriptor;
private boolean enabled = true;
private List<ArtifactVersion> requirements;
private List<ArtifactVersion> dependencies;
private List<ArtifactVersion> dependants;
private String internalVersion;
private boolean overridesMetadata;
private EventBus eventBus;
private LoadController controller;
@@ -74,24 +87,61 @@ public class FMLModContainer implements ModContainer
private DefaultArtifactVersion processedVersion;
private boolean isNetworkMod;
private static final BiMap<Class<? extends FMLStateEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLStateEvent>, Class<? extends Annotation>>builder()
private static final BiMap<Class<? extends FMLEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLEvent>, Class<? extends Annotation>>builder()
.put(FMLPreInitializationEvent.class, Mod.PreInit.class)
.put(FMLInitializationEvent.class, Mod.Init.class)
.put(FMLPostInitializationEvent.class, Mod.PostInit.class)
.put(FMLServerAboutToStartEvent.class, Mod.ServerAboutToStart.class)
.put(FMLServerStartingEvent.class, Mod.ServerStarting.class)
.put(FMLServerStartedEvent.class, Mod.ServerStarted.class)
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
.put(FMLServerStoppedEvent.class, Mod.ServerStopped.class)
.put(IMCEvent.class,Mod.IMCCallback.class)
.put(FMLFingerprintViolationEvent.class, Mod.FingerprintWarning.class)
.build();
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
private String annotationDependencies;
private VersionRange minecraftAccepted;
private boolean fingerprintNotPresent;
private Set<String> sourceFingerprints;
private Certificate certificate;
private String modLanguage;
private ILanguageAdapter languageAdapter;
public static interface ILanguageAdapter {
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader) throws Exception;
}
public static class ScalaAdapter implements ILanguageAdapter {
@Override
public Object getNewInstance(FMLModContainer container, Class<?> scalaObjectClass, ClassLoader classLoader) throws Exception
{
System.out.println("Scala class : "+ scalaObjectClass);
Class<?> sObjectClass = Class.forName(scalaObjectClass.getName()+"$",true,classLoader);
return sObjectClass.getField("MODULE$").get(null);
}
}
public static class JavaAdapter implements ILanguageAdapter {
@Override
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader) throws Exception
{
return objectClass.newInstance();
}
}
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
{
this.className = className;
this.source = modSource;
this.descriptor = modDescriptor;
this.modLanguage = (String) modDescriptor.get("modLanguage");
this.languageAdapter = "scala".equals(modLanguage) ? new ScalaAdapter() : new JavaAdapter();
}
private ILanguageAdapter getLanguageAdapter()
{
return languageAdapter;
}
@Override
public String getModId()
{
@@ -107,7 +157,7 @@ public class FMLModContainer implements ModContainer
@Override
public String getVersion()
{
return modMetadata.version;
return internalVersion;
}
@Override
@@ -127,20 +177,100 @@ public class FMLModContainer implements ModContainer
{
modMetadata = mc.getMetadataForId(getModId(), descriptor);
if (descriptor.containsKey("usesMetadata"))
if (descriptor.containsKey("useMetadata"))
{
overridesMetadata = !((Boolean)descriptor.get("usesMetadata")).booleanValue();
overridesMetadata = !((Boolean)descriptor.get("useMetadata")).booleanValue();
}
if (overridesMetadata || !modMetadata.useDependencyInformation)
{
List<ArtifactVersion> requirements = Lists.newArrayList();
Set<ArtifactVersion> requirements = Sets.newHashSet();
List<ArtifactVersion> dependencies = Lists.newArrayList();
List<ArtifactVersion> dependants = Lists.newArrayList();
Loader.instance().computeDependencies((String) descriptor.get("dependencies"), requirements, dependencies, dependants);
annotationDependencies = (String) descriptor.get("dependencies");
Loader.instance().computeDependencies(annotationDependencies, requirements, dependencies, dependants);
modMetadata.requiredMods = requirements;
modMetadata.dependencies = dependencies;
modMetadata.dependants = dependants;
FMLLog.log(getModId(), Level.FINEST, "Parsed dependency info : %s %s %s", requirements, dependencies, dependants);
}
else
{
FMLLog.log(getModId(), Level.FINEST, "Using mcmod dependency info : %s %s %s", modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants);
}
if (Strings.isNullOrEmpty(modMetadata.name))
{
FMLLog.log(getModId(), Level.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.log(getModId(), Level.FINE, "Found version %s for mod %s in version.properties, using", internalVersion, getModId());
}
}
if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version))
{
FMLLog.log(getModId(), Level.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.log(getModId(), Level.WARNING, "Mod %s is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId());
modMetadata.version = internalVersion = "1.0";
}
String mcVersionString = (String) descriptor.get("acceptedMinecraftVersions");
if (!Strings.isNullOrEmpty(mcVersionString))
{
minecraftAccepted = VersionParser.parseRange(mcVersionString);
}
else
{
minecraftAccepted = Loader.instance().getMinecraftModContainer().getStaticVersionRange();
}
}
public Properties searchForVersionProperties()
{
try
{
FMLLog.log(getModId(), Level.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.log(getModId(), Level.FINEST, "Failed to find a usable version.properties file");
return null;
}
}
@@ -151,7 +281,7 @@ public class FMLModContainer implements ModContainer
}
@Override
public List<ArtifactVersion> getRequirements()
public Set<ArtifactVersion> getRequirements()
{
return modMetadata.requiredMods;
}
@@ -171,7 +301,7 @@ public class FMLModContainer implements ModContainer
@Override
public String getSortingRules()
{
return modMetadata.printableSortingRules();
return ((overridesMetadata || !modMetadata.useDependencyInformation) ? Strings.nullToEmpty(annotationDependencies) : modMetadata.printableSortingRules());
}
@Override
@@ -191,7 +321,7 @@ public class FMLModContainer implements ModContainer
{
if (this.enabled)
{
FMLLog.fine("Enabling mod %s", getModId());
FMLLog.log(getModId(), Level.FINE, "Enabling mod %s", getModId());
this.eventBus = bus;
this.controller = controller;
eventBus.register(this);
@@ -207,55 +337,103 @@ public class FMLModContainer implements ModContainer
{
Multimap<Class<? extends Annotation>,Object> anns = ArrayListMultimap.create();
for (Field f : clazz.getDeclaredFields())
{
for (Annotation a : f.getAnnotations())
{
f.setAccessible(true);
anns.put(a.annotationType(), f);
}
}
for (Method m : clazz.getDeclaredMethods())
{
for (Annotation a : m.getAnnotations())
{
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
if (modTypeAnnotations.containsKey(a.annotationType()))
{
Class<?>[] paramTypes = new Class[] { modTypeAnnotations.get(a.annotationType()) };
if (Arrays.equals(m.getParameterTypes(), paramTypes))
{
m.setAccessible(true);
anns.put(a.annotationType(), m);
}
else
{
FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
if (Arrays.equals(m.getParameterTypes(), paramTypes))
{
m.setAccessible(true);
anns.put(a.annotationType(), m);
}
else
{
FMLLog.log(getModId(), Level.SEVERE,"The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes));
}
}
}
}
return anns;
}
private void processFieldAnnotations() throws Exception
private void processFieldAnnotations(ASMDataTable asmDataTable) throws Exception
{
// Instance annotation
for (Object o : annotations.get(Instance.class))
{
Field f = (Field) o;
f.set(modInstance, modInstance);
}
SetMultimap<String, ASMData> annotations = asmDataTable.getAnnotationsFor(this);
for (Object o : annotations.get(Metadata.class))
parseSimpleFieldAnnotation(annotations, Instance.class.getName(), new Function<ModContainer, Object>()
{
Field f = (Field) o;
f.set(modInstance, modMetadata);
public Object apply(ModContainer mc)
{
return mc.getMod();
}
});
parseSimpleFieldAnnotation(annotations, Metadata.class.getName(), new Function<ModContainer, Object>()
{
public Object apply(ModContainer mc)
{
return mc.getMetadata();
}
});
}
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
{
String[] annName = annotationClassName.split("\\.");
String annotationName = annName[annName.length - 1];
for (ASMData targets : annotations.get(annotationClassName))
{
String targetMod = (String) targets.getAnnotationInfo().get("value");
Field f = null;
Object injectedMod = null;
ModContainer mc = this;
boolean isStatic = false;
Class<?> clz = modInstance.getClass();
if (!Strings.isNullOrEmpty(targetMod))
{
if (Loader.isModLoaded(targetMod))
{
mc = Loader.instance().getIndexedModList().get(targetMod);
}
else
{
mc = null;
}
}
if (mc != null)
{
try
{
clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader());
f = clz.getDeclaredField(targets.getObjectName());
f.setAccessible(true);
isStatic = Modifier.isStatic(f.getModifiers());
injectedMod = retreiver.apply(mc);
}
catch (Exception e)
{
Throwables.propagateIfPossible(e);
FMLLog.log(getModId(), 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.log(getModId(), Level.WARNING, "Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId());
continue;
}
}
f.set(target, injectedMod);
}
}
//TODO
// for (Object o : annotations.get(Block.class))
// {
// Field f = (Field) o;
// f.set(modInstance, GameRegistry.buildBlock(this, f.getType(), f.getAnnotation(Block.class)));
// }
}
@Subscribe
@@ -266,14 +444,53 @@ public class FMLModContainer implements ModContainer
ModClassLoader modClassLoader = event.getModClassLoader();
modClassLoader.addFile(source);
Class<?> clazz = Class.forName(className, true, modClassLoader);
ASMDataTable asmHarvestedAnnotations = event.getASMHarvestedData();
// TODO
asmHarvestedAnnotations.getAnnotationsFor(this);
Certificate[] certificates = clazz.getProtectionDomain().getCodeSource().getCertificates();
int len = 0;
if (certificates != null)
{
len = certificates.length;
}
Builder<String> certBuilder = ImmutableList.<String>builder();
for (int i = 0; i < len; i++)
{
certBuilder.add(CertificateHelper.getFingerprint(certificates[i]));
}
ImmutableList<String> certList = certBuilder.build();
sourceFingerprints = ImmutableSet.copyOf(certList);
String expectedFingerprint = (String) descriptor.get("certificateFingerprint");
fingerprintNotPresent = true;
if (expectedFingerprint != null && !expectedFingerprint.isEmpty())
{
if (!sourceFingerprints.contains(expectedFingerprint))
{
Level warnLevel = Level.SEVERE;
if (source.isDirectory())
{
warnLevel = Level.FINER;
}
FMLLog.log(getModId(), warnLevel, "The mod %s is expecting signature %s for source %s, however there is no signature matching that description", getModId(), expectedFingerprint, source.getName());
}
else
{
certificate = certificates[certList.indexOf(expectedFingerprint)];
fingerprintNotPresent = false;
}
}
annotations = gatherAnnotations(clazz);
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
modInstance = clazz.newInstance();
modInstance = getLanguageAdapter().getNewInstance(this,clazz, modClassLoader);
if (fingerprintNotPresent)
{
eventBus.post(new FMLFingerprintViolationEvent(source.isDirectory(), source, ImmutableSet.copyOf(this.sourceFingerprints), expectedFingerprint));
}
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
processFieldAnnotations();
processFieldAnnotations(event.getASMHarvestedData());
}
catch (Throwable e)
{
@@ -283,7 +500,7 @@ public class FMLModContainer implements ModContainer
}
@Subscribe
public void handleModStateEvent(FMLStateEvent event)
public void handleModStateEvent(FMLEvent event)
{
Class<? extends Annotation> annotation = modAnnotationTypes.get(event.getClass());
if (annotation == null)
@@ -325,4 +542,22 @@ public class FMLModContainer implements ModContainer
{
return isNetworkMod;
}
@Override
public String getDisplayVersion()
{
return modMetadata.version;
}
@Override
public VersionRange acceptableMinecraftVersionRange()
{
return minecraftAccepted;
}
@Override
public Certificate getSigningCertificate()
{
return certificate;
}
}
+34
View File
@@ -0,0 +1,34 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import org.objectweb.asm.tree.ClassNode;
public interface IASMHook {
/**
* Inject the {@link Mod} class node into this instance. This allows retrieval from custom
* attributes or other artifacts in your mod class
*
* @param modClassNode The mod class
* @return optionally some code generated classes that will be injected into the classloader
*/
ClassNode[] inject(ClassNode modClassNode);
/**
* Allow mods to manipulate classes loaded from this {@link Mod}'s jar file. The {@link Mod}
* class is always guaranteed to be called first.
* The node state should be changed in place.
*
* @param node The class being loaded
*/
void modifyClass(String className, ClassNode node);
}
@@ -1,15 +1,13 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
@@ -1,21 +1,20 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
/**
* Return a crafting handler for the mod container to call
@@ -29,15 +28,15 @@ public interface ICraftingHandler
* The object array contains these three arguments
*
* @param player
* @param craftedItem
* @param craftingGrid
* @param item
* @param craftMatrix
*/
void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix);
/**
* The object array contains these two arguments
* @param player
* @param smeltedItem
* @param item
*/
void onSmelting(EntityPlayer player, ItemStack item);
}
@@ -0,0 +1,20 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.concurrent.Callable;
public interface ICrashCallable extends Callable<String>
{
String getLabel();
}
@@ -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;
import net.minecraft.src.ItemStack;
import net.minecraft.src.World;
public interface IDispenseHandler
{
/**
* Return -1 if you don't want to dispense anything. the other values seem to have specific meanings
* to blockdispenser.
* @param x
* @param y
* @param z
* @param xVelocity
* @param zVelocity
* @param data
* @return
*/
int dispense(double x, double y, double z, int xVelocity, int zVelocity, World world, ItemStack item);
}
@@ -0,0 +1,18 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
public interface IFMLHandledException
{
}
@@ -1,27 +1,36 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import com.google.common.collect.MapDifference;
import net.minecraft.entity.Entity;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet131MapData;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.DedicatedServer;
import net.minecraft.src.Entity;
import net.minecraft.src.World;
import cpw.mods.fml.common.modloader.ModProperty;
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.registry.ItemData;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
import cpw.mods.fml.relauncher.Side;
public interface IFMLSidedHandler
{
void profileStart(String profileLabel);
void profileEnd();
List<String> getAdditionalBrandingInformation();
Side getSide();
@@ -30,7 +39,7 @@ public interface IFMLSidedHandler
void showGuiScreen(Object clientGuiElement);
Entity spawnEntityIntoClientWorld(Class<? extends Entity> entityClass, EntitySpawnPacket packet);
Entity spawnEntityIntoClientWorld(EntityRegistration registration, EntitySpawnPacket packet);
void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket);
@@ -39,4 +48,18 @@ public interface IFMLSidedHandler
void finishServerLoading();
MinecraftServer getServer();
void sendPacket(Packet packet);
void displayMissingMods(ModMissingPacket modMissingPacket);
void handleTinyPacket(NetHandler handler, Packet131MapData mapData);
void setClientCompatibilityLevel(byte compatibilityLevel);
byte getClientCompatibilityLevel();
boolean shouldServerShouldBeKilledQuietly();
void disconnectIDMismatch(MapDifference<Integer, ItemData> s, NetHandler toKill, INetworkManager mgr);
}
+14 -2
View File
@@ -1,8 +1,20 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import net.minecraft.src.ItemStack;
import net.minecraft.item.ItemStack;
public interface IFuelHandler
{
int getBurnTime(ItemStack fuel);
}
}
+14 -12
View File
@@ -1,19 +1,21 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
public interface IPickupNotifier
{
void notifyPickup(Object... pickupData);
void notifyPickup(EntityItem item, EntityPlayer player);
}
+18 -14
View File
@@ -1,26 +1,30 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import net.minecraft.entity.player.EntityPlayer;
/**
* @author cpw
*
*/
public interface IPlayerTracker
{
void onPlayerLogin(Object player);
void onPlayerLogout(Object player);
void onPlayerChangedDimension(Object player);
void onPlayerLogin(EntityPlayer player);
void onPlayerLogout(EntityPlayer player);
void onPlayerChangedDimension(EntityPlayer player);
void onPlayerRespawn(EntityPlayer player);
}
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
public interface IScheduledTickHandler extends ITickHandler
@@ -6,8 +18,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();
}
+9 -14
View File
@@ -1,15 +1,13 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
@@ -51,14 +49,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();
}
+17 -18
View File
@@ -1,26 +1,25 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.Random;
import net.minecraft.src.IChunkProvider;
import net.minecraft.src.World;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
/**
* This is called back during world generation. The {@link #generate(Random, int, int, Object...)} method passes in some additional data that
* can be cast into minecraft objects.
* This is called back during world generation.
*
* @author cpw
*
@@ -31,10 +30,10 @@ public interface IWorldGenerator
* Generate some world
*
* @param random the chunk specific {@link Random}.
* @param chunkX the block X coordinate of this chunk.
* @param chunkZ the block Z coordinate of this chunk.
* @param chunkX the chunk X coordinate of this chunk.
* @param chunkZ the chunk Z coordinate of this chunk.
* @param world : additionalData[0] The minecraft {@link World} we're generating for.
* @param generator : additionalData[1] The {@link IChunkProvider} that is generating.
* @param chunkGenerator : additionalData[1] The {@link IChunkProvider} that is generating.
* @param chunkProvider : additionalData[2] {@link IChunkProvider} that is requesting the world generation.
*
*/
@@ -1,11 +1,26 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Set;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionRange;
public class InjectedModContainer implements ModContainer
{
@@ -53,7 +68,7 @@ public class InjectedModContainer implements ModContainer
wrappedContainer.setEnabledState(enabled);
}
public List<ArtifactVersion> getRequirements()
public Set<ArtifactVersion> getRequirements()
{
return wrappedContainer.getRequirements();
}
@@ -103,4 +118,34 @@ public class InjectedModContainer implements ModContainer
{
return true;
}
@Override
public String getDisplayVersion()
{
return wrappedContainer.getDisplayVersion();
}
@Override
public VersionRange acceptableMinecraftVersionRange()
{
return wrappedContainer.acceptableMinecraftVersionRange();
}
public WorldAccessContainer getWrappedWorldAccessContainer()
{
if (wrappedContainer instanceof WorldAccessContainer)
{
return (WorldAccessContainer) wrappedContainer;
}
else
{
return null;
}
}
@Override
public Certificate getSigningCertificate()
{
return wrappedContainer.getSigningCertificate();
}
}
+119 -42
View File
@@ -1,30 +1,41 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.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 java.util.logging.Logger;
import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimap;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLEvent;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
public class LoadController
{
@@ -36,7 +47,7 @@ public class LoadController
private Multimap<String, Throwable> errors = ArrayListMultimap.create();
private Map<String, ModContainer> modList;
private List<ModContainer> activeModList = Lists.newArrayList();
private String activeContainer;
private ModContainer activeContainer;
private BiMap<ModContainer, Object> modObjectList;
public LoadController(Loader loader)
@@ -62,14 +73,16 @@ public class LoadController
boolean isActive = mod.registerBus(bus, this);
if (isActive)
{
FMLLog.fine("Activating mod %s", mod.getModId());
Level level = Logger.getLogger(mod.getModId()).getLevel();
FMLLog.log(mod.getModId(), Level.FINE, "Mod Logging channel %s configured at %s level.", mod.getModId(), level == null ? "default" : level);
FMLLog.log(mod.getModId(), Level.INFO, "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());
FMLLog.log(mod.getModId(), Level.WARNING, "Mod %s has been disabled through configuration", mod.getModId());
modStates.put(mod.getModId(), ModState.UNLOADED);
modStates.put(mod.getModId(), ModState.DISABLED);
}
@@ -92,74 +105,119 @@ public class LoadController
state = state.transition(!errors.isEmpty());
if (state != desiredState)
{
Throwable toThrow = null;
FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState);
StringBuilder sb = new StringBuilder();
printModStates(sb);
FMLLog.severe(sb.toString());
FMLLog.severe("The following problems were captured during this phase");
for (Entry<String, Throwable> error : errors.entries())
FMLLog.getLogger().severe(sb.toString());
if (errors.size()>0)
{
FMLLog.log(Level.SEVERE, error.getValue(), "Caught exception from %s", error.getKey());
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();
}
}
}
else
{
FMLLog.severe("The ForgeModLoader state engine has become corrupted. Probably, a state was missed by and invalid modification to a base class" +
"ForgeModLoader depends on. This is a critical error and not recoverable. Investigate any modifications to base classes outside of" +
"ForgeModLoader, especially Optifine, to see if there are fixes available.");
throw new RuntimeException("The ForgeModLoader state engine is invalid");
}
if (toThrow != null && toThrow instanceof RuntimeException)
{
throw (RuntimeException)toThrow;
}
else
{
throw new LoaderException(toThrow);
}
// Throw embedding the first error (usually the only one)
throw new LoaderException(errors.values().iterator().next());
}
}
public ModContainer activeContainer()
{
return activeContainer!=null ? modList.get(activeContainer) : null;
return activeContainer;
}
@Subscribe
public void propogateStateMessage(FMLStateEvent stateEvent)
public void propogateStateMessage(FMLEvent stateEvent)
{
for (Map.Entry<String,EventBus> entry : eventChannels.entrySet())
if (stateEvent instanceof FMLPreInitializationEvent)
{
activeContainer = entry.getKey();
stateEvent.applyModContainer(activeContainer());
FMLLog.finer("Posting state event %s to mod %s", stateEvent, entry.getKey());
entry.getValue().post(stateEvent);
FMLLog.finer("State event %s delivered to mod %s", stateEvent, entry.getKey());
activeContainer = null;
if (!errors.containsKey(entry.getKey()))
{
modStates.put(entry.getKey(), stateEvent.getModState());
}
else
{
modStates.put(entry.getKey(), ModState.ERRORED);
}
modObjectList = buildModObjectList();
}
if (stateEvent instanceof FMLConstructionEvent)
for (ModContainer mc : activeModList)
{
buildModObjectList();
activeContainer = mc;
String modId = mc.getModId();
stateEvent.applyModContainer(activeContainer());
FMLLog.log(modId, Level.FINEST, "Sending event %s to mod %s", stateEvent.getEventType(), modId);
eventChannels.get(modId).post(stateEvent);
FMLLog.log(modId, Level.FINEST, "Sent event %s to mod %s", stateEvent.getEventType(), modId);
activeContainer = null;
if (stateEvent instanceof FMLStateEvent)
{
if (!errors.containsKey(modId))
{
modStates.put(modId, ((FMLStateEvent)stateEvent).getModState());
}
else
{
modStates.put(modId, ModState.ERRORED);
}
}
}
}
public void buildModObjectList()
public ImmutableBiMap<ModContainer, Object> buildModObjectList()
{
ImmutableBiMap.Builder<ModContainer, Object> builder = ImmutableBiMap.<ModContainer, Object>builder();
for (ModContainer mc : activeModList)
{
builder.put(mc, mc.getMod());
if (!mc.isImmutable() && mc.getMod()!=null)
{
builder.put(mc, mc.getMod());
}
if (mc.getMod()==null && !mc.isImmutable() && state!=LoaderState.CONSTRUCTING)
{
FMLLog.severe("There is a severe problem with %s - it appears not to have constructed correctly", mc.getModId());
if (state != LoaderState.CONSTRUCTING)
{
this.errorOccurred(mc, new RuntimeException());
}
}
}
modObjectList = builder.build();
return builder.build();
}
public void errorOccurred(ModContainer modContainer, Throwable exception)
{
errors.put(modContainer.getModId(), exception);
if (exception instanceof InvocationTargetException)
{
errors.put(modContainer.getModId(), ((InvocationTargetException)exception).getCause());
}
else
{
errors.put(modContainer.getModId(), exception);
}
}
public void printModStates(StringBuilder ret)
{
for (String modId : modStates.keySet())
for (ModContainer mc : loader.getModList())
{
ModContainer mod = modList.get(modId);
ret.append("\n\t").append(mod.getName()).append(" (").append(mod.getSource().getName()).append(") ");
Joiner.on("->"). appendTo(ret, modStates.get(modId));
ret.append("\n\t").append(mc.getModId()).append(" [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
Joiner.on("->"). appendTo(ret, modStates.get(mc.getModId()));
}
}
@@ -188,6 +246,25 @@ public class LoadController
public BiMap<ModContainer, Object> getModObjectList()
{
if (modObjectList == null)
{
FMLLog.severe("Detected an attempt by a mod %s to perform game activity during mod construction. This is a serious programming error.", activeContainer);
return buildModObjectList();
}
return ImmutableBiMap.copyOf(modObjectList);
}
public boolean isInState(LoaderState state)
{
return this.state == state;
}
boolean hasReachedState(LoaderState state) {
return this.state.ordinal()>=state.ordinal() && this.state!=LoaderState.ERRORED;
}
void forceState(LoaderState newState)
{
this.state = newState;
}
}
+273 -77
View File
@@ -1,60 +1,67 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* 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
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.regex.Matcher;
import net.minecraft.server.MinecraftServer;
import net.minecraft.crash.CallableMinecraftVersion;
import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Splitter.MapSplitter;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Multiset.Entry;
import com.google.common.collect.Multisets;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets.SetView;
import com.google.common.collect.TreeMultimap;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.discovery.ContainerType;
import cpw.mods.fml.common.discovery.ModDiscoverer;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLLoadEvent;
import cpw.mods.fml.common.functions.ModIdFunction;
import cpw.mods.fml.common.modloader.BaseModProxy;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.toposort.ModSorter;
import cpw.mods.fml.common.toposort.ModSortingException;
import cpw.mods.fml.common.toposort.TopologicalSort;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
/**
* The loader class performs the actual loading of the mod code from disk.
@@ -103,7 +110,7 @@ public class Loader
private static String rev;
private static String build;
private static String mccversion;
private static String mcsversion;
private static String mcpversion;
/**
* The class loader we load the mods into.
@@ -131,9 +138,12 @@ public class Loader
private Exception capturedError;
private File canonicalModsDir;
private LoadController modController;
private MinecraftDummyContainer minecraft;
private MCPDummyContainer mcp;
private static File minecraftDir;
private static List<String> injectedContainers;
private File loggingProperties;
public static Loader instance()
{
@@ -152,7 +162,7 @@ public class Loader
rev = (String) data[2];
build = (String) data[3];
mccversion = (String) data[4];
mcsversion = (String) data[5];
mcpversion = (String) data[5];
minecraftDir = (File) data[6];
injectedContainers = (List<String>)data[7];
}
@@ -160,6 +170,15 @@ public class Loader
private Loader()
{
modClassLoader = new ModClassLoader(getClass().getClassLoader());
String actualMCVersion = new CallableMinecraftVersion(null).func_71493_a();
if (!mccversion.equals(actualMCVersion))
{
FMLLog.severe("This version of FML is built for Minecraft %s, we have detected Minecraft %s in your minecraft jar file", mccversion, actualMCVersion);
throw new LoaderException();
}
minecraft = new MinecraftDummyContainer(actualMCVersion);
mcp = new MCPDummyContainer(MetadataCollection.from(getClass().getResourceAsStream("/mcpmod.info"), "MCP").getMetadataForId("mcp", null));
}
/**
@@ -169,17 +188,40 @@ public class Loader
*/
private void sortModList()
{
FMLLog.fine("Verifying mod requirements are satisfied");
FMLLog.finer("Verifying mod requirements are satisfied");
try
{
Map<String, ArtifactVersion> modVersions = Maps.newHashMap();
for (ModContainer mod : mods)
BiMap<String, ArtifactVersion> modVersions = HashBiMap.create();
for (ModContainer mod : getActiveModList())
{
modVersions.put(mod.getModId(), mod.getProcessedVersion());
}
for (ModContainer mod : mods)
for (ModContainer mod : getActiveModList())
{
if (!mod.acceptableMinecraftVersionRange().containsVersion(minecraft.getProcessedVersion()))
{
FMLLog.severe("The mod %s does not wish to run in Minecraft version %s. You will have to remove it to play.", mod.getModId(), getMCVersionString());
throw new WrongMinecraftVersionException(mod);
}
Map<String,ArtifactVersion> names = Maps.uniqueIndex(mod.getRequirements(), new Function<ArtifactVersion, String>()
{
public String apply(ArtifactVersion v)
{
return v.getLabel();
}
});
Set<ArtifactVersion> versionMissingMods = Sets.newHashSet();
Set<String> missingMods = Sets.difference(names.keySet(), modVersions.keySet());
if (!missingMods.isEmpty())
{
FMLLog.severe("The mod %s (%s) requires mods %s to be available", mod.getModId(), mod.getName(), missingMods);
for (String modid : missingMods)
{
versionMissingMods.add(names.get(modid));
}
throw new MissingModsException(versionMissingMods);
}
ImmutableList<ArtifactVersion> allDeps = ImmutableList.<ArtifactVersion>builder().addAll(mod.getDependants()).addAll(mod.getDependencies()).build();
for (ArtifactVersion v : allDeps)
{
@@ -187,22 +229,33 @@ public class Loader
{
if (!v.containsVersion(modVersions.get(v.getLabel())))
{
FMLLog.log(Level.SEVERE, "The mod %s (%s) requires mods %s to be available, one or more are not", mod.getModId(), mod.getName(), allDeps);
throw new LoaderException();
versionMissingMods.add(v);
}
}
}
if (!versionMissingMods.isEmpty())
{
FMLLog.severe("The mod %s (%s) requires mod versions %s to be available", mod.getModId(), mod.getName(), versionMissingMods);
throw new MissingModsException(versionMissingMods);
}
}
FMLLog.fine("All mod requirements are satisfied");
FMLLog.finer("All mod requirements are satisfied");
ModSorter sorter = new ModSorter(mods, namedMods);
ModSorter sorter = new ModSorter(getActiveModList(), namedMods);
try
{
FMLLog.fine("Sorting mods into an ordered list");
mods = sorter.sort();
FMLLog.fine("Mod sorting completed successfully");
FMLLog.finer("Sorting mods into an ordered list");
List<ModContainer> sortedMods = sorter.sort();
// Reset active list to the sorted list
modController.getActiveModList().clear();
modController.getActiveModList().addAll(sortedMods);
// And inject the sorted list into the overall list
mods.removeAll(sortedMods);
sortedMods.addAll(mods);
mods = sortedMods;
FMLLog.finer("Mod sorting completed successfully");
}
catch (ModSortingException sortException)
{
@@ -215,17 +268,19 @@ public class Loader
}
finally
{
FMLLog.fine("Mod sorting data:");
for (ModContainer mod : mods)
FMLLog.fine("Mod sorting data");
int unprintedMods = mods.size();
for (ModContainer mod : getActiveModList())
{
if (!mod.isImmutable())
{
FMLLog.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules());
FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), mod.getSortingRules());
unprintedMods--;
}
}
if (mods.size()==0)
if (unprintedMods == mods.size())
{
FMLLog.fine("No mods found to sort");
FMLLog.fine("No user mods found to sort");
}
}
@@ -255,6 +310,8 @@ public class Loader
private ModDiscoverer identifyMods()
{
FMLLog.fine("Building injected Mod Containers %s", injectedContainers);
// Add in the MCP mod container
mods.add(new InjectedModContainer(mcp,new File("minecraft.jar")));
File coremod = new File(minecraftDir,"coremods");
for (String cont : injectedContainers)
{
@@ -279,13 +336,55 @@ public class Loader
discoverer.findModDirMods(canonicalModsDir);
mods.addAll(discoverer.identifyMods());
identifyDuplicates(mods);
namedMods = Maps.uniqueIndex(mods, new ModIdFunction());
FMLLog.info("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 1 ? "s" : "");
for (String modId: namedMods.keySet())
{
FMLLog.makeLog(modId);
}
return discoverer;
}
private class ModIdComparator implements Comparator<ModContainer>
{
@Override
public int compare(ModContainer o1, ModContainer o2)
{
return o1.getModId().compareTo(o2.getModId());
}
}
private void identifyDuplicates(List<ModContainer> mods)
{
TreeMultimap<ModContainer, File> dupsearch = TreeMultimap.create(new ModIdComparator(), Ordering.arbitrary());
for (ModContainer mc : mods)
{
if (mc.getSource() != null)
{
dupsearch.put(mc, mc.getSource());
}
}
ImmutableMultiset<ModContainer> duplist = Multisets.copyHighestCountFirst(dupsearch.keys());
SetMultimap<ModContainer, File> dupes = LinkedHashMultimap.create();
for (Entry<ModContainer> e : duplist.entrySet())
{
if (e.getCount() > 1)
{
FMLLog.severe("Found a duplicate mod %s at %s", e.getElement().getModId(), dupsearch.get(e.getElement()));
dupes.putAll(e.getElement(),dupsearch.get(e.getElement()));
}
}
if (!dupes.isEmpty())
{
throw new DuplicateModsFoundException(dupes);
}
}
/**
* @return
*
*/
private void initializeLoader()
{
@@ -344,16 +443,21 @@ public class Loader
FMLLog.severe("Attempting to load configuration from %s, which is not a directory", canonicalConfigPath);
throw new LoaderException();
}
loggingProperties = new File(canonicalConfigDir, "logging.properties");
FMLLog.info("Reading custom logging properties from %s", loggingProperties.getPath());
FMLRelaunchLog.loadLogConfiguration(loggingProperties);
FMLLog.log(Level.OFF,"Logging level for ForgeModLoader logging is set to %s", FMLRelaunchLog.log.getLogger().getLevel());
}
public List<ModContainer> getModList()
{
return ImmutableList.copyOf(instance().mods);
return instance().mods != null ? ImmutableList.copyOf(instance().mods) : ImmutableList.<ModContainer>of();
}
/**
* Called from the hook to start mod loading. We trigger the
* {@link #identifyMods()} and {@link #preModInit()} phases here. Finally,
* {@link #identifyMods()} and Constructing, Preinitalization, and Initalization phases here. Finally,
* the mod list is frozen completely and is consider immutable from then on.
*/
public void loadMods()
@@ -365,11 +469,38 @@ public class Loader
modController.transition(LoaderState.LOADING);
ModDiscoverer disc = identifyMods();
disableRequestedMods();
FMLLog.fine("Reloading logging properties from %s", loggingProperties.getPath());
FMLRelaunchLog.loadLogConfiguration(loggingProperties);
FMLLog.fine("Reloaded logging properties");
modController.distributeStateMessage(FMLLoadEvent.class);
sortModList();
mods = ImmutableList.copyOf(mods);
modController.distributeStateMessage(FMLLoadEvent.class);
for (File nonMod : disc.getNonModLibs())
{
if (nonMod.isFile())
{
FMLLog.info("FML has found a non-mod file %s in your mods directory. It will now be injected into your classpath. This could severe stability issues, it should be removed if possible.", nonMod.getName());
try
{
modClassLoader.addFile(nonMod);
}
catch (MalformedURLException e)
{
FMLLog.log(Level.SEVERE, e, "Encountered a weird problem with non-mod file injection : %s", nonMod.getName());
}
}
}
modController.transition(LoaderState.CONSTRUCTING);
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, disc.getASMTable());
FMLLog.fine("Mod signature data");
for (ModContainer mod : getActiveModList())
{
FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), CertificateHelper.getFingerprint(mod.getSigningCertificate()));
}
if (getActiveModList().isEmpty())
{
FMLLog.fine("No user mod signature data found");
}
modController.transition(LoaderState.PREINITIALIZATION);
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, disc.getASMTable(), canonicalConfigDir);
modController.transition(LoaderState.INITIALIZATION);
@@ -377,30 +508,30 @@ public class Loader
private void disableRequestedMods()
{
String disabledModList = System.getProperty("fml.modStates", "");
FMLLog.fine("Received a system property request \'%s\'",disabledModList);
String forcedModList = System.getProperty("fml.modStates", "");
FMLLog.finer("Received a system property request \'%s\'",forcedModList);
Map<String, String> sysPropertyStateList = Splitter.on(CharMatcher.anyOf(";:"))
.omitEmptyStrings().trimResults().withKeyValueSeparator("=")
.split(disabledModList);
FMLLog.fine("System property request managing the state of %d mods", sysPropertyStateList.size());
.split(forcedModList);
FMLLog.finer("System property request managing the state of %d mods", sysPropertyStateList.size());
Map<String, String> modStates = Maps.newHashMap();
File disabledModFile = new File(canonicalConfigDir, "fmlModState.properties");
Properties disabledModListProperties = new Properties();
if (disabledModFile.exists() && disabledModFile.isFile())
File forcedModFile = new File(canonicalConfigDir, "fmlModState.properties");
Properties forcedModListProperties = new Properties();
if (forcedModFile.exists() && forcedModFile.isFile())
{
FMLLog.fine("Found a mod state file %s", disabledModFile.getName());
FMLLog.finer("Found a mod state file %s", forcedModFile.getName());
try
{
disabledModListProperties.load(new FileReader(disabledModFile));
FMLLog.fine("Loaded states for %d mods from file", disabledModListProperties.size());
forcedModListProperties.load(new FileReader(forcedModFile));
FMLLog.finer("Loaded states for %d mods from file", forcedModListProperties.size());
}
catch (Exception e)
{
FMLLog.log(Level.INFO, e, "An error occurred reading the fmlModState.properties file");
}
}
modStates.putAll(Maps.fromProperties(disabledModListProperties));
modStates.putAll(Maps.fromProperties(forcedModListProperties));
modStates.putAll(sysPropertyStateList);
FMLLog.fine("After merging, found state information for %d mods", modStates.size());
@@ -408,7 +539,7 @@ public class Loader
{
public Boolean apply(String input)
{
return !Boolean.parseBoolean(input);
return Boolean.parseBoolean(input);
}
});
@@ -426,16 +557,13 @@ public class Loader
* Query if we know of a mod named modname
*
* @param modname
* @return
* @return If the mod is loaded
*/
public static boolean isModLoaded(String modname)
{
return instance().namedMods.containsKey(modname);
return instance().namedMods.containsKey(modname) && instance().modController.getModState(instance.namedMods.get(modname))!=ModState.DISABLED;
}
/**
* @return
*/
public File getConfigDir()
{
return canonicalConfigDir;
@@ -443,6 +571,11 @@ public class Loader
public String getCrashInformation()
{
// Handle being called before we've begun setup
if (modController == null)
{
return "";
}
StringBuilder ret = new StringBuilder();
List<String> branding = FMLCommonHandler.instance().getBrandings();
@@ -454,23 +587,17 @@ public class Loader
return ret.toString();
}
/**
* @return
*/
public String getFMLVersionString()
{
return String.format("FML v%s.%s.%s.%s", major, minor, rev, build);
return String.format("%s.%s.%s.%s", major, minor, rev, build);
}
/**
* @return
*/
public ClassLoader getModClassLoader()
{
return modClassLoader;
}
public void computeDependencies(String dependencyString, List<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
public void computeDependencies(String dependencyString, Set<ArtifactVersion> requirements, List<ArtifactVersion> dependencies, List<ArtifactVersion> dependants)
{
if (dependencyString == null || dependencyString.length() == 0)
{
@@ -553,26 +680,35 @@ public class Loader
// Mod controller should be in the initialization state here
modController.distributeStateMessage(LoaderState.INITIALIZATION);
modController.transition(LoaderState.POSTINITIALIZATION);
// Construct the "mod object table" so mods can refer to it in IMC and postinit
GameData.buildModObjectTable();
modController.distributeStateMessage(FMLInterModComms.IMCEvent.class);
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
modController.transition(LoaderState.AVAILABLE);
modController.distributeStateMessage(LoaderState.AVAILABLE);
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size()==1 ? "" : "s");
}
public Callable getCallableCrashInformation()
public ICrashCallable getCallableCrashInformation()
{
return new Callable<String>() {
return new ICrashCallable() {
@Override
public String call() throws Exception
{
return getCrashInformation();
}
@Override
public String getLabel()
{
return "FML";
}
};
}
public List<ModContainer> getActiveModList()
{
return modController.getActiveModList();
return modController != null ? modController.getActiveModList() : ImmutableList.<ModContainer>of();
}
public ModState getModState(ModContainer selectedMod)
@@ -585,10 +721,19 @@ public class Loader
return "Minecraft " + mccversion;
}
public void serverStarting(Object server)
public boolean serverStarting(Object server)
{
modController.distributeStateMessage(LoaderState.SERVER_STARTING, server);
modController.transition(LoaderState.SERVER_STARTING);
try
{
modController.distributeStateMessage(LoaderState.SERVER_STARTING, server);
modController.transition(LoaderState.SERVER_STARTING);
}
catch (Throwable t)
{
FMLLog.log(Level.SEVERE, t, "A fatal exception occurred during the server starting event");
return false;
}
return true;
}
public void serverStarted()
@@ -601,8 +746,6 @@ public class Loader
{
modController.distributeStateMessage(LoaderState.SERVER_STOPPING);
modController.transition(LoaderState.SERVER_STOPPING);
modController.transition(LoaderState.AVAILABLE);
}
public BiMap<ModContainer, Object> getModObjectList()
@@ -614,4 +757,57 @@ public class Loader
{
return getModObjectList().inverse();
}
public ModContainer activeModContainer()
{
return modController != null ? modController.activeContainer() : null;
}
public boolean isInState(LoaderState state)
{
return modController.isInState(state);
}
public MinecraftDummyContainer getMinecraftModContainer()
{
return minecraft;
}
public boolean hasReachedState(LoaderState state) {
return modController != null ? modController.hasReachedState(state) : false;
}
public String getMCPVersionString() {
return String.format("MCP v%s", mcpversion);
}
public void serverStopped()
{
modController.distributeStateMessage(LoaderState.SERVER_STOPPED);
try
{
modController.transition(LoaderState.SERVER_STOPPED);
}
catch (LoaderException e)
{
modController.forceState(LoaderState.SERVER_STOPPED);
// Discard any exceptions here - they mask other, real, exceptions
}
modController.transition(LoaderState.AVAILABLE);
}
public boolean serverAboutToStart(Object server)
{
try
{
modController.distributeStateMessage(LoaderState.SERVER_ABOUT_TO_START, server);
modController.transition(LoaderState.SERVER_ABOUT_TO_START);
}
catch (Throwable t)
{
FMLLog.log(Level.SEVERE, t, "A fatal exception occurred during the server about to start event");
return false;
}
return true;
}
}
+11 -12
View File
@@ -1,16 +1,15 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
public class LoaderException extends RuntimeException
@@ -28,4 +27,4 @@ public class LoaderException extends RuntimeException
public LoaderException()
{
}
}
}
+21 -4
View File
@@ -1,14 +1,29 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.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.FMLServerAboutToStartEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppedEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import cpw.mods.fml.common.event.FMLStateEvent;
@@ -26,9 +41,11 @@ public enum LoaderState
INITIALIZATION("Initializing mods", FMLInitializationEvent.class),
POSTINITIALIZATION("Post-initializing mods", FMLPostInitializationEvent.class),
AVAILABLE("Mod loading complete", FMLLoadCompleteEvent.class),
SERVER_ABOUT_TO_START("Server about to start", FMLServerAboutToStartEvent.class),
SERVER_STARTING("Server starting", FMLServerStartingEvent.class),
SERVER_STARTED("Server started", FMLServerStartedEvent.class),
SERVER_STOPPING("Server stopping", FMLServerStoppingEvent.class),
SERVER_STOPPED("Server stopped", FMLServerStoppedEvent.class),
ERRORED("Mod Loading errored",null);
@@ -48,7 +65,7 @@ public enum LoaderState
return ERRORED;
}
// stopping -> available
if (this == SERVER_STOPPING)
if (this == SERVER_STOPPED)
{
return AVAILABLE;
}
@@ -59,7 +76,7 @@ public enum LoaderState
{
return eventClass != null;
}
public FMLStateEvent getEvent(Object... eventData)
{
try
@@ -87,7 +104,7 @@ public enum LoaderState
AVAILABLE("Available"),
DISABLED("Disabled"),
ERRORED("Errored");
private String label;
private ModState(String label)
@@ -100,4 +117,4 @@ public enum LoaderState
return this.label;
}
}
}
}
@@ -0,0 +1,26 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import com.google.common.eventbus.EventBus;
public class MCPDummyContainer extends DummyModContainer {
public MCPDummyContainer(ModMetadata metadata) {
super(metadata);
}
@Override
public boolean registerBus(EventBus bus, LoadController controller) {
return true;
}
}
@@ -1,12 +1,21 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import argo.jdom.JdomParser;
import argo.jdom.JsonNode;
@@ -14,7 +23,6 @@ import argo.jdom.JsonRootNode;
import argo.saj.InvalidSyntaxException;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class MetadataCollection
@@ -23,13 +31,13 @@ public class MetadataCollection
private Map<String, ModMetadata> metadatas = Maps.newHashMap();
private int metadataVersion = 1;
public static MetadataCollection from(InputStream inputStream)
public static MetadataCollection from(InputStream inputStream, String sourceName)
{
if (inputStream == null)
{
return new MetadataCollection();
}
InputStreamReader reader = new InputStreamReader(inputStream);
try
{
@@ -43,6 +51,11 @@ public class MetadataCollection
return parseModInfo(root);
}
}
catch (InvalidSyntaxException e)
{
FMLLog.log(Level.SEVERE, e, "The mcmod.info file in %s cannot be parsed as valid JSON. It will be ignored", sourceName);
return new MetadataCollection();
}
catch (Exception e)
{
throw Throwables.propagate(e);
@@ -0,0 +1,38 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.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,30 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.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;
}
}
+120 -31
View File
@@ -1,16 +1,15 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.lang.annotation.ElementType;
@@ -18,14 +17,10 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import net.minecraft.item.ItemBlock;
import net.minecraft.src.ItemBlock;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage;
/**
* The new mod style in FML 1.3
@@ -39,31 +34,106 @@ public @interface Mod
{
/**
* The unique mod identifier for this mod
* @return
*/
String modid();
/**
* A user friendly name for the mod
* @return
*/
String name() default "";
/**
* A version string for this mod
* @return
*/
String version() default "";
/**
* A simple dependency string for this mod (see modloader's "priorities" string specification)
* @return
*/
String dependencies() default "";
/**
* Whether to use the mcmod.info metadata by default for this mod.
* If true, settings in the mcmod.info file will override settings in these annotations.
* @return
*/
boolean useMetadata() default false;
/**
* The acceptable range of minecraft versions that this mod will load and run in
* The default ("empty string") indicates that only the current minecraft version is acceptable.
* FML will refuse to run with an error if the minecraft version is not in this range across all mods.
* @return A version range as specified by the maven version range specification or the empty string
*/
String acceptedMinecraftVersions() default "";
/**
* An optional bukkit plugin that will be injected into the bukkit plugin framework if
* this mod is loaded into the FML framework and the bukkit coremod is present.
* Instances of the bukkit plugin can be obtained via the {@link BukkitPluginRef} annotation on fields.
* @return The name of the plugin to load for this mod
*/
String bukkitPlugin() default "";
/**
* Mods that this mod will <strong>not</strong> load with.
* An optional comma separated string of (+|-)(*|modid[@value]) which specify mods that
* this mod will refuse to load with, resulting in the game failing to start.
* Entries can be prefixed with a + for a positive exclusion assertion, or - for a negative exclusion
* assertion. Asterisk is the wildcard and represents <strong>all</strong> mods.
*
* The <strong>only</strong> mods that cannot be excluded are FML and MCP, trivially.
* Other special values:
* <ul>
* <li>+f indicates that the mod will accept a minecraft forge environment.</li>
* <li>-* indicates that the mod will not accept any other mods.</li>
* </ul>
*
* Some examples:
* <ul>
* <li><em>-*,+f,+IronChest</em>: Will run only in a minecraft forge environment with the mod IronChests.
* The -* forces all mods to be excluded, then the +f and +IronChest add into the "allowed list".</li>
* <li><em>+f,-IC2</em>: Will run in a minecraft forge environment but will <strong>not</strong> run if
* IndustrialCraft 2 (IC2) is loaded alongside.</li>
* <li><em>-*</em>: Will not run if <strong>any</strong> othe mod is loaded except MCP/FML itself.</li>
* </ul>
*
* If a mod is present on the excluded list, the game will stop and show an error screen. If the
* class containing the {@link Mod} annotation has a "getCustomErrorException" method, it will be
* called to retrieve a custom error message for display in this case. If two mods have a declared
* exclusion which is matched, the screen that is shown is indeterminate.
*
* @return A string listing modids to exclude from loading with this mod.
*/
String modExclusionList() default "";
/**
* Specifying this field allows for a mod to expect a signed jar with a fingerprint matching this value.
* The fingerprint should be SHA-1 encoded, lowercase with ':' removed. An empty value indicates that
* the mod is not expecting to be signed.
*
* Any incorrectness of the fingerprint, be it missing or wrong, will result in the {@link FingerprintWarning}
* method firing <i>prior to any other event on the mod</i>.
*
* @return A certificate fingerprint that is expected for this mod.
*/
String certificateFingerprint() default "";
/**
* The language the mod is authored in. This will be used to control certain libraries being downloaded.
* Valid values are currently "java", "scala"
*
* @return The language the mod is authored in
*/
String modLanguage() default "java";
/**
* An optional ASM hook class, that can be used to apply ASM to classes loaded from this mod. It is also given
* the ASM tree of the class declaring {@link Mod} to with what it will.
*
* @return The name of a class to be loaded and executed. Must implement {@link IASMHook}.
*/
String asmHookClass() default "";
/**
* Mark the designated method as to be called at if there is something wrong with the certificate fingerprint of
* the mod's jar, or it is missing, or otherwise a problem.
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FingerprintWarning {}
/**
* Mark the designated method as being called at the "pre-initialization" phase
* @author cpw
@@ -88,6 +158,14 @@ public @interface Mod
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PostInit {}
/**
* Mark the designated method as being called at the "server-about-to-start" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServerAboutToStart {}
/**
* Mark the designated method as being called at the "server-starting" phase
* @author cpw
@@ -97,7 +175,7 @@ public @interface Mod
@Target(ElementType.METHOD)
public @interface ServerStarting {}
/**
* Mark the designated method as being called at the "post-initialization" phase
* Mark the designated method as being called at the "server-started" phase
* @author cpw
*
*/
@@ -105,13 +183,30 @@ public @interface Mod
@Target(ElementType.METHOD)
public @interface ServerStarted {}
/**
* Mark the designated method as being called at the "post-initialization" phase
* Mark the designated method as being called at the "server-stopping" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServerStopping {}
/**
* Mark the designated method as being called at the "server-stopped" phase
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServerStopped {}
/**
* Mark the designated method as the receiver for {@link FMLInterModComms} messages
* Called between {@link Init} and {@link PostInit}
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface IMCCallback {}
/**
* Populate the annotated field with the mod instance.
* @author cpw
@@ -122,7 +217,6 @@ public @interface Mod
public @interface Instance {
/**
* The mod object to inject into this field
* @return
*/
String value() default "";
}
@@ -136,7 +230,6 @@ public @interface Mod
public @interface Metadata {
/**
* The mod id specifying the metadata to load here
* @return
*/
String value() default "";
}
@@ -150,12 +243,10 @@ public @interface Mod
public @interface Block {
/**
* The block's name
* @return
*/
String name();
/**
* The associated ItemBlock subtype for the item (can be null for an ItemBlock)
* @return
*/
Class<?> itemTypeClass() default ItemBlock.class;
}
@@ -169,12 +260,10 @@ public @interface Mod
public @interface Item {
/**
* The name of the item
* @return
*/
String name();
/**
* The type of the item
* @return
*/
String typeClass();
}
+21 -15
View File
@@ -1,20 +1,18 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
@@ -24,8 +22,9 @@ import java.util.logging.Level;
import com.google.common.collect.ImmutableList;
import cpw.mods.fml.common.discovery.ModCandidate;
import cpw.mods.fml.relauncher.FMLRelauncher;
import cpw.mods.fml.common.asm.ASMTransformer;
import cpw.mods.fml.common.asm.transformers.AccessTransformer;
import cpw.mods.fml.common.modloader.BaseModProxy;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
/**
@@ -70,7 +69,7 @@ public class ModClassLoader extends URLClassLoader
}
catch (URISyntaxException e)
{
FMLLog.log(Level.SEVERE, "Unable to process our input to locate the minecraft code", e);
FMLLog.log(Level.SEVERE, e, "Unable to process our input to locate the minecraft code");
throw new LoaderException(e);
}
}
@@ -79,4 +78,11 @@ public class ModClassLoader extends URLClassLoader
{
return STANDARD_LIBRARIES;
}
public Class<? extends BaseModProxy> loadBaseModClass(String modClazzName) throws Exception
{
AccessTransformer transformer = (AccessTransformer)mainClassLoader.getTransformers().get(0);
transformer.ensurePublicAccessFor(modClazzName);
return (Class<? extends BaseModProxy>) Class.forName(modClazzName, true, this);
}
}
+22 -41
View File
@@ -1,25 +1,26 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Set;
import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.LoaderState.ModState;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionRange;
/**
* The container that wraps around mods in the system.
@@ -38,83 +39,61 @@ public interface ModContainer
{
/**
* The globally unique modid for this mod
*
* @return
*/
String getModId();
/**
* A human readable name
*
* @return
*/
String getName();
/**
* A human readable version identifier
*
* @return
*/
String getVersion();
/**
* The location on the file system which this mod came from
*
* @return
*/
File getSource();
/**
* The metadata for this mod
*
* @return
*/
ModMetadata getMetadata();
/**
* Attach this mod to it's metadata from the supplied metadata collection
*
* @param mc
*/
void bindMetadata(MetadataCollection mc);
/**
* Set the enabled/disabled state of this mod
*
* @param enabled
*/
void setEnabledState(boolean enabled);
/**
* A list of the modids that this mod requires loaded prior to loading
*
* @return
*/
List<ArtifactVersion> getRequirements();
Set<ArtifactVersion> getRequirements();
/**
* A list of modids that should be loaded prior to this one. The special
* value <strong>*</strong> indicates to load <em>before</em> any other mod.
*
* @return
* value <strong>*</strong> indicates to load <em>after</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
* special value <strong>*</strong> indicates to load <em>before</em> any
* other mod.
*
* @return
*/
List<ArtifactVersion> getDependants();
/**
* A representative string encapsulating the sorting preferences for this
* mod
*
* @return
*/
String getSortingRules();
@@ -126,7 +105,6 @@ public interface ModContainer
*
* @param bus
* @param controller
* @return
*/
boolean registerBus(EventBus bus, LoadController controller);
@@ -134,14 +112,11 @@ public interface ModContainer
* Does this mod match the supplied mod
*
* @param mod
* @return
*/
boolean matches(Object mod);
/**
* Get the actual mod object
*
* @return
*/
Object getMod();
@@ -150,4 +125,10 @@ public interface ModContainer
boolean isImmutable();
boolean isNetworkMod();
String getDisplayVersion();
VersionRange acceptableMinecraftVersionRange();
Certificate getSigningCertificate();
}
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.File;
@@ -5,6 +17,7 @@ import java.util.regex.Pattern;
import org.objectweb.asm.Type;
import cpw.mods.fml.common.discovery.ModCandidate;
import cpw.mods.fml.common.discovery.asm.ASMModParser;
import cpw.mods.fml.common.discovery.asm.ModAnnotation;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
@@ -16,20 +29,38 @@ public class ModContainerFactory
public static ModContainerFactory instance() {
return INSTANCE;
}
public ModContainer build(ASMModParser modParser, File modSource)
public ModContainer build(ASMModParser modParser, File modSource, ModCandidate container)
{
String className = modParser.getASMType().getClassName();
if (modParser.isBaseMod() && modClass.matcher(className).find())
if (modParser.isBaseMod(container.getRememberedBaseMods()) && modClass.matcher(className).find())
{
FMLLog.fine("Identified a BaseMod type mod %s", className);
return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties());
}
else if (modClass.matcher(className).find())
{
FMLLog.fine("Identified a class %s following modloader naming convention but not directly a BaseMod or currently seen subclass", className);
container.rememberModCandidateType(modParser);
}
else if (modParser.isBaseMod(container.getRememberedBaseMods()))
{
FMLLog.fine("Found a basemod %s of non-standard naming format", className);
container.rememberBaseModType(className);
}
// We warn if it's not a basemod instance -- compatibility requires it to be in net.minecraft.src *sigh*
if (className.startsWith("net.minecraft.src.") && container.isClasspath() && !container.isMinecraftJar())
{
FMLLog.severe("FML has detected a mod that is using a package name based on 'net.minecraft.src' : %s. This is generally a severe programming error. "
+ " There should be no mod code in the minecraft namespace. MOVE YOUR MOD! If you're in eclipse, select your source code and 'refactor' it into "
+ "a new package. Go on. DO IT NOW!",className);
}
for (ModAnnotation ann : modParser.getAnnotations())
{
if (ann.getASMType().equals(Type.getType(Mod.class)))
{
FMLLog.fine("Identified a FMLMod type mod %s", className);
FMLLog.fine("Identified an FMLMod type mod %s", className);
return new FMLModContainer(className, modSource, ann.getValues());
}
}
+39 -38
View File
@@ -1,27 +1,26 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import static argo.jdom.JsonNodeBuilders.aStringBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.zip.ZipInputStream;
import java.util.Set;
import java.util.logging.Level;
import argo.jdom.JsonNode;
import argo.jdom.JsonStringNode;
@@ -35,12 +34,9 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.functions.ModNameFunction;
import cpw.mods.fml.common.modloader.ModLoaderModContainer;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.VersionParser;
import static argo.jdom.JsonNodeBuilders.*;
/**
* @author cpw
*
@@ -88,19 +84,20 @@ public class ModMetadata
public List<ModContainer> childMods = Lists.newArrayList();
public boolean useDependencyInformation;
public List<ArtifactVersion> requiredMods;
public Set<ArtifactVersion> requiredMods;
public List<ArtifactVersion> dependencies;
public List<ArtifactVersion> dependants;
public boolean autogenerated;
/**
* @param mod2
* @param type2
*/
public ModMetadata(JsonNode node)
{
Map<JsonStringNode, Object> processedFields = Maps.transformValues(node.getFields(), new JsonStringConverter());
modId = (String)processedFields.get(aStringBuilder("modid"));
if (Strings.isNullOrEmpty(modId))
{
FMLLog.log(Level.SEVERE, "Found an invalid mod metadata file - missing modid");
throw new LoaderException();
}
name = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("name")));
description = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("description")));
url = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("url")));
@@ -109,10 +106,10 @@ public class ModMetadata
version = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("version")));
credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
parent = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
authorList = Optional.fromNullable((List<String>)processedFields.get(aStringBuilder("authorList"))).or(authorList);
requiredMods = processReferences((List<String>)processedFields.get(aStringBuilder("requiredMods")));
dependencies = processReferences((List<String>)processedFields.get(aStringBuilder("dependencies")));
dependants = processReferences((List<String>)processedFields.get(aStringBuilder("dependants")));
authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), HashSet.class);
dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), ArrayList.class);
dependants = processReferences(processedFields.get(aStringBuilder("dependants")), ArrayList.class);
useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
}
@@ -120,22 +117,29 @@ public class ModMetadata
{
}
private List<ArtifactVersion> processReferences(List<String> refs)
private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
{
List<ArtifactVersion> res = Lists.newArrayList();
T res = null;
try
{
res = retType.newInstance();
}
catch (Exception e)
{
// unpossible
}
if (refs == null)
{
return res;
}
for (String ref : refs)
for (String ref : ((List<String>)refs))
{
res.add(VersionParser.parseVersionReference(ref));
}
return res;
}
/**
* @return
*/
public String getChildModCountString()
{
return String.format("%d child mod%s", childMods.size(), childMods.size() != 1 ? "s" : "");
@@ -146,9 +150,6 @@ public class ModMetadata
return Joiner.on(", ").join(authorList);
}
/**
* @return
*/
public String getChildModList()
{
return Joiner.on(", ").join(Lists.transform(childMods, new ModNameFunction()));
@@ -156,6 +157,6 @@ public class ModMetadata
public String printableSortingRules()
{
return null;
return "";
}
}
@@ -15,6 +15,7 @@ package cpw.mods.fml.common;
import java.util.Arrays;
import java.util.logging.Level;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.relauncher.ReflectionHelper;
import cpw.mods.fml.relauncher.ReflectionHelper.UnableToAccessFieldException;
import cpw.mods.fml.relauncher.ReflectionHelper.UnableToFindFieldException;
@@ -27,8 +28,6 @@ import cpw.mods.fml.relauncher.ReflectionHelper.UnableToFindFieldException;
*/
public class ObfuscationReflectionHelper
{
public static boolean obfuscation;
@SuppressWarnings("unchecked")
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, int fieldIndex)
{
@@ -43,12 +42,23 @@ public class ObfuscationReflectionHelper
}
}
public static String[] remapFieldNames(String className, String... fieldNames)
{
String internalClassName = FMLDeobfuscatingRemapper.INSTANCE.unmap(className.replace('.', '/'));
String[] mappedNames = new String[fieldNames.length];
int i = 0;
for (String fName : fieldNames)
{
mappedNames[i++] = FMLDeobfuscatingRemapper.INSTANCE.mapFieldName(internalClassName, fName, null);
}
return mappedNames;
}
@SuppressWarnings("unchecked")
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, String... fieldNames)
{
try
{
return ReflectionHelper.getPrivateValue(classToAccess, instance, fieldNames);
return ReflectionHelper.getPrivateValue(classToAccess, instance, remapFieldNames(classToAccess.getName(),fieldNames));
}
catch (UnableToFindFieldException e)
{
@@ -91,7 +101,7 @@ public class ObfuscationReflectionHelper
{
try
{
ReflectionHelper.setPrivateValue(classToAccess, instance, value, fieldNames);
ReflectionHelper.setPrivateValue(classToAccess, instance, value, remapFieldNames(classToAccess.getName(), fieldNames));
}
catch (UnableToFindFieldException e)
{
@@ -104,13 +114,4 @@ public class ObfuscationReflectionHelper
throw e;
}
}
/**
*
*/
public static void detectObfuscation(Class<?> clazz)
{
obfuscation = !clazz.getSimpleName().equals("World");
}
}
+10 -13
View File
@@ -1,15 +1,13 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
@@ -19,10 +17,9 @@ import java.lang.reflect.Modifier;
import java.util.Set;
import java.util.logging.Level;
import org.objectweb.asm.Type;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
import cpw.mods.fml.relauncher.Side;
/**
* @author cpw
-35
View File
@@ -1,35 +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;
public enum Side {
CLIENT, SERVER, BUKKIT;
/**
* @return
*/
public boolean isServer()
{
return !isClient();
}
/**
* @return
*/
public boolean isClient()
{
return this == CLIENT;
}
}
+9 -13
View File
@@ -1,15 +1,13 @@
/*
* 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
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
@@ -29,13 +27,11 @@ public @interface SidedProxy
{
/**
* The name of the client side class to load and populate
* @return
*/
String clientSide() default "";
/**
* The name of the server side class to load and populate
* @return
*/
String serverSide() default "";
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.EnumSet;
+9 -28
View File
@@ -1,15 +1,13 @@
/*
* The FML Forge Mod Loader suite.
* Copyright (C) 2012 cpw
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* 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
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
@@ -30,19 +28,6 @@ public enum TickType {
* arg 0 : float "partial render time"
*/
RENDER,
/**
* client side
* Fired during the render processing phase if a GUI is open
* arg 0 : float "partial render time"
* arg 1 : the open gui or null if no gui is open
*/
GUI,
/**
* client side
* Fired during the client evaluation loop
* arg 0 : The open gui or null if no gui is open
*/
CLIENTGUI,
/**
* server side
* Fired once as the world loads from disk
@@ -69,15 +54,11 @@ public enum TickType {
/**
* Partner ticks that are also cancelled by returning false from onTickInGame
*
* @return
*/
public EnumSet<TickType> partnerTicks()
{
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,25 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
import java.util.Map;
import net.minecraft.nbt.*;
import net.minecraft.world.storage.*;
public interface WorldAccessContainer
{
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info);
public void readData(SaveHandler handler, WorldInfo info, Map<String,NBTBase> propertyMap, NBTTagCompound tag);
}
@@ -0,0 +1,25 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common;
public class WrongMinecraftVersionException extends RuntimeException
{
public ModContainer mod;
public WrongMinecraftVersionException(ModContainer mod)
{
this.mod = mod;
}
}
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm;
import org.objectweb.asm.ClassReader;
@@ -12,7 +24,7 @@ import cpw.mods.fml.relauncher.IClassTransformer;
public class ASMTransformer implements IClassTransformer
{
@Override
public byte[] transform(String name, byte[] bytes)
public byte[] transform(String name,String transformedName, byte[] bytes)
{
if ("net.minecraft.src.Block".equals(name))
{
@@ -24,7 +36,7 @@ public class ASMTransformer implements IClassTransformer
cn.accept(cw);
return cw.toByteArray();
}
return bytes;
}
@@ -1,5 +1,35 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.io.ObjectInputStream.GetField;
import java.io.StringReader;
import java.net.JarURLConnection;
import java.nio.charset.Charset;
import java.security.CodeSource;
import java.security.cert.CertPath;
import java.security.cert.CertPathValidator;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.PKIXCertPathValidatorResult;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import javax.swing.JOptionPane;
@@ -9,12 +39,16 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import cpw.mods.fml.relauncher.FMLRelauncher;
import cpw.mods.fml.common.CertificateHelper;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import cpw.mods.fml.relauncher.IFMLCallHook;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
public class FMLSanityChecker implements IFMLCallHook
{
private static final String FMLFINGERPRINT = "AE:F6:54:79:96:E9:1B:D1:59:70:6C:B4:6B:F5:4A:89:C5:CE:08:1D".toLowerCase().replace(":","");
private static final String FORGEFINGERPRINT = "DE:4C:F8:A3:F3:BC:15:63:58:10:04:4C:39:24:0B:F9:68:04:EA:7D".toLowerCase().replace(":", "");
static class MLDetectorClassVisitor extends ClassVisitor
{
private boolean foundMarker = false;
@@ -39,6 +73,42 @@ public class FMLSanityChecker implements IFMLCallHook
@Override
public Void call() throws Exception
{
CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
boolean goodFML = false;
if (codeSource.getLocation().getProtocol().equals("jar"))
{
Certificate[] certificates = codeSource.getCertificates();
if (certificates!=null)
{
for (Certificate cert : certificates)
{
String fingerprint = CertificateHelper.getFingerprint(cert);
if (fingerprint.equals(FMLFINGERPRINT))
{
FMLRelaunchLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint);
goodFML = true;
}
else if (fingerprint.equals(FORGEFINGERPRINT))
{
FMLRelaunchLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint);
goodFML = true;
}
else
{
FMLRelaunchLog.severe("Found invalid fingerprint for FML: %s", fingerprint);
}
}
}
}
else
{
goodFML = true;
}
if (!goodFML)
{
FMLRelaunchLog.severe("FML appears to be missing any signature data. This is not a good thing");
}
byte[] mlClass = cl.getClassBytes("ModLoader");
// Only care in obfuscated env
if (mlClass == null)
@@ -68,6 +138,7 @@ public class FMLSanityChecker implements IFMLCallHook
public void injectData(Map<String, Object> data)
{
cl = (RelaunchClassLoader) data.get("classLoader");
FMLDeobfuscatingRemapper.INSTANCE.setup((File)data.get("mcLocation"), cl, (String) data.get("deobfuscationFileName"));
}
}
@@ -0,0 +1,29 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to force certain classes to reobfuscate
* @author cpw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ReobfuscationMarker {
}
@@ -1,14 +0,0 @@
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();
}
@@ -1,27 +1,32 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -29,15 +34,12 @@ import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -45,10 +47,12 @@ import com.google.common.collect.Multimap;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.relauncher.IClassTransformer;
public class AccessTransformer implements IClassTransformer
{
private static final boolean DEBUG = false;
private class Modifier
{
public String name = "";
@@ -58,13 +62,14 @@ public class AccessTransformer implements IClassTransformer
public int targetAccess = 0;
public boolean changeFinal = false;
public boolean markFinal = false;
protected boolean modifyClassVisibility;
private void setTargetAccess(String name)
{
if (name.startsWith("public")) targetAccess = ACC_PUBLIC;
else if (name.startsWith("private")) targetAccess = ACC_PRIVATE;
else if (name.startsWith("protected")) targetAccess = ACC_PROTECTED;
if (name.endsWith("-f"))
{
changeFinal = true;
@@ -118,25 +123,32 @@ public class AccessTransformer implements IClassTransformer
return true;
}
List<String> parts = Lists.newArrayList(Splitter.on(" ").trimResults().split(line));
if (parts.size()>2 || parts.get(1).indexOf('.') == -1)
if (parts.size()>2)
{
throw new RuntimeException("Invalid config file line "+ input);
}
Modifier m = new Modifier();
m.setTargetAccess(parts.get(0));
List<String> descriptor = Lists.newArrayList(Splitter.on(".").trimResults().split(parts.get(1)));
String nameReference = descriptor.get(1);
int parenIdx = nameReference.indexOf('(');
if (parenIdx>0)
if (descriptor.size() == 1)
{
m.desc = nameReference.substring(parenIdx);
m.name = nameReference.substring(0,parenIdx);
m.modifyClassVisibility = true;
}
else
{
m.name = nameReference;
String nameReference = descriptor.get(1);
int parenIdx = nameReference.indexOf('(');
if (parenIdx>0)
{
m.desc = nameReference.substring(parenIdx);
m.name = nameReference.substring(0,parenIdx);
}
else
{
m.name = nameReference;
}
}
modifiers.put(descriptor.get(0), m);
modifiers.put(descriptor.get(0).replace('/', '.'), m);
return true;
}
});
@@ -144,27 +156,73 @@ public class AccessTransformer implements IClassTransformer
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (!modifiers.containsKey(name)) { return bytes; }
if (bytes == null) { return null; }
boolean makeAllPublic = FMLDeobfuscatingRemapper.INSTANCE.isRemappedClass(name);
if (DEBUG)
{
System.out.printf("Considering all methods and fields on %s (%s): %b\n", name, transformedName, makeAllPublic);
}
if (!makeAllPublic && !modifiers.containsKey(name)) { return bytes; }
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
if (makeAllPublic)
{
// class
Modifier m = new Modifier();
m.targetAccess = ACC_PUBLIC;
m.modifyClassVisibility = true;
modifiers.put(name,m);
// fields
m = new Modifier();
m.targetAccess = ACC_PUBLIC;
m.name = "*";
modifiers.put(name,m);
// methods
m = new Modifier();
m.targetAccess = ACC_PUBLIC;
m.name = "*";
m.desc = "<dummy>";
modifiers.put(name,m);
if (DEBUG)
{
System.out.printf("Injected all public modifiers for %s (%s)\n", name, transformedName);
}
}
Collection<Modifier> mods = modifiers.get(name);
for (Modifier m : mods)
{
if (m.modifyClassVisibility)
{
classNode.access = getFixedAccess(classNode.access, m);
if (DEBUG)
{
System.out.println(String.format("Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess)));
}
continue;
}
if (m.desc.isEmpty())
{
for (FieldNode n : (List<FieldNode>) classNode.fields)
{
if (n.name.equals(m.name))
if (n.name.equals(m.name) || m.name.equals("*"))
{
n.access = getFixedAccess(n.access, m);
System.out.println(String.format("Field: %s.%s %s -> %s", name, m.name, Integer.toBinaryString(m.oldAccess),
Integer.toBinaryString(m.newAccess)));
break;
if (DEBUG)
{
System.out.println(String.format("Field: %s.%s %s -> %s", name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess)));
}
if (!m.name.equals("*"))
{
break;
}
}
}
}
@@ -172,11 +230,18 @@ public class AccessTransformer implements IClassTransformer
{
for (MethodNode n : (List<MethodNode>) classNode.methods)
{
if (n.name.equals(m.name) && n.desc.equals(m.desc))
if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*"))
{
n.access = getFixedAccess(n.access, m);
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, m.name, m.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
break;
if (DEBUG)
{
System.out.println(String.format("Method: %s.%s%s %s -> %s", name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
}
if (!m.name.equals("*"))
{
break;
}
}
}
}
@@ -215,7 +280,7 @@ public class AccessTransformer implements IClassTransformer
default:
throw new RuntimeException("The fuck?");
}
// Clear the "final" marker on fields only if specified in control field
if (target.changeFinal && target.desc == "")
{
@@ -237,7 +302,7 @@ public class AccessTransformer implements IClassTransformer
if (args.length < 2)
{
System.out.println("Usage: AccessTransformer <JarPath> <MapFile> [MapFile2]... ");
return;
System.exit(1);
}
boolean hasTransformer = false;
@@ -259,7 +324,7 @@ public class AccessTransformer implements IClassTransformer
if (!hasTransformer)
{
System.out.println("Culd not find a valid transformer to perform");
return;
System.exit(1);
}
File orig = new File(args[0]);
@@ -267,13 +332,13 @@ public class AccessTransformer implements IClassTransformer
if (!orig.exists() && !temp.exists())
{
System.out.println("Could not find target jar: " + orig);
return;
System.exit(1);
}
if (!orig.renameTo(temp))
{
System.out.println("Could not rename file: " + orig + " -> " + temp);
return;
System.exit(1);
}
try
@@ -283,8 +348,9 @@ public class AccessTransformer implements IClassTransformer
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
if (!temp.delete())
{
System.out.println("Could not delete temp file: " + temp);
@@ -352,7 +418,7 @@ public class AccessTransformer implements IClassTransformer
for (AccessTransformer trans : transformers)
{
entryData = trans.transform(name, entryData);
entryData = trans.transform(name, name, entryData);
}
}
@@ -386,4 +452,11 @@ public class AccessTransformer implements IClassTransformer
}
}
}
}
public void ensurePublicAccessFor(String modClazzName)
{
Modifier m = new Modifier();
m.setTargetAccess("public");
m.modifyClassVisibility = true;
modifiers.put(modClazzName, m);
}
}
@@ -0,0 +1,54 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.tree.ClassNode;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.common.asm.transformers.deobf.FMLRemappingAdapter;
import cpw.mods.fml.relauncher.IClassNameTransformer;
import cpw.mods.fml.relauncher.IClassTransformer;
public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer {
@Override
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (bytes == null)
{
return null;
}
ClassReader classReader = new ClassReader(bytes);
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter);
classReader.accept(remapAdapter, ClassReader.EXPAND_FRAMES);
return classWriter.toByteArray();
}
@Override
public String remapClassName(String name)
{
return FMLDeobfuscatingRemapper.INSTANCE.map(name.replace('.','/')).replace('/', '.');
}
@Override
public String unmapClassName(String name)
{
return FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/','.');
}
}
@@ -1,22 +1,54 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.zip.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class MCPMerger
{
@@ -25,13 +57,15 @@ public class MCPMerger
private static Hashtable<String, ClassInfo> servers = new Hashtable<String, ClassInfo>();
private static HashSet<String> copyToServer = new HashSet<String>();
private static HashSet<String> copyToClient = new HashSet<String>();
private static HashSet<String> dontAnnotate = new HashSet<String>();
private static final boolean DEBUG = false;
public static void main(String[] args)
{
if (args.length != 3)
{
System.out.println("Usage: AccessTransformer <MapFile> <minecraft.jar> <minecraft_server.jar>");
return;
System.out.println("Usage: MCPMerger <MapFile> <minecraft.jar> <minecraft_server.jar>");
System.exit(1);
}
File map_file = new File(args[0]);
@@ -54,31 +88,31 @@ public class MCPMerger
if (!client_jar.exists())
{
System.out.println("Could not find minecraft.jar: " + client_jar);
return;
System.exit(1);
}
if (!server_jar.exists())
{
System.out.println("Could not find minecraft_server.jar: " + server_jar);
return;
System.exit(1);
}
if (!client_jar.renameTo(client_jar_tmp))
{
System.out.println("Could not rename file: " + client_jar + " -> " + client_jar_tmp);
return;
System.exit(1);
}
if (!server_jar.renameTo(server_jar_tmp))
{
System.out.println("Could not rename file: " + server_jar + " -> " + server_jar_tmp);
return;
System.exit(1);
}
if (!readMapFile(map_file))
{
System.out.println("Could not read map file: " + map_file);
return;
System.exit(1);
}
try
@@ -88,6 +122,7 @@ public class MCPMerger
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
if (!client_jar_tmp.delete())
@@ -112,10 +147,16 @@ public class MCPMerger
String line;
while ((line = br.readLine()) != null)
{
boolean toClient = line.charAt(0) == '<';
line = line.substring(1);
if (toClient) copyToClient.add(line);
else copyToServer.add(line);
line = line.split("#")[0];
char cmd = line.charAt(0);
line = line.substring(1).trim();
switch (cmd)
{
case '!': dontAnnotate.add(line); break;
case '<': copyToClient.add(line); break;
case '>': copyToServer.add(line); break;
}
}
in.close();
@@ -157,6 +198,8 @@ public class MCPMerger
}
Hashtable<String, ZipEntry> cClasses = getClassEntries(cInJar, cOutJar);
Hashtable<String, ZipEntry> sClasses = getClassEntries(sInJar, sOutJar);
HashSet<String> cAdded = new HashSet<String>();
HashSet<String> sAdded = new HashSet<String>();
for (Entry<String, ZipEntry> entry : cClasses.entrySet())
{
@@ -168,12 +211,18 @@ public class MCPMerger
{
if (!copyToServer.contains(name))
{
copyEntry(cInJar, cEntry, cOutJar);
copyClass(cInJar, cEntry, cOutJar, null, true);
cAdded.add(name);
}
else
{
System.out.println("Copy class c->s : " + name);
if (DEBUG)
{
System.out.println("Copy class c->s : " + name);
}
copyClass(cInJar, cEntry, cOutJar, sOutJar, true);
cAdded.add(name);
sAdded.add(name);
}
continue;
}
@@ -191,28 +240,34 @@ public class MCPMerger
cOutJar.write(data);
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
cAdded.add(name);
sAdded.add(name);
}
for (Entry<String, ZipEntry> entry : sClasses.entrySet())
{
if (!copyToClient.contains(entry.getKey()))
{
copyEntry(sInJar, entry.getValue(), sOutJar);
}
else
if (DEBUG)
{
System.out.println("Copy class s->c : " + entry.getKey());
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
}
copyClass(sInJar, entry.getValue(), cOutJar, sOutJar, false);
}
for (String name : new String[]{SideOnly.class.getName(), Side.class.getName()})
{
String eName = name.replace(".", "/");
byte[] data = getClassBytes(name);
ZipEntry newEntry = new ZipEntry(name.replace(".", "/").concat(".class"));
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
if (!cAdded.contains(eName))
{
cOutJar.putNextEntry(newEntry);
cOutJar.write(data);
}
if (!sAdded.contains(eName))
{
sOutJar.putNextEntry(newEntry);
sOutJar.write(data);
}
}
}
@@ -245,18 +300,28 @@ public class MCPMerger
ClassNode classNode = new ClassNode();
reader.accept(classNode, 0);
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
if (!dontAnnotate.contains(classNode.name))
{
if (classNode.visibleAnnotations == null) classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
classNode.visibleAnnotations.add(getSideAnn(isClientOnly));
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
byte[] data = writer.toByteArray();
ZipEntry newEntry = new ZipEntry(entry.getName());
outJar.putNextEntry(newEntry);
outJar.write(data);
outJar2.putNextEntry(newEntry);
outJar2.write(data);
if (outJar != null)
{
outJar.putNextEntry(newEntry);
outJar.write(data);
}
if (outJar2 != null)
{
outJar2.putNextEntry(newEntry);
outJar2.write(data);
}
}
private static AnnotationNode getSideAnn(boolean isClientOnly)
@@ -282,7 +347,9 @@ public class MCPMerger
String entryName = entry.getName();
if (!entryName.endsWith(".class") || entryName.startsWith("."))
{
copyEntry(inFile, entry, outFile);
ZipEntry newEntry = new ZipEntry(entry.getName());
outFile.putNextEntry(newEntry);
outFile.write(readEntry(inFile, entry));
}
else
{
@@ -291,12 +358,6 @@ public class MCPMerger
}
return ret;
}
private static void copyEntry(ZipFile inFile, ZipEntry entry, ZipOutputStream outFile) throws IOException
{
ZipEntry newEntry = new ZipEntry(entry.getName());
outFile.putNextEntry(newEntry);
outFile.write(readEntry(inFile, entry));
}
private static byte[] readEntry(ZipFile inFile, ZipEntry entry) throws IOException
{
return readFully(inFile.getInputStream(entry));
@@ -444,7 +505,10 @@ public class MCPMerger
mw.server = this.server | mw.server;
this.client = this.client | mw.client;
this.server = this.server | mw.server;
System.out.printf(" eq: %s %s\n", this, mw);
if (DEBUG)
{
System.out.printf(" eq: %s %s\n", this, mw);
}
}
return eq;
}
@@ -486,13 +550,19 @@ public class MCPMerger
serverName = sM.name;
if (!serverName.equals(lastName) && cPos != cLen)
{
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
if (DEBUG)
{
System.out.printf("Server -skip : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
break;
}
MethodWrapper mw = new MethodWrapper(sM);
mw.server = true;
allMethods.add(mw);
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
if (DEBUG)
{
System.out.printf("Server *add* : %s %s %d (%s %d) %d [%s]\n", sClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
sPos++;
}
while (sPos < sLen);
@@ -507,13 +577,19 @@ public class MCPMerger
clientName = cM.name;
if (!clientName.equals(lastName) && sPos != sLen)
{
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
if (DEBUG)
{
System.out.printf("Client -skip : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
break;
}
MethodWrapper mw = new MethodWrapper(cM);
mw.client = true;
allMethods.add(mw);
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
if (DEBUG)
{
System.out.printf("Client *add* : %s %s %d (%s %d) %d [%s]\n", cClass.name, clientName, cLen - cPos, serverName, sLen - sPos, allMethods.size(), lastName);
}
cPos++;
}
while (cPos < cLen);
@@ -524,7 +600,10 @@ public class MCPMerger
for (MethodWrapper mw : allMethods)
{
System.out.println(mw);
if (DEBUG)
{
System.out.println(mw);
}
cMethods.add(mw.node);
sMethods.add(mw.node);
if (mw.server && mw.client)
@@ -1,27 +1,26 @@
package cpw.mods.fml.common.asm.transformers;
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
package cpw.mods.fml.common.asm.transformers;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -29,20 +28,14 @@ import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
@@ -106,8 +99,9 @@ public class MarkerTransformer implements IClassTransformer
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (bytes == null) { return null; }
if (!markers.containsKey(name)) { return bytes; }
ClassNode classNode = new ClassNode();
@@ -258,7 +252,7 @@ public class MarkerTransformer implements IClassTransformer
for (MarkerTransformer trans : transformers)
{
entryData = trans.transform(name, entryData);
entryData = trans.transform(name, name, entryData);
}
}
@@ -292,4 +286,4 @@ public class MarkerTransformer implements IClassTransformer
}
}
}
}
}
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers;
import java.util.Iterator;
@@ -11,29 +23,43 @@ import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly;
import cpw.mods.fml.relauncher.FMLRelauncher;
import cpw.mods.fml.relauncher.IClassTransformer;
import cpw.mods.fml.relauncher.SideOnly;
public class SideTransformer implements IClassTransformer
{
private static String SIDE = FMLRelauncher.side();
private static final boolean DEBUG = false;
@SuppressWarnings("unchecked")
@Override
public byte[] transform(String name, byte[] bytes)
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (bytes == null) { return null; }
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
if (remove((List<AnnotationNode>)classNode.visibleAnnotations, SIDE))
{
if (DEBUG)
{
System.out.println(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
}
throw new RuntimeException(String.format("Attempted to load class %s for invalid side %s", classNode.name, SIDE));
}
Iterator<FieldNode> fields = classNode.fields.iterator();
while(fields.hasNext())
{
FieldNode field = fields.next();
if (remove((List<AnnotationNode>)field.visibleAnnotations, SIDE))
{
System.out.println("Removing Field: " + field.name);
if (DEBUG)
{
System.out.println(String.format("Removing Field: %s.%s", classNode.name, field.name));
}
fields.remove();
}
}
@@ -43,7 +69,10 @@ public class SideTransformer implements IClassTransformer
MethodNode method = methods.next();
if (remove((List<AnnotationNode>)method.visibleAnnotations, SIDE))
{
System.out.println("Removing Method: " + method.name + " " + method.desc);
if (DEBUG)
{
System.out.println(String.format("Removing Method: %s.%s%s", classNode.name, method.name, method.desc));
}
methods.remove();
}
}
@@ -52,7 +81,7 @@ public class SideTransformer implements IClassTransformer
classNode.accept(writer);
return writer.toByteArray();
}
private boolean remove(List<AnnotationNode> anns, String side)
{
if (anns == null)
@@ -0,0 +1,322 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers.deobf;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.commons.Remapper;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableBiMap.Builder;
import com.google.common.io.CharStreams;
import com.google.common.io.InputSupplier;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import cpw.mods.fml.relauncher.RelaunchClassLoader;
public class FMLDeobfuscatingRemapper extends Remapper {
public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper();
private BiMap<String, String> classNameBiMap;
private BiMap<String, String> mcpNameBiMap;
private Map<String,Map<String,String>> rawFieldMaps;
private Map<String,Map<String,String>> rawMethodMaps;
private Map<String,Map<String,String>> fieldNameMaps;
private Map<String,Map<String,String>> methodNameMaps;
private RelaunchClassLoader classLoader;
private FMLDeobfuscatingRemapper()
{
classNameBiMap=ImmutableBiMap.of();
mcpNameBiMap=ImmutableBiMap.of();
}
public void setup(File mcDir, RelaunchClassLoader classLoader, String deobfFileName)
{
this.classLoader = classLoader;
try
{
File libDir = new File(mcDir, "lib");
File mapData = new File(libDir, deobfFileName);
mapData = mapData.getCanonicalFile();
ZipFile mapZip = new ZipFile(mapData);
ZipEntry classData = mapZip.getEntry("joined.srg");
ZipInputSupplier zis = new ZipInputSupplier(mapZip, classData);
InputSupplier<InputStreamReader> srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8);
List<String> srgList = CharStreams.readLines(srgSupplier);
rawMethodMaps = Maps.newHashMap();
rawFieldMaps = Maps.newHashMap();
Builder<String, String> builder = ImmutableBiMap.<String,String>builder();
Builder<String, String> mcpBuilder = ImmutableBiMap.<String,String>builder();
Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults();
for (String line : srgList)
{
String[] parts = Iterables.toArray(splitter.split(line),String.class);
String typ = parts[0];
if ("CL".equals(typ))
{
parseClass(builder, parts);
parseMCPClass(mcpBuilder,parts);
}
else if ("MD".equals(typ))
{
parseMethod(parts);
}
else if ("FD".equals(typ))
{
parseField(parts);
}
}
classNameBiMap = builder.build();
// Special case some mappings for modloader mods
mcpBuilder.put("BaseMod","net/minecraft/src/BaseMod");
mcpBuilder.put("ModLoader","net/minecraft/src/ModLoader");
mcpBuilder.put("EntityRendererProxy","net/minecraft/src/EntityRendererProxy");
mcpBuilder.put("MLProp","net/minecraft/src/MLProp");
mcpBuilder.put("TradeEntry","net/minecraft/src/TradeEntry");
mcpNameBiMap = mcpBuilder.build();
}
catch (IOException ioe)
{
FMLRelaunchLog.log(Level.SEVERE, ioe, "An error occurred loading the deobfuscation map data");
}
methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size());
fieldNameMaps = Maps.newHashMapWithExpectedSize(rawFieldMaps.size());
}
public boolean isRemappedClass(String className)
{
return classNameBiMap.containsKey(className) || mcpNameBiMap.containsKey(className);
}
private void parseField(String[] parts)
{
String oldSrg = parts[1];
int lastOld = oldSrg.lastIndexOf('/');
String cl = oldSrg.substring(0,lastOld);
String oldName = oldSrg.substring(lastOld+1);
String newSrg = parts[2];
int lastNew = newSrg.lastIndexOf('/');
String newName = newSrg.substring(lastNew+1);
if (!rawFieldMaps.containsKey(cl))
{
rawFieldMaps.put(cl, Maps.<String,String>newHashMap());
}
rawFieldMaps.get(cl).put(oldName, newName);
}
private void parseClass(Builder<String, String> builder, String[] parts)
{
builder.put(parts[1],parts[2]);
}
private void parseMCPClass(Builder<String, String> builder, String[] parts)
{
int clIdx = parts[2].lastIndexOf('/');
builder.put("net/minecraft/src/"+parts[2].substring(clIdx+1),parts[2]);
}
private void parseMethod(String[] parts)
{
String oldSrg = parts[1];
int lastOld = oldSrg.lastIndexOf('/');
String cl = oldSrg.substring(0,lastOld);
String oldName = oldSrg.substring(lastOld+1);
String sig = parts[2];
String newSrg = parts[3];
int lastNew = newSrg.lastIndexOf('/');
String newName = newSrg.substring(lastNew+1);
if (!rawMethodMaps.containsKey(cl))
{
rawMethodMaps.put(cl, Maps.<String,String>newHashMap());
}
rawMethodMaps.get(cl).put(oldName+sig, newName);
}
@Override
public String mapFieldName(String owner, String name, String desc)
{
if (classNameBiMap == null || classNameBiMap.isEmpty())
{
return name;
}
Map<String, String> fieldMap = getFieldMap(owner);
return fieldMap!=null && fieldMap.containsKey(name) ? fieldMap.get(name) : name;
}
@Override
public String map(String typeName)
{
if (classNameBiMap == null || classNameBiMap.isEmpty())
{
return typeName;
}
int dollarIdx = typeName.indexOf('$');
String realType = dollarIdx > -1 ? typeName.substring(0, dollarIdx) : typeName;
String subType = dollarIdx > -1 ? typeName.substring(dollarIdx+1) : "";
String result = classNameBiMap.containsKey(realType) ? classNameBiMap.get(realType) : mcpNameBiMap.containsKey(realType) ? mcpNameBiMap.get(realType) : realType;
result = dollarIdx > -1 ? result+"$"+subType : result;
// System.out.printf("Mapping %s=>%s\n",typeName,result);
return result;
}
public String unmap(String typeName)
{
if (classNameBiMap == null || classNameBiMap.isEmpty())
{
return typeName;
}
int dollarIdx = typeName.indexOf('$');
String realType = dollarIdx > -1 ? typeName.substring(0, dollarIdx) : typeName;
String subType = dollarIdx > -1 ? typeName.substring(dollarIdx+1) : "";
String result = classNameBiMap.containsValue(realType) ? classNameBiMap.inverse().get(realType) : mcpNameBiMap.containsValue(realType) ? mcpNameBiMap.inverse().get(realType) : realType;
result = dollarIdx > -1 ? result+"$"+subType : result;
// System.out.printf("Unmapping %s=>%s\n",typeName,result);
return result;
}
@Override
public String mapMethodName(String owner, String name, String desc)
{
if (classNameBiMap==null || classNameBiMap.isEmpty())
{
return name;
}
Map<String, String> methodMap = getMethodMap(owner);
String methodDescriptor = name+desc;
return methodMap!=null && methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name;
}
private Map<String,String> getFieldMap(String className)
{
if (!fieldNameMaps.containsKey(className))
{
findAndMergeSuperMaps(className);
}
return fieldNameMaps.get(className);
}
private Map<String,String> getMethodMap(String className)
{
if (!methodNameMaps.containsKey(className))
{
findAndMergeSuperMaps(className);
}
return methodNameMaps.get(className);
}
private void findAndMergeSuperMaps(String name)
{
try
{
byte[] classBytes = classLoader.getClassBytes(name);
if (classBytes == null)
{
return;
}
ClassReader cr = new ClassReader(classBytes);
String superName = cr.getSuperName();
String[] interfaces = cr.getInterfaces();
if (interfaces == null)
{
interfaces = new String[0];
}
mergeSuperMaps(name, superName, interfaces);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void mergeSuperMaps(String name, String superName, String[] interfaces)
{
// System.out.printf("Computing super maps for %s: %s %s\n", name, superName, Arrays.asList(interfaces));
if (classNameBiMap == null || classNameBiMap.isEmpty())
{
return;
}
// Skip Object
if (Strings.isNullOrEmpty(superName))
{
return;
}
List<String> allParents = ImmutableList.<String>builder().add(superName).addAll(Arrays.asList(interfaces)).build();
// generate maps for all parent objects
for (String parentThing : allParents)
{
if (!methodNameMaps.containsKey(parentThing))
{
findAndMergeSuperMaps(parentThing);
}
}
Map<String, String> methodMap = Maps.<String,String>newHashMap();
Map<String, String> fieldMap = Maps.<String,String>newHashMap();
for (String parentThing : allParents)
{
if (methodNameMaps.containsKey(parentThing))
{
methodMap.putAll(methodNameMaps.get(parentThing));
}
if (fieldNameMaps.containsKey(parentThing))
{
fieldMap.putAll(fieldNameMaps.get(parentThing));
}
}
if (rawMethodMaps.containsKey(name))
{
methodMap.putAll(rawMethodMaps.get(name));
}
if (rawFieldMaps.containsKey(name))
{
fieldMap.putAll(rawFieldMaps.get(name));
}
methodNameMaps.put(name, ImmutableMap.copyOf(methodMap));
fieldNameMaps.put(name, ImmutableMap.copyOf(fieldMap));
// System.out.printf("Maps: %s %s\n", name, methodMap);
}
}
@@ -0,0 +1,35 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers.deobf;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.commons.RemappingClassAdapter;
public class FMLRemappingAdapter extends RemappingClassAdapter {
public FMLRemappingAdapter(ClassVisitor cv)
{
super(cv, FMLDeobfuscatingRemapper.INSTANCE);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
{
if (interfaces == null)
{
interfaces = new String[0];
}
FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces);
super.visit(version, access, name, signature, superName, interfaces);
}
}
@@ -0,0 +1,38 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.asm.transformers.deobf;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import com.google.common.io.InputSupplier;
public class ZipInputSupplier implements InputSupplier<InputStream> {
private ZipFile zipFile;
private ZipEntry zipEntry;
public ZipInputSupplier(ZipFile zip, ZipEntry entry)
{
this.zipFile = zip;
this.zipEntry = entry;
}
@Override
public InputStream getInput() throws IOException
{
return zipFile.getInputStream(zipEntry);
}
}
@@ -1,7 +1,17 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -10,12 +20,10 @@ import com.google.common.base.Predicate;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.ImmutableBiMap.Builder;
import cpw.mods.fml.common.ModContainer;
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.util.List;
@@ -29,4 +41,4 @@ public enum ContainerType
{
return discoverer.discover(candidate, table);
}
}
}
@@ -1,19 +1,30 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.regex.Matcher;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.MetadataCollection;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModContainerFactory;
@@ -54,12 +65,14 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
try
{
FileInputStream fis = new FileInputStream(metadata);
mc = MetadataCollection.from(fis);
mc = MetadataCollection.from(fis,modDir.getName());
fis.close();
FMLLog.fine("Found an mcmod.info file in directory %s", modDir.getName());
}
catch (Exception e)
{
mc = MetadataCollection.from(null);
mc = MetadataCollection.from(null,"");
FMLLog.fine("No mcmod.info file found in directory %s", modDir.getName());
}
}
@@ -86,6 +99,11 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
modParser = new ASMModParser(fis);
fis.close();
}
catch (LoaderException e)
{
FMLLog.log(Level.SEVERE, e, "There was a problem reading the file %s - probably this is a corrupt file", file.getPath());
throw e;
}
catch (Exception e)
{
Throwables.propagate(e);
@@ -93,7 +111,7 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
modParser.validate();
modParser.sendToTable(table, candidate);
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
if (container!=null)
{
harvestedMods.add(container);
@@ -1,3 +1,15 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.util.List;
@@ -1,8 +1,20 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -10,6 +22,7 @@ import java.util.zip.ZipFile;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
import cpw.mods.fml.common.MetadataCollection;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModContainerFactory;
@@ -32,17 +45,36 @@ public class JarDiscoverer implements ITypeDiscoverer
if (modInfo != null)
{
FMLLog.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName());
mc = MetadataCollection.from(jar.getInputStream(modInfo));
mc = MetadataCollection.from(jar.getInputStream(modInfo), candidate.getModContainer().getName());
}
else
{
FMLLog.fine("The mod container %s appears to be missing an mcmod.info file", candidate.getModContainer().getName());
mc = MetadataCollection.from(null, "");
}
for (ZipEntry ze : Collections.list(jar.entries()))
{
if (ze.getName()!=null && ze.getName().startsWith("__MACOSX"))
{
continue;
}
Matcher match = classFile.matcher(ze.getName());
if (match.matches())
{
ASMModParser modParser = new ASMModParser(jar.getInputStream(ze));
ASMModParser modParser;
try
{
modParser = new ASMModParser(jar.getInputStream(ze));
}
catch (LoaderException e)
{
FMLLog.log(Level.SEVERE, e, "There was a problem reading the entry %s in the jar %s - probably a corrupt zip", ze.getName(), candidate.getModContainer().getPath());
jar.close();
throw e;
}
modParser.validate();
modParser.sendToTable(table, candidate);
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer());
ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
if (container!=null)
{
table.addContainer(container);
@@ -54,7 +86,7 @@ public class JarDiscoverer implements ITypeDiscoverer
}
catch (Exception e)
{
FMLLog.warning("Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
FMLLog.log(Level.WARNING, e, "Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
}
finally
{
@@ -1,9 +1,25 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.util.List;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.discovery.asm.ASMModParser;
public class ModCandidate
@@ -12,16 +28,20 @@ public class ModCandidate
private File modContainer;
private ContainerType sourceType;
private boolean classpath;
private List<String> baseModTypes = Lists.newArrayList();
private boolean isMinecraft;
private List<ASMModParser> baseModCandidateTypes = Lists.newArrayListWithCapacity(1);
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType)
{
this(classPathRoot, modContainer, sourceType, false);
this(classPathRoot, modContainer, sourceType, false, false);
}
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean classpath)
public ModCandidate(File classPathRoot, File modContainer, ContainerType sourceType, boolean isMinecraft, boolean classpath)
{
this.classPathRoot = classPathRoot;
this.modContainer = modContainer;
this.sourceType = sourceType;
this.isMinecraft = isMinecraft;
this.classpath = classpath;
}
@@ -41,6 +61,36 @@ public class ModCandidate
}
public List<ModContainer> explore(ASMDataTable table)
{
return sourceType.findMods(this, table);
List<ModContainer> mods = sourceType.findMods(this, table);
if (!baseModCandidateTypes.isEmpty())
{
FMLLog.info("Attempting to reparse the mod container %s", getModContainer().getName());
return sourceType.findMods(this, table);
}
else
{
return mods;
}
}
}
public boolean isClasspath()
{
return classpath;
}
public void rememberBaseModType(String className)
{
baseModTypes.add(className);
}
public List<String> getRememberedBaseMods()
{
return baseModTypes;
}
public boolean isMinecraftJar()
{
return isMinecraft;
}
public void rememberModCandidateType(ASMModParser modParser)
{
baseModCandidateTypes.add(modParser);
}
}
@@ -1,44 +1,27 @@
/*
* Forge Mod Loader
* Copyright (c) 2012-2013 cpw.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* cpw - implementation
*/
package cpw.mods.fml.common.discovery;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Tables;
import com.google.common.collect.ImmutableTable.Builder;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
@@ -54,6 +37,8 @@ public class ModDiscoverer
private ASMDataTable dataTable = new ASMDataTable();
private List<File> nonModLibs = Lists.newArrayList();
public void findClasspathMods(ModClassLoader modClassLoader)
{
List<String> knownLibraries = ImmutableList.<String>builder().addAll(modClassLoader.getDefaultLibraries()).addAll(RelaunchLibraryManager.getLibraries()).build();
@@ -61,7 +46,7 @@ public class ModDiscoverer
if (minecraftSources.length == 1 && minecraftSources[0].isFile())
{
FMLLog.fine("Minecraft is a file at %s, loading", minecraftSources[0].getAbsolutePath());
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR));
candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR, true, true));
}
else
{
@@ -71,18 +56,18 @@ public class ModDiscoverer
{
if (knownLibraries.contains(minecraftSources[i].getName()))
{
FMLLog.fine("Skipping known library file %s", minecraftSources[i].getAbsolutePath());
FMLLog.finer("Skipping known library file %s", minecraftSources[i].getAbsolutePath());
}
else
{
FMLLog.fine("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, true));
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, i==0, true));
}
}
else if (minecraftSources[i].isDirectory())
{
FMLLog.fine("Found a minecraft related directory at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath());
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, true));
candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, i==0, true));
}
}
}
@@ -128,7 +113,14 @@ public class ModDiscoverer
try
{
List<ModContainer> mods = candidate.explore(dataTable);
modList.addAll(mods);
if (mods.isEmpty() && !candidate.isClasspath())
{
nonModLibs.add(candidate.getModContainer());
}
else
{
modList.addAll(mods);
}
}
catch (LoaderException le)
{
@@ -148,4 +140,9 @@ public class ModDiscoverer
return dataTable;
}
public List<File> getNonModLibs()
{
return nonModLibs;
}
}
Loaded 100 of 395 files, more files were not shown because too many files have changed in this diff. Show more