Compare commits

..
1333 Commits
Author SHA1 Message Date
Christian b852e30285 First functional release under reobfuscation. 2013-12-12 18:01:09 -05:00
Christian 7ea571f593 Fix AT, Fix exc. Almost works now! 2013-12-12 01:39:30 -05:00
Lex Manos 7a4ceebf5e Kill old patches and add rejects to ignore file. 2013-12-11 20:39:15 -08:00
Christian 31efcfc3b2 Clean up patches for latest exc. 2013-12-11 23:03:30 -05:00
Christian 49cb893d12 Fix exc this time *sigh* 2013-12-11 22:58:46 -05:00
Christian 009d4dee23 Fix the exc file. Fix the deobfremapper for handling inner classes. 2013-12-11 22:54:51 -05:00
Christian 3e278acb71 Fix stupid possible compiler error. 2013-12-11 20:17:08 -05:00
Christian d0d31d9575 SpawnAdjustment packet. Clean up stuffs. No more compile errors. 2013-12-11 19:29:52 -05:00
Christian ef492407ef Entity spawning works. 2013-12-11 18:46:25 -05:00
Christian cd417c6786 Fixed remote and local connections work with mods now. 2013-12-11 12:35:08 -05:00
Christian 89e4e483c2 Add in a remapping event for mods to consume. 2013-12-10 19:25:49 -05:00
Christian fd36f50d82 Cleanups 2013-12-10 17:29:26 -05:00
Christian 1d71c017f4 ID syncing. 2013-12-10 14:32:06 -05:00
Lex Manos 99c681ad87 Did it manually, forgot it needed the end comma 2013-12-09 20:49:37 -08:00
Lex Manos 57f7f1d7ab Update for fixed Enum cleaning and names. 2013-12-09 20:44:17 -08:00
Lex Manos b2550b8a69 Add mappings for Items/Blocks fields. 2013-12-09 20:43:57 -08:00
Lex Manos a30f173627 Add sonatype snapshots repo for SpecialSource snapshots. 2013-12-09 20:43:27 -08:00
Christian 2aaaeba15e ID loading from the server save now works. 2013-12-09 21:36:49 -05:00
Christian 9c96a0a10a More network stuff, partially done id syncing. 2013-12-09 01:22:24 -05:00
Christian f5c38e2359 OK, network channels appear to be working well for both dedi and integrated servers.
The beginnings of the new mod structure too.
2013-12-06 14:52:33 -05:00
Christian e544adba5c More cleanup. Bidirectional server <-> client network works for mods as well as FML|HS now. 2013-12-06 11:17:40 -05:00
Christian 58f7487cfa Check in patches. Add in some network timeout tweaking values so you can debug the network. 2013-12-06 08:07:09 -05:00
Christian 9f928963f2 A network design I like. It uses the netty embedded channel to allow mods to build channel pipelines on top of
custom payload packets.
2013-12-06 03:11:03 -05:00
Christian 38cec7a11f The basic network handshaking for FML is done. All scenarios seem to work. 2013-12-04 00:11:08 -05:00
Christian 7ab3c3a37c Update gitignore 2013-12-02 23:54:15 -05:00
Christian 53127eec30 Merge branch 'master' of github.com:MinecraftForge/FML
Conflicts:
	install/build.gradle
	patches/minecraft/net/minecraft/client/multiplayer/NetClientHandler.java.patch
	patches/minecraft/net/minecraft/network/NetServerHandler.java.patch
2013-12-02 23:52:27 -05:00
Christian 30d532f4fc Pass 1: Most patches are restored.
NOTES: 1. Network is completely broken. 2. GameRegistry is partially broken. 3. ID sync is not in.
2013-12-02 23:48:26 -05:00
cpw 01fb451b69 Merge pull request #311 from AbrarSyed/patch-3
fix derp in example builscript
2013-11-27 02:13:42 -08:00
Abrar Syed 3714426e19 fix derp in example builscript 2013-11-26 14:23:31 -06:00
Lex Manos c2b919d339 Don't validate signatures in dev env. 2013-11-20 13:18:26 -08:00
Lex Manos c4b8a393f9 Make the working directory the root of the eclipse workspace. 2013-11-17 19:26:21 -08:00
LexManos 30894f7afa Merge pull request #307 from AbrarSyed/master
updated samples
2013-11-17 17:58:01 -08:00
AbrarSyed e9a7660cb8 updated samples 2013-11-17 18:21:24 -06:00
LexManos 4d46abf761 Merge pull request #306 from MinecraftForge/1.6.4
Actually do it correctly. Should be more forge friendly now.
2013-11-17 10:04:27 -08:00
Christian 23baf3a8ce Actually do it correctly. Should be more forge friendly now. 2013-11-13 19:10:11 -05:00
Christian c6a21d0d62 Merge branch '1.6.4' 2013-11-13 07:55:12 -05:00
Christian da72640c7e Way to go, missing import. *sigh* 2013-11-13 07:45:37 -05:00
Christian b7f34629c3 Don't try and open GUIs on the server. 2013-11-12 18:04:25 -05:00
Christian 5500d69b77 Merge branch '1.6.4' 2013-11-12 17:02:08 -05:00
pahimar 6af42bc656 Add in null protection for client/server sides of handleChat 2013-11-11 14:12:02 -05:00
Christian e19fcb8844 Kill more references to modloader. 2013-11-10 13:15:26 -05:00
Christian 0a62333890 Remove all public all the time from Minecraft. It is unnecessary with ModLoader gone. DEAL WITH IT. File AT public requests, make a coremod, whatever. This needed to die. 2013-11-10 12:01:26 -05:00
Christian e7512f13e4 Deprecation cleanup. Bye bye more modloader stuffs 2013-11-10 11:58:34 -05:00
Christian 4708d77c98 First pass : kill modloader, clean up warnings 2013-11-10 11:49:06 -05:00
Lex Manos 9b1d2bdd13 Join the developers list in the pom and fix the client run configs in the workspace. 2013-11-09 19:22:17 -08:00
LexManos a6dc03aa7e Merge pull request #302 from AbrarSyed/patch-1
Update 1.6.4-rel.json
2013-11-09 19:15:34 -08:00
Abrar Syed 6cd8349542 Update 1.6.4-rel.json 2013-11-09 21:14:58 -06:00
Christian 976c589c78 Change the build to capture an MCP version, also, tweak the sources so mavenLocal can be used for ForgeGradle 2013-11-09 20:00:05 -05:00
Christian 24ec338a51 Fix license and naming 2013-11-09 14:28:54 -05:00
AbrarSyed 4f634855ac added src distribution gradle file 2013-11-09 14:28:54 -05:00
Lex Manos 9f01e3407e Move to install to not clutter root directory with the .bat and .sh files I know are coming. 2013-11-09 14:28:54 -05:00
Lex Manos adeaeb74aa Include eclipse template workspace, for packaging in src distro. 2013-11-09 14:28:54 -05:00
Lex Manos e13c3966e0 Add gradle wrapper 2013-11-09 14:28:53 -05:00
Lex Manos 02c3b4e74b Publish to repo folder for local testing. 2013-11-09 14:28:53 -05:00
AbrarSyed 89a07d3668 Step 3: The Rebirth 2013-11-09 14:28:53 -05:00
Lex Manos b52eb6d699 Step 2: The Reformation 2013-11-09 14:28:53 -05:00
AbrarSyed 3281faf2be Step 1: The Purge 2013-11-09 14:28:53 -05:00
Christian 3d25b4e793 Add in the ability to strip interface references for specific interfaces - this is probably mostly useful for
scala scenarios where sythetic methods are generated and is not a substitute for using Optional.Method where appropriate.
Closes #300
2013-11-09 14:27:15 -05:00
Christian f4532410ec Change a couple of warnings, as a prelude to 1.7- preinit is now required for all GameRegistry activity, and every item and block REQUIRES registration. 2013-11-06 16:18:41 -05:00
Christian 8f87021b0f Fix derp with custom properties. They work now! 2013-11-05 22:23:24 -05:00
Christian bc57ff9e83 Fix recursive API dependency resolution. Allows nested APIs, such as BuildCraft's 2013-10-31 09:39:34 -04:00
Christian de8ab934d8 Fix up duplicate entries 2013-10-30 22:46:19 -04:00
Christian 81fe1c9682 Add in an API marker for API type packages.
This does several things:
1. Packages marked as API will generate a new "modid" (the provides) that can be depended on.
2. Packages marked as API will be searched systemwide, and anything declaring that package (even without the API marker)
will get an implicit dependency on the API package.
3. The API package itself will get a soft dependency on the "owner" package.

@Optional elements can refer to the API packages instead of a concrete mod as well.
2013-10-30 22:20:28 -04:00
Christian 58a299aabc Attempt to inject coremods as tweakers, so both can share a dependency ordering 2013-10-27 13:28:50 -04:00
Christian 243a21a353 Wrapping coremods as tweakers. Part 1. 2013-10-20 11:53:07 +02:00
Christian f0dc530b28 Fix up documentation of VersionCheckHandler - it only ever accepted a String and only works on the NetworkMod annotated class 2013-10-20 11:45:00 +02:00
Christian dac7f590ea Modify ordering of networkmod registration and mod instantiation. This fixes VersionCheckHandler logging an incorrect failure message due
to NPE.
2013-10-20 11:41:28 +02:00
Lex Manos bf54d4d667 Make each mod's EventBus log a child of it's main logger. 2013-10-19 18:24:24 -07:00
Christian da4337efbf Fix up handling the new method signature data for NetworkCheckHandlers 2013-10-14 21:28:15 -04:00
Christian f92962bbbb Use null to empty, so missing values work. *sigh* 2013-10-13 22:36:47 -04:00
Christian 2714da1022 Primitive capability for tweakers to order. Add a "TweakOrder" integer
property to your manifest, or accept the default of zero.
2013-10-12 10:28:11 -04:00
LexManos 96be82343c Merge pull request #280 from mc10/patch-1
Very minor style fixes
2013-10-09 20:56:05 -07:00
Kevin Ji 58577775d2 Very minor style fixes
Replacing tabs with spaces consistently, making brace styles consistent, etc.
2013-10-09 19:53:50 -07:00
Christian fc3e7647d2 Support, and fix up, interface lists for Optional 2013-10-09 13:58:14 -04:00
Lex Manos a381874bb9 Delay sound system backend initalization to speed up startup and prevent race condition on some computers. 2013-10-06 11:13:07 -07:00
Christian 55525f6d2e ModLoader is officially deprecated. It will all cease to be with 1.7. 2013-10-06 11:06:31 -04:00
Christian bc64ceabef Optional shouldn't be constructable itself. It's purely a wrapper thing. 2013-10-06 10:56:47 -04:00
Christian 63ba3aa009 Add in support for Optional interfaces and methods. Be gone coremods! 2013-10-04 17:20:05 -04:00
Christian 5265e34a35 Fix null killing the server 2013-09-29 15:51:38 -04:00
Lex Manos 35ab9f52b0 Fix md5s for new checksums.sha1 in scala libraries. 2013-09-28 19:47:32 -07:00
Christian 9b55f1f48f Attempt at a shared modlist implementation - should allow visibility between liteloader and fml for "mod list display" 2013-09-27 10:45:20 -04:00
Christian e356f4d713 Cross-modsystem compatibility fix with thanks to Mumfrey @ liteloader 2013-09-27 10:01:39 -04:00
Christian bfc25bc5da Add to both the classloader and the parent 2013-09-26 13:01:00 -04:00
Christian 9f0f9e7288 Fix deobf tweaker 2013-09-26 10:11:29 -04:00
Christian ce6404fd5b TYPOS!!! 2013-09-26 09:33:48 -04:00
Christian 8f18a3de9a Separate deobf tweaker so it runs last. Should fix problems with cascaded tweakers
expecting an obf environment.
2013-09-26 09:23:25 -04:00
Christian 9815d8c379 Update for launchwrapper 1.8 2013-09-25 16:40:59 -04:00
Christian 1d902df581 Use the negative cache in latest legacylauncher. 2013-09-25 11:46:11 -04:00
Christian 8e26c99de3 Add debugging for deobfuscation
Add negative caching for field and method maps. Should shortcut some work

Fix handling the case where a class doesn't exist, but still needs deobf

Ask the patch manager for the bytes for the class, not the classLoader

Fix up some more places where we should look for a patched class

Fix problem with empty source classes and runtime deobfuscation
2013-09-25 07:37:25 -04:00
Lex Manos fc8c3bef03 Update to new installer that uses xz compression and better support for non-standard jvms 2013-09-24 23:21:17 -07:00
Christian a4de22c1ad And use the parent that's actually going to be valid. *sigh* 2013-09-24 08:42:13 -04:00
Christian 70cffe6982 Herpaderp. Make addURL accessible. *sigh* 2013-09-24 07:33:11 -04:00
Christian 39620f1e41 Fix injection of tweaker into system 2013-09-23 13:33:16 -04:00
cpw 0e80fcb8f7 Merge pull request #284 from smcv/uninit
Fix NPE when loading second single-player world
2013-09-22 18:24:56 -07:00
Simon McVittie 4a94c2c71b Fix NPE when loading second single-player world
After leaving a single-player world, getServer() can return null, resulting
in the stack trace below, "Fatal errors were detected during the
transition from SERVER_STOPPING to SERVER_ABOUT_TO_START",
"The ForgeModLoader state engine has become corrupted" and the client
getting stuck forever.

Exception in thread "Server thread" java.lang.NullPointerException
at cpw.mods.fml.client.FMLClientHandler.serverStopped(FMLClientHandler.java:620)
at cpw.mods.fml.common.FMLCommonHandler.handleServerStopped(FMLCommonHandler.java:468)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:471)
at net.minecraft.server.ThreadMinecraftServer.run(SourceFile:583)
2013-09-22 16:56:24 +01:00
Christian 79c39f8b7c Fix classpath for launchwrapper 1.7 2013-09-21 16:15:05 -04:00
Christian f6190e8752 Update workspaces for 1.6.4 2013-09-20 17:23:18 -04:00
Christian 0950b9fc84 Fix up a deep crash in the early server init hanging the client 2013-09-20 17:12:01 -04:00
Christian 25981706ef Update for MC 1.6.4 2013-09-20 16:25:12 -04:00
Lex Manos 82d896a35e Make final transformers actually work on methods as well. 2013-09-19 12:59:12 -07:00
Christian e7dd728f95 Format the log messages through MessageFormat. Thanks CovertJaguar for the pointer. Closes #282 2013-09-19 08:23:56 -04:00
Lex Manos 8f2e675581 Update the src distro's eclipse workspace. 2013-09-18 15:21:56 -07:00
Christian ff75416a32 Update mc_versions data and commands patch and eclipse workspace 2013-09-18 18:01:04 -04:00
Christian 95afc95b24 Update mcp mod info 2013-09-18 17:02:41 -04:00
Christian 34493b0d99 Update for real 1.6.3 update 2013-09-18 16:59:28 -04:00
Christian e77d2547ad Update for pre-ninja 1.6.3 update 2013-09-18 16:33:11 -04:00
Christian 40a34af431 Merge branch 'master' into newtweak 2013-09-18 14:49:53 -04:00
Christian 352117fd78 Update for new installer and thank you. 2013-09-17 21:56:25 -04:00
Christian 81328b6684 Add in support for using a mirror list and provide checksums for packed download of libs 2013-09-15 22:58:39 -04:00
Christian b5af446d71 Fix sidedness derp in LanguageRegistry. 2013-09-13 19:04:25 -05:00
Christian d0c6e92900 Update MCP data 2013-09-03 17:56:09 -04:00
Christian 2a9c485edc Remove @SideOnly from 70318 (getDistance) it makes no sense that it's not on the server. 2013-09-02 12:24:17 -04:00
Christian a13598b17e Use java 1.6 compatible method of closing the zip file. Stops stupid compile error. 2013-09-02 00:12:36 -04:00
Christian 40b54013b4 Allow server side lang file injection, hopefully 2013-08-27 22:45:10 -04:00
Christian 1c9a853868 Allow coremods to properly inject asset readers. 2013-08-27 12:31:37 -04:00
Christian da70cdd35a Update tweaker for new Launcher API 2013-08-23 10:42:26 -04:00
Christian b993cf4a98 More exception handling for less derpiness. 2013-08-20 20:46:18 -04:00
Christian ac065ff5f7 Reset the IWorldGenerator seed for each mod, before calling. That should mean worldgen is consistent
and not dependent on mod ordering, or mod sideeffects.
2013-08-19 14:56:01 -04:00
Christian 913f6f6d36 Try and use the relaunch log, which should be classloaded.. 2013-08-19 14:55:37 -04:00
Christian 9468e41bbf Fix up scala refs, for better results 2013-08-18 18:58:36 -04:00
Christian ffdd056a18 Check keys, not values *sigh* 2013-08-17 13:27:43 -04:00
Christian f157e7a6ec And more coremod logging 2013-08-17 13:14:55 -04:00
Christian 4a9d0f9bd5 Add in some log information 2013-08-17 13:10:28 -04:00
Christian 0398916666 And actually instantiate the collection *sigh* 2013-08-17 12:57:15 -04:00
Christian dec9a3924d Add in "FMLCorePluginContainsMod" in the manifest. If this value is
present, FML will attempt to parse your mod jar file as a normal mod
file as well, instantiating mod containers there.
2013-08-17 12:48:38 -04:00
Christian 2470120680 Clean up a couple of resources. Also, don't parse jars just because
they're in the mods dir
2013-08-17 11:40:15 -04:00
Christian ba90b61607 Make sure we only add args to the argument list if a tweaker hasn't already.
Should fix LiteLoader compatibility issue.
2013-08-16 16:28:55 -04:00
Christian 9a5e24e338 Fix stupid derp is stupid. Closes #275 and means sp614x can do his thing 2013-08-16 16:18:50 -04:00
LexManos 29ef3d5ab4 Update installer. 2013-08-06 11:42:38 -07:00
LexManos f46a538b41 Merge pull request #268 from Bo98/sh-args-fix
Fixed install.sh not passing arguments to install.py
2013-08-04 15:32:06 -07:00
Bo 182aa9c0cb Fixed install.sh not passing arguments to install.py 2013-08-03 17:43:57 +01:00
cpw 1857064afa Merge pull request #266 from grompe/patch-1
Add missing SideOnly in BaseMod
2013-08-01 04:21:22 -07:00
Grom PE cb05c8c4aa Add missing SideOnly in BaseMod
NetClientHandler exists only on client side and thus method using it should be annotated with SideOnly.
2013-08-01 14:19:30 +07:00
cpw f275a24b43 Add in some reverse lookup methods for game registry data 2013-07-29 22:05:22 +02:00
cpw 1d84e8063e Temporarily add a version of 'reobfuscate.py' that will resolve complex
reobfuscation graph issues with specialsource. Copy it over 'reobfuscate.py'
in the mcp runtime dir. Hopefully will have an MCP/specialsource fix in
the coming days.
2013-07-28 22:38:26 +02:00
cpw 57befa89bb Fix keybindings being derped 2013-07-28 20:52:12 +02:00
LexManos 10b16d32da Use json 2.9.1 nightly for OSX in release json like vanilla does. 2013-07-17 12:21:26 -07:00
LexManos 3f21a2c1b4 Stupid spaces and windows escaping -.- 2013-07-16 14:34:43 -07:00
LexManos b2958c9066 Add quotes for paths with spaces -.- 2013-07-16 13:35:14 -07:00
LexManos 9520978b81 Use a temporary file for recompile's command line to combat command length to long issues. 2013-07-16 13:08:26 -07:00
LexManos 4981aa3421 Fix potential NPE in villager skin registry. 2013-07-16 10:32:29 -07:00
LexManos c48b48ee15 Fix server launching. 2013-07-15 10:57:44 -07:00
Christian 9947ba8503 Fix logo handling. no more NPE if the logo can't be found. Also, fix location of mcp logo now. 2013-07-14 13:40:55 -04:00
Christian a3f48734ff Fix up jar sanity check code. FML validation of the jar works now and doesn't derp classloading. 2013-07-14 13:11:32 -04:00
Christian 0378355c37 The server.classpath generates the runtime manifest, so it needs the
non-debug asm jars.
2013-07-14 11:12:42 -04:00
LexManos c625ef3009 Update Forge signature for new private key 2013-07-12 03:05:20 -07:00
LexManos d4b30422b6 Update build and eclipse workspaces for debug asm. 2013-07-12 00:22:11 -07:00
Christian 6de36d78f5 Coremods now have a primitive dependency capability. Also, we search mods dir for special
"TweakClass" manifests. These are using the vanilla tweak mechanism to inject into
Minecraft. Helpful for other "platform" systems, when you don't want to have to deal
with json changes!
2013-07-11 23:23:33 -04:00
LexManos 7348929819 Kill release time scala libraries, to be re-evaluated after all movement is done and shit is fixed. May require manual instalation for mods that use scala. 2013-07-11 15:24:54 -07:00
LexManos b9f4b02cb0 Kill mcp's truncate method, for more useful logs. 2013-07-10 15:23:21 -07:00
Christian 20e93a412e Fix up logos in the mod screen. Clean up some unnecessary casts and suppressions, use the -debug asm
library at dev time, since it contains full symbols and code in compiled form.
2013-07-10 15:47:13 -04:00
Christian e44e8b3112 Force a global asset scan prior to mod construction : you should be able to
reference assets anywhere in your mod now.
2013-07-10 00:42:40 -04:00
Christian bab4d87ce7 Update FML for new stealth update for 1.6.2 2013-07-09 15:00:28 -04:00
cpw bc9d1fe657 Merge pull request #254 from CaptainShadows/patch-1
@InstanceFactory was set to look for Fields instead of methods
2013-07-09 07:19:24 -07:00
Christian d4d522c597 And don't forget to remove the test code 2013-07-09 08:31:40 -04:00
Christian 97269a5e3d Decode the file URL. Hopefully will make things work more.. 2013-07-09 08:30:47 -04:00
LexManos c913258ca3 Disable signature check of client for now, it's broken. 2013-07-09 05:04:11 -07:00
LexManos c7ab872c85 Temporarily disable GuiModList's Mod logos. 2013-07-09 03:27:49 -07:00
LexManos e91431fb70 Don't validate signatures on servers, they are not signed. 2013-07-09 03:27:29 -07:00
LexManos dfa3a2665d Add MC Version to installed version name. 2013-07-09 03:27:01 -07:00
LexManos 4fa375683f Fix NPE in new debug line when patch targets don't exist. 2013-07-09 01:21:50 -07:00
Christian 0db4624b27 Don't initialize the server. 2013-07-08 22:31:15 -04:00
Christian c997f2adbc FML now verifies that the minecraft jar is correct and intact. This is intended to discourage those who think that
modifying the minecraft jar is still acceptable.
2013-07-08 22:10:06 -04:00
Christian 26e5f4b4ff Test server-siding ResourceLocation 2013-07-08 19:31:00 -04:00
Christian 2336002f20 The game is going to exit in face of patch mismatch, unless you force it to run with fml.ignorePatchDiscrepancies in the system properties. 2013-07-08 14:34:03 -04:00
Christian e88a0cd13f Update for stealth update. Thanks mojang! 2013-07-08 13:19:55 -04:00
Christian dbf5fe38ce We now generate an adler32 checksum for each patched file and verify at load time that they match.
Mismatch won't crash, but will emit a big warning..
2013-07-08 13:19:14 -04:00
Christian c47d08c89d Tweak debug data on patched classes 2013-07-08 12:28:32 -04:00
Captain Shadows 7af5c21d74 @InstanceFactory was set to look for Fields instead of methods
"fix it" to now match the javadoc :P

if it was set like that so modders wouldn't use it, it might be better to just say so in the documentation
2013-07-08 00:07:54 -04:00
LexManos 6f96d89e2b Update eclipse workspaces for 1.6.2 2013-07-07 13:11:22 -07:00
Christian 111b0216fd Add the jsons for 1.6.2 2013-07-07 16:05:53 -04:00
Christian 1d0384f8f6 Update for 1.6.2 and MCP 8.04 2013-07-07 15:49:11 -04:00
Christian adc8972277 Add cascadedTweaks. This will allow simple coexistence for any other mod framework using
the tweaker system as well. Hi Voxel and LiteLoader!
2013-07-06 22:26:03 -04:00
cpw 5990e29af7 Merge pull request #247 from jk-5/patch-1
Pull request for #232
2013-07-06 18:54:54 -07:00
Christian 2676c8999c Update mcp data. fixes #248 2013-07-06 21:25:36 -04:00
Christian 3a200e901e Fix coremod injection into main system. Should stop double-dipping coremods. 2013-07-06 20:51:00 -04:00
Jeffrey Kog c97ac284a5 Update ModLoaderFuelHelper.java 2013-07-04 08:33:03 +02:00
LexManos 54e06e841d Move Resource refreshing until affter postInit. 2013-07-03 22:29:10 -07:00
LexManos 7ce84491d1 Fix missing argument and startclient/startserver support. 2013-07-03 19:30:30 -07:00
LexManos 532bee7ce1 Update to new MCP bugfix version, Fixes: Missing Armor/Item rendering, and Boss health mapping issues. 2013-07-03 18:23:38 -07:00
LexManos e24f949517 Fix eclipse workspaces and launch configurations. 2013-07-03 18:22:57 -07:00
LexManos 4545beb49d Add deobf-data to setup env. 2013-07-03 18:22:06 -07:00
Christian 3f4bf61ae6 Update key 2013-07-03 08:28:59 -04:00
Christian 155e846818 Add in support for mods/<mcversion> as a mod location. Also drop coremods as a location. They go in mods too now. 2013-07-02 23:03:01 -04:00
Christian ba3707af22 More javadoc cleanup 2013-07-02 19:39:02 -04:00
Christian ad79b9ed86 Fix up some deprecation warnings, and clean up coremod code that's going
away.
2013-07-02 19:27:50 -04:00
Christian 5f7df5e742 Revert "Keep these on our servers until the launcher is actually fixed -.-"
This reverts commit f1b533ad87.
2013-07-02 19:03:06 -04:00
Christian 7aa7221756 Fix transformer search 2013-07-02 18:40:23 -04:00
cpw 8844554da6 Merge pull request #243 from jrtc27/modclassloader
Fixed ClassCastException when loading ModLoader mods
2013-07-02 15:32:35 -07:00
James Clarke 6f0eedc9a6 Fixed ClassCastException when loading ModLoader mods 2013-07-02 20:48:00 +01:00
Christian f21cd286ca Resource packs, part two. FML mods are now resource packs. Vanilla will scan anything under 'assets'
and turn it into a resource prefix. Use resourcelocations to look stuff up.
2013-07-02 11:11:50 -04:00
LexManos f1b533ad87 Keep these on our servers until the launcher is actually fixed -.- 2013-07-01 23:26:40 -07:00
Christian 5a97d183df Remember to update your patches!!!! 2013-07-02 02:14:31 -04:00
Christian fbd57b3264 Mods are now loaded as resource packs. Vanilla will scan for valid prefixes based on subdirs of 'assets' which
can then be referenced as ResourceLocations with the "<prefix>:path" notation.
2013-07-02 01:39:40 -04:00
Christian efc369ee83 Fix EventHandler annotation. 2013-07-02 01:08:51 -04:00
Christian 91ecf71109 Fix -rel json 2013-07-02 01:02:02 -04:00
LexManos 9b6525e805 Point scala downloads to our servers, Launcher doesn't like standard maven repos. 2013-07-01 21:53:13 -07:00
LexManos dc7d02ebf6 Fix json syntax error. 2013-07-01 20:33:26 -07:00
Christian 7037184a4e Fix up release JSON 2013-07-01 23:14:31 -04:00
Christian bf38d94756 Update json samples 2013-07-01 22:58:08 -04:00
LexManos 3d17434510 Build installer package for the new client launcher. 2013-07-01 19:40:19 -07:00
LexManos 29d6c875d0 Add FML Installer logo crated by @ZaverSLO https://twitter.com/ZaverSLO/status/349947190300508162 2013-07-01 19:38:44 -07:00
LexManos 902772ed0c Revert common folder fix, Common folder does nothing, feel free to delete it after first load. 2013-07-01 16:25:11 -07:00
LexManos 1229c4c4ea Fix src distrabution, and got rid of pesky common folder in eclipse workspace. src is now installable. 2013-07-01 15:50:49 -07:00
Christian 7fecf2ad6b Update mcp URL. 2013-07-01 11:06:20 -04:00
Christian c418da353f Cleanup coremod code, server side working now. 2013-06-30 22:51:56 -04:00
LexManos 110cf372eb Add deobf data to merge-common, worspace is now actually runnable! 2013-06-30 19:41:51 -07:00
LexManos 7a004087f7 Add deobf data to src dist.
Dont create deobf jar as we ship the lzma
Added *.lzma to .gitignore
2013-06-30 19:15:53 -07:00
LexManos 70cfe24e67 Fix wrong project name in distro eclipse launch. 2013-06-30 18:33:26 -07:00
LexManos 8960f6869f Add windows lzma executable
http://tukaani.org/xz/
He states that most things are under public domain, But I couldn't find an exact reference to this executable.
I'm going to assume it under public domain and distribuiting it here is fine. If not someone please direct me to the apropriate license and I will act accordingly.
2013-06-30 18:31:24 -07:00
Christian 71a92de5d9 Client launch for eclipse 2013-06-30 21:06:33 -04:00
Christian 3f15cd54c2 Functional client @ 1.6.1 2013-06-30 21:02:23 -04:00
Christian 12c928c538 Tweak commands patch 2013-06-30 19:33:47 -04:00
Christian 7406b38d8a 1.6.1 2013-06-30 16:50:30 -04:00
Christian ef646d3146 Merge branch '16launch' 2013-06-30 13:20:46 -04:00
Christian 18371bd8c9 Some fixes for updated mcp code 2013-06-30 13:17:20 -04:00
Christian e35e4b16ff More fixups 2013-06-30 09:04:50 -04:00
LexManos 3711da9c45 Another typo 2013-06-30 03:55:26 -07:00
LexManos 6a318ddb78 Fix typo in new packages. 2013-06-30 01:01:55 -07:00
LexManos 2766f9a293 Push conf folder for 1.6, Relied heavily on a yet-unreleased version of MCP. 2013-06-29 22:48:24 -07:00
Christian 2e3f2461fa More fixes, binpatching works 2013-06-29 15:16:18 -04:00
Christian 95f7345ff7 First draft of 1.6 update 2013-06-29 13:33:14 -04:00
Christian bc02f3e67b New mappings for marker 2013-06-29 09:20:59 -04:00
Christian 8db42c44bf Tweak missing mapping 2013-06-29 09:20:59 -04:00
LexManos 404e6f1cc0 Add support for alternative maven servers in libraries.
Also download sources for public libraries, and atach them in eclipse. DOCUMENTATION!! YAYA!
2013-06-29 02:54:29 -07:00
LexManos 5741f669d5 Base GenDiff off deobf data's class list instead of the merged jar. Add option to delete target files that generate patches. 2013-06-29 01:40:01 -07:00
LexManos 6a67149b16 Add Clean Server/Client launcher. Update Start.java to new Main class and login system. 2013-06-28 22:12:07 -07:00
LexManos c8d934bafd Update eclipse projects for new libraries dependancies, and update packages for new 1.6 classes. 2013-06-28 20:31:02 -07:00
LexManos 075e240303 Add suggestions output if it can. 2013-06-27 22:58:00 -07:00
LexManos d00665ee65 Fixed update_packages.py for new folder strcture. 2013-06-27 22:30:40 -07:00
LexManos ebb74a5f30 Add missing argument 2013-06-27 22:29:10 -07:00
LexManos 5b0117ec76 Re-wrote/orginized a lot of fml.py. Almost everything is re-written/moved.
This is done in preperation for MCP to roll out SpecialSource support and the new 1.6 structure.
Also done for my sanity while reading through the code.

Intruduced a new function. If there is a 'mcp_data' folder in the FML folder, it will be copied to the MCP work directory after MCP is extracted.
It DOES overwrite anything that already exists.
This is intended for places like BuildServer to place libraries/assets to prevent them from needing to be downloaded every version.

Introduced a dev-env json. Need to write the eclipse workspace references to the new libraries.
Out custom json includes asm and legacylauncher.

Added proper OptionParsing to decompile.py
2013-06-27 20:48:52 -07:00
Christian e06d9d0fbc Add a simple property annotation system for mods. 2013-06-27 08:40:31 -04:00
Christian ab91647546 Changed to the EventHandler annotation universally, documentation and stuff. 2013-06-26 14:52:56 -04:00
Christian b236a4a4db Fixes, so it builds again.. 2013-06-24 16:30:18 -04:00
Christian a480a83a98 Ignore binpatch 2013-06-24 16:03:54 -04:00
LexManos 3a9f123a16 Add filter support for MCPMerger, and filter out libraries from the server's 'fat jar'. 2013-06-23 23:06:25 -07:00
LexManos 8d27fb0692 Upgraded minecraft downloader to work with new launcher's asset/library system
New parameter:
  --no-assets: Disables the downloading of minecraft's asset tree, recomended that build servers supply this flag to prevent downloading of useless data.
2013-06-20 16:23:15 -07:00
Christian d369fe1c25 No more debug please 2013-06-15 01:11:29 -04:00
Christian 98b71f2dd4 Fix build script. Add a sample JSON file. You'll need the newest Launcher code to run this. 2013-06-14 21:00:15 -04:00
Christian fef0f6422d More fixups for new launcher model 2013-06-14 20:45:52 -04:00
Christian 2eb81ac88b Merge in binpatch and use launcher 2013-06-14 17:21:49 -04:00
Christian e02a91f008 More tweaks 2013-06-14 09:32:51 -04:00
Christian ced1b95155 Server side tested and working. Setup is complex atm. That will change. 2013-06-13 09:57:55 -04:00
Christian 8f910dfa5d First cut of runtime binary patching. Needs some work to actually test it in a real scenario.. 2013-06-12 08:53:10 -04:00
Christian 05a854cd2a Small tweaks to the mcp data. Nothing major.. 2013-06-11 14:47:23 -04:00
Christian 22738de028 Attempt to properly fix deadlock if the internal server derps. It should never hang now. Damn you fast computer.. 2013-06-11 14:41:19 -04:00
Christian cd0466395a Fix sysout with trailing messages after a newline 2013-06-06 11:52:15 -04:00
Christian 24c4056651 Add in an optional modid identifier for @SidedProxy. It's main use is when both scala and java @Mods reside in the
same package, and you want the @SidedProxy behaviour for a specific @Mod language type. In general it should not be needed otherwise.
2013-06-06 10:05:34 -04:00
Christian 59fe905695 Don't continue trying to send events to mods that depend on errored mods. 2013-06-04 13:59:04 -04:00
Christian 6f3da97365 Don't throw an exception if the scala adapter find a java proxy. I may add some distinguishers to @SidedProxy so you know which mod it's for. 2013-06-04 12:51:46 -04:00
Christian edc1fb24e2 Send the "suspect list", and print the suspect versions 2013-05-27 11:03:23 -04:00
Christian f1d68ed4c8 Throw the sorting exception 2013-05-27 10:46:22 -04:00
Christian ac97370f94 Add in a pretty sorting error screen 2013-05-27 10:28:00 -04:00
Christian 82e9de8641 More tweaks to the mod sorting code 2013-05-27 10:09:51 -04:00
Christian 843a13c1ab Try and clean up cycle detection output a bit 2013-05-27 09:25:50 -04:00
Christian 3bf50c4bbe Fix server side derp with Forge network packet handler 2013-05-21 11:01:50 -04:00
Christian 4922e90d81 Separate network mod config from setup. Allows for Forge Packet Handler nicety 2013-05-20 21:40:42 -04:00
cpw a3a920437f Merge pull request #230 from fnuecke/master
Alternative setter logic for @SidedProxy in Scala classes/mods.
2013-05-11 15:34:37 -07:00
LexManos 787c0c4a6a Don't spit error on LWJGL not supporting 4.3 just warning. 2013-05-11 10:55:39 -07:00
Florian Nücke 8517a824e5 Merge declaration and initialization of a variable. 2013-05-08 20:16:15 +02:00
Florian Nücke 2cca7aa759 Some more Scala @SidedProxy adjustments. Now properly supporting pure singletons, i.e.
object C {
  @SidedProxy(...)
  var proxy: P = null
}
Removed fallback, as all such singletons are properly handled by the new code now, and class implementations fall back to the code also used for plain Java mods.
2013-05-08 19:04:35 +02:00
Florian Nücke 23b070c7d0 Alternative @SidedProxy setter for Scala. 2013-05-08 05:36:28 +02:00
LexManos 49111e9c5c Add version detection to astyle and print error if it doesnt detect version 2.0+
Also fixed astyle's config for max-instatement-indent that sometimes caused crashes with certian versions of astyle.
2013-05-03 14:26:27 -07:00
cpw c0cca7f41d Merge pull request #227 from CovertJaguar/patch-1
Improved Entity Spawn Error
2013-04-29 22:10:53 -07:00
CovertJaguar 99bb50d8f8 Improved Entity Spawn Error 2013-04-29 20:41:20 -07:00
LexManos 00f00b17bf Fix scalac detection to actually use the located command instead of defaulting to 'scalac' 2013-04-28 16:35:23 -07:00
LexManos 62fdbad74c Update MCP's md5 for the fixed srg files. 2013-04-28 12:33:42 -07:00
Christian f0bba74a47 Update for minecraft 1.5.2 2013-04-27 01:24:06 -04:00
Christian cf9b5b445b Don't leave scala running in interactive mode. 2013-04-23 22:56:18 -04:00
LexManos aa200923f0 Fix patch derp. 2013-04-23 19:47:43 -07:00
Christian ddadf93ca1 Fix when an old scalac is present on the system to not fail the build 2013-04-23 22:43:51 -04:00
Christian 781c681216 Some fixups for scala compilation in MCP. Scala should now be compilable and reobfuscatable with srgnames in MCP. 2013-04-23 07:40:49 -04:00
Christian cfda7fc738 Fix URL for MCP 2013-04-23 07:22:25 -04:00
Christian 58ba24add2 Fix possible NPEs in GameData 2013-04-22 21:14:34 -04:00
Christian dcf069ca52 Attempt to reduce lines on the screen for id mismatch. Hopefully prevents game crashes. 2013-04-22 21:14:34 -04:00
cpw c3fda11d10 Merge pull request #225 from MarcinSc/master
Suggested fix for issue 221
2013-04-21 11:32:51 -07:00
Marcin Sciesinski 11ac46daeb Fixing the GameRegistry. Now it is possible to register a Block with a BlockItem using following code:
MyBlock myBlock = new MyBlock();
GameRegistry.registerBlock(myBlock, MyBlockItem.class, "myBlock");
where MyBlockItem class has one constructor with signature:
public MyBlockItem(int id, Block block)
2013-04-21 19:01:18 +01:00
Christian 2dcabe0123 Add a to string to fmlmodcontainer: should mean less derpy cyclic dependency data 2013-04-21 13:58:18 -04:00
cpw 42f1d87955 Merge pull request #224 from Glought/master
Fix for  Issue #223
2013-04-21 08:13:54 -07:00
Glought 334a76de75 Update FMLDeobfuscatingRemapper.java
Fixes a "Type mismath:cannot convert from element type Object to FieldNode" error at line 176.
2013-04-21 05:09:19 -07:00
Christian 677a6e578e Fix scala supporting SidedProxy. It should work now. 2013-04-20 23:31:22 -04:00
Christian a3b5eaacfd Fix a small modloader compatibility derp: closes #222 2013-04-20 22:55:56 -04:00
Christian b3d4ea05ec Fix possible NPE in findItemStack, closes #218 2013-04-17 07:55:33 -04:00
Christian 8f35adca7a Use more expressive language when a version specifier is a simple unbounded above condition 2013-04-16 13:46:55 -04:00
Christian 394f424185 Fix to output versions in crash logs 2013-04-16 13:46:55 -04:00
cpw ada52078c7 Merge pull request #216 from agaricusb/add-srgname
Add srgname to registerTileEntityWithAlternatives
2013-04-15 15:50:47 -07:00
Christian 0daf1a6df4 Merge branch 'agaricusb-fix-deobf-field' 2013-04-15 17:31:09 -04:00
Christian edffd04ed2 Add in some caching of the read field descriptions for efficiency 2013-04-15 17:30:35 -04:00
Agaricus 7aea09f4ca Add type info to properly deobfuscate overloaded fields. Fixes #210. 2013-04-14 16:54:11 -07:00
Agaricus 5673c1dd29 Add srgname to registerTileEntityWithAlternatives 2013-04-14 14:11:37 -07:00
Christian 1774e2bf30 MCP names update 2013-04-10 12:28:20 -04:00
LexManos 4836b3272a Re-worked the Texture patches, optifine helper function, and re-added support for dynamically rotating the texture for mod authors who do things horribly wrong. 2013-04-09 20:06:41 -07:00
Christian a31607ae7d Fix compilation derp, and clean up rotation helper. 2013-04-09 21:20:31 -04:00
Christian 57ad221cc6 And add the patches *sigh* 2013-04-09 20:26:10 -04:00
Christian 00c7883088 Very significant improvement in performance by using glSubImage to upload data. Inspired by frequent complaints about performance of hires
texture packs. They probably still need a beefy system but should work. Hopefully I can figure out why the subImage GL side copy isn't working
properly for an even more significant speed boost. But this gets things started.
2013-04-09 20:15:14 -04:00
LexManos 1de89525cc Fixed issue with instalation when java/javac commands had quotes. 2013-04-05 10:26:33 -07:00
LexManos 704a70902f Sanitize input to isRemappedClass to use '/' as a package seperator like the srg files. 2013-04-04 23:30:10 -07:00
LexManos 570faeb790 Added the ability to save transformed classes to disc for debugging. 2013-04-04 10:32:48 -07:00
Christian 8b8837c9ff Fix NPE when branding isn't present 2013-03-31 10:01:46 -04:00
Christian eff464cf0e And the core patches for that 2013-03-30 12:13:53 -04:00
Christian 26ccb9106e Change snooper/crash report brand handling. fmlbranding now loads another string! 2013-03-30 12:12:54 -04:00
Christian 0d84487412 Fix up derp in access transformer 2013-03-27 19:23:10 -04:00
Christian 2bc6a0666f Attempt to make any "default package" class public. This might fix problems with certain modloader mods that ship changes to vanilla classes. 2013-03-27 16:54:26 -04:00
Christian 82bc9f1b35 Add some information, and a log message letting you know it worked 2013-03-23 16:01:20 -04:00
Christian d73ac867df Add a mechanism to dump the registry- useful for mod developers. 2013-03-23 15:39:34 -04:00
Christian ede93d438f Validate supplied stack size 2013-03-23 15:10:13 -04:00
Christian 5e1949eb0e Clone the itemstack, and allow for passing in a stacksize 2013-03-23 14:58:25 -04:00
Christian 2d368c4c2e Itemstacks in the GameRegistry (manual registration by mods) 2013-03-23 14:48:57 -04:00
Christian d9db27275e Fix mismatch screen a bit. Should render more correctly now and
at least not be blank in a lot of circumstances..
2013-03-22 10:20:53 -04:00
cpw 591a25722b Merge pull request #208 from jrtc27/patch-1
Fixed FMLRelaunchLog's Newline Handling
2013-03-22 05:44:38 -07:00
James Clarke d1ff1967b5 Fixed FMLRelaunchLog's Newline Handling
System.out.println("\n") causes currentMessage to start with a newline character, which means idx will always be 0 from then on. Therefore if idx is 0 messages must still be logged, otherwise no more messages sent to stdout will be logged and they will just accumulate in currentMessage.
2013-03-22 09:19:39 +00:00
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
Christian b33cff3613 Fix NPE for server relaunch 2012-08-11 12:05:13 -04:00
Christian afc2a4a75c Fix up Package.getPackage(), also fix up loadcontroller construction 2012-08-11 11:44:55 -04:00
Christian 7c4583c87a Add in Package.getPackage() support for sengir 2012-08-11 11:12:16 -04:00
Christian f563815961 Lost of work to try and complete ML support - probably still bits missing, but mostly there 2012-08-11 11:02:09 -04:00
LexManos 0ce38f747c Newlines in diff file 2012-08-11 02:27:19 -07:00
LexManos efce8e916b Add special case to add Side/SideOnly to difflist 2012-08-11 02:25:40 -07:00
Christian 44728c9f93 Fix up some network related stuff and optimize mod lookup a bit 2012-08-11 02:43:04 -04:00
Christian d96a81e4f2 Fix up proxy injector to inject properly 2012-08-11 02:24:29 -04:00
LexManos f11844374e Fix decompile 2012-08-10 20:41:59 -07:00
Christian 8c63203bb4 Fix NPE on missing mods - still need to actually handle missing mods properly on client 2012-08-10 23:27:11 -04:00
Christian 751299d5f1 New downloader UI and new downloader backend - should be more robust now 2012-08-10 23:18:52 -04:00
LexManos 7d479bf854 Added -no_gen_conf to jenkins build 2012-08-10 20:09:47 -07:00
LexManos c812a4ede5 Added some extra error prints, hopeully get something useful when installed in the client. 2012-08-10 18:54:06 -07:00
LexManos a826283111 Updated conf merger script to just merge everything, and normalize the line endings so git doesn't complain. 2012-08-10 18:25:11 -07:00
Christian f61f30c1e6 SidedProxy should work again - anywhere. Make sure it's on a static field though 2012-08-10 17:42:43 -04:00
Christian 8f76e8ba8b More ticking hooks, and some other bits of clean up. Very close to "done" now. 2012-08-10 17:11:01 -04:00
Christian 537d89b9e0 Fix up modloader and clean up junk method 2012-08-10 16:42:21 -04:00
Christian 0927aaa0f1 A lot of missing patches to code re-added. Almost all functionality should now
be restored.

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

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

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

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

Conflicts:
	client/cpw/mods/fml/client/FMLClientHandler.java
	patches/minecraft_server/net/minecraft/server/MinecraftServer.java.patch
2012-07-05 15:30:21 -04:00
Christian 8ed36f583d Got the relauncher downloading and injecting library files 2012-07-05 15:23:37 -04:00
Christian 3e311fd4c1 Tweak ticking YET AGAIN. Should fire a solitary GUILOAD tick right as the game screen loads.
Hopefully fixes worldload tick issue too
2012-07-04 00:16:30 -04:00
Christian a4ce90a918 FFS let this fix that bloody ticking mess that is ML compatibility. 2012-07-03 23:03:51 -04:00
Christian ba46389a87 Separate gui ticking completely. send it as if it's a world tick. ML gui ticks are epically dumb.
Fix Worldload being filtered from the trigger arming.
Also, improve errors going to an error screen. There should be more information now.
2012-07-03 22:39:35 -04:00
Christian f7e07ca7d8 Change gui ticking and world load tick. Should close issue #40 and kill it deader
than a very very dead thing. *$^*(#% Modloader ticking b#%$hit
2012-07-03 21:37:54 -04:00
Christian 3e80a9ee7d Merge branch 'master' into minecraft1.3 2012-07-03 08:15:58 -04:00
Christian dfc6f7b1c1 Tweak build xml for more cleanliness 2012-07-03 08:14:35 -04:00
Christian 753f5f7bc8 Merge branch 'antscriptupdates' 2012-07-02 23:50:49 -04:00
Christian 982271e8ec Update some stuff 2012-07-02 23:49:40 -04:00
Christian 802ec3d86a Merge branch 'antscriptupdates' into minecraft1.3 2012-07-02 23:49:06 -04:00
Christian f1b0e33694 Add in more options for ant script and clean up needing to clean every time. 2012-07-02 23:43:29 -04:00
Christian 1d64fb01bd Merge branch 'testrecover' 2012-07-02 20:19:23 -04:00
Christian 086f575a41 Merge branch 'antscriptupdates' into minecraft1.3 2012-07-02 15:56:33 -04:00
Christian 3cda115cd5 Merge branch 'antscriptupdates' 2012-07-02 15:55:24 -04:00
Christian d491502750 Some more fixes to the ant stuff: apply patches now happens at the right time, I grab fernflower as part of
setup and added an updatepatches call too
2012-07-02 15:54:25 -04:00
Christian 1d4c33d161 Merge branch 'antscriptupdates' into minecraft1.3
Conflicts:
	build.xml
2012-07-02 15:21:15 -04:00
Christian 47a879a961 Merge branch 'antscriptupdates' 2012-07-02 15:17:32 -04:00
Christian b59184424b Add in a setupenvironment ant target specifically for setting up an FML environment from scratch 2012-07-02 15:16:40 -04:00
Christian a7803d1785 Harvest MC version from MCP 2012-07-02 13:31:45 -04:00
Christian 5415bf87ce fix sided proxy bukkit test (not used so not a biggie) 2012-07-02 12:32:41 -04:00
Christian a33f2dde77 Harvest MC version from MCP 2012-07-02 12:24:37 -04:00
Christian bb7ef791de Initial checkin. Some patches are probably missing, but client compiles. 2012-06-29 20:18:04 -04:00
Christian aa1a5d3c19 Working simple scheduled ticking, Player ticks 2012-06-28 23:37:30 -04:00
Christian a53d8c926e Support tick spacing through new IScheduledTickHandler 2012-06-28 17:10:35 -04:00
Christian 714cd8d8df Change TickType.WORLD to send the world as arg[0] to match the server. 2012-06-28 14:24:34 -04:00
Christian c9f7444d06 And there are not 1000 seconds in a second 2012-06-28 08:31:32 -04:00
Christian ea05777032 Seconds are 1000 milliseconds long. Not 1 millisecond long. 2012-06-28 08:27:21 -04:00
Christian 14fea4a3a3 Tweak profiler command on bukkit 2012-06-28 08:21:24 -04:00
Christian 0613858855 Fix up a derp in the timing command 2012-06-27 22:13:55 -04:00
Christian 6687ed360b Fix code to use guava 10 only. Stupid bukkit plugins and daft dependencies on guava 10! 2012-06-27 08:23:53 -04:00
Christian 409506d2b2 Tweak for end profiling 2012-06-26 23:37:54 -04:00
Christian b96d6e00c3 Add in simple profiler for bukkit 2012-06-26 23:16:23 -04:00
Christian b6ae926fd3 Add in a mechanism to get the modcontainer for a mod - so things can be programmatically changed 2012-06-26 16:24:50 -04:00
Christian 508c986166 Add in bukkit support for recipe change 2012-06-26 15:40:30 -04:00
Christian 725201040e Add in a new recipe handler registry method for ease of adding recipes to MC 2012-06-26 15:29:34 -04:00
Christian 70d7c8fc68 Update tester mod 2012-06-22 09:30:47 -04:00
Christian 05f9861da4 Fix ticking for GUI ticks too! 2012-06-22 09:30:27 -04:00
Christian c588750c96 Fix dependency string processing error 2012-06-22 06:21:04 -04:00
Christian d00e229198 ModSorting test case 2012-06-21 21:56:16 -04:00
Christian be1a80ebbd Fix ticking properly - ML world ticks now fire once, properly 2012-06-21 18:11:40 -04:00
LexManos 44706ae343 Added stupididty exception for common issue with getMinecraftLogger. 2012-06-21 03:17:33 -07:00
Christian 2af41e7c8c Rename unused ML prop config files if they exist (to .bak) and
skip generating if not needed
2012-06-20 21:17:32 -04:00
Christian e5c29a75de Update bukkit with changes 2012-06-20 12:36:48 -04:00
Christian 2a36dc64bd Revert "Test failing build"
This reverts commit 744febc38e915a12c388fe01ba6715d31b6b6ee2.
2012-06-20 08:44:49 -04:00
Christian dd128c8502 Revert "Revert "Fail the build when recompilation fails""
This reverts commit c2d920d738a294462338fbe955c62a0f4034304c.
2012-06-20 08:44:08 -04:00
Christian 3812dc4464 Revert "Fail the build when recompilation fails"
This reverts commit 482e3be3c9a96df8cefad81d78c7a4e83ad898b4.
2012-06-20 08:39:11 -04:00
Christian 851038679a Test failing build 2012-06-20 08:35:47 -04:00
Christian 146ee9b3c7 Fail the build when recompilation fails 2012-06-20 08:35:14 -04:00
Christian 6c42a77411 Fix huge bug/typo in basemodticker that stopped ticks getting sent 2012-06-20 08:03:57 -04:00
LexManos 7e24034fcc Fix compilation error, Protip: Don't use java7 things when compiling for java6, and Don't report successful build on compilation errors cpw. 2012-06-20 02:14:07 -07:00
LexManos e6eb550bfd Remove cr's from modinfo descriptions, they print oddly in Minecraft. 2012-06-19 19:58:48 -07:00
LexManos 2dbb374869 Print mod metadata info errors if we are in MCP. 2012-06-19 19:55:28 -07:00
LexManos e5efbea2ab Should fix concurent modification exceptions when using removeSpawns 2012-06-19 19:44:52 -07:00
LexManos bc74a16149 Remove some eclipse preference files 2012-06-19 19:44:07 -07:00
LexManos 4cd6c58159 Update gitignore to ignore some eclipse preference files. 2012-06-19 19:43:46 -07:00
LexManos 9e6fbea698 Merge pull request #29 from ScottKillen/master
Fixed WorldType to allow custom WorldTypes
2012-06-19 19:22:06 -07:00
LexManos e796630120 Added EntityRendererProxy class for compatibility with ModLoader mods that rely on it's existance. 2012-06-17 19:30:10 -07:00
Christian cad5ce54dc More ticking cleanup 2012-06-17 18:53:49 -04:00
Christian 3c3e4ca2ff Remove WorldLoad tick from modloader mods- too early. *sigh* 2012-06-17 18:49:19 -04:00
Christian b9b90c6eef Make sure to reset the clock trigger 2012-06-17 18:41:54 -04:00
Christian 747c6131bf Force all client modloader ticks to occur at render end 2012-06-17 18:41:05 -04:00
Scott Killen 5c65939330 Client
======
Added hook in GuiCreateWorld to allow WorldType to present GUI on world creation.
2012-06-17 15:05:16 -04:00
Scott Killen cddcd9ffb3 **Client**
* Delegated World.func_46068_G() (getHorizon), which depends on WorldType, to the WorldType class per LexManos' suggestion
2012-06-17 00:04:50 -04:00
Scott Killen 1295c3863e Client
======
- Fixed WorldType to allow custom WorldTypes in world creation GUI.
- Deprecated client WorldType.getSeaLevel() and renamed it with the more accurate name of getMinimumSpawnHeight.
- Changed related reference WorldProvider.

Server
======
- Fixed WorldType to allow custom WorldTypes
- Added methods to WorldType giving it the exact abilities of client WorldType
- Adjusted WorldProvider so that it relies on WorldType the same way it does on client.
2012-06-16 23:31:17 -04:00
Christian 99ce6e2dee Merge pull request #27 from TheNoid/master
Make FML logs use system line endings …
2012-06-14 12:06:19 -07:00
Dion Williams a9d4a15a4f Make FML logs use system line endings for consistency with Java stack traces in the logs. 2012-06-14 18:01:35 +01:00
LexManos 2fbf60a846 Server side fix for invalid parameter to onCrafting 2012-06-13 20:02:35 -07:00
LexManos 1838344b07 Proper fix for scroll list not covering all of the hidden scroll items. 2012-06-13 19:59:54 -07:00
Christian fd6aacd0fe Merge pull request #26 from GenuineSounds/patch-2
Incorrectly passing the IInventory of the extraction slot instead of the...
2012-06-13 18:52:46 -07:00
Christian 4b142cbdcc Merge pull request #25 from GenuineSounds/patch-1
Having the string trimmed to 9 made most long strings show a couple of p...
2012-06-13 18:50:26 -07:00
Brian Wiegand 802425b4d5 Incorrectly passing the IInventory of the extraction slot instead of the crafting matrix, get back to me on why it's doing this instead of the default behavior of ModLoader and Forge. 2012-06-13 15:17:33 -07:00
Brian Wiegand 745d388cb0 Having the string trimmed to 9 made most long strings show a couple of pixels at the very top and very bottom. ie
https://dl.dropbox.com/u/79514/2012-06-13_13.25.35.png
2012-06-13 14:09:07 -07:00
LexManos 1f52ee1dea Fixed KeyBinding issue with ModLoader container, if you register a KeyBinding twice it will discard the old one. And fixed issue where getVersion() could return null causing NPE. 2012-06-10 17:19:05 -07:00
LexManos 1af7d7970a Made it so it will attempt to scale any Texture Effects that return data for smaller texture resolutions. Made the size descrepancy only a error for ITextureFX texture effects. 2012-06-10 05:56:52 -07:00
Christian 201edc0249 Fix up "errored" mod states so they actually read as errors 2012-06-09 11:07:07 -04:00
Christian 2f4a572a23 Fix up bukkit for biome code 2012-06-09 10:47:43 -04:00
Christian 0cf8cca248 Fix up biome handling for client and server 2012-06-09 10:27:24 -04:00
Scott Killen af4a2589a6 - Fixed client crash bug in add/remove Biome functionality. Arrays.asList() returns a fixed-sized list per java spec. Adding and removing biomes throws UnsupportedOperationException.
- Fixed same on server and added disabled removeBiome functionality. This touched a lot of classes as the nonWorking removeBiome seemed to be lots of places inconsistent with addBiome.
2012-06-09 07:59:35 -04:00
Christian 2d55491692 Tweak error handling - report the exception that caused the bailout 2012-06-08 15:31:30 -04:00
Christian 1007720589 Fix parameter ordering in ticks 2012-06-08 15:22:40 -04:00
Christian b2f470464a Update bukkit for world gen tweaks 2012-06-07 19:47:11 -04:00
Christian 683c99c8b6 Change world generation to expose a mod interface 2012-06-07 19:44:03 -04:00
Christian 428cf691f1 Update bukkit for early load change 2012-06-07 19:28:07 -04:00
Christian bfe54ef7e7 Attempt early initialization of Minecraft Forge 2012-06-07 19:25:49 -04:00
Christian 40dff18025 Update bukkit handler 2012-06-07 17:57:07 -04:00
Christian 4d620d91e4 Add in a server side WORLDLOAD tick 2012-06-07 17:54:43 -04:00
Christian a502e1fc56 Fix ticking- need to register the basemod tickhandler *sigh* 2012-06-07 16:31:23 -04:00
Christian 4f0c220d99 Fix ticking for new name "GAME" vs "WORLD" 2012-06-07 16:21:01 -04:00
Christian Weeks 08a4b21460 Update bukkit handlers 2012-06-07 14:03:42 -04:00
Christian Weeks 9fd6f89fc3 Reorganize basemod ticking to use ITickHandler. Introduce "GAME" tick vs "WORLD" tick for
mods that want to tick per world and "globally"
2012-06-07 13:53:16 -04:00
Christian Weeks 11652d597f Expose a "clean" ticking interface and fix server tick loop for world ticks 2012-06-07 11:12:51 -04:00
Christian Weeks f943cd9b4b Tweak width of description 2012-06-07 08:39:22 -04:00
LexManos 1e392e0bb3 Fix for in game tick running when it shouldn't. Fixed some tabbing issue in crazy's PR. 2012-06-06 08:01:54 -07:00
LexManos e536c58f81 Interm implementation of keyboardEvent for ModLoader. 2012-06-06 01:43:49 -07:00
LexManos 63c02cbe35 Add static log() functions to the RenderAccessLibrary, and fixed up the logo rendering to better display the images. 2012-06-05 18:49:07 -07:00
Christian d9a8392723 Merge pull request #14 from crazyputje/master
onTickInGUI fix. Thanks crazyputje!
2012-06-04 14:41:59 -07:00
crazyputje ae52b91d13 removed 'if (client.theWorld != null)' so it also ticks in the main menu 2012-06-04 20:36:57 +03:00
Christian Weeks 370062cc55 Helps to have a retention policy 2012-06-02 22:41:50 -04:00
Christian Weeks 43eae28f55 Helps to have a retention policy for runtime annotations 2012-06-02 22:40:45 -04:00
Christian Weeks c2c27044b5 Add in bukkit proxy handler 2012-06-02 22:14:25 -04:00
Christian Weeks 09722f3ffc More proxy code 2012-06-02 22:12:15 -04:00
Christian Weeks 2cf960b64d Introduce a proxy side loader for mod use 2012-06-02 22:12:15 -04:00
LexManos 05b31bdd6e Fixed GuiModList Logo rendering to allow for logos of different sizes to be rendered properly. Logos will render themselves full underneath the text, It is the modder's job to make it look good. 2012-06-02 18:05:57 -07:00
Christian Weeks e115807351 Update credits information 2012-06-02 11:45:47 -04:00
Christian Weeks f5b29d2726 Update readme for the client side 2012-06-02 11:44:26 -04:00
Christian Weeks dfac296402 Update bukkit handler to inject names at startup 2012-06-02 11:03:20 -04:00
Christian Weeks 9e2117c955 Merge remote-tracking branch 'origin/master' 2012-06-01 23:25:18 -04:00
Christian Weeks 4fdf2ea290 Fix up optifine detection properly 2012-06-01 23:23:50 -04:00
Christian Weeks 10fb465525 Update bukkit handler 2012-06-01 23:10:38 -04:00
Christian Weeks d44822b7d0 Slight reorganization of texture ticking - accomodate optifine 2012-06-01 23:07:32 -04:00
Christian Weeks 18a35c1ab7 Add in optifine visibility for the mod list. Will search for an "optifine_mod.info" file on the
class path if sp614x wants to add one to optifine.
2012-06-01 14:55:49 -04:00
Christian Weeks 26cf077cfa Fix ticking on bukkit server 2012-06-01 11:08:32 -04:00
Christian Weeks c3379b44dd Fix ticking on the server 2012-06-01 11:07:14 -04:00
Christian Weeks 3ad305aa06 Implement missing language load hook for server 2012-06-01 10:22:08 -04:00
Christian Weeks 89d74da576 Tweaks to basemod setup 2012-06-01 00:33:51 -04:00
Christian Weeks 9ad4177bfa Bukkitside fixup 2012-06-01 00:27:46 -04:00
Christian Weeks 20c830c848 Merge branch 'bukkitreorg' 2012-05-31 23:07:16 -04:00
Christian Weeks 877bb029f9 Merge branch 'bukkit'
Conflicts:
	common/cpw/mods/fml/common/IWorldGenerator.java
	common/cpw/mods/fml/common/registry/FMLRegistry.java
	common/cpw/mods/fml/common/registry/IMinecraftRegistry.java
	common/net/minecraft/server/CommonRegistry.java
	common/net/minecraft/server/IMinecraftRegistry.java
	common/net/minecraft/src/CommonRegistry.java
	common/net/minecraft/src/IMinecraftRegistry.java
2012-05-31 23:00:06 -04:00
Christian Weeks cfb5cb1a2f Fix copied code. Derpbag. 2012-05-31 22:48:44 -04:00
Christian Weeks 245f562e1c Update FML with recent mainline changes 2012-05-31 22:48:44 -04:00
Christian Weeks 68dc92f0e1 Update bukkit with new mod fixes 2012-05-31 22:48:44 -04:00
Christian Weeks ee4089304a Damn you bukkit with your same names for different classes!!!! EntityPlayer->EntityHuman 2012-05-31 22:48:44 -04:00
Christian Weeks f3dfa1a955 Fix chunk generators for bukkit 2012-05-31 22:48:44 -04:00
Christian Weeks 2320e42163 Bukkit version 2012-05-31 22:48:44 -04:00
Christian Weeks bcc35775f4 Merge branch 'bukkit' - massive code reorganization for fml 2.0
Conflicts:
	common/cpw/mods/fml/common/IWorldGenerator.java
	common/cpw/mods/fml/common/registry/FMLRegistry.java
	common/cpw/mods/fml/common/registry/IMinecraftRegistry.java
	common/net/minecraft/server/CommonRegistry.java
	common/net/minecraft/server/IMinecraftRegistry.java
	common/net/minecraft/src/CommonRegistry.java
	common/net/minecraft/src/IMinecraftRegistry.java
2012-05-31 22:45:19 -04:00
Christian Weeks 3239536832 More tweaks for proper API 2012-05-31 22:42:23 -04:00
Christian Weeks 9c1c414ca7 Reorganize for bukkit integration 2012-05-31 22:09:45 -04:00
Christian Weeks 20e5963059 Fix project, new gui layout with screenshot, thanks Sengir! 2012-05-30 09:25:04 -04:00
Christian Weeks 70c57e2ad6 Add in missing hooks, add branding information to the crash report 2012-05-27 07:14:35 -04:00
LexManos 4639786521 Fixed regex issue in last push. 2012-05-27 01:40:22 -07:00
LexManos 71e873ed1f Fixed up for newline before case bodies. 2012-05-27 01:24:45 -07:00
LexManos c416a82e64 Should fix windows {me} generating different patches then linux {cpw} 2012-05-27 00:22:27 -07:00
Christian Weeks 539252053f Move first tick to the real first tick 2012-05-26 02:30:21 -04:00
Christian Weeks da791ef721 Merge in the mod texture changes from Lex 2012-05-26 02:29:35 -04:00
LexManos 49bca8998a Fixed location refs to fmlversion.properties 2012-05-25 23:25:05 -07:00
Christian Weeks 6e14c67e82 Add in a static render access class for optifine and other render editing mods to use 2012-05-25 22:13:51 -04:00
Christian Weeks 7fddb9d59e Add in a "world load" tick fired just as the world completes loading. This SHOULD fix millinaire. 2012-05-25 17:21:30 -04:00
Christian Weeks 006112f3d3 Changing up the mod list data 2012-05-25 15:25:35 -04:00
LexManos e075a430e2 Fixed up ModTexture* classes to use the ITextureFX events to resize the image as needed. Also fixed ModTextureStatic's not being applied properly. 2012-05-24 22:48:15 -07:00
Christian Weeks 134299b413 Fix up two stupid overwrites in my mergeup from lex 2012-05-24 23:18:04 -04:00
Christian Weeks 03059c5cd2 Fix derp in MTS 2012-05-24 22:13:33 -04:00
Christian Weeks 918d9d8687 Patch fixing 2012-05-24 21:40:34 -04:00
Christian Weeks 5017f8b038 Update some stuff for updated tweaks 2012-05-24 21:39:16 -04:00
Christian Weeks 78052d2ce2 Update FMLClient with my changes 2012-05-24 21:33:43 -04:00
Christian Weeks 8a6b10607d my tweaks 2012-05-24 21:06:27 -04:00
LexManos 034117e253 difflist should include server and client now. 2012-05-24 03:48:59 -07:00
LexManos a3ddd6140b Some patch cleanup. 2012-05-24 02:18:20 -07:00
LexManos ac292296fe Rewrote how HD Texture support worked, to make it easier for Optifine to integrate.
Fixed TextureFlamesFX for extramly large texture sizes.
Fixed the texture size sceme to allow for different sizes of textures in the same pack.
2012-05-24 01:35:37 -07:00
LexManos d50a66c8ba Line number changed.. 2012-05-24 01:33:50 -07:00
Christian Weeks fb4d3b2ca9 Fix up the watch 2012-05-18 20:42:12 -04:00
Christian Weeks fcdd2a9176 And some tweaks to the texture handling 2012-05-18 20:17:07 -04:00
Christian Weeks fa921f0aa9 Fix up some fubars in MTS and MTA 2012-05-18 20:16:41 -04:00
Christian Weeks ac221275d9 Lots of error handling. 2012-05-18 10:38:40 -04:00
Christian Weeks 33f8b158a9 Missed a patch *sigh* 2012-05-17 21:57:24 -04:00
Christian Weeks b9b33ebe79 Add simple API to allow mods to let their textures be overriden by other mods 2012-05-17 21:47:12 -04:00
Christian Weeks a23816134b Because, of course, I broke the first build... 2012-05-17 20:27:24 -04:00
Christian Weeks 4e8e84244b Some logging of texture overrides- also, only unregister if it's an actual ModTextureStatic, not if it's a subclass. 2012-05-17 15:39:04 -04:00
Christian Weeks a94316cc9e Derpy exceptions derpy exception handling 2012-05-17 15:19:25 -04:00
Christian Weeks 01a1bc9e6a Remove the dependency in RenderEngine, decided on the simple API for texture FX 2012-05-17 15:11:21 -04:00
Christian Weeks d2b69b2b08 Tweak the render patch- we won't fail if the updateTexture call fails 2012-05-16 00:34:50 -04:00
Christian Weeks 91fbba3873 Update patches: add in a setup for most of the texturefx classes 2012-05-16 00:01:12 -04:00
Christian Weeks a4f3bc853a Tweaking texture loading 2012-05-16 00:00:52 -04:00
Christian Weeks b7ece58caa Fix tileSize -> iconTileSize. Stupid MCP 2012-05-15 22:34:17 -04:00
Christian Weeks fe354c867d Catch throwable (NoClassDefFoundError) and don't abort loading- it's probably a badly named class file. 2012-05-15 22:23:00 -04:00
Christian Weeks 326d52f534 Fix some derpy 2012-05-15 22:18:41 -04:00
Christian Weeks fbd9ac7d95 Update patches for hd textures 2012-05-15 22:10:38 -04:00
Christian Weeks 96018996fc Change hd texture handling 2012-05-15 22:05:24 -04:00
Christian Weeks 9b205b1355 Refresh the renderengine patch- catch and log some texture pack reload errors 2012-05-15 16:21:40 -04:00
Christian Weeks 56f915eb66 More mod list fixes 2012-05-15 16:19:46 -04:00
Christian Weeks 46f8868961 Lots of cleanup on the mod list, pretend we're the mcpatcher for mod HD detection. 2012-05-15 15:52:19 -04:00
Christian Weeks 15089f9d87 Fix up fubar in worldprovider. Add in obfuscation detection. Capture the exception that crashes minecraft in the log file. 2012-05-14 18:21:35 -04:00
Christian Weeks 4783bfe01d ModLoader worldtype hackery compatibility 2012-05-14 16:21:05 -04:00
Christian Weeks 7b894946bf Fix derp 2012-05-14 14:16:50 -04:00
Christian Weeks a01e513822 Only log the warning once per texture 2012-05-14 13:20:50 -04:00
Christian Weeks 3061fd3d8f push patches 2012-05-14 12:22:46 -04:00
Christian Weeks 9b281f0a3c Fix millinaire support. Fix Portal eating rendering time. add in profile visibility for mod stuff. 2012-05-14 11:38:54 -04:00
Christian Weeks e433708056 Fix the serverside. FUUUUUUUU! 2012-05-14 01:45:56 -04:00
Christian Weeks 43eae51bb3 HD patching complete? Clean up mod info data, Dummy field for dummy mods 2012-05-14 01:39:21 -04:00
Christian Weeks 72edbe596e Improving the scroll list, HD texture patches 2012-05-13 02:46:39 -04:00
Christian Weeks 53b5533936 Actually pass in the mod name 2012-05-12 02:25:15 -04:00
Christian Weeks 84c86fd475 Fix up incorrect dependency handling 2012-05-12 02:10:50 -04:00
Christian Weeks a9d644e1e8 Fix stupid problem with braces 2012-05-12 01:06:58 -04:00
Christian Weeks 7ed6c7bd7f Tick only when there's a world 2012-05-12 01:03:36 -04:00
Christian Weeks 3fd23cee0f Fix nulls in the mod list, start building the gui screen 2012-05-12 00:47:04 -04:00
Christian Weeks 0665c93c2b Gui related ticking 2012-05-12 00:00:33 -04:00
Christian Weeks cd741d961e Try always loading the language data 2012-05-11 23:37:58 -04:00
Christian Weeks ea855f82b4 Always load the "en_US" langpack into the translation table first, then the actual language. 2012-05-11 22:20:09 -04:00
Christian Weeks d775f42703 Derpy derp- fix stupid pointless cast 2012-05-11 17:41:33 -04:00
Christian Weeks 0981d3106d Fix missing ml.sendpacket, call in renderers 2012-05-11 17:31:28 -04:00
Christian Weeks a20c7f6f76 Actually mark the sprite as used when you allocate it! 2012-05-11 16:49:21 -04:00
Christian Weeks cf9b57d9fa Helps to add the new hook! 2012-05-11 16:30:23 -04:00
Christian Weeks 7deedb26f5 Hook texture pack changes and loads so we can register override textures 2012-05-11 16:23:26 -04:00
Christian Weeks 4c2c7cb2f3 Fix problem with nulls in getModList
Work on the meta information file
2012-05-11 15:18:26 -04:00
Christian Weeks 7ec180ee7c More tweaks to stuff: mod list, branding, more hooks 2012-05-11 01:45:36 -04:00
Christian Weeks b1ee6c3c95 Tidying up and more hooks 2012-05-10 21:30:06 -04:00
Christian Weeks a36fccc9b0 Tweak block rendering organization. Add in worldgen for client. 2012-05-10 19:51:15 -04:00
Christian Weeks 36b05d9378 Tidy up a lot of code- ModLoader and BaseMod are now almost identical client and server side 2012-05-10 18:54:25 -04:00
Christian Weeks 2b8ac71253 Tweak ordering for sorting- should be a stable sort now 2012-05-10 15:48:26 -04:00
Christian Weeks 1ffb096508 Update git version capture 2012-05-10 13:01:39 -04:00
Christian Weeks 7a66d88e9f Ignore jenkins tags 2012-05-10 12:53:27 -04:00
Christian Weeks 42c5b9534a Tweak some build stuff for versioning 2012-05-10 12:24:17 -04:00
Christian Weeks 0b1f3b51e3 Update build to actually put Loader in... 2012-05-10 11:16:58 -04:00
Christian Weeks 6646b573e8 tweak location of build properties in src jar 2012-05-10 10:09:56 -04:00
Christian Weeks 201762ee50 Lots of tweaks to mod output pretty printing. new versioning scheme. 2012-05-10 09:42:31 -04:00
LexManos 99ee905038 Inventroy rendering 2012-05-10 01:25:56 -07:00
LexManos d2afbd9216 Fixed up the ModLoader render block hook, RP's blocks now render. 2012-05-10 01:00:07 -07:00
LexManos 5f49c5f646 Should fix colliding model ids with MC's internal IDs 2012-05-09 23:38:01 -07:00
Christian Weeks d91c22ea24 Fixes 2012-05-10 02:01:23 -04:00
Christian Weeks 4c9745f73c Fix up build script a bit, all modloader is public, and fix tile entity renderer 2012-05-10 00:07:46 -04:00
Christian Weeks edb0ba811f Add in some more stuff for handling key bindings, rendering 2012-05-07 17:44:49 -04:00
Christian Weeks a1ca27b997 Reorganize ticking a bit 2012-05-07 01:39:55 -04:00
Christian Weeks 285d187884 Separate sprite handling, fix worldtype 2012-05-07 01:26:21 -04:00
Christian Weeks 351c193b98 Working on the ticking stuff 2012-05-07 00:54:18 -04:00
LexManos 8586d8ae85 more client side hooks and Texture overrides/animations. 2012-05-06 16:32:59 -07:00
Christian Weeks 1a40f433a5 Halfway through ticking- won't compile 2012-05-06 00:58:40 -04:00
Christian Weeks 6c6f792c6b ModLoader moves forwards 2012-05-05 20:33:40 -04:00
Christian Weeks 149fa8a577 Let's get hooking! 2012-05-05 19:52:53 -04:00
Christian Weeks f279476684 API is restored for client side. Implementation starting. 2012-05-05 14:42:46 -04:00
Christian Weeks 0ca8ace988 And some patches for that 2012-05-04 17:04:18 -04:00
Christian Weeks 80f87ef569 The beginning 2012-05-04 17:02:12 -04:00
Christian Weeks 904efdd4d8 Introduce the client side FML 2012-05-03 19:40:55 -04:00
Christian Weeks 874d3f0b17 Implement addBiome, hopefully. Pushes biome list to the WorldType field. Sorry Bioxx. 2012-05-03 14:05:13 -04:00
Christian Weeks 603005ba18 Check in some eclipse crapola. 2012-05-03 14:04:16 -04:00
Christian Weeks 6b286543d4 Fix copied code. Derpbag. 2012-04-28 16:47:04 -04:00
Christian Weeks 28992c6f13 Update FML with recent mainline changes 2012-04-28 16:40:25 -04:00
Christian Weeks 174e208369 Merge branch 'master' into bukkit 2012-04-28 16:35:15 -04:00
Christian Weeks c632d5145e Fix a small issue with the build output script
Fix a significant issue with MLProp handling and primitives- they work now
2012-04-26 17:38:31 -04:00
Christian Weeks f3bee8c070 More text fixup 2012-04-19 23:07:07 -04:00
Christian Weeks 8bfeb5ac21 Typos 2012-04-19 22:54:10 -04:00
Christian Weeks 05dc6f8e4b Add in detection for MLMP and try to fail with a graceful message. 2012-04-19 22:40:59 -04:00
Christian Weeks 2eb77acf73 Update bukkit with new mod fixes 2012-04-18 14:06:54 -04:00
Christian Weeks f7cec9be38 Merge branch 'master', remote-tracking branch 'origin' into bukkit 2012-04-18 14:04:39 -04:00
Christian Weeks 8f8ee60eb1 Tweak the loader a little bit to just use file names, not fully qualified directories when referring
to mods.
2012-04-18 14:03:30 -04:00
Christian Weeks 8f14c7321b Damn you bukkit with your same names for different classes!!!! EntityPlayer->EntityHuman 2012-04-16 01:00:06 -04:00
Christian Weeks aedb80c251 Fix chunk generators for bukkit 2012-04-15 22:42:06 -04:00
Christian Weeks e7224c7bda Merge branch 'master' into bukkit 2012-04-15 21:58:18 -04:00
Christian Weeks cceeb88c6d Bukkit version 2012-04-14 23:01:03 -04:00
Christian Weeks 65f39a50c1 Fix "soft" dependencies so they can exist properly 2012-04-14 10:01:55 -04:00
Christian 0a52ed381d Fix server patch 2012-04-10 23:05:22 -04:00
Christian 78f2e8f38a Merge in fixes from chickenbones for tick related problem
and straighten out variable naming in ModLoaderModContainer
2012-04-10 22:22:13 -04:00
Christian Weeks 9fdc403396 Push the patched file, as well 2012-04-09 10:24:58 -04:00
Christian Weeks 9c3a2f052d Add in more "Player" related events. Fix up some MLProp stuff 2012-04-09 10:18:24 -04:00
Christian Weeks 5f26a86bf7 Fix regular expressions, thanks ChickenBones! 2012-04-09 09:19:20 -04:00
Christian Weeks b1d9f3d833 Tweak Console handler patch so we're more friendly to forge 2012-04-08 10:04:28 -04:00
Christian Weeks 05ff62d85f A proper console command handler, also fix ordering of loaded mods 2012-04-08 09:55:56 -04:00
Christian Weeks b0774b89c7 Add in a console command handler so you can access the command console 2012-04-08 02:00:57 -04:00
Christian Weeks 1ec797cddb Don't send a register unless I have channels. Add the channel to the mod channels list. 2012-04-08 01:11:32 -04:00
Christian Weeks 2ff2a78694 Split the packet salutation in two so we can work with or without forge 2012-04-08 00:18:37 -04:00
Christian Weeks 93664d10e6 Add the player object to the onLogin event so you don't need to dive internals for it during login 2012-04-07 22:38:29 -04:00
Christian Weeks 10e5d42522 Call my handleLogin hook from NetLoginHandler, tweak output in server gui and log file. 2012-04-07 22:11:01 -04:00
Christian Weeks d531d70f1f Fix subdirectory loading properly: mods will load inside eclipse.. 2012-04-06 16:14:01 -04:00
Christian Weeks 95596bc198 Actually figure out the path for directory class loading 2012-04-06 15:24:28 -04:00
Christian Weeks b32a92df5b regular expressions in java==fail 2012-04-06 15:03:41 -04:00
Christian Weeks ac6c35d7c4 Recurse into subdirectories found 2012-04-06 14:43:12 -04:00
Christian Weeks 2ed8a8b807 Try multiple "jar" sources- for eclipse testing 2012-04-06 14:23:14 -04:00
Christian Weeks 759e92cc2a it's addURL not addUrl dumbo 2012-04-06 13:57:40 -04:00
Christian Weeks feede96d6d it's getdeclaredmethod, dipstick 2012-04-06 13:47:01 -04:00
Christian Weeks fc33249d32 Fix package private resolution of fields/methods from base minecraft by loading into minecraft's class loader not our own 2012-04-06 13:27:50 -04:00
Christian Weeks ff48f13746 Add in a missing client side method to modloader stubbed for the server 2012-04-06 12:24:52 -04:00
Christian Weeks 47e61610ca Add the hooks for crafting and smelting 2012-04-06 10:34:44 -04:00
Christian Weeks 4f97aedbb2 Should load from whatever minecraft comes from now... 2012-04-06 09:59:58 -04:00
Christian Weeks 51203e49f9 Build should work now. Fix a stupid javadoc import. 2012-04-05 21:44:06 -04:00
Christian Weeks 1906a085ad New build script- version the src dist as well 2012-04-05 21:40:16 -04:00
Christian Weeks 5a3ac6b96e Documentation: lots
Some eclipse workspace settings that might help?
2012-04-05 16:22:47 -04:00
Christian Weeks 1146660fc6 Handle the minecraft object registry better- now the client compiles too
Also a quickie astyle run over the code..
2012-04-05 12:36:54 -04:00
Christian Weeks 2888e1680e Update the patches and fix the shell script 2012-04-05 11:42:33 -04:00
Christian Weeks 7bf22659e7 Reorganize the code a little bit- move some stuff that was on FMLHandler to the common handler. Add a delegate
into the common handler that delegates to the right sided handler
2012-04-05 11:34:57 -04:00
Christian Weeks 86f8bbd47d Clean up extraneous print statements from the build 2012-04-05 10:42:15 -04:00
Christian Weeks 5bc8929795 Fix INSTALL-fml.txt file location in the server zip 2012-04-05 10:37:05 -04:00
Christian Weeks b2853aa811 Append a .class to the diff file list. Now you should just be able to iterate it and read every file in it directly. 2012-04-05 10:16:23 -04:00
Christian Weeks c06fc00f24 Run Astyle over the FML code. Happy lex? 2012-04-05 10:07:52 -04:00
Christian Weeks 1e6eec768c OK. Now the script works 2012-04-05 08:42:10 -04:00
Christian Weeks 33d7d77775 Crap at writing good python apparently 2012-04-05 08:29:07 -04:00
Christian Weeks 83b060b573 Tweak file list script to print obf names 2012-04-05 08:25:04 -04:00
LexManos df656cb98d Merge remote-tracking branch 'origin/master' 2012-04-05 00:10:36 -07:00
LexManos cb21ddc438 Rebuilt patches with new scripts. 2012-04-05 00:10:13 -07:00
LexManos 7b45203461 Cleaned up update_patches to fix a few bugs. Updated applypatches to normalize the patch file's line endings to make them work cross platform. Added download_firnflower and setup script. As well as added the GnuWin32's diff binary, so windows can create patches as well. http://gnuwin32.sourceforge.net/ 2012-04-05 00:09:29 -07:00
LexManos ecb07e2abb Created eclipse workspace, should allow simple and quick access to working on FML 2012-04-05 00:06:11 -07:00
Christian Weeks 647c40ba5e Missed a couple of wording tweaks 2012-04-05 00:58:17 -04:00
Christian Weeks 9210fe1a57 Tweak the build a bit, add some more data and generate the
touched file list for forge
2012-04-04 11:05:31 -04:00
Christian Weeks 9efb9741d1 Tidy up some of the installation media 2012-04-04 09:48:36 -04:00
Christian Weeks 87b5c870d5 links to implementation 2012-04-03 23:09:22 -04:00
Christian Weeks bd34b97e9b Channel validation 2012-04-03 22:45:27 -04:00
Christian Weeks c74e119993 NetworkHandler doesn't care about channel ownership 2012-04-03 17:06:02 -04:00
Christian Weeks 96e23dda6b Update patches for network handler 2012-04-03 17:04:57 -04:00
Christian Weeks c6a0bc2487 Modloader complete 2012-04-03 17:04:26 -04:00
Christian Weeks d1efbce945 Generic container 2012-04-03 16:12:19 -04:00
Christian Weeks 381b2b8aa1 Config dir handling 2012-04-03 15:53:59 -04:00
Christian Weeks 72478fac83 MLProp 2012-04-03 15:41:25 -04:00
Christian Weeks c4fd53d628 Mod sorting 2012-04-03 12:03:21 -04:00
Christian Weeks ec4750f422 Everything except ordering 2012-04-02 23:06:30 -04:00
Christian Weeks bc0caee371 Fix build script for generating md5s 2012-04-02 18:12:49 -04:00
Christian Weeks 8087bd82bf Update to 1.2.5 and hopefully forge compatibility 2012-04-02 18:09:06 -04:00
Christian Weeks ec3fb620dc Forge support 2012-04-01 02:14:14 -04:00
Christian Weeks d6e5df9092 Initial attempts to support forge stuff 2012-03-31 02:28:14 -04:00
Christian Weeks 160399cee7 Fix NPE 2012-03-31 01:04:29 -04:00
Christian Weeks 4b4e4b30a9 More logging and maybe fix default package mods 2012-03-31 00:59:43 -04:00
Christian Weeks 67ed21052f Logging fun. Whee! 2012-03-31 00:52:50 -04:00
Christian Weeks 532f8cfce9 Fail 2012-03-31 00:46:47 -04:00
Christian Weeks a45af9ac39 More logging 2012-03-31 00:43:54 -04:00
Christian Weeks 3b487511d7 Tweak class loader 2012-03-31 00:22:08 -04:00
Christian Weeks a1cbb799be Add more patches 2012-03-30 22:28:12 -04:00
Christian Weeks 8b9545d622 Some implementation 2012-03-30 22:26:16 -04:00
Christian Weeks cd325dc3fd tweak MC server hook 2012-03-30 21:23:04 -04:00
Christian Weeks 9768774896 some build and logging tweaks 2012-03-30 21:21:43 -04:00
Christian Weeks e1781bf2ae Fix build 2012-03-30 21:10:43 -04:00
Christian Weeks b566a7b692 Fix derpy 2012-03-30 21:07:42 -04:00
Christian Weeks e7aa295b47 Tweak loader a bit 2012-03-30 21:03:25 -04:00
Christian Weeks 2d44b44372 Fix patching 2012-03-30 20:43:58 -04:00
Christian Weeks 17e19b8cc6 More build stuff 2012-03-30 20:38:31 -04:00
Christian Weeks e88b897635 More building fun 2012-03-30 17:36:50 -04:00
Christian Weeks 7a0bd95113 fix build script 2012-03-30 17:00:49 -04:00
Christian Weeks be52c01b9f Add in more ignore stuff and a sample "fmlbuild.properties" file 2012-03-30 16:42:11 -04:00
Christian Weeks c02319cec1 More build stuff, adding in readme etc copied from forge 2012-03-30 16:40:54 -04:00
Christian Weeks f7507d3f79 Move more stuff around 2012-03-30 16:25:49 -04:00
Christian Weeks 31d2c84541 Build system 2012-03-30 16:22:10 -04:00
Christian Weeks 84d4f7765c Start patching fun 2012-03-30 13:33:29 -04:00
Christian Weeks aed6bcc737 Ignore stuff 2012-03-30 11:35:35 -04:00
Christian Weeks 73e2229fb4 We're Forge Mod Loader, not Forge ModLoader 2012-03-30 11:35:04 -04:00
Christian Weeks a0633ae5e3 Tweak license to refer to github 2012-03-30 10:16:36 -04:00
Christian Weeks bdce70e891 Add licenses reorganize code 2012-03-30 10:11:13 -04:00
Christian Weeks 3197817a76 Starting to get somewhere 2012-03-30 01:12:59 -04:00
Christian Weeks 0a7e8a8c3e Thoughts on how to do the modloading properly 2012-03-28 16:44:36 -04:00
Christian Weeks b23bdc628b Tab cleanup 2012-03-28 13:29:23 -04:00
Christian Weeks d727aed293 Initial commit 2012-03-28 12:53:08 -04:00
650 changed files with 97964 additions and 34516 deletions

No files matched your search

+9 -2
View File
@@ -1,7 +1,14 @@
* text eol=lf
*.bat text eol=crlf
*.patch text
*.patch text eol=lf
*.java text eol=lf
*.gradle text eol=crlf
*.png binary
*.exe binary
*.dll binary
*.zip binary
*.jar binary
*.lzma binary
*.zip binary
*.pyd binary
*.cfg text eol=lf
*.py text eol=lf
+20 -6
View File
@@ -1,7 +1,21 @@
*.DS_Store
/logs/
/*.pyc
/forge-*/
/patches-old/
/mcp/
#eclipse
/bin
/.settings
/.classpath
#idea
/.idea
*.iml
#gradle
/build
/buildSrc
/.gradle
#occupational hazards
/eclipse/
/repo/
#Patch reject
*.rej
-3
View File
@@ -1,3 +0,0 @@
[submodule "fml"]
path = fml
url = https://github.com/MinecraftForge/FML.git
+27
View File
@@ -0,0 +1,27 @@
This is Forge Mod Loader.
You can find the source code at all times at https://github.com/MinecraftForge/FML
This minecraft mod is a clean open source implementation of a mod loader for
minecraft servers, minecraft bukkit servers, and minecraft clients.
The code is authored by cpw.
It (partially) implements API defined by the client side ModLoader, authored by Risugami.
http://www.minecraftforum.net/topic/75440-
It also contains suggestions and hints and generous helpings of code from LexManos, author of MinecraftForge.
http://www.minecraftforge.net/
Additionally, it contains an implementation of topological sort based on that
published at http://keithschwarz.com/interesting/code/?dir=topological-sort
It also contains code from the Maven project for performing versioned dependency
resolution. http://maven.apache.org/
It also contains a partial repackaging of the javaxdelta library from http://sourceforge.net/projects/javaxdelta/
with credit to it's authors.
Forge Mod Loader downloads components from the Minecraft Coder Pack
(http://mcp.ocean-labs.de/index.php/Main_Page) with kind permission from the MCP team.
+491
View File
@@ -0,0 +1,491 @@
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/MinecraftForge/FML
This software includes portions from the Apache Maven project at
http://maven.apache.org/ specifically the ComparableVersion.java code. It is
included based on guidelines at
http://www.softwarefreedom.org/resources/2007/gpl-non-gpl-collaboration.html
with notices intact. The only change is a non-functional change of package name.
This software contains a partial repackaging of javaxdelta, a BSD licensed program for generating
binary differences and applying them, sourced from the subversion at http://sourceforge.net/projects/javaxdelta/
authored by genman, heikok, pivot.
The only changes are to replace some Trove collection types with standard Java collections, and repackaged.
=== 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 ===
I grant permission for some parts of FML to be redistributed outside the terms of the LGPL, for the benefit of
the minecraft modding community. All contributions to these parts should be licensed under the same additional grant.
-- Runtime patcher --
License is granted to redistribute the runtime patcher code (common/cpw/mods/fml/patcher and subdirectories) under
any alternative open source license as classified by the OSI (http://opensource.org/licenses)
-- ASM transformers --
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
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
-6
View File
@@ -1,6 +0,0 @@
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.7.0_09-b30 (Oracle Corporation)
Main-Class: net.minecraft.server.MinecraftServer
Class-Path: minecraft_server.jar
+117
View File
@@ -0,0 +1,117 @@
This is Forge Mod Loader, or FML for short, by cpw.
More information can be found at https://github.com/MinecraftForge/FML/wiki
It is a clean reimplementation of a mod loading system for client, server and
bukkit use, incorporating API implementations of client side ModLoader by
Risugami.
It can be installed on its own, or as part of Minecraft Forge.
----------------------
About Forge Mod Loader
----------------------
Environments and compatibility
==============================
FML covers the three main environments: client, server and bukkit. All
environments share the main mod loading code base, with additional varying hooks
based on the specific environment. Compatibility is almost 100% with all
ModLoader based mods- any mod with any difficulty (unless noted below) should
be reported as a ticket to the github, please.
Client side mods should be 100% compatible with ModLoader. The only exception is
Optifine, however new versions of optifine are compatible. There are some very
visible changes to the client when FML is installed.
Server side mods are mostly compatible with previous MLMP based incarnations,
however, this compatibility is not guaranteed. Most mods have adapted to FML
and MLMP is not assured and will cause errors. Ask your mod author to update
to FML.
Bukkit side modding is an adaptation of the server side mod code to the bukkit
environment. Mods need to be recompiled against the bukkit decompilation to work
however there are guides and tools in development to make this process easier.
Consult mcportcentral.co.za for more information.
Minecraft Forge in all cases bundles FML as it's modloading technology of choice
because FML is open source, freely distributable, and can be easily updated by
contributors through github.
Notable integrations
====================
Optifine has FML compatibility. It varies from Optifine release to release, however
in general it will work well alongside an FML or
Minecraft Forge installation. FML will detect and ensure the good operation of
Optifine (you can see it in your client as an additional data line on the
bottom left).
Client notes
============
FML does provide a standard pattern for mods to provide HD textures. This is why
optifine needed integration code. FML supports HD texture packs
up to 128x resolution.
Mod information
===============
FML exposes the mod information through a mod list visible on the main screen as
well as some small branding enhancements. For full data mods need to provide an
information file. This file is a standard format so hopefully tools providing
launch capabilities can also leverage this content.
-------------------------------
Binary installation information
-------------------------------
If you have downloaded a binary zip file you can install it as follows (client
or server):
Installation
============
To install on a server, simply execute the FML or Forge jar file, with a copy of
minecraft_server.jar placed in the same directory. FML will launch it's patched
copy.
To install on a client, FIRST delete META-INF from the minecraft.jar file, then
copy the contents of the FML or Forge jar file into it. FML and Forge provide
their own META-INF data which should *not* be deleted.
Forge Installation
==================
This code also ships as a part of Minecraft Forge. You do not need to install it
separately from your Minecraft Forge installation. Minecraft Forge contains the
exact same code as this. Generally, you should not install FML if you are also
installing Minecraft Forge.
-------------------------------------------
Source installation information for modders
-------------------------------------------
This code follows the Minecraft Forge installation methodology. It will apply
some small patches to your MCP extracted source code, giving you and it access
to some of the data and functions you need to build a successful mod.
Note also that the patches are built against "unrenamed" MCP source code- this
means that you will not be able to read them directly against normal code.
Source pack installation information:
Standalone source installation
==============================
To install this source code for development purposes, extract this zip file
into an mcp installation containing vanilla jars only. It should create a new
folder "fml" inside that installation.
Be sure that you have both vanilla client jars, and the vanilla server jar installed
as per the MCP install instructions. Both are required for FML to run properly.
Once extracted, run the install.sh or install.bat script provided from the fml
directory. It should decompile and patch your MCP source code for the client
and server.
Forge source installation
=========================
MinecraftForge ships with this code and installs it as part of the forge
installation process, no further action is required on your part.
For reference this is version @MAJOR@.@MINOR@.@REV@.@BUILD@ of FML
for Minecraft version @MCVERSION@.
+110
View File
@@ -0,0 +1,110 @@
buildscript {
repositories {
mavenCentral()
mavenLocal()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.1-SNAPSHOT'
}
}
import static net.minecraftforge.gradle.dev.FmlDevPlugin.*
apply plugin: 'maven'
apply plugin: 'fmldev'
repositories {
flatDir {
name "fileRepo"
dirs "repo"
}
}
minecraft {
version = '1.7.2'
mcpVersion = '9.01-pre'
fmlDir = projectDir.getAbsolutePath();
mainClass = 'cpw.mods.fml.relauncher.ServerLaunchWrapper'
installerVersion = "1.4"
}
group = 'cpw.mods'
version = getVersionFromGit(getProject())
jenkins {
job = 'fml'
}
uploadArchives {
repositories {
if (project.hasProperty("filesmaven")) {
logger.info('Publishing to files server')
mavenDeployer {
configuration = configurations.deployerJars
repository(url: project.filesmaven.url) {
authentication(userName: project.filesmaven.username, privateKey: project.filesmaven.key)
}
pom {
groupId = project.group
version = project.version
artifactId = project.archivesBaseName
project {
name project.archivesBaseName
packaging 'jar'
description 'ForgeModLoader'
url 'https://github.com/MinecraftForge/FML'
scm {
url 'https://github.com/MinecraftForge/FML'
connection 'scm:git:git://github.com/MinecraftForge/FML.git'
developerConnection 'scm:git:[email protected]:MinecraftForge/FML.git'
}
issueManagement {
system 'github'
url 'https://github.com/MinecraftForge/FML/issues'
}
licenses {
license {
name 'GNU Lesser Public License (LGPL), Version 2.1'
url 'http://www.gnu.org/licenses/lgpl-2.1.txt'
distribution 'repo'
}
}
developers {
developer {
id 'cpw'
name 'cpw'
roles { role 'developer' }
}
developer {
id 'LexManos'
name 'Lex Manos'
roles { role 'developer' }
}
}
}
}
}
} else {
logger.info('Publishing to repo folder')
mavenDeployer {
repository(url: 'file://localhost/' + project.file('repo').getAbsolutePath())
}
}
}
}
-34
View File
@@ -1,34 +0,0 @@
import os, os.path, sys
from optparse import OptionParser
forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..')
from forge import build_forge_dev
def main():
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='MCP Path', default=None)
parser.add_option('-b', '--build', action='store', dest='build', help='Build number', default=None)
options, _ = parser.parse_args()
build_num = 0
if not options.build is None:
try:
build_num = int(options.build)
except:
pass
fml_dir = os.path.join(forge_dir, 'fml')
mcp_dir = os.path.join(forge_dir, 'mcp')
if not options.mcp_dir is None:
mcp_dir = os.path.abspath(options.mcp_dir)
elif os.path.isfile(os.path.join('..', 'runtime', 'commands.py')):
mcp_dir = os.path.abspath('..')
sys.exit(build_forge_dev(mcp_dir, forge_dir, fml_dir, build_num))
if __name__ == '__main__':
main()
-89
View File
@@ -1,89 +0,0 @@
import os, os.path, sys, re
import json, urllib2
from pprint import pprint
from urlparse import urlparse
import base64
import optparse, ast
class PreemptiveBasicAuthHandler(urllib2.BaseHandler):
def __init__(self, password_mgr=None):
if password_mgr is None:
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
self.passwd = password_mgr
self.add_password = self.passwd.add_password
def http_request(self,req):
uri = req.get_full_url()
user, pw = self.passwd.find_user_password(None,uri)
if pw is None: return req
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
req.add_unredirected_header('Authorization', auth)
return req
def https_request(self,req):
return self.http_request(req)
def getBuildInfo(url, current_version=None):
handler = PreemptiveBasicAuthHandler()
handler.add_password(None, 'jenkins.minecraftforge.net:81', 'console_script', 'fd584bffa72fcac12181f37f80001200')
file = urllib2.build_opener(handler).open(url)
data = file.read()
file.close()
data = ast.literal_eval(data)['allBuilds']
data = sorted(data, key=lambda key: key['number'], reverse=False)
items = []
output = []
for build in data:
build['actions'] = filter(lambda act: act is not None, build['actions'])
build['actions'] = filter(lambda act: 'text' in act, build['actions'])
build['actions'] = filter(lambda act: not ' ' in act['text'], build['actions'])
if len(build['actions']) == 0:
build['version'] = current_version
current_version = None
else:
build['version'] = build['actions'][0]['text']
build['items'] = build['changeSet']['items']
for item in build['items']:
item['author'] = item['author']['fullName']
if build['result'] != 'SUCCESS':
items += build['items']
else:
build['items'] = items + build['items']
items = []
output += [build]
build.pop('changeSet')
build.pop('actions')
return sorted(output, key=lambda key: key['number'], reverse=True)
def make_changelog(job_path, target_build, change_file, current_version=None):
builds = getBuildInfo('%s/api/python?tree=allBuilds[result,number,actions[text],changeSet[items[author[fullName],comment]]]&pretty=true' % job_path, current_version)
log = [ "Changelog:" ]
for build in builds:
if int(build['number']) > target_build: continue
if len(build['items']) == 0: continue
log.append('')
if build['version'] is None:
log.append('Build %s' % build['number'])
else:
log.append('Build %s' % build['version'])
for change in build['items']:
comments = filter(lambda cmt: len(cmt) > 0, change['comment'].split('\n'))
if len(comments) > 1:
log.append('\t' + change['author'])
for comment in comments:
log.append('\t\t' + comment)
elif len(comments) == 1:
log.append('\t%s: %s' % (change['author'], comments[0]))
file = open(change_file, 'wb')
for line in log:
file.write('%s\n' % line)
file.close()
if __name__ == '__main__':
make_changelog("http://jenkins.minecraftforge.net:81/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

-946
View File
@@ -1,946 +0,0 @@
package ibxm;
public class Channel {
public int pattern_loop_row;
private Module module;
private Instrument instrument;
private Sample sample;
private int[] global_volume, current_note;
private boolean linear_periods, fast_volume_slides, key_on, silent;
private int sample_idx, sample_frac, step, left_gain, right_gain;
private int volume, panning, fine_tune, period, porta_period, key_add;
private int tremolo_speed, tremolo_depth, tremolo_tick, tremolo_wave, tremolo_add;
private int vibrato_speed, vibrato_depth, vibrato_tick, vibrato_wave, vibrato_add;
private int volume_slide_param, portamento_param, retrig_param;
private int volume_envelope_tick, panning_envelope_tick;
private int effect_tick, trigger_tick, fade_out_volume, random_seed;
private int log_2_sampling_rate;
private static final int LOG_2_29024 = LogTable.log_2( 29024 );
private static final int LOG_2_8287 = LogTable.log_2( 8287 );
private static final int LOG_2_8363 = LogTable.log_2( 8363 );
private static final int LOG_2_1712 = LogTable.log_2( 1712 );
private static final int[] sine_table = new int[] {
0, 24 , 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253,
255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24
};
public Channel( Module mod, int sampling_rate, int[] global_vol ) {
module = mod;
global_volume = global_vol;
linear_periods = module.linear_periods;
fast_volume_slides = module.fast_volume_slides;
current_note = new int[ 5 ];
log_2_sampling_rate = LogTable.log_2( sampling_rate );
}
public void reset() {
tremolo_speed = 0;
tremolo_depth = 0;
tremolo_wave = 0;
vibrato_speed = 0;
vibrato_depth = 0;
vibrato_wave = 0;
volume_slide_param = 0;
portamento_param = 0;
retrig_param = 0;
random_seed = 0xABC123;
instrument = module.get_instrument( 0 );
row( 48, 256, 0, 0, 0 );
}
public void resample( int[] mixing_buffer, int frame_offset, int frames, int quality ) {
if( !silent ) {
switch( quality ) {
default:
sample.resample_nearest( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames );
break;
case 1:
sample.resample_linear( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames );
break;
case 2:
sample.resample_sinc( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames );
break;
}
}
}
public void update_sample_idx( int samples ) {
sample_frac += step * samples;
sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK;
}
public void set_volume( int vol ) {
if( vol < 0 ) {
vol = 0;
}
if( vol > 64 ) {
vol = 64;
}
volume = vol;
}
public void set_panning( int pan ) {
if( pan < 0 ) {
pan = 0;
}
if( pan > 255 ) {
pan = 255;
}
panning = pan;
}
public void row( int key, int inst_idx, int volume_column, int effect, int effect_param ) {
effect = effect & 0xFF;
if( effect >= 0x30 ) {
/* Effects above 0x30 are internal.*/
effect = 0;
}
if( effect == 0x00 && effect_param != 0 ) {
/* Arpeggio.*/
effect = 0x40;
}
if( effect == 0x0E ) {
/* Renumber 0x0Ex effect command.*/
effect = 0x30 + ( ( effect_param & 0xF0 ) >> 4 );
effect_param = effect_param & 0x0F;
}
if( effect == 0x21 ) {
/* Renumber 0x21x effect command.*/
effect = 0x40 + ( ( effect_param & 0xF0 ) >> 4 );
effect_param = effect_param & 0x0F;
}
current_note[ 0 ] = key;
current_note[ 1 ] = inst_idx;
current_note[ 2 ] = volume_column;
current_note[ 3 ] = effect;
current_note[ 4 ] = effect_param;
effect_tick = 0;
trigger_tick += 1;
update_envelopes();
key_add = 0;
vibrato_add = 0;
tremolo_add = 0;
if( ! ( effect == 0x3D && effect_param > 0 ) ) {
/* Not note delay.*/
trigger( key, inst_idx, volume_column, effect );
/* Handle volume column.*/
switch( volume_column & 0xF0 ) {
case 0x00:
/* Do nothing.*/
break;
case 0x60:
/* Volume slide down.*/
break;
case 0x70:
/* Volume slide up.*/
break;
case 0x80:
/* Fine volume slide down.*/
set_volume( volume - ( volume_column & 0x0F ) );
break;
case 0x90:
/* Fine volume slide up.*/
set_volume( volume + ( volume_column & 0x0F ) );
break;
case 0xA0:
/* Set vibrato speed.*/
set_vibrato_speed( volume_column & 0x0F );
break;
case 0xB0:
/* Vibrato.*/
set_vibrato_depth( volume_column & 0x0F );
vibrato();
break;
case 0xC0:
/* Set panning.*/
set_panning( ( volume_column & 0x0F ) << 4 );
break;
case 0xD0:
/* Panning slide left.*/
break;
case 0xE0:
/* Panning slide right.*/
break;
case 0xF0:
/* Tone portamento.*/
set_portamento_param( volume_column & 0x0F );
break;
default:
/* Set volume.*/
set_volume( volume_column - 0x10 );
break;
}
}
if( instrument.vibrato_depth > 0 ) {
auto_vibrato();
}
switch( effect ) {
case 0x01:
/* Portmento Up.*/
set_portamento_param( effect_param );
portamento_up();
break;
case 0x02:
/* Portamento Down.*/
set_portamento_param( effect_param );
portamento_down();
break;
case 0x03:
/* Tone Portamento.*/
set_portamento_param( effect_param );
break;
case 0x04:
/* Vibrato.*/
set_vibrato_speed( ( effect_param & 0xF0 ) >> 4 );
set_vibrato_depth( effect_param & 0x0F );
vibrato();
break;
case 0x05:
/* Tone Portamento + Volume Slide.*/
set_volume_slide_param( effect_param );
volume_slide();
break;
case 0x06:
/* Vibrato + Volume Slide.*/
set_volume_slide_param( effect_param );
vibrato();
volume_slide();
break;
case 0x07:
/* Tremolo.*/
set_tremolo_speed( ( effect_param & 0xF0 ) >> 4 );
set_tremolo_depth( effect_param & 0x0F );
tremolo();
break;
case 0x08:
/* Set Panning.*/
set_panning( effect_param );
break;
case 0x09:
/* Set Sample Index.*/
set_sample_index( effect_param << 8 );
break;
case 0x0A:
/* Volume Slide.*/
set_volume_slide_param( effect_param );
volume_slide();
break;
case 0x0B:
/* Pattern Jump.*/
break;
case 0x0C:
/* Set volume.*/
set_volume( effect_param );
break;
case 0x0D:
/* Pattern Break.*/
break;
case 0x0E:
/* Extended Commands (See 0x30-0x3F).*/
break;
case 0x0F:
/* Set Speed/Tempo.*/
break;
case 0x10:
/* Set Global Volume.*/
set_global_volume( effect_param );
break;
case 0x11:
/* global Volume Slide.*/
set_volume_slide_param( effect_param );
break;
case 0x14:
/* Key Off*/
if( effect_param == 0 ) {
key_on = false;
}
break;
case 0x15:
/* Set Envelope Tick.*/
set_envelope_tick( effect_param );
break;
case 0x19:
/* Panning Slide.*/
set_volume_slide_param( effect_param );
break;
case 0x1B:
/* Retrig + Volume Slide.*/
set_retrig_param( effect_param );
retrig_volume_slide();
break;
case 0x1D:
/* Tremor.*/
set_retrig_param( effect_param );
tremor();
break;
case 0x24:
/* S3M Fine Vibrato.*/
set_vibrato_speed( ( effect_param & 0xF0 ) >> 4 );
set_vibrato_depth( effect_param & 0x0F );
fine_vibrato();
break;
case 0x25:
/* S3M Set Speed.*/
break;
case 0x30:
/* Amiga Set Filter.*/
break;
case 0x31:
/* Fine Portamento Up.*/
set_portamento_param( 0xF0 | effect_param );
portamento_up();
break;
case 0x32:
/* Fine Portamento Down.*/
set_portamento_param( 0xF0 | effect_param );
portamento_down();
break;
case 0x33:
/* Set Glissando Mode.*/
break;
case 0x34:
/* Set Vibrato Waveform.*/
set_vibrato_wave( effect_param );
break;
case 0x35:
/* Set Fine Tune.*/
break;
case 0x36:
/* Pattern Loop.*/
break;
case 0x37:
/* Set Tremolo Waveform.*/
set_tremolo_wave( effect_param );
break;
case 0x38:
/* Set Panning(Obsolete).*/
break;
case 0x39:
/* Retrig.*/
set_retrig_param( effect_param );
break;
case 0x3A:
/* Fine Volume Slide Up.*/
set_volume_slide_param( ( effect_param << 4 ) | 0x0F );
volume_slide();
break;
case 0x3B:
/* Fine Volume Slide Down.*/
set_volume_slide_param( 0xF0 | effect_param );
volume_slide();
break;
case 0x3C:
/* Note Cut.*/
if( effect_param == 0 ) {
set_volume( 0 );
}
break;
case 0x3D:
/* Note Delay.*/
break;
case 0x3E:
/* Pattern Delay.*/
break;
case 0x3F:
/* Invert Loop.*/
break;
case 0x40:
/* Arpeggio.*/
break;
case 0x41:
/* Extra Fine Porta Up.*/
set_portamento_param( 0xE0 | effect_param );
portamento_up();
break;
case 0x42:
/* Extra Fine Porta Down.*/
set_portamento_param( 0xE0 | effect_param );
portamento_down();
break;
}
calculate_amplitude();
calculate_frequency();
}
public void tick() {
int volume_column, effect, effect_param;
volume_column = current_note[ 2 ];
effect = current_note[ 3 ];
effect_param = current_note[ 4 ];
effect_tick += 1;
if( effect == 0x3D && effect_param == effect_tick ) {
/* Note delay.*/
row( current_note[ 0 ], current_note[ 1 ], volume_column, 0, 0 );
} else {
trigger_tick += 1;
vibrato_tick += 1;
tremolo_tick += 1;
update_envelopes();
key_add = 0;
vibrato_add = 0;
tremolo_add = 0;
if( instrument.vibrato_depth > 0 ) {
auto_vibrato();
}
switch( volume_column & 0xF0 ) {
case 0x60:
/* Volume Slide Down.*/
set_volume( volume - ( volume_column & 0x0F ) );
break;
case 0x70:
/* Volume Slide Up.*/
set_volume( volume + ( volume_column & 0x0F ) );
break;
case 0xB0:
/* Vibrato.*/
vibrato();
break;
case 0xD0:
/* Panning Slide Left.*/
set_panning( panning - ( volume_column & 0x0F ) );
break;
case 0xE0:
/* Panning Slide Right.*/
set_panning( panning + ( volume_column & 0x0F ) );
break;
case 0xF0:
/* Tone Portamento.*/
tone_portamento();
break;
}
switch( effect ) {
case 0x01:
/* Portamento Up.*/
portamento_up();
break;
case 0x02:
/* Portamento Down.*/
portamento_down();
break;
case 0x03:
/* Tone Portamento.*/
tone_portamento();
break;
case 0x04:
/* Vibrato.*/
vibrato();
break;
case 0x05:
/* Tone Portamento + Volume Slide.*/
tone_portamento();
volume_slide();
break;
case 0x06:
/* Vibrato + Volume Slide */
vibrato();
volume_slide();
break;
case 0x07:
/* Tremolo.*/
tremolo();
break;
case 0x0A:
/* Volume Slide.*/
volume_slide();
break;
case 0x11:
/* Global Volume Slide.*/
global_volume_slide();
break;
case 0x14:
/* Key off.*/
if( effect_tick == effect_param ) {
key_on = false;
}
break;
case 0x19:
/* Panning Slide.*/
panning_slide();
break;
case 0x1B:
/* Retrig + Volume Slide.*/
retrig_volume_slide();
break;
case 0x1D:
/* Tremor.*/
tremor();
break;
case 0x24:
/* S3M Fine Vibrato.*/
fine_vibrato();
break;
case 0x39:
/* Retrig.*/
retrig_volume_slide();
break;
case 0x3C:
/* Note Cut.*/
if( effect_tick == effect_param ) {
set_volume( 0 );
}
break;
case 0x40:
/* Arpeggio.*/
switch( effect_tick % 3 ) {
case 1:
key_add = ( effect_param & 0xF0 ) >> 4;
break;
case 2:
key_add = effect_param & 0x0F;
break;
}
break;
}
}
calculate_amplitude();
calculate_frequency();
}
private void set_vibrato_speed( int speed ) {
if( speed > 0 ) {
vibrato_speed = speed;
}
}
private void set_vibrato_depth( int depth ) {
if( depth > 0 ) {
vibrato_depth = depth;
}
}
private void set_vibrato_wave( int wave ) {
if( wave < 0 || wave > 7 ) {
wave = 0;
}
vibrato_wave = wave;
}
private void set_tremolo_speed( int speed ) {
if( speed > 0 ) {
tremolo_speed = speed;
}
}
private void set_tremolo_depth( int depth ) {
if( depth > 0 ) {
tremolo_depth = depth;
}
}
private void set_tremolo_wave( int wave ) {
if( wave < 0 || wave > 7 ) {
wave = 0;
}
tremolo_wave = wave;
}
private void vibrato() {
int vibrato_phase;
vibrato_phase = vibrato_tick * vibrato_speed;
vibrato_add += waveform( vibrato_phase, vibrato_wave ) * vibrato_depth >> 5;
}
private void fine_vibrato() {
int vibrato_phase;
vibrato_phase = vibrato_tick * vibrato_speed;
vibrato_add += waveform( vibrato_phase, vibrato_wave ) * vibrato_depth >> 7;
}
private void tremolo() {
int tremolo_phase;
tremolo_phase = tremolo_tick * tremolo_speed;
tremolo_add += waveform( tremolo_phase, tremolo_wave ) * tremolo_depth >> 6;
}
private void set_portamento_param( int param ) {
if( param != 0 ) {
portamento_param = param;
}
}
private void tone_portamento() {
int new_period;
if( porta_period < period ) {
new_period = period - ( portamento_param << 2 );
if( new_period < porta_period ) {
new_period = porta_period;
}
set_period( new_period );
}
if( porta_period > period ) {
new_period = period + ( portamento_param << 2 );
if( new_period > porta_period ) {
new_period = porta_period;
}
set_period( new_period );
}
}
private void portamento_up() {
if( ( portamento_param & 0xF0 ) == 0xE0 ) {
/* Extra-fine porta.*/
if( effect_tick == 0 ) {
set_period( period - ( portamento_param & 0x0F ) );
}
} else if( ( portamento_param & 0xF0 ) == 0xF0 ) {
/* Fine porta.*/
if( effect_tick == 0 ) {
set_period( period - ( ( portamento_param & 0x0F ) << 2 ) );
}
} else {
/* Normal porta.*/
if( effect_tick > 0 ) {
set_period( period - ( portamento_param << 2 ) );
}
}
}
private void portamento_down() {
if( ( portamento_param & 0xF0 ) == 0xE0 ) {
/* Extra-fine porta.*/
if( effect_tick == 0 ) {
set_period( period + ( portamento_param & 0x0F ) );
}
} else if( ( portamento_param & 0xF0 ) == 0xF0 ) {
/* Fine porta.*/
if( effect_tick == 0 ) {
set_period( period + ( ( portamento_param & 0x0F ) << 2 ) );
}
} else {
/* Normal porta.*/
if( effect_tick > 0 ) {
set_period( period + ( portamento_param << 2 ) );
}
}
}
private void set_period( int p ) {
if( p < 32 ) {
p = 32;
}
if( p > 32768 ) {
p = 32768;
}
period = p;
}
private void set_global_volume( int vol ) {
if( vol < 0 ) {
vol = 0;
}
if( vol > 64 ) {
vol = 64;
}
global_volume[ 0 ] = vol;
}
private void set_volume_slide_param( int param ) {
if( param != 0 ) {
volume_slide_param = param;
}
}
private void global_volume_slide() {
int up, down;
up = ( volume_slide_param & 0xF0 ) >> 4;
down = volume_slide_param & 0x0F;
set_global_volume( global_volume[ 0 ] + up - down );
}
private void volume_slide() {
int up, down;
up = ( volume_slide_param & 0xF0 ) >> 4;
down = volume_slide_param & 0x0F;
if( down == 0x0F && up > 0 ) {
/* Fine slide up.*/
if( effect_tick == 0 ) {
set_volume( volume + up );
}
} else if( up == 0x0F && down > 0 ) {
/* Fine slide down.*/
if( effect_tick == 0 ) {
set_volume( volume - down );
}
} else {
/* Normal slide.*/
if( effect_tick > 0 || fast_volume_slides ) {
set_volume( volume + up - down );
}
}
}
private void panning_slide() {
int left, right;
left = ( volume_slide_param & 0xF0 ) >> 4;
right = volume_slide_param & 0x0F;
set_panning( panning - left + right );
}
private void set_retrig_param( int param ) {
if( param != 0 ) {
retrig_param = param;
}
}
private void tremor() {
int on_ticks, cycle_length, cycle_index;
on_ticks = ( ( retrig_param & 0xF0 ) >> 4 ) + 1;
cycle_length = on_ticks + ( retrig_param & 0x0F ) + 1;
cycle_index = trigger_tick % cycle_length;
if( cycle_index >= on_ticks ) {
tremolo_add = -64;
}
}
private void retrig_volume_slide() {
int retrig_volume, retrig_tick;
retrig_volume = ( retrig_param & 0xF0 ) >> 4;
retrig_tick = retrig_param & 0x0F;
if( retrig_tick > 0 && ( trigger_tick % retrig_tick ) == 0 ) {
set_sample_index( 0 );
switch( retrig_volume ) {
case 0x01:
set_volume( volume - 1 );
break;
case 0x02:
set_volume( volume - 2 );
break;
case 0x03:
set_volume( volume - 4 );
break;
case 0x04:
set_volume( volume - 8 );
break;
case 0x05:
set_volume( volume - 16 );
break;
case 0x06:
set_volume( volume - volume / 3 );
break;
case 0x07:
set_volume( volume / 2 );
break;
case 0x09:
set_volume( volume + 1 );
break;
case 0x0A:
set_volume( volume + 2 );
break;
case 0x0B:
set_volume( volume + 4 );
break;
case 0x0C:
set_volume( volume + 8 );
break;
case 0x0D:
set_volume( volume + 16 );
break;
case 0x0E:
set_volume( volume + volume / 2 );
break;
case 0x0F:
set_volume( volume * 2 );
break;
}
}
}
private void set_sample_index( int index ) {
if( index < 0 ) {
index = 0;
}
sample_idx = index;
sample_frac = 0;
}
private void set_envelope_tick( int tick ) {
volume_envelope_tick = tick;
panning_envelope_tick = tick;
}
private void trigger( int key, int instrument_idx, int volume_column, int effect ) {
if( instrument_idx > 0 ) {
instrument = module.get_instrument( instrument_idx );
sample = instrument.get_sample_from_key( key );
set_volume( sample.volume );
if( sample.set_panning ) {
set_panning( sample.panning );
}
set_envelope_tick( 0 );
fade_out_volume = 32768;
key_on = true;
}
if( key > 0 ) {
if( key < 97 ) {
porta_period = key_to_period( key );
if( effect != 0x03 && effect != 0x05 ) {
if( ( volume_column & 0xF0 ) != 0xF0 ) {
/* Not portamento.*/
trigger_tick = 0;
if( vibrato_wave < 4 ) {
vibrato_tick = 0;
}
if( tremolo_wave < 4 ) {
tremolo_tick = 0;
}
set_period( porta_period );
set_sample_index( 0 );
}
}
} else {
/* Key off.*/
key_on = false;
}
}
}
private void update_envelopes() {
Envelope envelope;
if( instrument.volume_envelope_active ) {
if( !key_on ) {
fade_out_volume -= instrument.volume_fade_out & 0xFFFF;
if( fade_out_volume < 0 ) {
fade_out_volume = 0;
}
}
envelope = instrument.get_volume_envelope();
volume_envelope_tick = envelope.next_tick( volume_envelope_tick, key_on );
}
if( instrument.panning_envelope_active ) {
envelope = instrument.get_panning_envelope();
panning_envelope_tick = envelope.next_tick( panning_envelope_tick, key_on );
}
}
private void auto_vibrato() {
int sweep, depth, rate;
sweep = instrument.vibrato_sweep & 0xFF;
depth = instrument.vibrato_depth & 0x0F;
rate = instrument.vibrato_rate & 0x3F;
if( trigger_tick < sweep ) {
depth = depth * trigger_tick / sweep;
}
vibrato_add += waveform( trigger_tick * rate, 0 ) * depth >> 9;
}
private int waveform( int phase, int wform ) {
int amplitude;
amplitude = 0;
switch( wform & 0x3 ) {
case 0:
/* Sine. */
if( ( phase & 0x20 ) == 0 ) {
amplitude = sine_table[ phase & 0x1F ];
} else {
amplitude = -sine_table[ phase & 0x1F ];
}
break;
case 1:
/* Saw. */
if( ( phase & 0x20 ) == 0 ) {
amplitude = ( phase & 0x1F ) << 3;
} else {
amplitude = ( ( phase & 0x1F ) << 3 ) - 255;
}
break;
case 2:
/* Square. */
if( ( phase & 0x20 ) == 0 ) {
amplitude = 255;
} else {
amplitude = -255;
}
break;
case 3:
/* Random. */
amplitude = ( random_seed >> 15 ) - 255;
random_seed = ( random_seed * 65 + 17 ) & 0xFFFFFF;
break;
}
return amplitude;
}
private int key_to_period( int key ) {
int octave, log_2_period, period_out;
octave = ( key << IBXM.FP_SHIFT ) / 12 + sample.transpose;
if( linear_periods ) {
period_out = 7744 - ( octave * 768 >> IBXM.FP_SHIFT );
} else {
log_2_period = LOG_2_29024 - octave;
period_out = LogTable.raise_2( log_2_period );
period_out = period_out >> ( IBXM.FP_SHIFT - 1 );
period_out = ( period_out >> 1 ) + ( period_out & 1 );
}
return period_out;
}
private void calculate_amplitude() {
int envelope_volume, tremolo_volume, amplitude;
int envelope_panning, mixer_panning, panning_range;
Envelope envelope;
envelope_volume = 0;
if( instrument.volume_envelope_active ) {
envelope = instrument.get_volume_envelope();
envelope_volume = envelope.calculate_ampl( volume_envelope_tick );
} else {
if( key_on ) {
envelope_volume = 64;
}
}
tremolo_volume = volume + tremolo_add;
if( tremolo_volume < 0 ) {
tremolo_volume = 0;
}
if( tremolo_volume > 64 ) {
tremolo_volume = 64;
}
amplitude = tremolo_volume << IBXM.FP_SHIFT - 6;
amplitude = amplitude * envelope_volume >> 6;
amplitude = amplitude * fade_out_volume >> 15;
amplitude = amplitude * global_volume[ 0 ] >> 6;
amplitude = amplitude * module.channel_gain >> IBXM.FP_SHIFT;
silent = sample.has_finished( sample_idx );
if( amplitude <= 0 ) {
silent = true;
} else {
envelope_panning = 32;
if( instrument.panning_envelope_active ) {
envelope = instrument.get_panning_envelope();
envelope_panning = envelope.calculate_ampl( panning_envelope_tick );
}
mixer_panning = ( panning & 0xFF ) << IBXM.FP_SHIFT - 8;
panning_range = IBXM.FP_ONE - mixer_panning;
if( panning_range > mixer_panning ) {
panning_range = mixer_panning;
}
mixer_panning = mixer_panning + ( panning_range * ( envelope_panning - 32 ) >> 5 );
left_gain = amplitude * ( IBXM.FP_ONE - mixer_panning ) >> IBXM.FP_SHIFT;
right_gain = amplitude * mixer_panning >> IBXM.FP_SHIFT;
}
}
private void calculate_frequency() {
int vibrato_period, log_2_freq;
vibrato_period = period + vibrato_add;
if( vibrato_period < 32 ) {
vibrato_period = 32;
}
if( vibrato_period > 32768 ) {
vibrato_period = 32768;
}
if( linear_periods ) {
log_2_freq = LOG_2_8363 + ( 4608 - vibrato_period << IBXM.FP_SHIFT ) / 768;
} else {
log_2_freq = module.pal ? LOG_2_8287 : LOG_2_8363;
log_2_freq = log_2_freq + LOG_2_1712 - LogTable.log_2( vibrato_period );
}
log_2_freq += ( key_add << IBXM.FP_SHIFT ) / 12;
step = LogTable.raise_2( log_2_freq - log_2_sampling_rate );
}
}
-111
View File
@@ -1,111 +0,0 @@
package ibxm;
public class Envelope {
public boolean sustain, looped;
private int sustain_tick, loop_start_tick, loop_end_tick;
private int[] ticks, ampls;
public Envelope() {
set_num_points( 1 );
}
public void set_num_points( int num_points ) {
int point;
if( num_points <= 0 ) {
num_points = 1;
}
ticks = new int[ num_points ];
ampls = new int[ num_points ];
set_point( 0, 0, 0, false );
}
/* When you set a point, all subsequent points are reset. */
public void set_point( int point, int tick, int ampl, boolean delta ) {
if( point >= 0 && point < ticks.length ) {
if( point == 0 ) {
tick = 0;
}
if( point > 0 ) {
if( delta ) tick += ticks[ point - 1 ];
if( tick <= ticks[ point - 1 ] ) {
System.out.println( "Envelope: Point not valid (" + tick + " <= " + ticks[ point - 1 ] + ")");
tick = ticks[ point - 1 ] + 1;
}
}
ticks[ point ] = tick;
ampls[ point ] = ampl;
point += 1;
while( point < ticks.length ) {
ticks[ point ] = ticks[ point - 1 ] + 1;
ampls[ point ] = 0;
point += 1;
}
}
}
public void set_sustain_point( int point ) {
if( point < 0 ) {
point = 0;
}
if( point >= ticks.length ) {
point = ticks.length - 1;
}
sustain_tick = ticks[ point ];
}
public void set_loop_points( int start, int end ) {
if( start < 0 ) {
start = 0;
}
if( start >= ticks.length ) {
start = ticks.length - 1;
}
if( end < start || end >= ticks.length ) {
end = start;
}
loop_start_tick = ticks[ start ];
loop_end_tick = ticks[ end ];
}
public int next_tick( int tick, boolean key_on ) {
tick = tick + 1;
if( looped && tick >= loop_end_tick ) {
tick = loop_start_tick;
}
if( sustain && key_on && tick >= sustain_tick ) {
tick = sustain_tick;
}
return tick;
}
public int calculate_ampl( int tick ) {
int idx, point, delta_t, delta_a, ampl;
ampl = ampls[ ticks.length - 1 ];
if( tick < ticks[ ticks.length - 1 ] ) {
point = 0;
for( idx = 1; idx < ticks.length; idx++ ) {
if( ticks[ idx ] <= tick ) {
point = idx;
}
}
delta_t = ticks[ point + 1 ] - ticks[ point ];
delta_a = ampls[ point + 1 ] - ampls[ point ];
ampl = ( delta_a << IBXM.FP_SHIFT ) / delta_t;
ampl = ampl * ( tick - ticks[ point ] ) >> IBXM.FP_SHIFT;
ampl = ampl + ampls[ point ];
}
return ampl;
}
public void dump() {
int idx, tick;
for( idx = 0; idx < ticks.length; idx++ ) {
System.out.println( ticks[ idx ] + ", " + ampls[ idx ] );
}
for( tick = 0; tick < 222; tick++ ) {
System.out.print( calculate_ampl( tick ) + ", " );
}
}
}
-256
View File
@@ -1,256 +0,0 @@
package ibxm;
import java.io.*;
public class FastTracker2 {
public static boolean is_xm( byte[] header_60_bytes ) {
String xm_identifier;
xm_identifier = ascii_text( header_60_bytes, 0, 17 );
return xm_identifier.equals( "Extended Module: " );
}
public static Module load_xm( byte[] header_60_bytes, DataInput data_input ) throws IOException {
int xm_version, song_header_length, sequence_length;
int num_channels, num_patterns, num_instruments, xm_flags, idx;
byte[] structure_header, song_header;
boolean delta_env;
String tracker_name;
Instrument instrument;
Module module;
if( !is_xm( header_60_bytes ) ) {
throw new IllegalArgumentException( "Not an XM file!" );
}
xm_version = unsigned_short_le( header_60_bytes, 58 );
if( xm_version != 0x0104 ) {
throw new IllegalArgumentException( "Sorry, XM version " + xm_version + " is not supported!" );
}
module = new Module();
module.song_title = ascii_text( header_60_bytes, 17, 20 );
tracker_name = ascii_text( header_60_bytes, 38, 20 );
delta_env = tracker_name.startsWith( "DigiBooster Pro" );
structure_header = new byte[ 4 ];
data_input.readFully( structure_header );
song_header_length = int_le( structure_header, 0 );
song_header = new byte[ song_header_length ];
data_input.readFully( song_header, 4, song_header_length - 4 );
sequence_length = unsigned_short_le( song_header, 4 );
module.restart_sequence_index = unsigned_short_le( song_header, 6 );
num_channels = unsigned_short_le( song_header, 8 );
num_patterns = unsigned_short_le( song_header, 10 );
num_instruments = unsigned_short_le( song_header, 12 );
xm_flags = unsigned_short_le( song_header, 14 );
module.linear_periods = ( xm_flags & 0x1 ) == 0x1;
module.global_volume = 64;
module.channel_gain = IBXM.FP_ONE * 3 / 8;
module.default_speed = unsigned_short_le( song_header, 16 );
module.default_tempo = unsigned_short_le( song_header, 18 );
module.set_num_channels( num_channels );
for( idx = 0; idx < num_channels; idx++ ) {
module.set_initial_panning( idx, 128 );
}
module.set_sequence_length( sequence_length );
for( idx = 0; idx < sequence_length; idx++ ) {
module.set_sequence( idx, song_header[ 20 + idx ] & 0xFF );
}
module.set_num_patterns( num_patterns );
for( idx = 0; idx < num_patterns; idx++ ) {
module.set_pattern( idx, read_xm_pattern( data_input, num_channels ) );
}
module.set_num_instruments( num_instruments );
for( idx = 1; idx <= num_instruments; idx++ ) {
try {
instrument = read_xm_instrument( data_input, delta_env );
module.set_instrument( idx, instrument );
} catch( EOFException e ) {
System.out.println( "Instrument " + idx + " is missing!" );
}
}
return module;
}
private static Pattern read_xm_pattern( DataInput data_input, int num_channels ) throws IOException {
int pattern_header_length, packing_type, num_rows, pattern_data_length;
byte[] structure_header, pattern_header, pattern_data;
Pattern pattern;
structure_header = new byte[ 4 ];
data_input.readFully( structure_header );
pattern_header_length = int_le( structure_header, 0 );
pattern_header = new byte[ pattern_header_length ];
data_input.readFully( pattern_header, 4, pattern_header_length - 4 );
packing_type = pattern_header[ 4 ];
if( packing_type != 0 ) {
throw new IllegalArgumentException( "Pattern packing type " + packing_type + " is not supported!" );
}
pattern = new Pattern();
pattern.num_rows = unsigned_short_le( pattern_header, 5 );
pattern_data_length = unsigned_short_le( pattern_header, 7 );
pattern_data = new byte[ pattern_data_length ];
data_input.readFully( pattern_data );
pattern.set_pattern_data( pattern_data );
return pattern;
}
private static Instrument read_xm_instrument( DataInput data_input, boolean delta_env ) throws IOException {
int instrument_header_length, num_samples, idx;
int env_tick, env_ampl, env_num_points, flags;
byte[] structure_header, instrument_header, sample_headers;
Instrument instrument;
Envelope envelope;
structure_header = new byte[ 4 ];
data_input.readFully( structure_header );
instrument_header_length = int_le( structure_header, 0 );
instrument_header = new byte[ instrument_header_length ];
data_input.readFully( instrument_header, 4, instrument_header_length - 4 );
instrument = new Instrument();
instrument.name = ascii_text( instrument_header, 4, 22 );
num_samples = unsigned_short_le( instrument_header, 27 );
if( num_samples > 0 ) {
instrument.set_num_samples( num_samples );
for( idx = 0; idx < 96; idx++ ) {
instrument.set_key_to_sample( idx + 1, instrument_header[ 33 + idx ] & 0xFF );
}
envelope = new Envelope();
env_num_points = instrument_header[ 225 ] & 0xFF;
envelope.set_num_points( env_num_points );
for( idx = 0; idx < env_num_points; idx++ ) {
env_tick = unsigned_short_le( instrument_header, 129 + idx * 4 );
env_ampl = unsigned_short_le( instrument_header, 131 + idx * 4 );
envelope.set_point( idx, env_tick, env_ampl, delta_env );
}
envelope.set_sustain_point( instrument_header[ 227 ] & 0xFF );
envelope.set_loop_points( instrument_header[ 228 ] & 0xFF, instrument_header[ 229 ] & 0xFF );
flags = instrument_header[ 233 ] & 0xFF;
instrument.volume_envelope_active = ( flags & 0x1 ) == 0x1;
envelope.sustain = ( flags & 0x2 ) == 0x2;
envelope.looped = ( flags & 0x4 ) == 0x4;
instrument.set_volume_envelope( envelope );
envelope = new Envelope();
env_num_points = instrument_header[ 226 ] & 0xFF;
envelope.set_num_points( env_num_points );
for( idx = 0; idx < env_num_points; idx++ ) {
env_tick = unsigned_short_le( instrument_header, 177 + idx * 4 );
env_ampl = unsigned_short_le( instrument_header, 179 + idx * 4 );
envelope.set_point( idx, env_tick, env_ampl, delta_env );
}
envelope.set_sustain_point( instrument_header[ 230 ] & 0xFF );
envelope.set_loop_points( instrument_header[ 231 ] & 0xFF, instrument_header[ 232 ] & 0xFF );
flags = instrument_header[ 234 ] & 0xFF;
instrument.panning_envelope_active = ( flags & 0x1 ) == 0x1;
envelope.sustain = ( flags & 0x2 ) == 0x2;
envelope.looped = ( flags & 0x4 ) == 0x4;
instrument.set_panning_envelope( envelope );
instrument.vibrato_type = instrument_header[ 235 ] & 0xFF;
instrument.vibrato_sweep = instrument_header[ 236 ] & 0xFF;
instrument.vibrato_depth = instrument_header[ 237 ] & 0xFF;
instrument.vibrato_rate = instrument_header[ 238 ] & 0xFF;
instrument.volume_fade_out = unsigned_short_le( instrument_header, 239 );
sample_headers = new byte[ num_samples * 40 ];
data_input.readFully( sample_headers );
for( idx = 0; idx < num_samples; idx++ ) {
instrument.set_sample( idx, read_xm_sample( sample_headers, idx, data_input ) );
}
}
return instrument;
}
private static Sample read_xm_sample( byte[] sample_headers, int sample_idx, DataInput data_input ) throws IOException {
int header_offset, sample_length, loop_start, loop_length;
int flags, in_idx, out_idx, sam, last_sam;
int fine_tune, relative_note;
boolean sixteen_bit, ping_pong;
byte[] raw_sample_data;
short[] decoded_sample_data;
Sample sample;
header_offset = sample_idx * 40;
sample = new Sample();
sample_length = int_le( sample_headers, header_offset );
loop_start = int_le( sample_headers, header_offset + 4 );
loop_length = int_le( sample_headers, header_offset + 8 );
sample.volume = sample_headers[ header_offset + 12 ] & 0xFF;
fine_tune = sample_headers[ header_offset + 13 ];
fine_tune = ( fine_tune << IBXM.FP_SHIFT ) / 1536;
sample.set_panning = true;
flags = sample_headers[ header_offset + 14 ] & 0xFF;
if( ( flags & 0x03 ) == 0 ) {
loop_length = 0;
}
ping_pong = ( flags & 0x02 ) == 0x02;
sixteen_bit = ( flags & 0x10 ) == 0x10;
sample.panning = sample_headers[ header_offset + 15 ] & 0xFF;
relative_note = sample_headers[ header_offset + 16 ];
relative_note = ( relative_note << IBXM.FP_SHIFT ) / 12;
sample.transpose = relative_note + fine_tune;
sample.name = ascii_text( sample_headers, header_offset + 18, 22 );
raw_sample_data = new byte[ sample_length ];
try {
data_input.readFully( raw_sample_data );
} catch( EOFException e ) {
System.out.println( "Sample has been truncated!" );
}
in_idx = 0;
out_idx = 0;
sam = 0;
last_sam = 0;
if( sixteen_bit ) {
decoded_sample_data = new short[ sample_length >> 1 ];
while( in_idx < raw_sample_data.length ) {
sam = raw_sample_data[ in_idx ] & 0xFF;
sam = sam | ( ( raw_sample_data[ in_idx + 1 ] & 0xFF ) << 8 );
last_sam = last_sam + sam;
decoded_sample_data[ out_idx ] = ( short ) last_sam;
in_idx += 2;
out_idx += 1;
}
sample.set_sample_data( decoded_sample_data, loop_start >> 1, loop_length >> 1, ping_pong );
} else {
decoded_sample_data = new short[ sample_length ];
while( in_idx < raw_sample_data.length ) {
sam = raw_sample_data[ in_idx ] & 0xFF;
last_sam = last_sam + sam;
decoded_sample_data[ out_idx ] = ( short ) ( last_sam << 8 );
in_idx += 1;
out_idx += 1;
}
sample.set_sample_data( decoded_sample_data, loop_start, loop_length, ping_pong );
}
return sample;
}
private static int unsigned_short_le( byte[] buffer, int offset ) {
int value;
value = buffer[ offset ] & 0xFF;
value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 );
return value;
}
private static int int_le( byte[] buffer, int offset ) {
int value;
value = buffer[ offset ] & 0xFF;
value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 );
value = value | ( ( buffer[ offset + 2 ] & 0xFF ) << 16 );
value = value | ( ( buffer[ offset + 3 ] & 0x7F ) << 24 );
return value;
}
private static String ascii_text( byte[] buffer, int offset, int length ) {
int idx, chr;
byte[] string_buffer;
String string;
string_buffer = new byte[ length ];
for( idx = 0; idx < length; idx++ ) {
chr = buffer[ offset + idx ];
if( chr < 32 ) {
chr = 32;
}
string_buffer[ idx ] = ( byte ) chr;
}
try {
string = new String( string_buffer, 0, length, "ISO-8859-1" );
} catch( UnsupportedEncodingException e ) {
string = "";
}
return string;
}
}
-343
View File
@@ -1,343 +0,0 @@
package ibxm;
public class IBXM {
public static final String VERSION = "ibxm alpha 51 (c)2008 [email protected]";
public static final int FP_SHIFT = 15;
public static final int FP_ONE = 1 << FP_SHIFT;
public static final int FP_MASK = FP_ONE - 1;
private int sampling_rate, resampling_quality, volume_ramp_length;
private int tick_length_samples, current_tick_samples;
private int[] mixing_buffer, volume_ramp_buffer;
private Module module;
private Channel[] channels;
private int[] global_volume, note;
private int current_sequence_index, next_sequence_index;
private int current_row, next_row;
private int tick_counter, ticks_per_row;
private int pattern_loop_count, pattern_loop_channel;
public IBXM( int sample_rate ) {
/** MODIFIED 13 Oct 2009 by Paul Lamb **/
// System.out.println( VERSION );
/***************************************/
if( sample_rate < 8000 ) {
sample_rate = 8000;
}
sampling_rate = sample_rate;
volume_ramp_length = sampling_rate >> 10;
volume_ramp_buffer = new int[ volume_ramp_length * 2 ];
mixing_buffer = new int[ sampling_rate / 6 ];
global_volume = new int[ 1 ];
note = new int[ 5 ];
set_module( new Module() );
set_resampling_quality( 1 );
}
public void set_module( Module m ) {
int channel_idx;
module = m;
channels = new Channel[ module.get_num_channels() ];
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ] = new Channel( module, sampling_rate, global_volume );
}
set_sequence_index( 0, 0 );
}
public void set_resampling_quality( int quality ) {
resampling_quality = quality;
}
public int calculate_song_duration() {
int song_duration;
set_sequence_index( 0, 0 );
next_tick();
song_duration = tick_length_samples;
while( !next_tick() ) {
song_duration += tick_length_samples;
}
set_sequence_index( 0, 0 );
return song_duration;
}
public void set_sequence_index( int sequence_index, int row ) {
int channel_idx;
global_volume[ 0 ] = 64;
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ].reset();
channels[ channel_idx ].set_panning( module.get_initial_panning( channel_idx ) );
}
set_global_volume( module.global_volume );
set_speed( 6 );
set_speed( module.default_speed );
set_tempo( 125 );
set_tempo( module.default_tempo );
pattern_loop_count = -1;
next_sequence_index = sequence_index;
next_row = row;
tick_counter = 0;
current_tick_samples = tick_length_samples;
clear_vol_ramp_buffer();
}
public void seek( int sample_position ) {
int idx;
set_sequence_index( 0, 0 );
next_tick();
while( sample_position > tick_length_samples ) {
sample_position -= tick_length_samples;
next_tick();
}
mix_tick();
current_tick_samples = sample_position;
}
public void get_audio( byte[] output_buffer, int frames ) {
int output_idx, mix_idx, mix_end, count, amplitude;
output_idx = 0;
while( frames > 0 ) {
count = tick_length_samples - current_tick_samples;
if( count > frames ) {
count = frames;
}
mix_idx = current_tick_samples << 1;
mix_end = mix_idx + ( count << 1 ) - 1;
while( mix_idx <= mix_end ) {
amplitude = mixing_buffer[ mix_idx ];
if( amplitude > 32767 ) {
amplitude = 32767;
}
if( amplitude < -32768 ) {
amplitude = -32768;
}
output_buffer[ output_idx ] = ( byte ) ( amplitude >> 8 );
output_buffer[ output_idx + 1 ] = ( byte ) ( amplitude & 0xFF );
output_idx += 2;
mix_idx += 1;
}
current_tick_samples = mix_idx >> 1;
frames -= count;
if( frames > 0 ) {
next_tick();
mix_tick();
current_tick_samples = 0;
}
}
}
private void mix_tick() {
int channel_idx, mix_idx, mix_len;
mix_idx = 0;
mix_len = tick_length_samples + volume_ramp_length << 1;
while( mix_idx < mix_len ) {
mixing_buffer[ mix_idx ] = 0;
mix_idx += 1;
}
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
mix_len = tick_length_samples + volume_ramp_length;
channels[ channel_idx ].resample( mixing_buffer, 0, mix_len, resampling_quality );
}
volume_ramp();
}
private boolean next_tick() {
int channel_idx;
boolean song_end;
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ].update_sample_idx( tick_length_samples );
}
tick_counter -= 1;
if( tick_counter <= 0 ) {
tick_counter = ticks_per_row;
song_end = next_row();
} else {
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ].tick();
}
song_end = false;
}
return song_end;
}
private boolean next_row() {
int channel_idx, effect, effect_param;
boolean song_end;
Pattern pattern;
song_end = false;
if( next_sequence_index < 0 ) {
/* Bad next sequence index.*/
next_sequence_index = 0;
next_row = 0;
}
if( next_sequence_index >= module.get_sequence_length() ) {
/* End of sequence.*/
song_end = true;
next_sequence_index = module.restart_sequence_index;
if( next_sequence_index < 0 ) {
next_sequence_index = 0;
}
if( next_sequence_index >= module.get_sequence_length() ) {
next_sequence_index = 0;
}
next_row = 0;
}
if( next_sequence_index < current_sequence_index ) {
/* Jump to previous pattern. */
song_end = true;
}
if( next_sequence_index == current_sequence_index ) {
if( next_row <= current_row ) {
if( pattern_loop_count < 0 ) {
/* Jump to previous row in the same pattern, but not a pattern loop. */
song_end = true;
}
}
}
current_sequence_index = next_sequence_index;
pattern = module.get_pattern_from_sequence( current_sequence_index );
if( next_row < 0 || next_row >= pattern.num_rows ) {
/* Bad next row.*/
next_row = 0;
}
current_row = next_row;
next_row = current_row + 1;
if( next_row >= pattern.num_rows ) {
next_sequence_index = current_sequence_index + 1;
next_row = 0;
}
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
pattern.get_note( note, current_row * channels.length + channel_idx );
effect = note[ 3 ];
effect_param = note[ 4 ];
channels[ channel_idx ].row( note[ 0 ], note[ 1 ], note[ 2 ], effect, effect_param );
switch( effect ) {
case 0x0B:
/* Pattern Jump.*/
if( pattern_loop_count < 0 ) {
next_sequence_index = effect_param;
next_row = 0;
}
break;
case 0x0D:
/* Pattern Break.*/
if( pattern_loop_count < 0 ) {
next_sequence_index = current_sequence_index + 1;
next_row = ( effect_param >> 4 ) * 10 + ( effect_param & 0x0F );
}
break;
case 0x0E:
/* Extended.*/
switch( effect_param & 0xF0 ) {
case 0x60:
/* Pattern loop.*/
if( ( effect_param & 0x0F ) == 0 ) {
/* Set loop marker on this channel. */
channels[ channel_idx ].pattern_loop_row = current_row;
}
if( channels[ channel_idx ].pattern_loop_row < current_row ) {
/* Marker and parameter are valid. Begin looping. */
if( pattern_loop_count < 0 ) {
/* Not already looping, begin. */
pattern_loop_count = effect_param & 0x0F;
pattern_loop_channel = channel_idx;
}
if( pattern_loop_channel == channel_idx ) {
/* Loop in progress on this channel. Next iteration. */
if( pattern_loop_count == 0 ) {
/* Loop finished. */
/* Invalidate current marker. */
channels[ channel_idx ].pattern_loop_row = current_row + 1;
} else {
/* Count must be higher than zero. */
/* Loop and cancel any breaks on this row. */
next_row = channels[ channel_idx ].pattern_loop_row;
next_sequence_index = current_sequence_index;
}
pattern_loop_count -= 1;
}
}
break;
case 0xE0:
/* Pattern delay.*/
tick_counter += ticks_per_row * ( effect_param & 0x0F );
break;
}
break;
case 0x0F:
/* Set Speed/Tempo.*/
if( effect_param < 32 ) {
set_speed( effect_param );
tick_counter = ticks_per_row;
} else {
set_tempo( effect_param );
}
break;
case 0x25:
/* S3M Set Speed.*/
set_speed( effect_param );
tick_counter = ticks_per_row;
break;
}
}
return song_end;
}
private void set_global_volume( int volume ) {
if( volume < 0 ) {
volume = 0;
}
if( volume > 64 ) {
volume = 64;
}
global_volume[ 0 ] = volume;
}
private void set_speed( int speed ) {
if( speed > 0 && speed < 256 ) {
ticks_per_row = speed;
}
}
private void set_tempo( int bpm ) {
if( bpm > 31 && bpm < 256 ) {
tick_length_samples = ( sampling_rate * 5 ) / ( bpm * 2 );
}
}
private void volume_ramp() {
int ramp_idx, next_idx, ramp_end;
int volume_ramp_delta, volume, sample;
sample = 0;
volume_ramp_delta = FP_ONE / volume_ramp_length;
volume = 0;
ramp_idx = 0;
next_idx = 2 * tick_length_samples;
ramp_end = volume_ramp_length * 2 - 1;
while( ramp_idx <= ramp_end ) {
sample = volume_ramp_buffer[ ramp_idx ] * ( FP_ONE - volume ) >> FP_SHIFT;
mixing_buffer[ ramp_idx ] = sample + ( mixing_buffer[ ramp_idx ] * volume >> FP_SHIFT );
volume_ramp_buffer[ ramp_idx ] = mixing_buffer[ next_idx + ramp_idx ];
sample = volume_ramp_buffer[ ramp_idx + 1 ] * ( FP_ONE - volume ) >> FP_SHIFT;
mixing_buffer[ ramp_idx + 1 ] = sample + ( mixing_buffer[ ramp_idx + 1 ] * volume >> FP_SHIFT );
volume_ramp_buffer[ ramp_idx + 1 ] = mixing_buffer[ next_idx + ramp_idx + 1 ];
volume += volume_ramp_delta;
ramp_idx += 2;
}
}
private void clear_vol_ramp_buffer() {
int ramp_idx, ramp_end;
ramp_idx = 0;
ramp_end = volume_ramp_length * 2 - 1;
while( ramp_idx <= ramp_end ) {
volume_ramp_buffer[ ramp_idx ] = 0;
ramp_idx += 1;
}
}
}
-90
View File
@@ -1,90 +0,0 @@
package ibxm;
public class Instrument {
public String name;
public int vibrato_type, vibrato_sweep;
public int vibrato_depth, vibrato_rate;
public boolean volume_envelope_active, panning_envelope_active;
public int volume_fade_out;
private Envelope volume_envelope, panning_envelope;
private int[] key_to_sample;
private Sample[] samples;
public Instrument() {
name = "";
set_volume_envelope( new Envelope() );
set_panning_envelope( new Envelope() );
key_to_sample = new int[ 96 ];
set_num_samples( 1 );
}
public Envelope get_volume_envelope() {
return volume_envelope;
}
public void set_volume_envelope( Envelope envelope ) {
if( envelope != null ) {
volume_envelope = envelope;
}
}
public Envelope get_panning_envelope() {
return panning_envelope;
}
public void set_panning_envelope( Envelope envelope ) {
if( envelope != null ) {
panning_envelope = envelope;
}
}
public Sample get_sample_from_key( int key ) {
int sample_idx;
sample_idx = 0;
if( key > 0 && key <= key_to_sample.length ) {
sample_idx = key_to_sample[ key - 1 ];
}
return get_sample( sample_idx );
}
public void set_key_to_sample( int key, int sample ) {
if( key > 0 && key <= key_to_sample.length ) {
key_to_sample[ key - 1 ] = sample;
}
}
public int get_num_samples() {
return samples.length;
}
public void set_num_samples( int num_samples ) {
if( num_samples < 1 ) {
num_samples = 1;
}
samples = new Sample[ num_samples ];
set_sample( 0, null );
}
public Sample get_sample( int sample_index ) {
Sample sample;
sample = null;
if( sample_index >= 0 && sample_index < samples.length ) {
sample = samples[ sample_index ];
}
if( sample == null ) {
sample = samples[ 0 ];
}
return sample;
}
public void set_sample( int sample_index, Sample sample ) {
if( sample_index >= 0 && sample_index < samples.length ) {
samples[ sample_index ] = sample;
}
if( samples[ 0 ] == null ) {
samples[ 0 ] = new Sample();
}
}
}
-91
View File
@@ -1,91 +0,0 @@
package ibxm;
/*
Base-2 Log and Exp functions, using linear-interpolated tables.
*/
public class LogTable {
private static final int TABLE_SHIFT = 7; // 128 points (+1 for interp)
private static final int INTERP_SHIFT = IBXM.FP_SHIFT - TABLE_SHIFT;
private static final int INTERP_MASK = ( 1 << INTERP_SHIFT ) - 1;
private static final int[] exp_2_table = {
32768, 32945, 33124, 33304, 33485, 33667, 33850, 34033,
34218, 34404, 34591, 34779, 34968, 35157, 35348, 35540,
35733, 35927, 36122, 36319, 36516, 36714, 36913, 37114,
37315, 37518, 37722, 37926, 38132, 38339, 38548, 38757,
38967, 39179, 39392, 39606, 39821, 40037, 40254, 40473,
40693, 40914, 41136, 41359, 41584, 41810, 42037, 42265,
42494, 42725, 42957, 43190, 43425, 43661, 43898, 44136,
44376, 44617, 44859, 45103, 45347, 45594, 45841, 46090,
46340, 46592, 46845, 47099, 47355, 47612, 47871, 48131,
48392, 48655, 48919, 49185, 49452, 49720, 49990, 50262,
50535, 50809, 51085, 51362, 51641, 51922, 52204, 52487,
52772, 53059, 53347, 53636, 53928, 54220, 54515, 54811,
55108, 55408, 55709, 56011, 56315, 56621, 56928, 57238,
57548, 57861, 58175, 58491, 58809, 59128, 59449, 59772,
60096, 60423, 60751, 61081, 61412, 61746, 62081, 62418,
62757, 63098, 63440, 63785, 64131, 64479, 64830, 65182,
65536
};
private static final int[] log_2_table = {
0, 367, 732, 1095, 1454, 1811, 2165, 2517,
2865, 3212, 3556, 3897, 4236, 4572, 4906, 5238,
5568, 5895, 6220, 6542, 6863, 7181, 7497, 7812,
8124, 8434, 8742, 9048, 9352, 9654, 9954, 10252,
10548, 10843, 11136, 11427, 11716, 12003, 12289, 12573,
12855, 13136, 13414, 13692, 13967, 14241, 14514, 14785,
15054, 15322, 15588, 15853, 16117, 16378, 16639, 16898,
17156, 17412, 17667, 17920, 18172, 18423, 18673, 18921,
19168, 19413, 19657, 19900, 20142, 20383, 20622, 20860,
21097, 21333, 21568, 21801, 22034, 22265, 22495, 22724,
22952, 23178, 23404, 23628, 23852, 24074, 24296, 24516,
24736, 24954, 25171, 25388, 25603, 25817, 26031, 26243,
26455, 26665, 26875, 27084, 27292, 27499, 27705, 27910,
28114, 28317, 28520, 28721, 28922, 29122, 29321, 29519,
29716, 29913, 30109, 30304, 30498, 30691, 30884, 31076,
31267, 31457, 31646, 31835, 32023, 32210, 32397, 32582,
32768
};
/*
Calculate log-base-2 of x (non-fixed-point).
A fixed point value is returned.
*/
public static int log_2( int x ) {
int shift;
/* Scale x to range 1.0 <= x < 2.0 */
shift = IBXM.FP_SHIFT;
while( x < IBXM.FP_ONE ) {
x <<= 1;
shift--;
}
while( x >= ( IBXM.FP_ONE << 1 ) ) {
x >>= 1;
shift++;
}
return ( IBXM.FP_ONE * shift ) + eval_table( log_2_table, x - IBXM.FP_ONE );
}
/*
Raise 2 to the power x (fixed point).
A fixed point value is returned.
*/
public static int raise_2( int x ) {
int y;
y = eval_table( exp_2_table, x & IBXM.FP_MASK ) << IBXM.FP_SHIFT;
return y >> IBXM.FP_SHIFT - ( x >> IBXM.FP_SHIFT );
}
private static int eval_table( int[] table, int x ) {
int table_idx, table_frac, c, m, y;
table_idx = x >> INTERP_SHIFT;
table_frac = x & INTERP_MASK;
c = table[ table_idx ];
m = table[ table_idx + 1 ] - c;
y = ( m * table_frac >> INTERP_SHIFT ) + c;
return y >> 15 - IBXM.FP_SHIFT;
}
}
-138
View File
@@ -1,138 +0,0 @@
package ibxm;
public class Module {
public String song_title;
public boolean linear_periods, fast_volume_slides, pal;
public int global_volume, channel_gain;
public int default_speed, default_tempo;
public int restart_sequence_index;
private int[] initial_panning, sequence;
private Pattern[] patterns;
private Instrument[] instruments;
private Pattern default_pattern;
private Instrument default_instrument;
public Module() {
song_title = IBXM.VERSION;
set_num_channels( 1 );
set_sequence_length( 1 );
set_num_patterns( 0 );
set_num_instruments( 0 );
default_pattern = new Pattern();
default_instrument = new Instrument();
}
public int get_num_channels() {
return initial_panning.length;
}
public void set_num_channels( int num_channels ) {
if( num_channels < 1 ) {
num_channels = 1;
}
initial_panning = new int[ num_channels ];
}
public int get_initial_panning( int channel ) {
int panning;
panning = 128;
if( channel >= 0 && channel < initial_panning.length ) {
panning = initial_panning[ channel ];
}
return panning;
}
public void set_initial_panning( int channel, int panning ) {
if( channel >= 0 && channel < initial_panning.length ) {
initial_panning[ channel ] = panning;
}
}
public int get_sequence_length() {
return sequence.length;
}
public void set_sequence_length( int sequence_length ) {
if( sequence_length < 0 ) {
sequence_length = 0;
}
sequence = new int[ sequence_length ];
}
public void set_sequence( int sequence_index, int pattern_index ) {
if( sequence_index >= 0 && sequence_index < sequence.length ) {
sequence[ sequence_index ] = pattern_index;
}
}
public int get_num_patterns() {
return patterns.length;
}
public void set_num_patterns( int num_patterns ) {
if( num_patterns < 0 ) {
num_patterns = 0;
}
patterns = new Pattern[ num_patterns ];
}
public Pattern get_pattern_from_sequence( int sequence_index ) {
Pattern pattern;
pattern = default_pattern;
if( sequence_index >= 0 && sequence_index < sequence.length ) {
pattern = get_pattern( sequence[ sequence_index ] );
}
return pattern;
}
public Pattern get_pattern( int pattern_index ) {
Pattern pattern;
pattern = null;
if( pattern_index >= 0 && pattern_index < patterns.length ) {
pattern = patterns[ pattern_index ];
}
if( pattern == null ) {
pattern = default_pattern;
}
return pattern;
}
public void set_pattern( int pattern_index, Pattern pattern ) {
if( pattern_index >= 0 && pattern_index < patterns.length ) {
patterns[ pattern_index ] = pattern;
}
}
public int get_num_instruments() {
return instruments.length;
}
public void set_num_instruments( int num_instruments ) {
if( num_instruments < 0 ) {
num_instruments = 0;
}
instruments = new Instrument[ num_instruments ];
}
public Instrument get_instrument( int instrument_index ) {
Instrument instrument;
instrument = null;
if( instrument_index > 0 && instrument_index <= instruments.length ) {
instrument = instruments[ instrument_index - 1 ];
}
if( instrument == null ) {
instrument = default_instrument;
}
return instrument;
}
public void set_instrument( int instrument_index, Instrument instrument ) {
if( instrument_index > 0 && instrument_index <= instruments.length ) {
instruments[ instrument_index - 1 ] = instrument;
}
}
}
-61
View File
@@ -1,61 +0,0 @@
package ibxm;
public class Pattern {
public int num_rows;
private int data_offset, note_index;
private byte[] pattern_data;
public Pattern() {
num_rows = 1;
set_pattern_data( new byte[ 0 ] );
}
public void set_pattern_data( byte[] data ) {
if( data != null ) {
pattern_data = data;
}
data_offset = 0;
note_index = 0;
}
public void get_note( int[] note, int index ) {
if( index < note_index ) {
note_index = 0;
data_offset = 0;
}
while( note_index <= index ) {
data_offset = next_note( data_offset, note );
note_index += 1;
}
}
public int next_note( int data_offset, int[] note ) {
int bitmask, field;
if( data_offset < 0 ) {
data_offset = pattern_data.length;
}
bitmask = 0x80;
if( data_offset < pattern_data.length ) {
bitmask = pattern_data[ data_offset ] & 0xFF;
}
if( ( bitmask & 0x80 ) == 0x80 ) {
data_offset += 1;
} else {
bitmask = 0x1F;
}
for( field = 0; field < 5; field++ ) {
note[ field ] = 0;
if( ( bitmask & 0x01 ) == 0x01 ) {
if( data_offset < pattern_data.length ) {
note[ field ] = pattern_data[ data_offset ] & 0xFF;
data_offset += 1;
}
}
bitmask = bitmask >> 1;
}
return data_offset;
}
}
-132
View File
@@ -1,132 +0,0 @@
package ibxm;
import java.io.*;
import javax.sound.sampled.*;
public class Player {
private Thread play_thread;
private IBXM ibxm;
private Module module;
private int song_duration, play_position;
private boolean running, loop;
private byte[] output_buffer;
private SourceDataLine output_line;
/**
Simple command-line test player.
*/
public static void main( String[] args ) throws Exception {
if( args.length < 1 ) {
System.err.println( "Usage: java ibxm.Player <module file>" );
System.exit( 0 );
}
FileInputStream file_input_stream = new FileInputStream( args[ 0 ] );
Player player = new Player();
player.set_module( Player.load_module( file_input_stream ) );
file_input_stream.close();
player.play();
}
/**
Decode the data in the specified InputStream into a Module instance.
@param input an InputStream containing the module file to be decoded.
@throws IllegalArgumentException if the data is not recognised as a module file.
*/
public static Module load_module( InputStream input ) throws IllegalArgumentException, IOException {
DataInputStream data_input_stream = new DataInputStream( input );
/* Check if data is in XM format.*/
byte[] xm_header = new byte[ 60 ];
data_input_stream.readFully( xm_header );
if( FastTracker2.is_xm( xm_header ) )
return FastTracker2.load_xm( xm_header, data_input_stream );
/* Check if data is in ScreamTracker 3 format.*/
byte[] s3m_header = new byte[ 96 ];
System.arraycopy( xm_header, 0, s3m_header, 0, 60 );
data_input_stream.readFully( s3m_header, 60, 36 );
if( ScreamTracker3.is_s3m( s3m_header ) )
return ScreamTracker3.load_s3m( s3m_header, data_input_stream );
/* Check if data is in ProTracker format.*/
byte[] mod_header = new byte[ 1084 ];
System.arraycopy( s3m_header, 0, mod_header, 0, 96 );
data_input_stream.readFully( mod_header, 96, 988 );
return ProTracker.load_mod( mod_header, data_input_stream );
}
/**
Instantiate a new Player.
*/
public Player() throws LineUnavailableException {
ibxm = new IBXM( 48000 );
set_loop( true );
output_line = AudioSystem.getSourceDataLine( new AudioFormat( 48000, 16, 2, true, true ) );
output_buffer = new byte[ 1024 * 4 ];
}
/**
Set the Module instance to be played.
*/
public void set_module( Module m ) {
if( m != null ) module = m;
stop();
ibxm.set_module( module );
song_duration = ibxm.calculate_song_duration();
}
/**
If loop is true, playback will continue indefinitely,
otherwise the module will play through once and stop.
*/
public void set_loop( boolean loop ) {
this.loop = loop;
}
/**
Open the audio device and begin playback.
If a module is already playing it will be restarted.
*/
public void play() {
stop();
play_thread = new Thread( new Driver() );
play_thread.start();
}
/**
Stop playback and close the audio device.
*/
public void stop() {
running = false;
if( play_thread != null ) {
try {
play_thread.join();
} catch( InterruptedException ie ) {}
}
}
private class Driver implements Runnable {
public void run() {
if( running ) return;
try {
output_line.open();
output_line.start();
play_position = 0;
running = true;
while( running ) {
int frames = song_duration - play_position;
if( frames > 1024 ) frames = 1024;
ibxm.get_audio( output_buffer, frames );
output_line.write( output_buffer, 0, frames * 4 );
play_position += frames;
if( play_position >= song_duration ) {
play_position = 0;
if( !loop ) running = false;
}
}
output_line.drain();
output_line.close();
} catch( LineUnavailableException lue ) {
lue.printStackTrace();
}
}
}
}
-234
View File
@@ -1,234 +0,0 @@
package ibxm;
import java.io.*;
public class ProTracker {
public static boolean is_mod( byte[] header_1084_bytes ) {
boolean is_mod;
is_mod = false;
if( calculate_num_channels( header_1084_bytes ) > 0 ) {
is_mod = true;
}
return is_mod;
}
public static Module load_mod( byte[] header_1084_bytes, DataInput data_input ) throws IOException {
int num_channels, channel_idx, panning;
int sequence_length, restart_idx, sequence_idx;
int num_patterns, pattern_idx, instrument_idx;
Module module;
num_channels = calculate_num_channels( header_1084_bytes );
if( num_channels < 1 ) {
throw new IllegalArgumentException( "ProTracker: Unrecognised module format!" );
}
module = new Module();
module.song_title = ascii_text( header_1084_bytes, 0, 20 );
module.pal = ( num_channels == 4 );
module.global_volume = 64;
module.channel_gain = IBXM.FP_ONE * 3 / 8;
module.default_speed = 6;
module.default_tempo = 125;
module.set_num_channels( num_channels );
for( channel_idx = 0; channel_idx < num_channels; channel_idx++ ) {
panning = 64;
if( ( channel_idx & 0x03 ) == 0x01 || ( channel_idx & 0x03 ) == 0x02 ) {
panning = 192;
}
module.set_initial_panning( channel_idx, panning );
}
sequence_length = header_1084_bytes[ 950 ] & 0x7F;
restart_idx = header_1084_bytes[ 951 ] & 0x7F;
if( restart_idx >= sequence_length ) {
restart_idx = 0;
}
module.restart_sequence_index = restart_idx;
module.set_sequence_length( sequence_length );
for( sequence_idx = 0; sequence_idx < sequence_length; sequence_idx++ ) {
module.set_sequence( sequence_idx, header_1084_bytes[ 952 + sequence_idx ] & 0x7F );
}
num_patterns = calculate_num_patterns( header_1084_bytes );
module.set_num_patterns( num_patterns );
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
module.set_pattern( pattern_idx, read_mod_pattern( data_input, num_channels ) );
}
module.set_num_instruments( 31 );
for( instrument_idx = 1; instrument_idx <= 31; instrument_idx++ ) {
module.set_instrument( instrument_idx, read_mod_instrument( header_1084_bytes, instrument_idx, data_input ) );
}
return module;
}
private static int calculate_num_patterns( byte[] module_header ) {
int num_patterns, order_entry, pattern_idx;
num_patterns = 0;
for( pattern_idx = 0; pattern_idx < 128; pattern_idx++ ) {
order_entry = module_header[ 952 + pattern_idx ] & 0x7F;
if( order_entry >= num_patterns ) {
num_patterns = order_entry + 1;
}
}
return num_patterns;
}
private static int calculate_num_channels( byte[] module_header ) {
int num_channels;
switch( ( module_header[ 1082 ] << 8 ) | module_header[ 1083 ] ) {
case 0x4b2e: /* M.K. */
case 0x4b21: /* M!K! */
case 0x542e: /* N.T. */
case 0x5434: /* FLT4 */
num_channels = 4;
break;
case 0x484e: /* xCHN */
num_channels = module_header[ 1080 ] - 48;
break;
case 0x4348: /* xxCH */
num_channels = ( ( module_header[ 1080 ] - 48 ) * 10 ) + ( module_header[ 1081 ] - 48 );
break;
default:
/* Not recognised. */
num_channels = 0;
break;
}
return num_channels;
}
private static Pattern read_mod_pattern( DataInput data_input, int num_channels ) throws IOException {
int input_idx, output_idx;
int period, instrument, effect, effect_param;
Pattern pattern;
byte[] input_pattern_data, output_pattern_data;
pattern = new Pattern();
pattern.num_rows = 64;
input_pattern_data = new byte[ 64 * num_channels * 4 ];
output_pattern_data = new byte[ 64 * num_channels * 5 ];
data_input.readFully( input_pattern_data );
input_idx = 0;
output_idx = 0;
while( input_idx < input_pattern_data.length ) {
period = ( input_pattern_data[ input_idx ] & 0x0F ) << 8;
period = period | ( input_pattern_data[ input_idx + 1 ] & 0xFF );
output_pattern_data[ output_idx ] = to_key( period );
instrument = input_pattern_data[ input_idx ] & 0x10;
instrument = instrument | ( ( input_pattern_data[ input_idx + 2 ] & 0xF0 ) >> 4 );
output_pattern_data[ output_idx + 1 ] = ( byte ) instrument;
effect = input_pattern_data[ input_idx + 2 ] & 0x0F;
effect_param = input_pattern_data[ input_idx + 3 ] & 0xFF;
if( effect == 0x01 && effect_param == 0 ) {
/* Portamento up of zero has no effect. */
effect = 0;
}
if( effect == 0x02 && effect_param == 0 ) {
/* Portamento down of zero has no effect. */
effect = 0;
}
if( effect == 0x08 && num_channels == 4 ) {
/* Some Amiga mods use effect 0x08 for reasons other than panning.*/
effect = 0;
effect_param = 0;
}
if( effect == 0x0A && effect_param == 0 ) {
/* Volume slide of zero has no effect.*/
effect = 0;
}
if( effect == 0x05 && effect_param == 0 ) {
/* Porta + Volume slide of zero has no effect.*/
effect = 0x03;
}
if( effect == 0x06 && effect_param == 0 ) {
/* Vibrato + Volume slide of zero has no effect.*/
effect = 0x04;
}
output_pattern_data[ output_idx + 3 ] = ( byte ) effect;
output_pattern_data[ output_idx + 4 ] = ( byte ) effect_param;
input_idx += 4;
output_idx += 5;
}
pattern.set_pattern_data( output_pattern_data );
return pattern;
}
private static Instrument read_mod_instrument( byte[] mod_header, int idx, DataInput data_input ) throws IOException {
int header_offset, sample_data_length;
int loop_start, loop_length, sample_idx, fine_tune;
Instrument instrument;
Sample sample;
byte[] raw_sample_data;
short[] sample_data;
header_offset = ( idx - 1 ) * 30 + 20;
instrument = new Instrument();
instrument.name = ascii_text( mod_header, header_offset, 22 );
sample = new Sample();
sample_data_length = unsigned_short_be( mod_header, header_offset + 22 ) << 1;
fine_tune = mod_header[ header_offset + 24 ] & 0x0F;
if( fine_tune > 7 ) {
fine_tune -= 16;
}
sample.transpose = ( fine_tune << IBXM.FP_SHIFT ) / 96;
sample.volume = mod_header[ header_offset + 25 ] & 0x7F;
loop_start = unsigned_short_be( mod_header, header_offset + 26 ) << 1;
loop_length = unsigned_short_be( mod_header, header_offset + 28 ) << 1;
if( loop_length < 4 ) {
loop_length = 0;
}
raw_sample_data = new byte[ sample_data_length ];
sample_data = new short[ sample_data_length ];
try {
data_input.readFully( raw_sample_data );
} catch( EOFException e ) {
System.out.println( "ProTracker: Instrument " + idx + " has samples missing." );
}
for( sample_idx = 0; sample_idx < raw_sample_data.length; sample_idx++ ) {
sample_data[ sample_idx ] = ( short ) ( raw_sample_data[ sample_idx ] << 8 );
}
sample.set_sample_data( sample_data, loop_start, loop_length, false );
instrument.set_num_samples( 1 );
instrument.set_sample( 0, sample );
return instrument;
}
private static byte to_key( int period ) {
int oct, key;
if( period < 32 ) {
key = 0;
} else {
oct = LogTable.log_2( 7256 ) - LogTable.log_2( period );
if( oct < 0 ) {
key = 0;
} else {
key = oct * 12;
key = key >> ( IBXM.FP_SHIFT - 1 );
key = ( key >> 1 ) + ( key & 1 );
}
}
return ( byte ) key;
}
private static int unsigned_short_be( byte[] buf, int offset ) {
int value;
value = ( buf[ offset ] & 0xFF ) << 8;
value = value | ( buf[ offset + 1 ] & 0xFF );
return value;
}
private static String ascii_text( byte[] buffer, int offset, int length ) {
int idx, chr;
byte[] string_buffer;
String string;
string_buffer = new byte[ length ];
for( idx = 0; idx < length; idx++ ) {
chr = buffer[ offset + idx ];
if( chr < 32 ) {
chr = 32;
}
string_buffer[ idx ] = ( byte ) chr;
}
try {
string = new String( string_buffer, 0, length, "ISO-8859-1" );
} catch( UnsupportedEncodingException e ) {
string = "";
}
return string;
}
}
-239
View File
@@ -1,239 +0,0 @@
package ibxm;
public class Sample {
public String name;
public boolean set_panning;
public int volume, panning;
public int transpose;
private int loop_start, loop_length;
private short[] sample_data;
/* For the sinc interpolator.*/
private static final int POINT_SHIFT = 4;
private static final int POINTS = 1 << POINT_SHIFT;
private static final int OVERLAP = POINTS >> 1;
private static final int INTERP_SHIFT = IBXM.FP_SHIFT - 4;
private static final int INTERP_BITMASK = ( 1 << INTERP_SHIFT ) - 1;
private static final short[] sinc_table = {
0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0, 0,
0, 0, -5, 36, -142, 450, -1439, 32224, 2302, -974, 455, -190, 64, -15, 2, 0,
0, 6, -33, 128, -391, 1042, -2894, 31584, 4540, -1765, 786, -318, 105, -25, 3, 0,
0, 10, -55, 204, -597, 1533, -4056, 30535, 6977, -2573, 1121, -449, 148, -36, 5, 0,
-1, 13, -71, 261, -757, 1916, -4922, 29105, 9568, -3366, 1448, -578, 191, -47, 7, 0,
-1, 15, -81, 300, -870, 2185, -5498, 27328, 12263, -4109, 1749, -698, 232, -58, 9, 0,
-1, 15, -86, 322, -936, 2343, -5800, 25249, 15006, -4765, 2011, -802, 269, -68, 10, 0,
-1, 15, -87, 328, -957, 2394, -5849, 22920, 17738, -5298, 2215, -885, 299, -77, 12, 0,
0, 14, -83, 319, -938, 2347, -5671, 20396, 20396, -5671, 2347, -938, 319, -83, 14, 0,
0, 12, -77, 299, -885, 2215, -5298, 17738, 22920, -5849, 2394, -957, 328, -87, 15, -1,
0, 10, -68, 269, -802, 2011, -4765, 15006, 25249, -5800, 2343, -936, 322, -86, 15, -1,
0, 9, -58, 232, -698, 1749, -4109, 12263, 27328, -5498, 2185, -870, 300, -81, 15, -1,
0, 7, -47, 191, -578, 1448, -3366, 9568, 29105, -4922, 1916, -757, 261, -71, 13, -1,
0, 5, -36, 148, -449, 1121, -2573, 6977, 30535, -4056, 1533, -597, 204, -55, 10, 0,
0, 3, -25, 105, -318, 786, -1765, 4540, 31584, -2894, 1042, -391, 128, -33, 6, 0,
0, 2, -15, 64, -190, 455, -974, 2302, 32224, -1439, 450, -142, 36, -5, 0, 0,
0, 0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0
};
public Sample() {
name = "";
set_sample_data( new short[ 0 ], 0, 0, false );
}
public void set_sample_data( short[] data, int loop_start, int loop_length, boolean ping_pong ) {
int offset;
short sample;
if( loop_start < 0 ) {
loop_start = 0;
}
if( loop_start >= data.length ) {
loop_start = data.length - 1;
}
if( loop_start + loop_length > data.length ) {
loop_length = data.length - loop_start;
}
if( loop_length <= 1 ) {
sample_data = new short[ OVERLAP + data.length + OVERLAP * 3 ];
System.arraycopy( data, 0, sample_data, OVERLAP, data.length );
offset = 0;
while( offset < OVERLAP ) {
sample = sample_data[ OVERLAP + data.length - 1 ];
sample = ( short ) ( sample * ( OVERLAP - offset ) / OVERLAP );
sample_data[ OVERLAP + data.length + offset ] = sample;
offset += 1;
}
loop_start = OVERLAP + data.length + OVERLAP;
loop_length = 1;
} else {
if( ping_pong ) {
sample_data = new short[ OVERLAP + loop_start + loop_length * 2 + OVERLAP * 2 ];
System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length );
offset = 0;
while( offset < loop_length ) {
sample = data[ loop_start + loop_length - offset - 1 ];
sample_data[ OVERLAP + loop_start + loop_length + offset ] = sample;
offset += 1;
}
loop_start = loop_start + OVERLAP;
loop_length = loop_length * 2;
} else {
sample_data = new short[ OVERLAP + loop_start + loop_length + OVERLAP * 2 ];
System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length );
loop_start = loop_start + OVERLAP;
}
offset = 0;
while( offset < OVERLAP * 2 ) {
sample = sample_data[ loop_start + offset ];
sample_data[ loop_start + loop_length + offset ] = sample;
offset += 1;
}
}
this.loop_start = loop_start;
this.loop_length = loop_length;
}
public void resample_nearest(
int sample_idx, int sample_frac, int step, int left_gain, int right_gain,
int[] mix_buffer, int frame_offset, int frames ) {
int loop_end, offset, end, max_sample_idx;
sample_idx += OVERLAP;
loop_end = loop_start + loop_length - 1;
offset = frame_offset << 1;
end = ( frame_offset + frames - 1 ) << 1;
while( frames > 0 ) {
if( sample_idx > loop_end ) {
if( loop_length <= 1 ) {
break;
}
sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length;
}
max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT );
if( max_sample_idx > loop_end ) {
while( sample_idx <= loop_end ) {
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT;
sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK;
}
} else {
while( offset <= end ) {
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT;
sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK;
}
}
frames = ( end - offset + 2 ) >> 1;
}
}
public void resample_linear(
int sample_idx, int sample_frac, int step, int left_gain, int right_gain,
int[] mix_buffer, int frame_offset, int frames ) {
int loop_end, offset, end, max_sample_idx, amplitude;
sample_idx += OVERLAP;
loop_end = loop_start + loop_length - 1;
offset = frame_offset << 1;
end = ( frame_offset + frames - 1 ) << 1;
while( frames > 0 ) {
if( sample_idx > loop_end ) {
if( loop_length <= 1 ) {
break;
}
sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length;
}
max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT );
if( max_sample_idx > loop_end ) {
while( sample_idx <= loop_end ) {
amplitude = sample_data[ sample_idx ];
amplitude += ( sample_data[ sample_idx + 1 ] - amplitude ) * sample_frac >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * right_gain >> IBXM.FP_SHIFT;
sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK;
}
} else {
while( offset <= end ) {
amplitude = sample_data[ sample_idx ];
amplitude += ( sample_data[ sample_idx + 1 ] - amplitude ) * sample_frac >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * right_gain >> IBXM.FP_SHIFT;
sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK;
}
}
frames = ( end - offset + 2 ) >> 1;
}
}
public void resample_sinc(
int sample_idx, int sample_frac, int step, int left_gain, int right_gain,
int[] mix_buffer, int frame_offset, int frames ) {
int offset, end, loop_end, table_idx, a1, a2, amplitude;
loop_end = loop_start + loop_length - 1;
offset = frame_offset << 1;
end = ( frame_offset + frames - 1 ) << 1;
while( offset <= end ) {
if( sample_idx > loop_end ) {
if( loop_length <= 1 ) {
break;
}
sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length;
}
table_idx = ( sample_frac >> INTERP_SHIFT ) << POINT_SHIFT;
a1 = sinc_table[ table_idx + 0 ] * sample_data[ sample_idx + 0 ] >> 15;
a1 += sinc_table[ table_idx + 1 ] * sample_data[ sample_idx + 1 ] >> 15;
a1 += sinc_table[ table_idx + 2 ] * sample_data[ sample_idx + 2 ] >> 15;
a1 += sinc_table[ table_idx + 3 ] * sample_data[ sample_idx + 3 ] >> 15;
a1 += sinc_table[ table_idx + 4 ] * sample_data[ sample_idx + 4 ] >> 15;
a1 += sinc_table[ table_idx + 5 ] * sample_data[ sample_idx + 5 ] >> 15;
a1 += sinc_table[ table_idx + 6 ] * sample_data[ sample_idx + 6 ] >> 15;
a1 += sinc_table[ table_idx + 7 ] * sample_data[ sample_idx + 7 ] >> 15;
a1 += sinc_table[ table_idx + 8 ] * sample_data[ sample_idx + 8 ] >> 15;
a1 += sinc_table[ table_idx + 9 ] * sample_data[ sample_idx + 9 ] >> 15;
a1 += sinc_table[ table_idx + 10 ] * sample_data[ sample_idx + 10 ] >> 15;
a1 += sinc_table[ table_idx + 11 ] * sample_data[ sample_idx + 11 ] >> 15;
a1 += sinc_table[ table_idx + 12 ] * sample_data[ sample_idx + 12 ] >> 15;
a1 += sinc_table[ table_idx + 13 ] * sample_data[ sample_idx + 13 ] >> 15;
a1 += sinc_table[ table_idx + 14 ] * sample_data[ sample_idx + 14 ] >> 15;
a1 += sinc_table[ table_idx + 15 ] * sample_data[ sample_idx + 15 ] >> 15;
a2 = sinc_table[ table_idx + 16 ] * sample_data[ sample_idx + 0 ] >> 15;
a2 += sinc_table[ table_idx + 17 ] * sample_data[ sample_idx + 1 ] >> 15;
a2 += sinc_table[ table_idx + 18 ] * sample_data[ sample_idx + 2 ] >> 15;
a2 += sinc_table[ table_idx + 19 ] * sample_data[ sample_idx + 3 ] >> 15;
a2 += sinc_table[ table_idx + 20 ] * sample_data[ sample_idx + 4 ] >> 15;
a2 += sinc_table[ table_idx + 21 ] * sample_data[ sample_idx + 5 ] >> 15;
a2 += sinc_table[ table_idx + 22 ] * sample_data[ sample_idx + 6 ] >> 15;
a2 += sinc_table[ table_idx + 23 ] * sample_data[ sample_idx + 7 ] >> 15;
a2 += sinc_table[ table_idx + 24 ] * sample_data[ sample_idx + 8 ] >> 15;
a2 += sinc_table[ table_idx + 25 ] * sample_data[ sample_idx + 9 ] >> 15;
a2 += sinc_table[ table_idx + 26 ] * sample_data[ sample_idx + 10 ] >> 15;
a2 += sinc_table[ table_idx + 27 ] * sample_data[ sample_idx + 11 ] >> 15;
a2 += sinc_table[ table_idx + 28 ] * sample_data[ sample_idx + 12 ] >> 15;
a2 += sinc_table[ table_idx + 29 ] * sample_data[ sample_idx + 13 ] >> 15;
a2 += sinc_table[ table_idx + 30 ] * sample_data[ sample_idx + 14 ] >> 15;
a2 += sinc_table[ table_idx + 31 ] * sample_data[ sample_idx + 15 ] >> 15;
amplitude = a1 + ( ( a2 - a1 ) * ( sample_frac & INTERP_BITMASK ) >> INTERP_SHIFT );
mix_buffer[ offset ] += amplitude * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset + 1 ] += amplitude * right_gain >> IBXM.FP_SHIFT;
offset += 2;
sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK;
}
}
public boolean has_finished( int sample_idx ) {
boolean finished;
finished = false;
if( loop_length <= 1 && sample_idx > loop_start ) {
finished = true;
}
return finished;
}
}
-489
View File
@@ -1,489 +0,0 @@
package ibxm;
import java.io.*;
public class ScreamTracker3 {
private static final int[] effect_map = new int[] {
0xFF,
0x25, /* A: Set Speed.*/
0x0B, /* B: Pattern Jump.*/
0x0D, /* C: Pattern Break.*/
0x0A, /* D: Volume Slide.*/
0x02, /* E: Portamento Down.*/
0x01, /* F: Portamento Up.*/
0x03, /* G: Tone Portamento.*/
0x04, /* H: Vibrato.*/
0x1D, /* I: Tremor.*/
0x00, /* J: Arpeggio.*/
0x06, /* K: Vibrato + Volume Slide.*/
0x05, /* L: Tone Portamento + Volume Slide.*/
0xFF, /* M: */
0xFF, /* N: */
0x09, /* O: Sample Offset.*/
0xFF, /* P: */
0x1B, /* Q: Retrig + Volume Slide.*/
0x07, /* R: Tremolo.*/
0x0E, /* S: Extended Effects.*/
0x0F, /* T: Set Tempo.*/
0x24, /* U: Fine Vibrato.*/
0x10, /* V: Set Global Volume. */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF
};
private static final int[] effect_s_map = new int[] {
0x00, /* 0: Set Filter.*/
0x03, /* 1: Glissando.*/
0x05, /* 2: Set Fine Tune.*/
0x04, /* 3: Set Vibrato Waveform.*/
0x07, /* 4: Set Tremolo Waveform.*/
0xFF, /* 5: */
0xFF, /* 6: */
0xFF, /* 7: */
0x08, /* 8: Set Panning.*/
0xFF, /* 9: */
0x09, /* A: Stereo Control.*/
0x06, /* B: Pattern Loop.*/
0x0C, /* C: Note Cut.*/
0x0D, /* D: Note Delay.*/
0x0E, /* E: Pattern Delay.*/
0x0F /* F: Invert Loop.*/
};
public static boolean is_s3m( byte[] header_96_bytes ) {
String s3m_identifier;
s3m_identifier = ascii_text( header_96_bytes, 44, 4 );
return s3m_identifier.equals( "SCRM" );
}
public static Module load_s3m( byte[] header_96_bytes, DataInput data_input ) throws IOException {
int num_pattern_orders, num_instruments, num_patterns, num_channels;
int flags, tracker_version, master_volume, panning, channel_config, sequence_length;
int instrument_idx, pattern_idx, channel_idx, order_idx, panning_offset;
boolean signed_samples, stereo_mode, default_panning;
int[] channel_map, sequence;
byte[] s3m_file;
Module module;
Instrument instrument;
s3m_file = read_s3m_file( header_96_bytes, data_input );
module = new Module();
module.song_title = ascii_text( s3m_file, 0, 28 );
num_pattern_orders = get_num_pattern_orders( s3m_file );
num_instruments = get_num_instruments( s3m_file );
num_patterns = get_num_patterns( s3m_file );
flags = unsigned_short_le( s3m_file, 38 );
tracker_version = unsigned_short_le( s3m_file, 40 );
if( ( flags & 0x40 ) == 0x40 || tracker_version == 0x1300 ) {
module.fast_volume_slides = true;
}
signed_samples = false;
if( unsigned_short_le( s3m_file, 42 ) == 0x01 ) {
signed_samples = true;
}
module.global_volume = s3m_file[ 48 ] & 0xFF;
module.default_speed = s3m_file[ 49 ] & 0xFF;
module.default_tempo = s3m_file[ 50 ] & 0xFF;
master_volume = s3m_file[ 51 ] & 0x7F;
module.channel_gain = ( master_volume << IBXM.FP_SHIFT ) >> 7;
stereo_mode = ( s3m_file[ 51 ] & 0x80 ) == 0x80;
default_panning = ( s3m_file[ 53 ] & 0xFF ) == 0xFC;
channel_map = new int[ 32 ];
num_channels = 0;
for( channel_idx = 0; channel_idx < 32; channel_idx++ ) {
channel_config = s3m_file[ 64 + channel_idx ] & 0xFF;
channel_map[ channel_idx ] = -1;
if( channel_config < 16 ) {
channel_map[ channel_idx ] = num_channels;
num_channels += 1;
}
}
module.set_num_channels( num_channels );
panning_offset = 96 + num_pattern_orders + num_instruments * 2 + num_patterns * 2;
for( channel_idx = 0; channel_idx < 32; channel_idx++ ) {
if( channel_map[ channel_idx ] < 0 ) continue;
panning = 7;
if( stereo_mode ) {
panning = 12;
if( ( s3m_file[ 64 + channel_idx ] & 0xFF ) < 8 ) {
panning = 3;
}
}
if( default_panning ) {
flags = s3m_file[ panning_offset + channel_idx ] & 0xFF;
if( ( flags & 0x20 ) == 0x20 ) {
panning = flags & 0xF;
}
}
module.set_initial_panning( channel_map[ channel_idx ], panning * 17 );
}
sequence = read_s3m_sequence( s3m_file );
module.set_sequence_length( sequence.length );
for( order_idx = 0; order_idx < sequence.length; order_idx++ ) {
module.set_sequence( order_idx, sequence[ order_idx ] );
}
module.set_num_instruments( num_instruments );
for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) {
instrument = read_s3m_instrument( s3m_file, instrument_idx, signed_samples );
module.set_instrument( instrument_idx + 1, instrument );
}
module.set_num_patterns( num_patterns );
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
module.set_pattern( pattern_idx, read_s3m_pattern( s3m_file, pattern_idx, channel_map ) );
}
return module;
}
private static int[] read_s3m_sequence( byte[] s3m_file ) {
int num_pattern_orders, sequence_length;
int sequence_idx, order_idx, pattern_order;
int[] sequence;
num_pattern_orders = get_num_pattern_orders( s3m_file );
sequence_length = 0;
for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) {
pattern_order = s3m_file[ 96 + order_idx ] & 0xFF;
if( pattern_order == 255 ) {
break;
} else if( pattern_order < 254 ) {
sequence_length += 1;
}
}
sequence = new int[ sequence_length ];
sequence_idx = 0;
for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) {
pattern_order = s3m_file[ 96 + order_idx ] & 0xFF;
if( pattern_order == 255 ) {
break;
} else if( pattern_order < 254 ) {
sequence[ sequence_idx ] = pattern_order;
sequence_idx += 1;
}
}
return sequence;
}
private static Instrument read_s3m_instrument( byte[] s3m_file, int instrument_idx, boolean signed_samples ) {
int instrument_offset;
int sample_data_offset, sample_data_length;
int loop_start, loop_length, c2_rate, sample_idx, amplitude;
boolean sixteen_bit;
Instrument instrument;
Sample sample;
short[] sample_data;
instrument_offset = get_instrument_offset( s3m_file, instrument_idx );
instrument = new Instrument();
instrument.name = ascii_text( s3m_file, instrument_offset + 48, 28 );
sample = new Sample();
if( s3m_file[ instrument_offset ] == 1 ) {
sample_data_length = get_sample_data_length( s3m_file, instrument_offset );
loop_start = unsigned_short_le( s3m_file, instrument_offset + 20 );
loop_length = unsigned_short_le( s3m_file, instrument_offset + 24 ) - loop_start;
sample.volume = s3m_file[ instrument_offset + 28 ] & 0xFF;
if( s3m_file[ instrument_offset + 30 ] != 0 ) {
throw new IllegalArgumentException( "ScreamTracker3: Packed samples not supported!" );
}
if( ( s3m_file[ instrument_offset + 31 ] & 0x01 ) == 0 ) {
loop_length = 0;
}
if( ( s3m_file[ instrument_offset + 31 ] & 0x02 ) != 0 ) {
throw new IllegalArgumentException( "ScreamTracker3: Stereo samples not supported!" );
}
sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0;
c2_rate = unsigned_short_le( s3m_file, instrument_offset + 32 );
sample.transpose = LogTable.log_2( c2_rate ) - LogTable.log_2( 8363 );
sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset );
if( sixteen_bit ) {
if( signed_samples ) {
throw new IllegalArgumentException( "ScreamTracker3: Signed 16-bit samples not supported!" );
}
sample_data_length >>= 1;
sample_data = new short[ sample_data_length ];
for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) {
amplitude = s3m_file[ sample_data_offset + sample_idx * 2 ] & 0xFF;
amplitude |= ( s3m_file[ sample_data_offset + sample_idx * 2 + 1 ] & 0xFF ) << 8;
sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 );
}
} else {
sample_data = new short[ sample_data_length ];
if( signed_samples ) {
for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) {
amplitude = s3m_file[ sample_data_offset + sample_idx ] << 8;
sample_data[ sample_idx ] = ( short ) amplitude;
}
} else {
for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) {
amplitude = ( s3m_file[ sample_data_offset + sample_idx ] & 0xFF ) << 8;
sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 );
}
}
}
sample.set_sample_data( sample_data, loop_start, loop_length, false );
}
instrument.set_num_samples( 1 );
instrument.set_sample( 0, sample );
return instrument;
}
private static Pattern read_s3m_pattern( byte[] s3m_file, int pattern_idx, int[] channel_map ) {
int pattern_offset;
int num_channels, num_notes;
int row_idx, channel_idx, note_idx;
int token, key, volume_column, effect, effect_param;
byte[] pattern_data;
Pattern pattern;
num_channels = 0;
for( channel_idx = 0; channel_idx < 32; channel_idx++ ) {
if( channel_map[ channel_idx ] >= num_channels ) {
num_channels = channel_idx + 1;
}
}
num_notes = num_channels * 64;
pattern_data = new byte[ num_notes * 5 ];
row_idx = 0;
pattern_offset = get_pattern_offset( s3m_file, pattern_idx ) + 2;
while( row_idx < 64 ) {
token = s3m_file[ pattern_offset ] & 0xFF;
pattern_offset += 1;
if( token > 0 ) {
channel_idx = channel_map[ token & 0x1F ];
note_idx = ( num_channels * row_idx + channel_idx ) * 5;
if( ( token & 0x20 ) == 0x20 ) {
/* Key + Instrument.*/
if( channel_idx >= 0 ) {
key = s3m_file[ pattern_offset ] & 0xFF;
if( key == 255 ) {
key = 0;
} else if( key == 254 ) {
key = 97;
} else {
key = ( ( key & 0xF0 ) >> 4 ) * 12 + ( key & 0x0F ) + 1;
while( key > 96 ) {
key = key - 12;
}
}
pattern_data[ note_idx ] = ( byte ) key;
pattern_data[ note_idx + 1 ] = s3m_file[ pattern_offset + 1 ];
}
pattern_offset += 2;
}
if( ( token & 0x40 ) == 0x40 ) {
/* Volume.*/
if( channel_idx >= 0 ) {
volume_column = ( s3m_file[ pattern_offset ] & 0xFF ) + 0x10;
pattern_data[ note_idx + 2 ] = ( byte ) volume_column;
}
pattern_offset += 1;
}
if( ( token & 0x80 ) == 0x80 ) {
/* Effect + Param.*/
if( channel_idx >= 0 ) {
effect = s3m_file[ pattern_offset ] & 0xFF;
effect_param = s3m_file[ pattern_offset + 1 ] & 0xFF;
effect = effect_map[ effect & 0x1F ];
if( effect == 0xFF ) {
effect = 0;
effect_param = 0;
}
if( effect == 0x0E ) {
effect = effect_s_map[ ( effect_param & 0xF0 ) >> 4 ];
effect_param = effect_param & 0x0F;
switch( effect ) {
case 0x08:
effect = 0x08;
effect_param = effect_param * 17;
break;
case 0x09:
effect = 0x08;
if( effect_param > 7 ) {
effect_param -= 8;
} else {
effect_param += 8;
}
effect_param = effect_param * 17;
break;
case 0xFF:
effect = 0;
effect_param = 0;
break;
default:
effect_param = ( ( effect & 0x0F ) << 4 ) | ( effect_param & 0x0F );
effect = 0x0E;
break;
}
}
pattern_data[ note_idx + 3 ] = ( byte ) effect;
pattern_data[ note_idx + 4 ] = ( byte ) effect_param;
}
pattern_offset += 2;
}
} else {
row_idx += 1;
}
}
pattern = new Pattern();
pattern.num_rows = 64;
pattern.set_pattern_data( pattern_data );
return pattern;
}
private static byte[] read_s3m_file( byte[] header_96_bytes, DataInput data_input ) throws IOException {
int s3m_file_length;
int num_pattern_orders, num_instruments, num_patterns;
int instrument_idx, pattern_idx;
int instrument_offset, sample_data_offset, pattern_offset;
byte[] s3m_file;
if( !is_s3m( header_96_bytes ) ) {
throw new IllegalArgumentException( "ScreamTracker3: Not an S3M file!" );
}
s3m_file = header_96_bytes;
s3m_file_length = header_96_bytes.length;
num_pattern_orders = get_num_pattern_orders( s3m_file );
num_instruments = get_num_instruments( s3m_file );
num_patterns = get_num_patterns( s3m_file );
s3m_file_length += num_pattern_orders;
s3m_file_length += num_instruments * 2;
s3m_file_length += num_patterns * 2;
/* Read enough of file to calculate the length.*/
s3m_file = read_more( s3m_file, s3m_file_length, data_input );
for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) {
instrument_offset = get_instrument_offset( s3m_file, instrument_idx );
instrument_offset += 80;
if( instrument_offset > s3m_file_length ) {
s3m_file_length = instrument_offset;
}
}
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
pattern_offset = get_pattern_offset( s3m_file, pattern_idx );
pattern_offset += 2;
if( pattern_offset > s3m_file_length ) {
s3m_file_length = pattern_offset;
}
}
s3m_file = read_more( s3m_file, s3m_file_length, data_input );
/* Read rest of file.*/
for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) {
instrument_offset = get_instrument_offset( s3m_file, instrument_idx );
sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset );
sample_data_offset += get_sample_data_length( s3m_file, instrument_offset );
if( sample_data_offset > s3m_file_length ) {
s3m_file_length = sample_data_offset;
}
}
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
pattern_offset = get_pattern_offset( s3m_file, pattern_idx );
pattern_offset += get_pattern_length( s3m_file, pattern_offset );
pattern_offset += 2;
if( pattern_offset > s3m_file_length ) {
s3m_file_length = pattern_offset;
}
}
s3m_file = read_more( s3m_file, s3m_file_length, data_input );
return s3m_file;
}
private static int get_num_pattern_orders( byte[] s3m_file ) {
int num_pattern_orders;
num_pattern_orders = unsigned_short_le( s3m_file, 32 );
return num_pattern_orders;
}
private static int get_num_instruments( byte[] s3m_file ) {
int num_instruments;
num_instruments = unsigned_short_le( s3m_file, 34 );
return num_instruments;
}
private static int get_num_patterns( byte[] s3m_file ) {
int num_patterns;
num_patterns = unsigned_short_le( s3m_file, 36 );
return num_patterns;
}
private static int get_instrument_offset( byte[] s3m_file, int instrument_idx ) {
int instrument_offset, pointer_offset;
pointer_offset = 96 + get_num_pattern_orders( s3m_file );
instrument_offset = unsigned_short_le( s3m_file, pointer_offset + instrument_idx * 2 ) << 4;
return instrument_offset;
}
private static int get_sample_data_offset( byte[] s3m_file, int instrument_offset ) {
int sample_data_offset;
sample_data_offset = 0;
if( s3m_file[ instrument_offset ] == 1 ) {
sample_data_offset = ( s3m_file[ instrument_offset + 13 ] & 0xFF ) << 20;
sample_data_offset |= unsigned_short_le( s3m_file, instrument_offset + 14 ) << 4;
}
return sample_data_offset;
}
private static int get_sample_data_length( byte[] s3m_file, int instrument_offset ) {
int sample_data_length;
boolean sixteen_bit;
sample_data_length = 0;
if( s3m_file[ instrument_offset ] == 1 ) {
sample_data_length = unsigned_short_le( s3m_file, instrument_offset + 16 );
sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0;
if( sixteen_bit ) {
sample_data_length <<= 1;
}
}
return sample_data_length;
}
private static int get_pattern_offset( byte[] s3m_file, int pattern_idx ) {
int pattern_offset, pointer_offset;
pointer_offset = 96 + get_num_pattern_orders( s3m_file );
pointer_offset += get_num_instruments( s3m_file ) * 2;
pattern_offset = unsigned_short_le( s3m_file, pointer_offset + pattern_idx * 2 ) << 4;
return pattern_offset;
}
private static int get_pattern_length( byte[] s3m_file, int pattern_offset ) {
int pattern_length;
pattern_length = unsigned_short_le( s3m_file, pattern_offset );
return pattern_length;
}
private static byte[] read_more( byte[] old_data, int new_length, DataInput data_input ) throws IOException {
byte[] new_data;
new_data = old_data;
if( new_length > old_data.length ) {
new_data = new byte[ new_length ];
System.arraycopy( old_data, 0, new_data, 0, old_data.length );
try {
data_input.readFully( new_data, old_data.length, new_data.length - old_data.length );
} catch( EOFException e ) {
System.out.println( "ScreamTracker3: Module has been truncated!" );
}
}
return new_data;
}
private static int unsigned_short_le( byte[] buffer, int offset ) {
int value;
value = buffer[ offset ] & 0xFF;
value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 );
return value;
}
private static String ascii_text( byte[] buffer, int offset, int length ) {
int idx, chr;
byte[] string_buffer;
String string;
string_buffer = new byte[ length ];
for( idx = 0; idx < length; idx++ ) {
chr = buffer[ offset + idx ];
if( chr < 32 ) {
chr = 32;
}
string_buffer[ idx ] = ( byte ) chr;
}
try {
string = new String( string_buffer, 0, length, "ISO-8859-1" );
} catch( UnsupportedEncodingException e ) {
string = "";
}
return string;
}
}
@@ -1,44 +0,0 @@
package net.minecraftforge.client;
import net.minecraft.world.EnumGameType;
import net.minecraft.util.EnumOS;
import net.minecraft.client.settings.EnumOptions;
import net.minecraft.item.EnumRarity;
import net.minecraftforge.common.EnumHelper;
public class EnumHelperClient extends EnumHelper
{
private static Class[][] clentTypes =
{
{EnumGameType.class, int.class, String.class},
{EnumOptions.class, String.class, boolean.class, boolean.class},
{EnumOS.class},
{EnumRarity.class, int.class, String.class}
};
public static EnumGameType addGameType(String name, int id, String displayName)
{
return addEnum(EnumGameType.class, name, id, displayName);
}
public static EnumOptions addOptions(String name, String langName, boolean isSlider, boolean isToggle)
{
return addEnum(EnumOptions.class, name, langName, isSlider, isToggle);
}
public static EnumOS addOS2(String name)
{
return addEnum(EnumOS.class, name);
}
public static EnumRarity addRarity(String name, int color, String displayName)
{
return addEnum(EnumRarity.class, name, color, displayName);
}
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues)
{
return addEnum(clentTypes, enumType, enumName, paramValues);
}
}
@@ -1,286 +0,0 @@
package net.minecraftforge.client;
import java.util.HashMap;
import java.util.Random;
import java.util.TreeSet;
import javax.imageio.ImageIO;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.PixelFormat;
import cpw.mods.fml.client.FMLClientHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.block.Block;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.*;
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.*;
public class ForgeHooksClient
{
static TextureManager engine()
{
return FMLClientHandler.instance().getClient().renderEngine;
}
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, int layer, String type)
{
String result = armor.getItem().getArmorTexture(armor, entity, slot, layer);
return result != null ? result : _default;
}
public static boolean renderEntityItem(EntityItem entity, ItemStack item, float bobing, float rotation, Random random, TextureManager engine, RenderBlocks renderBlocks)
{
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, ENTITY);
if (customRenderer == null)
{
return false;
}
if (customRenderer.shouldUseRenderHelper(ENTITY, item, ENTITY_ROTATION))
{
GL11.glRotatef(rotation, 0.0F, 1.0F, 0.0F);
}
if (!customRenderer.shouldUseRenderHelper(ENTITY, item, ENTITY_BOBBING))
{
GL11.glTranslatef(0.0F, -bobing, 0.0F);
}
boolean is3D = customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
Block block = (item.itemID < Block.blocksList.length ? Block.blocksList[item.itemID] : null);
if (is3D || (block != null && RenderBlocks.renderItemIn3d(block.getRenderType())))
{
int renderType = (block != null ? block.getRenderType() : 1);
float scale = (renderType == 1 || renderType == 19 || renderType == 12 || renderType == 2 ? 0.5F : 0.25F);
if (RenderItem.renderInFrame)
{
GL11.glScalef(1.25F, 1.25F, 1.25F);
GL11.glTranslatef(0.0F, 0.05F, 0.0F);
GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
}
GL11.glScalef(scale, scale, scale);
int size = item.stackSize;
int count = (size > 40 ? 5 : (size > 20 ? 4 : (size > 5 ? 3 : (size > 1 ? 2 : 1))));
for(int j = 0; j < count; j++)
{
GL11.glPushMatrix();
if (j > 0)
{
GL11.glTranslatef(
((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / scale,
((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / scale,
((random.nextFloat() * 2.0F - 1.0F) * 0.2F) / scale);
}
customRenderer.renderItem(ENTITY, item, renderBlocks, entity);
GL11.glPopMatrix();
}
}
else
{
GL11.glScalef(0.5F, 0.5F, 0.5F);
customRenderer.renderItem(ENTITY, item, renderBlocks, entity);
}
return true;
}
public static boolean renderInventoryItem(RenderBlocks renderBlocks, TextureManager engine, ItemStack item, boolean inColor, float zLevel, float x, float y)
{
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, INVENTORY);
if (customRenderer == null)
{
return false;
}
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
if (customRenderer.shouldUseRenderHelper(INVENTORY, item, INVENTORY_BLOCK))
{
GL11.glPushMatrix();
GL11.glTranslatef(x - 2, y + 3, -3.0F + zLevel);
GL11.glScalef(10F, 10F, 10F);
GL11.glTranslatef(1.0F, 0.5F, 1.0F);
GL11.glScalef(1.0F, 1.0F, -1F);
GL11.glRotatef(210F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(45F, 0.0F, 1.0F, 0.0F);
if(inColor)
{
int color = Item.itemsList[item.itemID].getColorFromItemStack(item, 0);
float r = (float)(color >> 16 & 0xff) / 255F;
float g = (float)(color >> 8 & 0xff) / 255F;
float b = (float)(color & 0xff) / 255F;
GL11.glColor4f(r, g, b, 1.0F);
}
GL11.glRotatef(-90F, 0.0F, 1.0F, 0.0F);
renderBlocks.useInventoryTint = inColor;
customRenderer.renderItem(INVENTORY, item, renderBlocks);
renderBlocks.useInventoryTint = true;
GL11.glPopMatrix();
}
else
{
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glPushMatrix();
GL11.glTranslatef(x, y, -3.0F + zLevel);
if (inColor)
{
int color = Item.itemsList[item.itemID].getColorFromItemStack(item, 0);
float r = (float)(color >> 16 & 255) / 255.0F;
float g = (float)(color >> 8 & 255) / 255.0F;
float b = (float)(color & 255) / 255.0F;
GL11.glColor4f(r, g, b, 1.0F);
}
customRenderer.renderItem(INVENTORY, item, renderBlocks);
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
}
return true;
}
public static void renderEquippedItem(ItemRenderType type, IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLivingBase entity, ItemStack item)
{
if (customRenderer.shouldUseRenderHelper(type, item, EQUIPPED_BLOCK))
{
GL11.glPushMatrix();
GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
customRenderer.renderItem(type, item, renderBlocks, entity);
GL11.glPopMatrix();
}
else
{
GL11.glPushMatrix();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glTranslatef(0.0F, -0.3F, 0.0F);
GL11.glScalef(1.5F, 1.5F, 1.5F);
GL11.glRotatef(50.0F, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(335.0F, 0.0F, 0.0F, 1.0F);
GL11.glTranslatef(-0.9375F, -0.0625F, 0.0F);
customRenderer.renderItem(type, item, renderBlocks, entity);
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
GL11.glPopMatrix();
}
}
//Optifine Helper Functions u.u, these are here specifically for Optifine
//Note: When using Optfine, these methods are invoked using reflection, which
//incurs a major performance penalty.
public static void orientBedCamera(Minecraft mc, EntityLivingBase entity)
{
int x = MathHelper.floor_double(entity.posX);
int y = MathHelper.floor_double(entity.posY);
int z = MathHelper.floor_double(entity.posZ);
Block block = Block.blocksList[mc.theWorld.getBlockId(x, y, z)];
if (block != null && block.isBed(mc.theWorld, x, y, z, entity))
{
int var12 = block.getBedDirection(mc.theWorld, x, y, z);
GL11.glRotatef((float)(var12 * 90), 0.0F, 1.0F, 0.0F);
}
}
public static boolean onDrawBlockHighlight(RenderGlobal context, EntityPlayer player, MovingObjectPosition target, int subID, ItemStack currentItem, float partialTicks)
{
return MinecraftForge.EVENT_BUS.post(new DrawBlockHighlightEvent(context, player, target, subID, currentItem, partialTicks));
}
public static void dispatchRenderLast(RenderGlobal context, float partialTicks)
{
MinecraftForge.EVENT_BUS.post(new RenderWorldLastEvent(context, partialTicks));
}
public static void onTextureStitchedPre(TextureMap map)
{
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
}
public static void onTextureStitchedPost(TextureMap map)
{
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
}
/**
* This is added for Optifine's convenience. And to explode if a ModMaker is developing.
* @param texture
*/
public static void onTextureLoadPre(String texture)
{
if (Tessellator.renderingWorldRenderer)
{
String msg = String.format("Warning: Texture %s not preloaded, will cause render glitches!", texture);
System.out.println(msg);
if (Tessellator.class.getPackage() != null)
{
if (Tessellator.class.getPackage().getName().startsWith("net.minecraft."))
{
Minecraft mc = FMLClientHandler.instance().getClient();
if (mc.ingameGUI != null)
{
mc.ingameGUI.getChatGUI().printChatMessage(msg);
}
}
}
}
}
static int renderPass = -1;
public static void setRenderPass(int pass)
{
renderPass = pass;
}
public static ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int slotID, ModelBiped _default)
{
ModelBiped modelbiped = itemStack.getItem().getArmorModel(entityLiving, itemStack, slotID);
return modelbiped == null ? _default : modelbiped;
}
static int stencilBits = 0;
public static void createDisplay() throws LWJGLException
{
ImageIO.setUseCache(false); //Disable on-disc stream cache should speed up texture pack reloading.
PixelFormat format = new PixelFormat().withDepthBits(24);
try
{
//TODO: Figure out how to determine the max bits.
Display.create(format.withStencilBits(8));
stencilBits = 8;
}
catch(LWJGLException e)
{
Display.create(format);
stencilBits = 0;
}
}
}
@@ -1,127 +0,0 @@
package net.minecraftforge.client;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.gui.GuiControls;
import net.minecraft.client.gui.GuiSlot;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.EnumChatFormatting;
public class GuiControlsScrollPanel extends GuiSlot
{
private GuiControls controls;
private GameSettings options;
private Minecraft mc;
private String[] message;
private int _mouseX;
private int _mouseY;
private int selected = -1;
public GuiControlsScrollPanel(GuiControls controls, GameSettings options, Minecraft mc)
{
super(mc, controls.width, controls.height, 16, (controls.height - 32) + 4, 25);
this.controls = controls;
this.options = options;
this.mc = mc;
}
@Override
protected int getSize()
{
return options.keyBindings.length;
}
@Override
protected void elementClicked(int i, boolean flag)
{
if (!flag)
{
if (selected == -1)
{
selected = i;
}
else
{
options.setKeyBinding(selected, -100);
selected = -1;
KeyBinding.resetKeyBindingArrayAndHash();
}
}
}
@Override
protected boolean isSelected(int i)
{
return false;
}
@Override
protected void func_130003_c() {}
@Override
public void drawScreen(int mX, int mY, float f)
{
_mouseX = mX;
_mouseY = mY;
if (selected != -1 && !Mouse.isButtonDown(0) && Mouse.getDWheel() == 0)
{
if (Mouse.next() && Mouse.getEventButtonState())
{
System.out.println(Mouse.getEventButton());
options.setKeyBinding(selected, -100 + Mouse.getEventButton());
selected = -1;
KeyBinding.resetKeyBindingArrayAndHash();
}
}
super.drawScreen(mX, mY, f);
}
@Override
protected void drawSlot(int index, int xPosition, int yPosition, int l, Tessellator tessellator)
{
int width = 70;
int height = 20;
xPosition -= 20;
boolean flag = _mouseX >= xPosition && _mouseY >= yPosition && _mouseX < xPosition + width && _mouseY < yPosition + height;
int k = (flag ? 2 : 1);
mc.renderEngine.func_110577_a(TextureMap.field_110576_c);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
controls.drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height);
controls.drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height);
controls.drawString(mc.fontRenderer, options.getKeyBindingDescription(index), xPosition + width + 4, yPosition + 6, 0xFFFFFFFF);
boolean conflict = false;
for (int x = 0; x < options.keyBindings.length; x++)
{
if (x != index && options.keyBindings[x].keyCode == options.keyBindings[index].keyCode)
{
conflict = true;
break;
}
}
String str = (conflict ? EnumChatFormatting.RED : "") + options.getOptionDisplayString(index);
str = (index == selected ? EnumChatFormatting.WHITE + "> " + EnumChatFormatting.YELLOW + "??? " + EnumChatFormatting.WHITE + "<" : str);
controls.drawCenteredString(mc.fontRenderer, str, xPosition + (width / 2), yPosition + (height - 8) / 2, 0xFFFFFFFF);
}
public boolean keyTyped(char c, int i)
{
if (selected != -1)
{
options.setKeyBinding(selected, i);
selected = -1;
KeyBinding.resetKeyBindingArrayAndHash();
return false;
}
return true;
}
}
@@ -1,871 +0,0 @@
package net.minecraftforge.client;
import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.*;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiIngame;
import net.minecraft.client.gui.GuiPlayerInfo;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.ResourceLocation;
import net.minecraft.crash.CallableMinecraftVersion;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeInstance;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.scoreboard.Score;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.util.Direction;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.FoodStats;
import net.minecraft.util.MathHelper;
import net.minecraft.util.StatCollector;
import net.minecraft.util.StringUtils;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.MinecraftForge;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import cpw.mods.fml.common.FMLCommonHandler;
public class GuiIngameForge extends GuiIngame
{
private static final ResourceLocation VIGNETTE = new ResourceLocation("textures/misc/vignette.png");
private static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
private static final ResourceLocation PUMPKIN_BLUR = new ResourceLocation("textures/misc/pumpkinblur.png");
private static final int WHITE = 0xFFFFFF;
//Flags to toggle the rendering of certain aspects of the HUD, valid conditions
//must be met for them to render normally. If those conditions are met, but this flag
//is false, they will not be rendered.
public static boolean renderHelmet = true;
public static boolean renderPortal = true;
public static boolean renderHotbar = true;
public static boolean renderCrosshairs = true;
public static boolean renderBossHealth = true;
public static boolean renderHealth = true;
public static boolean renderArmor = true;
public static boolean renderFood = true;
public static boolean renderHealthMount = true;
public static boolean renderAir = true;
public static boolean renderExperiance = true;
public static boolean renderJumpBar = true;
public static boolean renderObjective = true;
public static int left_height = 39;
public static int right_height = 39;
private ScaledResolution res = null;
private FontRenderer fontrenderer = null;
private RenderGameOverlayEvent eventParent;
private static final String MC_VERSION = (new CallableMinecraftVersion(null)).minecraftVersion();
public GuiIngameForge(Minecraft mc)
{
super(mc);
}
@Override
public void renderGameOverlay(float partialTicks, boolean hasScreen, int mouseX, int mouseY)
{
res = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);
eventParent = new RenderGameOverlayEvent(partialTicks, res, mouseX, mouseY);
int width = res.getScaledWidth();
int height = res.getScaledHeight();
renderHealthMount = mc.thePlayer.ridingEntity instanceof EntityLivingBase;
renderFood = mc.thePlayer.ridingEntity == null;
renderJumpBar = mc.thePlayer.func_110317_t();
right_height = 39;
left_height = 39;
if (pre(ALL)) return;
fontrenderer = mc.fontRenderer;
mc.entityRenderer.setupOverlayRendering();
GL11.glEnable(GL11.GL_BLEND);
if (Minecraft.isFancyGraphicsEnabled())
{
renderVignette(mc.thePlayer.getBrightness(partialTicks), width, height);
}
else
{
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
if (renderHelmet) renderHelmet(res, partialTicks, hasScreen, mouseX, mouseY);
if (renderPortal && !mc.thePlayer.isPotionActive(Potion.confusion))
{
renderPortal(width, height, partialTicks);
}
if (!mc.playerController.enableEverythingIsScrewedUpMode())
{
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
zLevel = -90.0F;
rand.setSeed((long)(updateCounter * 312871));
if (renderCrosshairs) renderCrosshairs(width, height);
if (renderBossHealth) renderBossHealth();
if (this.mc.playerController.shouldDrawHUD())
{
if (renderHealth) renderHealth(width, height);
if (renderArmor) renderArmor(width, height);
if (renderFood) renderFood(width, height);
if (renderHealthMount) renderHealthMount(width, height);
if (renderAir) renderAir(width, height);
}
if (renderHotbar) renderHotbar(width, height, partialTicks);
}
if (renderJumpBar)
{
renderJumpBar(width, height);
}
else if (renderExperiance)
{
renderExperience(width, height);
}
renderSleepFade(width, height);
renderToolHightlight(width, height);
renderHUDText(width, height);
renderRecordOverlay(width, height, partialTicks);
ScoreObjective objective = mc.theWorld.getScoreboard().func_96539_a(1);
if (renderObjective && objective != null)
{
this.func_96136_a(objective, height, width, fontrenderer);
}
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_ALPHA_TEST);
renderChat(width, height);
renderPlayerList(width, height);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_ALPHA_TEST);
post(ALL);
}
public ScaledResolution getResolution()
{
return res;
}
protected void renderHotbar(int width, int height, float partialTicks)
{
if (pre(HOTBAR)) return;
mc.mcProfiler.startSection("actionBar");
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.renderEngine.func_110577_a(WIDGITS);
InventoryPlayer inv = mc.thePlayer.inventory;
drawTexturedModalRect(width / 2 - 91, height - 22, 0, 0, 182, 22);
drawTexturedModalRect(width / 2 - 91 - 1 + inv.currentItem * 20, height - 22 - 1, 0, 22, 24, 22);
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
RenderHelper.enableGUIStandardItemLighting();
for (int i = 0; i < 9; ++i)
{
int x = width / 2 - 90 + i * 20 + 2;
int z = height - 16 - 3;
renderInventorySlot(i, x, z, partialTicks);
}
RenderHelper.disableStandardItemLighting();
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
mc.mcProfiler.endSection();
post(HOTBAR);
}
protected void renderCrosshairs(int width, int height)
{
if (pre(CROSSHAIRS)) return;
bind(Gui.field_110324_m);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR);
drawTexturedModalRect(width / 2 - 7, height / 2 - 7, 0, 0, 16, 16);
GL11.glDisable(GL11.GL_BLEND);
post(CROSSHAIRS);
}
@Override
protected void renderBossHealth()
{
if (pre(BOSSHEALTH)) return;
mc.mcProfiler.startSection("bossHealth");
super.renderBossHealth();
mc.mcProfiler.endSection();
post(BOSSHEALTH);
}
private void renderHelmet(ScaledResolution res, float partialTicks, boolean hasScreen, int mouseX, int mouseY)
{
if (pre(HELMET)) return;
ItemStack itemstack = this.mc.thePlayer.inventory.armorItemInSlot(3);
if (this.mc.gameSettings.thirdPersonView == 0 && itemstack != null && itemstack.getItem() != null)
{
if (itemstack.itemID == Block.pumpkin.blockID)
{
renderPumpkinBlur(res.getScaledWidth(), res.getScaledHeight());
}
else
{
itemstack.getItem().renderHelmetOverlay(itemstack, mc.thePlayer, res, partialTicks, hasScreen, mouseX, mouseY);
}
}
post(HELMET);
}
protected void renderArmor(int width, int height)
{
if (pre(ARMOR)) return;
mc.mcProfiler.startSection("armor");
int left = width / 2 - 91;
int top = height - left_height;
int level = ForgeHooks.getTotalArmorValue(mc.thePlayer);
for (int i = 1; level > 0 && i < 20; i += 2)
{
if (i < level)
{
drawTexturedModalRect(left, top, 34, 9, 9, 9);
}
else if (i == level)
{
drawTexturedModalRect(left, top, 25, 9, 9, 9);
}
else if (i > level)
{
drawTexturedModalRect(left, top, 16, 9, 9, 9);
}
left += 8;
}
left_height += 10;
mc.mcProfiler.endSection();
post(ARMOR);
}
protected void renderPortal(int width, int height, float partialTicks)
{
if (pre(PORTAL)) return;
float f1 = mc.thePlayer.prevTimeInPortal + (mc.thePlayer.timeInPortal - mc.thePlayer.prevTimeInPortal) * partialTicks;
if (f1 > 0.0F)
{
func_130015_b(f1, width, height);
}
post(PORTAL);
}
protected void renderAir(int width, int height)
{
if (pre(AIR)) return;
mc.mcProfiler.startSection("air");
int left = width / 2 + 91;
int top = height - right_height;
if (mc.thePlayer.isInsideOfMaterial(Material.water))
{
int air = mc.thePlayer.getAir();
int full = MathHelper.ceiling_double_int((double)(air - 2) * 10.0D / 300.0D);
int partial = MathHelper.ceiling_double_int((double)air * 10.0D / 300.0D) - full;
for (int i = 0; i < full + partial; ++i)
{
drawTexturedModalRect(left - i * 8 - 9, top, (i < full ? 16 : 25), 18, 9, 9);
}
right_height += 10;
}
mc.mcProfiler.endSection();
post(AIR);
}
public void renderHealth(int width, int height)
{
bind(field_110324_m);
if (pre(HEALTH)) return;
mc.mcProfiler.startSection("health");
boolean highlight = mc.thePlayer.hurtResistantTime / 3 % 2 == 1;
if (mc.thePlayer.hurtResistantTime < 10)
{
highlight = false;
}
AttributeInstance attrMaxHealth = this.mc.thePlayer.func_110148_a(SharedMonsterAttributes.field_111267_a);
int health = MathHelper.ceiling_float_int(mc.thePlayer.func_110143_aJ());
int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
float healthMax = (float)attrMaxHealth.func_111126_e();
float absorb = this.mc.thePlayer.func_110139_bj();
int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
int rowHeight = Math.max(10 - (healthRows - 2), 3);
this.rand.setSeed((long)(updateCounter * 312871));
int left = width / 2 - 91;
int top = height - left_height;
left_height += (healthRows * rowHeight);
if (rowHeight != 10) left_height += 10 - rowHeight;
int regen = -1;
if (mc.thePlayer.isPotionActive(Potion.regeneration))
{
regen = updateCounter % 25;
}
final int TOP = 9 * (mc.theWorld.getWorldInfo().isHardcoreModeEnabled() ? 5 : 0);
final int BACKGROUND = (highlight ? 25 : 16);
int MARGIN = 16;
if (mc.thePlayer.isPotionActive(Potion.poison)) MARGIN += 36;
else if (mc.thePlayer.isPotionActive(Potion.wither)) MARGIN += 72;
float absorbRemaining = absorb;
for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i)
{
int b0 = (highlight ? 1 : 0);
int row = MathHelper.ceiling_float_int((float)(i + 1) / 10.0F) - 1;
int x = left + i % 10 * 8;
int y = top - row * rowHeight;
if (health <= 4) y += rand.nextInt(2);
if (i == regen) y -= 2;
drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9);
if (highlight)
{
if (i * 2 + 1 < healthLast)
drawTexturedModalRect(x, y, MARGIN + 54, TOP, 9, 9); //6
else if (i * 2 + 1 == healthLast)
drawTexturedModalRect(x, y, MARGIN + 63, TOP, 9, 9); //7
}
if (absorbRemaining > 0.0F)
{
if (absorbRemaining == absorb && absorb % 2.0F == 1.0F)
drawTexturedModalRect(x, y, MARGIN + 153, TOP, 9, 9); //17
else
drawTexturedModalRect(x, y, MARGIN + 144, TOP, 9, 9); //16
absorbRemaining -= 2.0F;
}
else
{
if (i * 2 + 1 < health)
drawTexturedModalRect(x, y, MARGIN + 36, TOP, 9, 9); //4
else if (i * 2 + 1 == health)
drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); //5
}
}
mc.mcProfiler.endSection();
post(HEALTH);
}
public void renderFood(int width, int height)
{
if (pre(FOOD)) return;
mc.mcProfiler.startSection("food");
int left = width / 2 + 91;
int top = height - right_height;
right_height += 10;
boolean unused = false;// Unused flag in vanilla, seems to be part of a 'fade out' mechanic
FoodStats stats = mc.thePlayer.getFoodStats();
int level = stats.getFoodLevel();
int levelLast = stats.getPrevFoodLevel();
for (int i = 0; i < 10; ++i)
{
int idx = i * 2 + 1;
int x = left - i * 8 - 9;
int y = top;
int icon = 16;
byte backgound = 0;
if (mc.thePlayer.isPotionActive(Potion.hunger))
{
icon += 36;
backgound = 13;
}
if (unused) backgound = 1; //Probably should be a += 1 but vanilla never uses this
if (mc.thePlayer.getFoodStats().getSaturationLevel() <= 0.0F && updateCounter % (level * 3 + 1) == 0)
{
y = top + (rand.nextInt(3) - 1);
}
drawTexturedModalRect(x, y, 16 + backgound * 9, 27, 9, 9);
if (unused)
{
if (idx < levelLast)
drawTexturedModalRect(x, y, icon + 54, 27, 9, 9);
else if (idx == levelLast)
drawTexturedModalRect(x, y, icon + 63, 27, 9, 9);
}
if (idx < level)
drawTexturedModalRect(x, y, icon + 36, 27, 9, 9);
else if (idx == level)
drawTexturedModalRect(x, y, icon + 45, 27, 9, 9);
}
mc.mcProfiler.endSection();
post(FOOD);
}
protected void renderSleepFade(int width, int height)
{
if (mc.thePlayer.getSleepTimer() > 0)
{
mc.mcProfiler.startSection("sleep");
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_ALPHA_TEST);
int sleepTime = mc.thePlayer.getSleepTimer();
float opacity = (float)sleepTime / 100.0F;
if (opacity > 1.0F)
{
opacity = 1.0F - (float)(sleepTime - 100) / 10.0F;
}
int color = (int)(220.0F * opacity) << 24 | 1052704;
drawRect(0, 0, width, height, color);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glEnable(GL11.GL_DEPTH_TEST);
mc.mcProfiler.endSection();
}
}
protected void renderExperience(int width, int height)
{
bind(field_110324_m);
if (pre(EXPERIENCE)) return;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
if (mc.playerController.func_78763_f())
{
mc.mcProfiler.startSection("expBar");
int cap = this.mc.thePlayer.xpBarCap();
int left = width / 2 - 91;
if (cap > 0)
{
short barWidth = 182;
int filled = (int)(mc.thePlayer.experience * (float)(barWidth + 1));
int top = height - 32 + 3;
drawTexturedModalRect(left, top, 0, 64, barWidth, 5);
if (filled > 0)
{
drawTexturedModalRect(left, top, 0, 69, filled, 5);
}
}
this.mc.mcProfiler.endSection();
if (mc.playerController.func_78763_f() && mc.thePlayer.experienceLevel > 0)
{
mc.mcProfiler.startSection("expLevel");
boolean flag1 = false;
int color = flag1 ? 16777215 : 8453920;
String text = "" + mc.thePlayer.experienceLevel;
int x = (width - fontrenderer.getStringWidth(text)) / 2;
int y = height - 31 - 4;
fontrenderer.drawString(text, x + 1, y, 0);
fontrenderer.drawString(text, x - 1, y, 0);
fontrenderer.drawString(text, x, y + 1, 0);
fontrenderer.drawString(text, x, y - 1, 0);
fontrenderer.drawString(text, x, y, color);
mc.mcProfiler.endSection();
}
}
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
post(EXPERIENCE);
}
protected void renderJumpBar(int width, int height)
{
bind(field_110324_m);
if (pre(JUMPBAR)) return;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.mcProfiler.startSection("jumpBar");
float charge = mc.thePlayer.func_110319_bJ();
final int barWidth = 182;
int x = (width / 2) - (barWidth / 2);
int filled = (int)(charge * (float)(barWidth + 1));
int top = height - 32 + 3;
drawTexturedModalRect(x, top, 0, 84, barWidth, 5);
if (filled > 0)
{
this.drawTexturedModalRect(x, top, 0, 89, filled, 5);
}
mc.mcProfiler.endSection();
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
post(JUMPBAR);
}
protected void renderToolHightlight(int width, int height)
{
if (this.mc.gameSettings.heldItemTooltips)
{
mc.mcProfiler.startSection("toolHighlight");
if (this.remainingHighlightTicks > 0 && this.highlightingItemStack != null)
{
String name = this.highlightingItemStack.getDisplayName();
int opacity = (int)((float)this.remainingHighlightTicks * 256.0F / 10.0F);
if (opacity > 255) opacity = 255;
if (opacity > 0)
{
int y = height - 59;
if (!mc.playerController.shouldDrawHUD()) y += 14;
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
FontRenderer font = highlightingItemStack.getItem().getFontRenderer(highlightingItemStack);
if (font != null)
{
int x = (width - font.getStringWidth(name)) / 2;
font.drawStringWithShadow(name, x, y, WHITE | (opacity << 24));
}
else
{
int x = (width - fontrenderer.getStringWidth(name)) / 2;
fontrenderer.drawStringWithShadow(name, x, y, WHITE | (opacity << 24));
}
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
}
mc.mcProfiler.endSection();
}
}
protected void renderHUDText(int width, int height)
{
mc.mcProfiler.startSection("forgeHudText");
ArrayList<String> left = new ArrayList<String>();
ArrayList<String> right = new ArrayList<String>();
if (mc.isDemo())
{
long time = mc.theWorld.getTotalWorldTime();
if (time >= 120500L)
{
right.add(StatCollector.translateToLocal("demo.demoExpired"));
}
else
{
right.add(String.format(StatCollector.translateToLocal("demo.remainingTime"), StringUtils.ticksToElapsedTime((int)(120500L - time))));
}
}
if (this.mc.gameSettings.showDebugInfo)
{
mc.mcProfiler.startSection("debug");
GL11.glPushMatrix();
left.add("Minecraft " + MC_VERSION + " (" + this.mc.debug + ")");
left.add(mc.debugInfoRenders());
left.add(mc.getEntityDebug());
left.add(mc.debugInfoEntities());
left.add(mc.getWorldProviderName());
left.add(null); //Spacer
long max = Runtime.getRuntime().maxMemory();
long total = Runtime.getRuntime().totalMemory();
long free = Runtime.getRuntime().freeMemory();
long used = total - free;
right.add("Used memory: " + used * 100L / max + "% (" + used / 1024L / 1024L + "MB) of " + max / 1024L / 1024L + "MB");
right.add("Allocated memory: " + total * 100L / max + "% (" + total / 1024L / 1024L + "MB)");
int x = MathHelper.floor_double(mc.thePlayer.posX);
int y = MathHelper.floor_double(mc.thePlayer.posY);
int z = MathHelper.floor_double(mc.thePlayer.posZ);
float yaw = mc.thePlayer.rotationYaw;
int heading = MathHelper.floor_double((double)(mc.thePlayer.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
left.add(String.format("x: %.5f (%d) // c: %d (%d)", mc.thePlayer.posX, x, x >> 4, x & 15));
left.add(String.format("y: %.3f (feet pos, %.3f eyes pos)", mc.thePlayer.boundingBox.minY, mc.thePlayer.posY));
left.add(String.format("z: %.5f (%d) // c: %d (%d)", mc.thePlayer.posZ, z, z >> 4, z & 15));
left.add(String.format("f: %d (%s) / %f", heading, Direction.directions[heading], MathHelper.wrapAngleTo180_float(yaw)));
if (mc.theWorld != null && mc.theWorld.blockExists(x, y, z))
{
Chunk chunk = this.mc.theWorld.getChunkFromBlockCoords(x, z);
left.add(String.format("lc: %d b: %s bl: %d sl: %d rl: %d",
chunk.getTopFilledSegment() + 15,
chunk.getBiomeGenForWorldCoords(x & 15, z & 15, mc.theWorld.getWorldChunkManager()).biomeName,
chunk.getSavedLightValue(EnumSkyBlock.Block, x & 15, y, z & 15),
chunk.getSavedLightValue(EnumSkyBlock.Sky, x & 15, y, z & 15),
chunk.getBlockLightValue(x & 15, y, z & 15, 0)));
}
else
{
left.add(null);
}
left.add(String.format("ws: %.3f, fs: %.3f, g: %b, fl: %d", mc.thePlayer.capabilities.getWalkSpeed(), mc.thePlayer.capabilities.getFlySpeed(), mc.thePlayer.onGround, mc.theWorld.getHeightValue(x, z)));
right.add(null);
for (String s : FMLCommonHandler.instance().getBrandings().subList(1, FMLCommonHandler.instance().getBrandings().size()))
{
right.add(s);
}
GL11.glPopMatrix();
mc.mcProfiler.endSection();
}
RenderGameOverlayEvent.Text event = new RenderGameOverlayEvent.Text(eventParent, left, right);
if (!MinecraftForge.EVENT_BUS.post(event))
{
for (int x = 0; x < left.size(); x++)
{
String msg = left.get(x);
if (msg == null) continue;
fontrenderer.drawStringWithShadow(msg, 2, 2 + x * 10, WHITE);
}
for (int x = 0; x < right.size(); x++)
{
String msg = right.get(x);
if (msg == null) continue;
int w = fontrenderer.getStringWidth(msg);
fontrenderer.drawStringWithShadow(msg, width - w - 10, 2 + x * 10, WHITE);
}
}
mc.mcProfiler.endSection();
post(TEXT);
}
protected void renderRecordOverlay(int width, int height, float partialTicks)
{
if (recordPlayingUpFor > 0)
{
mc.mcProfiler.startSection("overlayMessage");
float hue = (float)recordPlayingUpFor - partialTicks;
int opacity = (int)(hue * 256.0F / 20.0F);
if (opacity > 255) opacity = 255;
if (opacity > 0)
{
GL11.glPushMatrix();
GL11.glTranslatef((float)(width / 2), (float)(height - 48), 0.0F);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
int color = (recordIsPlaying ? Color.HSBtoRGB(hue / 50.0F, 0.7F, 0.6F) & WHITE : WHITE);
fontrenderer.drawString(recordPlaying, -fontrenderer.getStringWidth(recordPlaying) / 2, -4, color | (opacity << 24));
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
mc.mcProfiler.endSection();
}
}
protected void renderChat(int width, int height)
{
GL11.glPushMatrix();
GL11.glTranslatef(0.0F, (float)(height - 48), 0.0F);
mc.mcProfiler.startSection("chat");
persistantChatGUI.drawChat(updateCounter);
mc.mcProfiler.endSection();
GL11.glPopMatrix();
}
protected void renderPlayerList(int width, int height)
{
ScoreObjective scoreobjective = this.mc.theWorld.getScoreboard().func_96539_a(0);
NetClientHandler handler = mc.thePlayer.sendQueue;
if (mc.gameSettings.keyBindPlayerList.pressed && (!mc.isIntegratedServerRunning() || handler.playerInfoList.size() > 1 || scoreobjective != null))
{
this.mc.mcProfiler.startSection("playerList");
List players = handler.playerInfoList;
int maxPlayers = handler.currentServerMaxPlayers;
int rows = maxPlayers;
int columns = 1;
for (columns = 1; rows > 20; rows = (maxPlayers + columns - 1) / columns)
{
columns++;
}
int columnWidth = 300 / columns;
if (columnWidth > 150)
{
columnWidth = 150;
}
int left = (width - columns * columnWidth) / 2;
byte border = 10;
drawRect(left - 1, border - 1, left + columnWidth * columns, border + 9 * rows, Integer.MIN_VALUE);
for (int i = 0; i < maxPlayers; i++)
{
int xPos = left + i % columns * columnWidth;
int yPos = border + i / columns * 9;
drawRect(xPos, yPos, xPos + columnWidth - 1, yPos + 8, 553648127);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glEnable(GL11.GL_ALPHA_TEST);
if (i < players.size())
{
GuiPlayerInfo player = (GuiPlayerInfo)players.get(i);
ScorePlayerTeam team = mc.theWorld.getScoreboard().getPlayersTeam(player.name);
String displayName = ScorePlayerTeam.func_96667_a(team, player.name);
fontrenderer.drawStringWithShadow(displayName, xPos, yPos, 16777215);
if (scoreobjective != null)
{
int endX = xPos + fontrenderer.getStringWidth(displayName) + 5;
int maxX = xPos + columnWidth - 12 - 5;
if (maxX - endX > 5)
{
Score score = scoreobjective.getScoreboard().func_96529_a(player.name, scoreobjective);
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.func_96652_c();
fontrenderer.drawStringWithShadow(scoreDisplay, maxX - fontrenderer.getStringWidth(scoreDisplay), yPos, 16777215);
}
}
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.func_110434_K().func_110577_a(Gui.field_110324_m);
int pingIndex = 4;
int ping = player.responseTime;
if (ping < 0) pingIndex = 5;
else if (ping < 150) pingIndex = 0;
else if (ping < 300) pingIndex = 1;
else if (ping < 600) pingIndex = 2;
else if (ping < 1000) pingIndex = 3;
zLevel += 100.0F;
drawTexturedModalRect(xPos + columnWidth - 12, yPos, 0, 176 + pingIndex * 8, 10, 8);
zLevel -= 100.0F;
}
}
}
}
protected void renderHealthMount(int width, int height)
{
Entity tmp = mc.thePlayer.ridingEntity;
if (!(tmp instanceof EntityLivingBase)) return;
bind(field_110324_m);
if (pre(HEALTHMOUNT)) return;
boolean unused = false;
int left_align = width / 2 + 91;
mc.mcProfiler.endStartSection("mountHealth");
EntityLivingBase mount = (EntityLivingBase)tmp;
int health = (int)Math.ceil((double)mount.func_110143_aJ());
float healthMax = mount.func_110138_aP();
int hearts = (int)(healthMax + 0.5F) / 2;
if (hearts > 30) hearts = 30;
final int MARGIN = 52;
final int BACKGROUND = MARGIN + (unused ? 1 : 0);
final int HALF = MARGIN + 45;
final int FULL = MARGIN + 36;
for (int heart = 0; hearts > 0; heart += 20)
{
int top = height - right_height;
int rowCount = Math.min(hearts, 10);
hearts -= rowCount;
for (int i = 0; i < rowCount; ++i)
{
int x = left_align - i * 8 - 9;
drawTexturedModalRect(x, top, BACKGROUND, 9, 9, 9);
if (i * 2 + 1 + heart < health)
drawTexturedModalRect(x, top, FULL, 9, 9, 9);
else if (i * 2 + 1 + heart == health)
drawTexturedModalRect(x, top, HALF, 9, 9, 9);
}
right_height += 10;
}
post(HEALTHMOUNT);
}
//Helper macros
private boolean pre(ElementType type)
{
return MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Pre(eventParent, type));
}
private void post(ElementType type)
{
MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Post(eventParent, type));
}
private void bind(ResourceLocation res)
{
mc.func_110434_K().func_110577_a(res);
}
}
@@ -1,137 +0,0 @@
package net.minecraftforge.client;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLiving;
import net.minecraft.item.ItemStack;
import net.minecraft.client.renderer.RenderBlocks;
public interface IItemRenderer
{
public enum ItemRenderType
{
/**
* Called to render an in-world item, e.g. one that has been thrown or
* dropped. The appropriate OpenGL transformations and scaling have already
* been applied, so Tessellator location (0,0,0) is the center of the
* EntityItem.
*
* Data parameters:
* RenderBlocks render - The RenderBlocks instance
* EntityItem entity - The in-world item to be rendered
*/
ENTITY,
/**
* Called to render an item currently held in-hand by a living entity. If
* rendering as a 3D block, the item will be rotated to a 45-degree angle.
* To render a 2D texture with some thickness (like default items), see
* net.minecraft.src.ItemRenderer. In either case, rendering should be done
* in local coordinates from (0,0,0)-(1,1,1).
*
* Data parameters:
* RenderBlocks render - The RenderBlocks instance
* EntityLiving entity - The entity holding this item
*/
EQUIPPED,
/**
* Called to render an item currently held in-hand by a living entity in
* first person. If rendering as a 3D block, the item will be rotated to a
* 45-degree angle. To render a 2D texture with some thickness, see
* net.minecraft.src.ItemRenderer. In either case, rendering should be done
* in local coordinates from (0,0,0)-(1,1,1).
*
* Data parameters:
* RenderBlocks render - The RenderBlocks instance
* EntityLiving entity - The entity holding this item
*/
EQUIPPED_FIRST_PERSON,
/**
* Called to render an item in a GUI inventory slot. If rendering as a 3D
* block, the appropriate OpenGL translations and scaling have already been
* applied, and the rendering should be done in local coordinates from
* (0,0,0)-(1,1,1). If rendering as a 2D texture, the rendering should be in
* GUI pixel coordinates from (0, 0, 0)-(16, 16, 0).
*
* Data parameters:
* RenderBlocks render - The RenderBlocks instance
*/
INVENTORY,
/**
* The render type used for when a ItemMap is rendered in first person,
* All appropriate rotations have been applied, and the player's hands,
* and the map BG are already rendered.
*
* Data Parameters:
* EntityPlayer player - The player holding the map
* RenderEngine engine - The RenderEngine instance
* MapData mapData - The map data
*/
FIRST_PERSON_MAP
}
public enum ItemRendererHelper
{
/**
* Determines if a rotation effect should be used when rendering an
* EntityItem, like most default blocks do.
*/
ENTITY_ROTATION,
/**
* Determines if an up-and-down bobbing effect should be used when
* rendering an EntityItem, like most default items do.
*/
ENTITY_BOBBING,
/**
* Determines if the currently equipped item should be rendered as a 3D
* block or as a 2D texture.
*/
EQUIPPED_BLOCK,
/**
* Determines if the item should equate to a block that has
* RenderBlocks.renderItemIn3d return true
*/
BLOCK_3D,
/**
* Determines if the item should be rendered in GUI inventory slots as a 3D
* block or as a 2D texture.
*/
INVENTORY_BLOCK
}
/**
* Checks if this renderer should handle a specific item's render type
* @param item The item we are trying to render
* @param type A render type to check if this renderer handles
* @return true if this renderer should handle the given render type,
* otherwise false
*/
public boolean handleRenderType(ItemStack item, ItemRenderType type);
/**
* Checks if certain helper functionality should be executed for this renderer.
* See ItemRendererHelper for more info
*
* @param type The render type
* @param item The ItemStack being rendered
* @param helper The type of helper functionality to be ran
* @return True to run the helper functionality, false to not.
*/
public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper);
/**
* Called to do the actual rendering, see ItemRenderType for details on when specific
* types are run, and what extra data is passed into the data parameter.
*
* @param type The render type
* @param item The ItemStack being rendered
* @param data Extra Type specific data
*/
public void renderItem(ItemRenderType type, ItemStack item, Object... data);
}
@@ -1,17 +0,0 @@
/*
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.client;
public interface IRenderContextHandler
{
/** Run before the specified rendering context.
*/
public void beforeRenderContext();
/** Run after the specified rendering context.
*/
public void afterRenderContext();
}
@@ -1,12 +0,0 @@
package net.minecraftforge.client;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.WorldClient;
public abstract class IRenderHandler
{
@SideOnly(Side.CLIENT)
public abstract void render(float partialTicks, WorldClient world, Minecraft mc);
}
@@ -1,92 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.client;
import java.util.BitSet;
import org.lwjgl.opengl.Display;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.world.World;
import net.minecraftforge.client.IItemRenderer.ItemRenderType;
import net.minecraftforge.common.MinecraftForge;
public class MinecraftForgeClient
{
private static IItemRenderer[] customItemRenderers = new IItemRenderer[Item.itemsList.length];
/**
* Register a custom renderer for a specific item. This can be used to
* render the item in-world as an EntityItem, when the item is equipped, or
* when the item is in an inventory slot.
* @param itemID The item ID (shifted index) to handle rendering.
* @param renderer The IItemRenderer interface that handles rendering for
* this item.
*/
public static void registerItemRenderer(int itemID, IItemRenderer renderer)
{
customItemRenderers[itemID] = renderer;
}
public static IItemRenderer getItemRenderer(ItemStack item, ItemRenderType type)
{
IItemRenderer renderer = customItemRenderers[item.itemID];
if (renderer != null && renderer.handleRenderType(item, type))
{
return customItemRenderers[item.itemID];
}
return null;
}
public static int getRenderPass()
{
return ForgeHooksClient.renderPass;
}
public static int getStencilBits()
{
return ForgeHooksClient.stencilBits;
}
private static BitSet stencilBits = new BitSet(getStencilBits());
static
{
stencilBits.set(0,getStencilBits());
}
/**
* Reserve a stencil bit for use in rendering
*
* @return A bit or -1 if no further stencil bits are available
*/
public static int reserveStencilBit()
{
int bit = stencilBits.nextSetBit(0);
if (bit >= 0)
{
stencilBits.clear(bit);
}
return bit;
}
/**
* Release the stencil bit for other use
*
* @param bit The bit from {@link #reserveStencilBit()}
*/
public static void releaseStencilBit(int bit)
{
if (bit >= 0 && bit < getStencilBits())
{
stencilBits.set(bit);
}
}
}
@@ -1,14 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
@Cancelable
public class ClientChatReceivedEvent extends Event
{
public String message;
public ClientChatReceivedEvent(String message)
{
this.message = message;
}
}
@@ -1,30 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
@Cancelable
public class DrawBlockHighlightEvent extends Event
{
public final RenderGlobal context;
public final EntityPlayer player;
public final MovingObjectPosition target;
public final int subID;
public final ItemStack currentItem;
public final float partialTicks;
public DrawBlockHighlightEvent(RenderGlobal context, EntityPlayer player, MovingObjectPosition target, int subID, ItemStack currentItem, float partialTicks)
{
this.context = context;
this.player = player;
this.target = target;
this.subID = subID;
this.currentItem = currentItem;
this.partialTicks= partialTicks;
}
}
@@ -1,82 +0,0 @@
package net.minecraftforge.client.event;
import java.util.ArrayList;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
@Cancelable
public class RenderGameOverlayEvent extends Event
{
public static enum ElementType
{
ALL,
HELMET,
PORTAL,
CROSSHAIRS,
BOSSHEALTH,
ARMOR,
HEALTH,
FOOD,
AIR,
HOTBAR,
EXPERIENCE,
TEXT,
HEALTHMOUNT,
JUMPBAR
}
public final float partialTicks;
public final ScaledResolution resolution;
public final int mouseX;
public final int mouseY;
public final ElementType type;
public RenderGameOverlayEvent(float partialTicks, ScaledResolution resolution, int mouseX, int mouseY)
{
this.partialTicks = partialTicks;
this.resolution = resolution;
this.mouseX = mouseX;
this.mouseY = mouseY;
this.type = null;
}
private RenderGameOverlayEvent(RenderGameOverlayEvent parent, ElementType type)
{
this.partialTicks = parent.partialTicks;
this.resolution = parent.resolution;
this.mouseX = parent.mouseX;
this.mouseY = parent.mouseY;
this.type = type;
}
public static class Pre extends RenderGameOverlayEvent
{
public Pre(RenderGameOverlayEvent parent, ElementType type)
{
super(parent, type);
}
}
public static class Post extends RenderGameOverlayEvent
{
public Post(RenderGameOverlayEvent parent, ElementType type)
{
super(parent, type);
}
@Override public boolean isCancelable(){ return false; }
}
public static class Text extends Pre
{
public final ArrayList<String> left;
public final ArrayList<String> right;
public Text(RenderGameOverlayEvent parent, ArrayList<String> left, ArrayList<String> right)
{
super(parent, ElementType.TEXT);
this.left = left;
this.right = right;
}
}
}
@@ -1,33 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraft.client.renderer.entity.RendererLivingEntity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
public abstract class RenderLivingEvent extends Event
{
public final EntityLivingBase entity;
public final RendererLivingEntity renderer;
public RenderLivingEvent(EntityLivingBase entity, RendererLivingEntity renderer)
{
this.entity = entity;
this.renderer = renderer;
}
public abstract static class Specials extends RenderLivingEvent
{
public Specials(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
@Cancelable
public static class Pre extends Specials
{
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
public static class Post extends Specials
{
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
}
}
@@ -1,72 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.entity.player.PlayerEvent;
public abstract class RenderPlayerEvent extends PlayerEvent
{
public final RenderPlayer renderer;
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer)
{
super(player);
this.renderer = renderer;
}
@Cancelable
public static class Pre extends RenderPlayerEvent
{
public Pre(EntityPlayer player, RenderPlayer renderer){ super(player, renderer); }
}
public static class Post extends RenderPlayerEvent
{
public Post(EntityPlayer player, RenderPlayer renderer){ super(player, renderer); }
}
public abstract static class Specials extends RenderPlayerEvent
{
public final float partialTicks;
public Specials(EntityPlayer player, RenderPlayer renderer, float partialTicks)
{
super(player, renderer);
this.partialTicks = partialTicks;
}
@Cancelable
public static class Pre extends Specials
{
public boolean renderHelmet = true;
public boolean renderCape = true;
public boolean renderItem = true;
public Pre(EntityPlayer player, RenderPlayer renderer, float partialTicks){ super(player, renderer, partialTicks); }
}
public static class Post extends Specials
{
public Post(EntityPlayer player, RenderPlayer renderer, float partialTicks){ super(player, renderer, partialTicks); }
}
}
public static class SetArmorModel extends RenderPlayerEvent
{
/**
* Setting this to any value besides -1 will result in the function being
* Immediately exited with the return value specified.
*/
public int result = -1;
public final int slot;
public final float partialTick;
public final ItemStack stack;
public SetArmorModel(EntityPlayer player, RenderPlayer renderer, int slot, float partialTick, ItemStack stack)
{
super(player, renderer);
this.slot = slot;
this.partialTick = partialTick;
this.stack = stack;
}
}
}
@@ -1,15 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraftforge.event.Event;
public class RenderWorldLastEvent extends Event
{
public final RenderGlobal context;
public final float partialTicks;
public RenderWorldLastEvent(RenderGlobal context, float partialTicks)
{
this.context = context;
this.partialTicks = partialTicks;
}
}
@@ -1,35 +0,0 @@
package net.minecraftforge.client.event;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraftforge.event.Event;
public class TextureStitchEvent extends Event
{
public final TextureMap map;
public TextureStitchEvent(TextureMap map)
{
this.map = map;
}
/**
* Fired when the TextureMap is told to refresh it's stitched texture.
* Called after the Stitched list is cleared, but before any blocks or items
* add themselves to the list.
*/
public static class Pre extends TextureStitchEvent
{
public Pre(TextureMap map){ super(map); }
}
/**
* This event is fired once the texture map has loaded all textures and
* stitched them together. All Icons should have there locations defined
* by the time this is fired.
*/
public static class Post extends TextureStitchEvent
{
public Post(TextureMap map){ super(map); }
}
}
@@ -1,15 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
/**
* Raised when the SoundManager tries to play a Background Music file,
* If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played.
*/
public class PlayBackgroundMusicEvent extends SoundResultEvent
{
public PlayBackgroundMusicEvent(SoundManager manager, SoundPoolEntry entry)
{ super(manager, entry, null, 0.0f, 0.0f); }
}
@@ -1,10 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
public class PlaySoundEffectEvent extends SoundResultEvent
{
public PlaySoundEffectEvent(SoundManager manager, SoundPoolEntry source, String name, float volume, float pitch)
{ super(manager, source, name, volume, pitch); }
}
@@ -1,14 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
public class PlaySoundEffectSourceEvent extends SoundEvent
{
public final SoundManager manager;
public final String name;
public PlaySoundEffectSourceEvent(SoundManager manager, String name)
{
this.manager = manager;
this.name = name;
}
}
@@ -1,25 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
/***
* Raised when the SoundManager tries to play a normal sound,
* dogs barking, footsteps, etc. THe majority of all sounds during normal game play.
*
* If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played.
*/
public class PlaySoundEvent extends SoundResultEvent
{
public final float x;
public final float y;
public final float z;
public PlaySoundEvent(SoundManager manager, SoundPoolEntry source, String name, float x, float y, float z, float volume, float pitch)
{
super(manager, source, name, volume, pitch);
this.x = x;
this.y = y;
this.z = z;
}
}
@@ -1,20 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
public class PlaySoundSourceEvent extends SoundEvent
{
public final SoundManager manager;
public final String name;
public final float x;
public final float y;
public final float z;
public PlaySoundSourceEvent(SoundManager manager, String name, float x, float y, float z)
{
this.manager = manager;
this.name = name;
this.x = x;
this.y = y;
this.z = z;
}
}
@@ -1,26 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
/**
* Raised when the SoundManager tries to play a 'Streaming' file,
* in vanilla it is only the Jukebox that uses this function.
*
* If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played.
*
*/
public class PlayStreamingEvent extends SoundResultEvent
{
public final float x;
public final float y;
public final float z;
public PlayStreamingEvent(SoundManager manager, SoundPoolEntry source, String name, float x, float y, float z)
{
super(manager, source, name, 0.0f, 0.0f);
this.x = x;
this.y = y;
this.z = z;
}
}
@@ -1,20 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
public class PlayStreamingSourceEvent extends SoundEvent
{
public final SoundManager manager;
public final String name;
public final float x;
public final float y;
public final float z;
public PlayStreamingSourceEvent(SoundManager manager, String name, float x, float y, float z)
{
this.manager = manager;
this.name = name;
this.x = x;
this.y = y;
this.z = z;
}
}
@@ -1,19 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.entity.Entity;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
public class SoundEvent extends Event
{
public SoundEvent(){}
public static SoundPoolEntry getResult(SoundResultEvent event)
{
MinecraftForge.EVENT_BUS.post(event);
return event.result;
}
}
@@ -1,16 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
/**
* Raised by the SoundManager.loadSoundSettings, this would be a good place for
* adding your custom sounds to the SoundPool.
*/
public class SoundLoadEvent extends SoundEvent
{
public final SoundManager manager;
public SoundLoadEvent(SoundManager manager)
{
this.manager = manager;
}
}
@@ -1,24 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
public abstract class SoundResultEvent extends SoundEvent
{
public final SoundManager manager;
public final SoundPoolEntry source;
public final String name;
public final float volume;
public final float pitch;
public SoundPoolEntry result;
public SoundResultEvent(SoundManager manager, SoundPoolEntry source, String name, float volume, float pitch)
{
this.manager = manager;
this.source = source;
this.name = name;
this.volume = volume;
this.pitch = pitch;
this.result = source;
}
}
@@ -1,16 +0,0 @@
package net.minecraftforge.client.event.sound;
import net.minecraft.client.audio.SoundManager;
/**
* This event is raised by the SoundManager when it does its first setup of the
* SoundSystemConfig's codecs, use this function to add your own codecs.
*/
public class SoundSetupEvent extends SoundEvent
{
public final SoundManager manager;
public SoundSetupEvent(SoundManager manager)
{
this.manager = manager;
}
}
@@ -1,82 +0,0 @@
package net.minecraftforge.client.model;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import net.minecraftforge.client.model.obj.ObjModelLoader;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Common interface for advanced model loading from files, based on file suffix
* Model support can be queried through the {@link #getSupportedSuffixes()} method.
* Instances can be created by calling {@link #loadModel(String)} with a class-loadable-path
*
* @author cpw
*
*/
@SideOnly(Side.CLIENT)
public class AdvancedModelLoader {
private static Map<String, IModelCustomLoader> instances = Maps.newHashMap();
/**
* Register a new model handler
* @param modelHandler The model handler to register
*/
public static void registerModelHandler(IModelCustomLoader modelHandler)
{
for (String suffix : modelHandler.getSuffixes())
{
instances.put(suffix, modelHandler);
}
}
/**
* Load the model from the supplied classpath resolvable resource name
* @param resourceName The resource name
* @return A model
* @throws IllegalArgumentException if the resource name cannot be understood
* @throws ModelFormatException if the underlying model handler cannot parse the model format
*/
public static IModelCustom loadModel(String resourceName) throws IllegalArgumentException, ModelFormatException
{
int i = resourceName.lastIndexOf('.');
if (i == -1)
{
FMLLog.severe("The resource name %s is not valid", resourceName);
throw new IllegalArgumentException("The resource name is not valid");
}
String suffix = resourceName.substring(i+1);
IModelCustomLoader loader = instances.get(suffix);
if (loader == null)
{
FMLLog.severe("The resource name %s is not supported", resourceName);
throw new IllegalArgumentException("The resource name is not supported");
}
URL resource = AdvancedModelLoader.class.getResource(resourceName);
if (resource == null)
{
FMLLog.severe("The resource name %s could not be found", resourceName);
throw new IllegalArgumentException("The resource name could not be found");
}
return loader.loadInstance(resourceName, resource);
}
public static Collection<String> getSupportedSuffixes()
{
return instances.keySet();
}
static
{
registerModelHandler(new ObjModelLoader());
}
}
@@ -1,9 +0,0 @@
package net.minecraftforge.client.model;
public interface IModelCustom {
String getType();
void renderAll();
void renderPart(String partName);
}
@@ -1,31 +0,0 @@
package net.minecraftforge.client.model;
import java.io.InputStream;
import java.net.URL;
/**
* Instances of this class act as factories for their model type
*
* @author cpw
*
*/
public interface IModelCustomLoader {
/**
* Get the main type name for this loader
* @return the type name
*/
String getType();
/**
* Get resource suffixes this model loader recognizes
* @return a list of suffixes
*/
String[] getSuffixes();
/**
* Load a model instance from the supplied path
* @param resourceName The resource name to load
* @param resource The URL associated with the classloader resource
* @return A model instance
* @throws ModelFormatException if the model format is not correct
*/
IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException;
}
@@ -1,31 +0,0 @@
package net.minecraftforge.client.model;
/**
* Thrown if there is a problem parsing the model
*
* @author cpw
*
*/
public class ModelFormatException extends RuntimeException {
public ModelFormatException()
{
super();
}
public ModelFormatException(String message, Throwable cause)
{
super(message, cause);
}
public ModelFormatException(String message)
{
super(message);
}
public ModelFormatException(Throwable cause)
{
super(cause);
}
}
@@ -1,84 +0,0 @@
package net.minecraftforge.client.model.obj;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.Vec3;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class Face
{
public Vertex[] vertices;
public Vertex[] vertexNormals;
public Vertex faceNormal;
public TextureCoordinate[] textureCoordinates;
public void addFaceForRender(Tessellator tessellator)
{
addFaceForRender(tessellator, 0.0005F);
}
public void addFaceForRender(Tessellator tessellator, float textureOffset)
{
if (faceNormal == null)
{
faceNormal = this.calculateFaceNormal();
}
tessellator.setNormal(faceNormal.x, faceNormal.y, faceNormal.z);
float averageU = 0F;
float averageV = 0F;
if ((textureCoordinates != null) && (textureCoordinates.length > 0))
{
for (int i = 0; i < textureCoordinates.length; ++i)
{
averageU += textureCoordinates[i].u;
averageV += textureCoordinates[i].v;
}
averageU = averageU / textureCoordinates.length;
averageV = averageV / textureCoordinates.length;
}
float offsetU, offsetV;
for (int i = 0; i < vertices.length; ++i)
{
if ((textureCoordinates != null) && (textureCoordinates.length > 0))
{
offsetU = textureOffset;
offsetV = textureOffset;
if (textureCoordinates[i].u > averageU)
{
offsetU = -offsetU;
}
if (textureCoordinates[i].v > averageV)
{
offsetV = -offsetV;
}
tessellator.addVertexWithUV(vertices[i].x, vertices[i].y, vertices[i].z, textureCoordinates[i].u + offsetU, textureCoordinates[i].v + offsetV);
}
else
{
tessellator.addVertex(vertices[i].x, vertices[i].y, vertices[i].z);
}
}
}
public Vertex calculateFaceNormal()
{
Vec3 v1 = Vec3.createVectorHelper(vertices[1].x - vertices[0].x, vertices[1].y - vertices[0].y, vertices[1].z - vertices[0].z);
Vec3 v2 = Vec3.createVectorHelper(vertices[2].x - vertices[0].x, vertices[2].y - vertices[0].y, vertices[2].z - vertices[0].z);
Vec3 normalVector = null;
normalVector = v1.crossProduct(v2).normalize();
return new Vertex((float) normalVector.xCoord, (float) normalVector.yCoord, (float) normalVector.zCoord);
}
}
@@ -1,54 +0,0 @@
package net.minecraftforge.client.model.obj;
import java.util.ArrayList;
import net.minecraft.client.renderer.Tessellator;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GroupObject
{
public String name;
public ArrayList<Face> faces = new ArrayList<Face>();
public int glDrawingMode;
public GroupObject()
{
this("");
}
public GroupObject(String name)
{
this(name, -1);
}
public GroupObject(String name, int glDrawingMode)
{
this.name = name;
this.glDrawingMode = glDrawingMode;
}
public void render()
{
if (faces.size() > 0)
{
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawing(glDrawingMode);
render(tessellator);
tessellator.draw();
}
}
public void render(Tessellator tessellator)
{
if (faces.size() > 0)
{
for (Face face : faces)
{
face.addFaceForRender(tessellator);
}
}
}
}
@@ -1,31 +0,0 @@
package net.minecraftforge.client.model.obj;
import java.io.InputStream;
import java.net.URL;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.IModelCustomLoader;
import net.minecraftforge.client.model.ModelFormatException;
public class ObjModelLoader implements IModelCustomLoader {
@Override
public String getType()
{
return "OBJ model";
}
private static final String[] types = { "obj" };
@Override
public String[] getSuffixes()
{
return types;
}
@Override
public IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException
{
return new WavefrontObject(resourceName, resource);
}
}
@@ -1,23 +0,0 @@
package net.minecraftforge.client.model.obj;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class TextureCoordinate
{
public float u, v, w;
public TextureCoordinate(float u, float v)
{
this(u, v, 0F);
}
public TextureCoordinate(float u, float v, float w)
{
this.u = u;
this.v = v;
this.w = w;
}
}
@@ -1,23 +0,0 @@
package net.minecraftforge.client.model.obj;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class Vertex
{
public float x, y, z;
public Vertex(float x, float y)
{
this(x, y, 0F);
}
public Vertex(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
@@ -1,583 +0,0 @@
package net.minecraftforge.client.model.obj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.client.renderer.Tessellator;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.ModelFormatException;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Wavefront Object importer
* Based heavily off of the specifications found at http://en.wikipedia.org/wiki/Wavefront_.obj_file
*/
@SideOnly(Side.CLIENT)
public class WavefrontObject implements IModelCustom
{
private static Pattern vertexPattern = Pattern.compile("(v( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(v( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
private static Pattern vertexNormalPattern = Pattern.compile("(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
private static Pattern textureCoordinatePattern = Pattern.compile("(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *\\n)|(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *$)");
private static Pattern face_V_VT_VN_Pattern = Pattern.compile("(f( \\d+/\\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+/\\d+){3,4} *$)");
private static Pattern face_V_VT_Pattern = Pattern.compile("(f( \\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+){3,4} *$)");
private static Pattern face_V_VN_Pattern = Pattern.compile("(f( \\d+//\\d+){3,4} *\\n)|(f( \\d+//\\d+){3,4} *$)");
private static Pattern face_V_Pattern = Pattern.compile("(f( \\d+){3,4} *\\n)|(f( \\d+){3,4} *$)");
private static Pattern groupObjectPattern = Pattern.compile("([go]( [\\w\\d]+) *\\n)|([go]( [\\w\\d]+) *$)");
private static Matcher vertexMatcher, vertexNormalMatcher, textureCoordinateMatcher;
private static Matcher face_V_VT_VN_Matcher, face_V_VT_Matcher, face_V_VN_Matcher, face_V_Matcher;
private static Matcher groupObjectMatcher;
public ArrayList<Vertex> vertices = new ArrayList<Vertex>();
public ArrayList<Vertex> vertexNormals = new ArrayList<Vertex>();
public ArrayList<TextureCoordinate> textureCoordinates = new ArrayList<TextureCoordinate>();
public ArrayList<GroupObject> groupObjects = new ArrayList<GroupObject>();
private GroupObject currentGroupObject;
private String fileName;
public WavefrontObject(String fileName, URL resource) throws ModelFormatException
{
this.fileName = fileName;
loadObjModel(resource);
}
private void loadObjModel(URL fileURL) throws ModelFormatException
{
BufferedReader reader = null;
InputStream inputStream = null;
String currentLine = null;
int lineCount = 0;
try
{
inputStream = fileURL.openStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((currentLine = reader.readLine()) != null)
{
lineCount++;
currentLine = currentLine.replaceAll("\\s+", " ").trim();
if (currentLine.startsWith("#") || currentLine.length() == 0)
{
continue;
}
else if (currentLine.startsWith("v "))
{
Vertex vertex = parseVertex(currentLine, lineCount);
if (vertex != null)
{
vertices.add(vertex);
}
}
else if (currentLine.startsWith("vn "))
{
Vertex vertex = parseVertexNormal(currentLine, lineCount);
if (vertex != null)
{
vertexNormals.add(vertex);
}
}
else if (currentLine.startsWith("vt "))
{
TextureCoordinate textureCoordinate = parseTextureCoordinate(currentLine, lineCount);
if (textureCoordinate != null)
{
textureCoordinates.add(textureCoordinate);
}
}
else if (currentLine.startsWith("f "))
{
if (currentGroupObject == null)
{
currentGroupObject = new GroupObject("Default");
}
Face face = parseFace(currentLine, lineCount);
if (face != null)
{
currentGroupObject.faces.add(face);
}
}
else if (currentLine.startsWith("g ") | currentLine.startsWith("o "))
{
GroupObject group = parseGroupObject(currentLine, lineCount);
if (group != null)
{
if (currentGroupObject != null)
{
groupObjects.add(currentGroupObject);
}
}
currentGroupObject = group;
}
}
groupObjects.add(currentGroupObject);
}
catch (IOException e)
{
throw new ModelFormatException("IO Exception reading model format", e);
}
finally
{
try
{
reader.close();
}
catch (IOException e)
{
// hush
}
try
{
inputStream.close();
}
catch (IOException e)
{
// hush
}
}
}
public void renderAll()
{
Tessellator tessellator = Tessellator.instance;
if (currentGroupObject != null)
{
tessellator.startDrawing(currentGroupObject.glDrawingMode);
}
else
{
tessellator.startDrawing(GL11.GL_TRIANGLES);
}
for (GroupObject groupObject : groupObjects)
{
groupObject.render(tessellator);
}
tessellator.draw();
}
public void renderOnly(String... groupNames)
{
for (GroupObject groupObject : groupObjects)
{
for (String groupName : groupNames)
{
if (groupName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
}
}
}
}
public void renderPart(String partName)
{
for (GroupObject groupObject : groupObjects)
{
if (partName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
}
}
}
public void renderAllExcept(String... excludedGroupNames)
{
for (GroupObject groupObject : groupObjects)
{
for (String excludedGroupName : excludedGroupNames)
{
if (!excludedGroupName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
}
}
}
}
private Vertex parseVertex(String line, int lineCount) throws ModelFormatException
{
Vertex vertex = null;
if (isValidVertexLine(line))
{
line = line.substring(line.indexOf(" ") + 1);
String[] tokens = line.split(" ");
try
{
if (tokens.length == 2)
{
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]));
}
else if (tokens.length == 3)
{
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
}
}
catch (NumberFormatException e)
{
throw new ModelFormatException(String.format("Number formatting error at line %d",lineCount), e);
}
}
else
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return vertex;
}
private Vertex parseVertexNormal(String line, int lineCount) throws ModelFormatException
{
Vertex vertexNormal = null;
if (isValidVertexNormalLine(line))
{
line = line.substring(line.indexOf(" ") + 1);
String[] tokens = line.split(" ");
try
{
if (tokens.length == 3)
return new Vertex(Float.parseFloat(tokens[0]), Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
}
catch (NumberFormatException e)
{
throw new ModelFormatException(String.format("Number formatting error at line %d",lineCount), e);
}
}
else
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return vertexNormal;
}
private TextureCoordinate parseTextureCoordinate(String line, int lineCount) throws ModelFormatException
{
TextureCoordinate textureCoordinate = null;
if (isValidTextureCoordinateLine(line))
{
line = line.substring(line.indexOf(" ") + 1);
String[] tokens = line.split(" ");
try
{
if (tokens.length == 2)
return new TextureCoordinate(Float.parseFloat(tokens[0]), 1 - Float.parseFloat(tokens[1]));
else if (tokens.length == 3)
return new TextureCoordinate(Float.parseFloat(tokens[0]), 1 - Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
}
catch (NumberFormatException e)
{
throw new ModelFormatException(String.format("Number formatting error at line %d",lineCount), e);
}
}
else
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return textureCoordinate;
}
private Face parseFace(String line, int lineCount) throws ModelFormatException
{
Face face = null;
if (isValidFaceLine(line))
{
face = new Face();
String trimmedLine = line.substring(line.indexOf(" ") + 1);
String[] tokens = trimmedLine.split(" ");
String[] subTokens = null;
if (tokens.length == 3)
{
if (currentGroupObject.glDrawingMode == -1)
{
currentGroupObject.glDrawingMode = GL11.GL_TRIANGLES;
}
else if (currentGroupObject.glDrawingMode != GL11.GL_TRIANGLES)
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Invalid number of points for face (expected 4, found " + tokens.length + ")");
}
}
else if (tokens.length == 4)
{
if (currentGroupObject.glDrawingMode == -1)
{
currentGroupObject.glDrawingMode = GL11.GL_QUADS;
}
else if (currentGroupObject.glDrawingMode != GL11.GL_QUADS)
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Invalid number of points for face (expected 3, found " + tokens.length + ")");
}
}
// f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
if (isValidFace_V_VT_VN_Line(line))
{
face.vertices = new Vertex[tokens.length];
face.textureCoordinates = new TextureCoordinate[tokens.length];
face.vertexNormals = new Vertex[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("/");
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
face.textureCoordinates[i] = textureCoordinates.get(Integer.parseInt(subTokens[1]) - 1);
face.vertexNormals[i] = vertexNormals.get(Integer.parseInt(subTokens[2]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
// f v1/vt1 v2/vt2 v3/vt3 ...
else if (isValidFace_V_VT_Line(line))
{
face.vertices = new Vertex[tokens.length];
face.textureCoordinates = new TextureCoordinate[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("/");
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
face.textureCoordinates[i] = textureCoordinates.get(Integer.parseInt(subTokens[1]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
// f v1//vn1 v2//vn2 v3//vn3 ...
else if (isValidFace_V_VN_Line(line))
{
face.vertices = new Vertex[tokens.length];
face.vertexNormals = new Vertex[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("//");
face.vertices[i] = vertices.get(Integer.parseInt(subTokens[0]) - 1);
face.vertexNormals[i] = vertexNormals.get(Integer.parseInt(subTokens[1]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
// f v1 v2 v3 ...
else if (isValidFace_V_Line(line))
{
face.vertices = new Vertex[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
face.vertices[i] = vertices.get(Integer.parseInt(tokens[i]) - 1);
}
face.faceNormal = face.calculateFaceNormal();
}
else
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
}
else
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return face;
}
private GroupObject parseGroupObject(String line, int lineCount) throws ModelFormatException
{
GroupObject group = null;
if (isValidGroupObjectLine(line))
{
String trimmedLine = line.substring(line.indexOf(" ") + 1);
if (trimmedLine.length() > 0)
{
group = new GroupObject(trimmedLine);
}
}
else
{
throw new ModelFormatException("Error parsing entry ('" + line + "'" + ", line " + lineCount + ") in file '" + fileName + "' - Incorrect format");
}
return group;
}
/***
* Verifies that the given line from the model file is a valid vertex
* @param line the line being validated
* @return true if the line is a valid vertex, false otherwise
*/
private static boolean isValidVertexLine(String line)
{
if (vertexMatcher != null)
{
vertexMatcher.reset();
}
vertexMatcher = vertexPattern.matcher(line);
return vertexMatcher.matches();
}
/***
* Verifies that the given line from the model file is a valid vertex normal
* @param line the line being validated
* @return true if the line is a valid vertex normal, false otherwise
*/
private static boolean isValidVertexNormalLine(String line)
{
if (vertexNormalMatcher != null)
{
vertexNormalMatcher.reset();
}
vertexNormalMatcher = vertexNormalPattern.matcher(line);
return vertexNormalMatcher.matches();
}
/***
* Verifies that the given line from the model file is a valid texture coordinate
* @param line the line being validated
* @return true if the line is a valid texture coordinate, false otherwise
*/
private static boolean isValidTextureCoordinateLine(String line)
{
if (textureCoordinateMatcher != null)
{
textureCoordinateMatcher.reset();
}
textureCoordinateMatcher = textureCoordinatePattern.matcher(line);
return textureCoordinateMatcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by vertices, texture coordinates, and vertex normals
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1/vt1/vn1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_VT_VN_Line(String line)
{
if (face_V_VT_VN_Matcher != null)
{
face_V_VT_VN_Matcher.reset();
}
face_V_VT_VN_Matcher = face_V_VT_VN_Pattern.matcher(line);
return face_V_VT_VN_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by vertices and texture coordinates
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1/vt1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_VT_Line(String line)
{
if (face_V_VT_Matcher != null)
{
face_V_VT_Matcher.reset();
}
face_V_VT_Matcher = face_V_VT_Pattern.matcher(line);
return face_V_VT_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by vertices and vertex normals
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1//vn1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_VN_Line(String line)
{
if (face_V_VN_Matcher != null)
{
face_V_VN_Matcher.reset();
}
face_V_VN_Matcher = face_V_VN_Pattern.matcher(line);
return face_V_VN_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face that is described by only vertices
* @param line the line being validated
* @return true if the line is a valid face that matches the format "f v1 ..." (with a minimum of 3 points in the face, and a maximum of 4), false otherwise
*/
private static boolean isValidFace_V_Line(String line)
{
if (face_V_Matcher != null)
{
face_V_Matcher.reset();
}
face_V_Matcher = face_V_Pattern.matcher(line);
return face_V_Matcher.matches();
}
/***
* Verifies that the given line from the model file is a valid face of any of the possible face formats
* @param line the line being validated
* @return true if the line is a valid face that matches any of the valid face formats, false otherwise
*/
private static boolean isValidFaceLine(String line)
{
return isValidFace_V_VT_VN_Line(line) || isValidFace_V_VT_Line(line) || isValidFace_V_VN_Line(line) || isValidFace_V_Line(line);
}
/***
* Verifies that the given line from the model file is a valid group (or object)
* @param line the line being validated
* @return true if the line is a valid group (or object), false otherwise
*/
private static boolean isValidGroupObjectLine(String line)
{
if (groupObjectMatcher != null)
{
groupObjectMatcher.reset();
}
groupObjectMatcher = groupObjectPattern.matcher(line);
return groupObjectMatcher.matches();
}
@Override
public String getType()
{
return "obj";
}
}
@@ -1,642 +0,0 @@
package paulscode.sound.codecs;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import javax.sound.sampled.AudioFormat;
import paulscode.sound.ICodec;
import paulscode.sound.SoundBuffer;
import paulscode.sound.SoundSystemConfig;
import paulscode.sound.SoundSystemLogger;
import ibxm.FastTracker2;
import ibxm.IBXM;
import ibxm.Module;
import ibxm.ProTracker;
import ibxm.ScreamTracker3;
/**
* The CodecIBXM class provides an ICodec interface for reading from MOD/S3M/XM
* files via the IBXM library.
*<b><i> SoundSystem CodecIBXM Class License:</b></i><br><b><br>
* You are free to use this class for any purpose, commercial or otherwise.
* You may modify this class or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this class or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this class or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this class in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this class or any portion
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this class or any
* portion of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
*</b><br><br>
*<b>
* This software is based on or using the IBXM library available from
* http://www.geocities.com/sunet2000/
*</b><br><br>
*<br><b>
* IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD
* License.
*<br><br>
* All rights reserved.
*<br><br>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*<br><br>
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials
* provided with the distribution. Neither the name of mumart nor the names of
* its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* <br><br>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* <br><br><br></b>
*/
public class CodecIBXM implements ICodec
{
/**
* Used to return a current value from one of the synchronized
* boolean-interface methods.
*/
private static final boolean GET = false;
/**
* Used to set the value in one of the synchronized boolean-interface methods.
*/
private static final boolean SET = true;
/**
* Used when a parameter for one of the synchronized boolean-interface methods
* is not aplicable.
*/
private static final boolean XXX = false;
/**
* True if there is no more data to read in.
*/
private boolean endOfStream = false;
/**
* True if the stream has finished initializing.
*/
private boolean initialized = false;
/**
* Format the converted audio will be in.
*/
private AudioFormat myAudioFormat = null;
/**
* True if the using library requires data read by this codec to be
* reverse-ordered before returning it from methods read() and readAll().
*/
private boolean reverseBytes = false;
/**
* IBXM decoder.
*/
private IBXM ibxm;
/**
* Module instance to be played.
*/
private Module module;
/**
* Duration of the audio (in frames).
*/
private int songDuration;
/**
* Audio read position (in frames).
*/
private int playPosition;
/**
* Processes status messages, warnings, and error messages.
*/
private SoundSystemLogger logger;
/**
* Constructor: Grabs a handle to the logger.
*/
public CodecIBXM()
{
logger = SoundSystemConfig.getLogger();
}
/**
* Tells this codec when it will need to reverse the byte order of
* the data before returning it in the read() and readAll() methods. The
* IBXM library produces audio data in a format that some external audio
* libraries require to be reversed. Derivatives of the Library and Source
* classes for audio libraries which require this type of data to be reversed
* will call the reverseByteOrder() method.
* @param b True if the calling audio library requires byte-reversal.
*/
public void reverseByteOrder( boolean b )
{
reverseBytes = b;
}
/**
* Prepares an audio stream to read from. If another stream is already opened,
* it will be closed and a new audio stream opened in its place.
* @param url URL to an audio file to stream from.
* @return False if an error occurred or if end of stream was reached.
*/
public boolean initialize( URL url )
{
initialized( SET, false );
cleanup();
if( url == null )
{
errorMessage( "url null in method 'initialize'" );
cleanup();
return false;
}
InputStream is = null;
try
{
is = url.openStream();
}
catch( IOException ioe )
{
errorMessage( "Unable to open stream in method 'initialize'" );
printStackTrace( ioe );
return false;
}
if( ibxm == null )
ibxm = new IBXM( 48000 );
if( myAudioFormat == null )
myAudioFormat = new AudioFormat( 48000, 16, 2, true, true );
try
{
setModule( loadModule( is ) );
}
catch( IllegalArgumentException iae )
{
errorMessage( "Illegal argument in method 'initialize'" );
printStackTrace( iae );
if( is != null )
{
try
{
is.close();
}
catch( IOException ioe )
{}
}
return false;
}
catch( IOException ioe )
{
errorMessage( "Error loading module in method 'initialize'" );
printStackTrace( ioe );
if( is != null )
{
try
{
is.close();
}
catch( IOException ioe2 )
{}
}
return false;
}
if( is != null )
{
try
{
is.close();
}
catch( IOException ioe )
{}
}
endOfStream( SET, false );
initialized( SET, true );
return true;
}
/**
* Returns false if the stream is busy initializing.
* @return True if steam is initialized.
*/
public boolean initialized()
{
return initialized( GET, XXX );
}
/**
* Reads in one stream buffer worth of audio data. See
* {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more
* information about accessing and changing default settings.
* @return The audio data wrapped into a SoundBuffer context.
*/
public SoundBuffer read()
{
if( endOfStream( GET, XXX ) )
return null;
if( module == null )
{
errorMessage( "Module null in method 'read'" );
return null;
}
// Check to make sure there is an audio format:
if( myAudioFormat == null )
{
errorMessage( "Audio Format null in method 'read'" );
return null;
}
int bufferFrameSize = (int) SoundSystemConfig.getStreamingBufferSize()
/ 4;
int frames = songDuration - playPosition;
if( frames > bufferFrameSize )
frames = bufferFrameSize;
if( frames <= 0 )
{
endOfStream( SET, true );
return null;
}
byte[] outputBuffer = new byte[ frames * 4 ];
ibxm.get_audio( outputBuffer, frames );
playPosition += frames;
if( playPosition >= songDuration )
{
endOfStream( SET, true );
}
// Reverse the byte order if necessary:
if( reverseBytes )
reverseBytes( outputBuffer, 0, frames * 4 );
// Wrap the data into a SoundBuffer:
SoundBuffer buffer = new SoundBuffer( outputBuffer, myAudioFormat );
return buffer;
}
/**
* Reads in all the audio data from the stream (up to the default
* "maximum file size". See
* {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more
* information about accessing and changing default settings.
* @return the audio data wrapped into a SoundBuffer context.
*/
public SoundBuffer readAll()
{
if( module == null )
{
errorMessage( "Module null in method 'readAll'" );
return null;
}
// Check to make sure there is an audio format:
if( myAudioFormat == null )
{
errorMessage( "Audio Format null in method 'readAll'" );
return null;
}
int bufferFrameSize = (int) SoundSystemConfig.getFileChunkSize()
/ 4;
byte[] outputBuffer = new byte[ bufferFrameSize * 4 ];
// Buffer to contain the audio data:
byte[] fullBuffer = null;
// frames of audio data:
int frames;
// bytes of audio data:
int totalBytes = 0;
while( (!endOfStream(GET, XXX)) &&
(totalBytes < SoundSystemConfig.getMaxFileSize()) )
{
frames = songDuration - playPosition;
if( frames > bufferFrameSize )
frames = bufferFrameSize;
ibxm.get_audio( outputBuffer, frames );
totalBytes += (frames * 4);
fullBuffer = appendByteArrays( fullBuffer, outputBuffer,
frames * 4 );
playPosition += frames;
if( playPosition >= songDuration )
{
endOfStream( SET, true );
}
}
// Reverse the byte order if necessary:
if( reverseBytes )
reverseBytes( fullBuffer, 0, totalBytes );
// Wrap the data into a SoundBuffer:
SoundBuffer buffer = new SoundBuffer( fullBuffer, myAudioFormat );
return buffer;
}
/**
* Returns false if there is still more data available to be read in.
* @return True if end of stream was reached.
*/
public boolean endOfStream()
{
return endOfStream( GET, XXX );
}
/**
* Closes the audio stream and remove references to all instantiated objects.
*/
public void cleanup()
{
// if( ibxm != null )
// ibxm.seek( 0 );
playPosition = 0;
}
/**
* Returns the audio format of the data being returned by the read() and
* readAll() methods.
* @return Information wrapped into an AudioFormat context.
*/
public AudioFormat getAudioFormat()
{
return myAudioFormat;
}
/**
* Decodes the data in the specified InputStream into an instance of
* ibxm.Module.
* @param input an InputStream containing the module file to be decoded.
* @throws IllegalArgumentException if the data is not recognised as a module file.
*/
private static Module loadModule( InputStream input )
throws IllegalArgumentException, IOException
{
DataInputStream data_input_stream = new DataInputStream( input );
// Check if data is in XM format:
byte[] xm_header = new byte[ 60 ];
data_input_stream.readFully( xm_header );
if( FastTracker2.is_xm( xm_header ) )
return FastTracker2.load_xm( xm_header, data_input_stream );
// Check if data is in ScreamTracker 3 format:
byte[] s3m_header = new byte[ 96 ];
System.arraycopy( xm_header, 0, s3m_header, 0, 60 );
data_input_stream.readFully( s3m_header, 60, 36 );
if( ScreamTracker3.is_s3m( s3m_header ) )
return ScreamTracker3.load_s3m( s3m_header, data_input_stream );
// Check if data is in ProTracker format:
byte[] mod_header = new byte[ 1084 ];
System.arraycopy( s3m_header, 0, mod_header, 0, 96 );
data_input_stream.readFully( mod_header, 96, 988 );
return ProTracker.load_mod( mod_header, data_input_stream );
}
/**
* Sets the Module instance to be played.
*/
private void setModule( Module m )
{
if( m != null )
module = m;
ibxm.set_module( module );
songDuration = ibxm.calculate_song_duration();
}
/**
* Internal method for synchronizing access to the boolean 'initialized'.
* @param action GET or SET.
* @param value New value if action == SET, or XXX if action == GET.
* @return True if steam is initialized.
*/
private synchronized boolean initialized( boolean action, boolean value )
{
if( action == SET )
initialized = value;
return initialized;
}
/**
* Internal method for synchronizing access to the boolean 'endOfStream'.
* @param action GET or SET.
* @param value New value if action == SET, or XXX if action == GET.
* @return True if end of stream was reached.
*/
private synchronized boolean endOfStream( boolean action, boolean value )
{
if( action == SET )
endOfStream = value;
return endOfStream;
}
/**
* Trims down the size of the array if it is larger than the specified
* maximum length.
* @param array Array containing audio data.
* @param maxLength Maximum size this array may be.
* @return New array.
*/
private static byte[] trimArray( byte[] array, int maxLength )
{
byte[] trimmedArray = null;
if( array != null && array.length > maxLength )
{
trimmedArray = new byte[maxLength];
System.arraycopy( array, 0, trimmedArray, 0, maxLength );
}
return trimmedArray;
}
/**
* Reverse-orders all bytes contained in the specified array.
* @param buffer Array containing audio data.
*/
public static void reverseBytes( byte[] buffer )
{
reverseBytes( buffer, 0, buffer.length );
}
/**
* Reverse-orders the specified range of bytes contained in the specified array.
* @param buffer Array containing audio data.
* @param offset Array index to begin.
* @param size number of bytes to reverse-order.
*/
public static void reverseBytes( byte[] buffer, int offset, int size )
{
byte b;
for( int i = offset; i < ( offset + size ); i += 2 )
{
b = buffer[i];
buffer[i] = buffer[i + 1];
buffer[i + 1] = b;
}
}
/**
* Converts sound bytes to little-endian format.
* @param audio_bytes The original wave data
* @param two_bytes_data For stereo sounds.
* @return byte array containing the converted data.
*/
private static byte[] convertAudioBytes( byte[] audio_bytes,
boolean two_bytes_data )
{
ByteBuffer dest = ByteBuffer.allocateDirect( audio_bytes.length );
dest.order( ByteOrder.nativeOrder() );
ByteBuffer src = ByteBuffer.wrap( audio_bytes );
src.order( ByteOrder.LITTLE_ENDIAN );
if( two_bytes_data )
{
ShortBuffer dest_short = dest.asShortBuffer();
ShortBuffer src_short = src.asShortBuffer();
while( src_short.hasRemaining() )
{
dest_short.put(src_short.get());
}
}
else
{
while( src.hasRemaining() )
{
dest.put( src.get() );
}
}
dest.rewind();
if( !dest.hasArray() )
{
byte[] arrayBackedBuffer = new byte[dest.capacity()];
dest.get( arrayBackedBuffer );
dest.clear();
return arrayBackedBuffer;
}
return dest.array();
}
/**
* Creates a new array with the second array appended to the end of the first
* array.
* @param arrayOne The first array.
* @param arrayTwo The second array.
* @param length How many bytes to append from the second array.
* @return Byte array containing information from both arrays.
*/
private static byte[] appendByteArrays( byte[] arrayOne, byte[] arrayTwo,
int length )
{
byte[] newArray;
if( arrayOne == null && arrayTwo == null )
{
// no data, just return
return null;
}
else if( arrayOne == null )
{
// create the new array, same length as arrayTwo:
newArray = new byte[ length ];
// fill the new array with the contents of arrayTwo:
System.arraycopy( arrayTwo, 0, newArray, 0, length );
arrayTwo = null;
}
else if( arrayTwo == null )
{
// create the new array, same length as arrayOne:
newArray = new byte[ arrayOne.length ];
// fill the new array with the contents of arrayOne:
System.arraycopy( arrayOne, 0, newArray, 0, arrayOne.length );
arrayOne = null;
}
else
{
// create the new array large enough to hold both arrays:
newArray = new byte[ arrayOne.length + length ];
System.arraycopy( arrayOne, 0, newArray, 0, arrayOne.length );
// fill the new array with the contents of both arrays:
System.arraycopy( arrayTwo, 0, newArray, arrayOne.length,
length );
arrayOne = null;
arrayTwo = null;
}
return newArray;
}
/**
* Prints an error message.
* @param message Message to print.
*/
private void errorMessage( String message )
{
logger.errorMessage( "CodecWav", message, 0 );
}
/**
* Prints an exception's error message followed by the stack trace.
* @param e Exception containing the information to print.
*/
private void printStackTrace( Exception e )
{
logger.printStackTrace( e, 1 );
}
}
-162
View File
@@ -1,162 +0,0 @@
#Main Forge Access Transformer configuration file
# Tessellator
public-f bff.a #FD:Tessellator/field_78398_a #instance
public bff.u #FD:Tessellator/field_78409_u #drawMode
public bff.v #FD:Tessellator/field_78408_v #xOffset
public bff.w #FD:Tessellator/field_78407_w #yOffset
public bff.x #FD:Tessellator/field_78417_x #zOffset
public bff.z #FD:Tessellator/field_78415_z #isDrawing
# ItemPickaxe
public yi.<init>(ILxy;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yi.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
# ItemAxe
public xv.<init>(ILxy;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f xv.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
# ItemSpade
public yt.<init>(ILxy;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yt.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
# ItemTool
public xe.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
public xe.d #FD:ItemTool/field_77865_bY #damageVsEntity
# EntityEnderman
public td.br #FD:EntityEnderman/field_70827_d #carriableBlocks
# RenderEngine
# -- MISSING MAPPING public bge.f(Ljava/lang/String;)I #MD:RenderEngine/func_78341_b #getTexture
# -- MISSING MAPPING public bge.i #FD:RenderEngine/field_94154_l #terrainTextureMap
# -- MISSING MAPPING public bge.j #FD:RenderEngine/field_94155_m #itemTextureMap
# RenderGlobal
public bfa.k #FD:RenderGlobal/field_72769_h #theWorld
public bfa.l #FD:RenderGlobal/field_72770_i #renderEngine
public bfa.t #FD:RenderGlobal/field_72777_q #mc
public bfa.u #FD:RenderGlobal/field_72776_r #globalRenderBlocks
public bfa.H #FD:RenderGlobal/field_72738_E #damagedBlocks
# SoundManager
public blc.b #FD:SoundManager/field_77381_a #sndSystem
public blc.d #FD:SoundManager/field_77379_b #soundPoolSounds
public blc.e #FD:SoundManager/field_77380_c #soundPoolStreaming
public blc.f #FD:SoundManager/field_77377_d #soundPoolMusic
# EntityMinecart
protected sq.* #FD:EntityMinecart/* # All private -> protected
# -- MISSING MAPPING public py.h()Z #MD:EntityMinecart/func_70490_h #isMinecartPowered
# Block
public aqs.<init>(ILajv;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
public aqs.<init>(IILajv;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
public aqs.cH #FD:Block/field_72029_cc #blockResistance
public aqs.cG #FD:Block/field_71989_cb #blockHardness
# -- MISSING MAPPING public amq.r()Lamq; #MD:Block/func_71912_p #setRequiresSelfNotify
public aqs.a(Laqw;)Laqs; #MD:Block/func_71884_a #setStepSound
public aqs.b(F)Laqs; #MD:Block/func_71894_b #setResistance
public aqs.c(F)Laqs; #MD:Block/func_71848_c #setHardness
public aqs.k(I)Laqs; #MD:Block/func_71868_h #setLightOpacity
public aqs.a(F)Laqs; #MD:Block/func_71900_a #setLightValue
public aqs.r()Laqs; #MD:Block/func_71875_q #setBlockUnbreakable
public aqs.b(Z)Laqs; #MD:Block/func_71907_b #setTickRandomly
public aqs.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
# NetServerHandler
public jx.f #FD:NetServerHandler/field_72572_g #playerInAirTime
# TileEntity
public asi.k #FD:TileEntity/field_70331_k #worldObj
# BlockLeavesBase
public ara.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
# Item
public xx.<init>(I)V #MD:Item/<init>(I) #Constructor
public xx.e(I)Lxx; #MD:Item/func_77656_e #setMaxDamage
public-f xx.h(Lxz;)Lmp; #MD:Item/func_77650_f #getIconIndex
public xx.c(Ljava/lang/String;)Lxx; #MD:Item/func_77631_c #setPotionEffect
# RailLogic
public ams #CL:BlockBaseRailLogic
public ams.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
# EntityPlayer
public ua.a(Lsp;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
public ua.i()V #MD:EntityPlayer/func_71053_j #closeScreen
public ua.b #FD:EntityPlayer/field_71076_b #sleepTimer
# EntityPlayerMP
public bcx.a(Lsp;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
# World Gen Chests Related
public mh.* #FD:WeightedRandomChestContent/* #all
public jp.T #FD:WorldServer/field_73069_S #bonusChestContent
public agc.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
public ahg.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
public ahh.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
public ahh.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
public ahr.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
public ahv.b #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
public aia.c #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
public ajb.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
# AnvilChunkLoader.chunkSaveLocation
public adz.d #FD:AnvilChunkLoader/field_75825_d
# ChunkProviderServer.currentChunkLoader
public jo.e #FD:ChunkProviderServer/field_73247_e
# PlayerManager
public jm.a(IIZ)Ljn; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
# PlayerInstance
public jn #CL:PlayerInstance
# World
public-f abr.A #FD:World/field_72982_D #villageCollectionObj
public abr.G #FD:World/field_72993_I #activeChunkSet
# EntityLiving
public od.b #FD:EntityLiving/field_70728_aV #experienceValue
# -- MISSING MAPPING public ng.bt #FD:EntityLiving/field_94063_bt #combatTracker
public od.d #FD:EntityLiving/field_70715_bh #targetTasks
# GuiFlatPresets
public avq.a(Ljava/lang/String;ILacl;Ljava/util/List;[Lafy;)V #MD:GuiFlatPresets/func_82294_a
public avq.a(Ljava/lang/String;ILacl;[Lafy;)V #MD:GuiFlatPresets/func_82297_a
# BiomeGenBase
public acl.*() #MD:BiomeGenBase/* #Everything protected->public
# MapGenVillage
public-f aip.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
# ShapedRecipes
public+f aad.d #FD:ShapedRecipes/field_77574_d #recipeItems
public+f aad.b #FD:ShapedRecipes/field_77576_b #recipeWidth
public+f aad.c #FD:ShapedRecipes/field_77577_c #recipeHeight
# ShapelessRecipes
public aae.b #FD:ShapelessRecipes/field_77579_b #recipeItems
# GuiContainer
protected awp.a(Lvz;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
# ContainerPlayer
protected vq.h #FD:ContainerPlayer/field_82862_h #player
# BlockButton
protected amy.n(Labr;III)V #MD:BlockButton/func_82535_o #checkActivation
protected-f amy.a #FD:BlockButton/field_82537_a #sensible
# BiomeDecorator
public acp.* #FD:BiomeDecorator/* # All private -> protected
# CreativeTabs
public-f wr.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
# Packet
public ex.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
# SaveHandler
public alj.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
# World stuff
public abr.b(Lnk;)V #MD:World/func_72847_b #releaseEntitySkin
public abr.m #FD:World/field_73003_n #prevRainingStrength
public abr.n #FD:World/field_73004_o #rainingStrength
public abr.p #FD:World/field_73017_q #thunderingStrength
public abr.o #FD:World/field_73018_p #prevThunderingStrength
#WorldClient
public bcu.b(Lnk;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
#WorldServer
public jp.b(Lnk;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
public jp.N #FD:WorldServer/field_73068_P #allPlayersSleeping
#TextureMap
public bhz.g #FD:TextureMap/field_94255_a
# -- MISSING MAPPING public bir.b #FD:TextureMap/field_94253_b
public bhz.h #FD:TextureMap/field_94254_c
# -- MISSING MAPPING public bir.d #FD:TextureMap/field_94251_d
#Potion
public nf.b(II)Lnf; #MD:Potion/func_76399_b #setIconIndex
#PotionHelper
public zk.m #FD:PotionHelper/field_77927_l #potionRequirements
public zk.n #FD:PotionHelper/field_77928_m #potionAmplifiers
#PotionEffect
public ng.b #FD:PotionEffect/field_76460_b #duration
#BlockFluid
protected aov.a #FD:BlockFluid/field_94425_a #theIcon
#GuiIngame
protected ava.* #FD:GuiIngame/* # All private -> protected
protected ava.*() #MD:GuiIngame/* # All private -> protected
#ItemStack
default xz.f #FD:ItemStack/field_77991_e # make default access for itemDamage
#GuiSlot
protected avx.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
#EntityPlayer
public ua.bu #FD:EntityPlayer/field_71092_bJ #username
@@ -1,43 +0,0 @@
package net.minecraftforge.classloading;
import java.util.Map;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
public class FMLForgePlugin implements IFMLLoadingPlugin
{
public static boolean RUNTIME_DEOBF = false;
@Override
public String[] getLibraryRequestClass()
{
return null;
}
@Override
public String[] getASMTransformerClass()
{
return new String[]{
"net.minecraftforge.transformers.ForgeAccessTransformer",
"net.minecraftforge.transformers.EventTransformer"
};
}
@Override
public String getModContainerClass()
{
return "net.minecraftforge.common.ForgeDummyContainer";
}
@Override
public String getSetupClass()
{
return null;
}
@Override
public void injectData(Map<String, Object> data)
{
RUNTIME_DEOBF = (Boolean)data.get("runtimeDeobfuscationEnabled");
}
}
@@ -1,108 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import net.minecraft.stats.Achievement;
public class AchievementPage
{
private String name;
private LinkedList<Achievement> achievements;
public AchievementPage(String name, Achievement... achievements)
{
this.name = name;
this.achievements = new LinkedList<Achievement>(Arrays.asList(achievements));
}
public String getName()
{
return name;
}
public List<Achievement> getAchievements()
{
return achievements;
}
private static LinkedList<AchievementPage> achievementPages = new LinkedList<AchievementPage>();
/**
* Registers an achievement page.
* @param page The page.
*/
public static void registerAchievementPage(AchievementPage page)
{
if (getAchievementPage(page.getName()) != null)
{
throw new RuntimeException("Duplicate achievement page name \"" + page.getName() + "\"!");
}
achievementPages.add(page);
}
/**
* Will return an achievement page by its index on the list.
* @param index The page's index.
* @return the achievement page corresponding to the index or null if invalid index
*/
public static AchievementPage getAchievementPage(int index)
{
return achievementPages.get(index);
}
/**
* Will return an achievement page by its name.
* @param name The page's name.
* @return the achievement page with the given name or null if no such page
*/
public static AchievementPage getAchievementPage(String name)
{
for (AchievementPage page : achievementPages)
{
if (page.getName().equals(name))
{
return page;
}
}
return null;
}
/**
* Will return the list of achievement pages.
* @return the list's size
*/
public static Set<AchievementPage> getAchievementPages()
{
return new HashSet<AchievementPage>(achievementPages);
}
/**
* Will return whether an achievement is in any page or not.
* @param achievement The achievement.
*/
public static boolean isAchievementInPages(Achievement achievement)
{
for (AchievementPage page : achievementPages)
{
if (page.getAchievements().contains(achievement))
{
return true;
}
}
return false;
}
public static String getTitle(int index)
{
return index == -1 ? "Minecraft" : getAchievementPage(index).getName();
}
}
@@ -1,301 +0,0 @@
package net.minecraftforge.common;
import java.util.*;
import net.minecraft.world.biome.*;
import static net.minecraft.world.biome.BiomeGenBase.*;
import static net.minecraftforge.common.BiomeDictionary.Type.*;
public class BiomeDictionary
{
public enum Type
{
FOREST,
PLAINS,
MOUNTAIN,
HILLS,
SWAMP,
WATER,
DESERT,
FROZEN,
JUNGLE,
WASTELAND,
BEACH,
NETHER,
END,
MUSHROOM,
MAGICAL;
}
private static final int BIOME_LIST_SIZE = 256;
private static BiomeInfo[] biomeList = new BiomeInfo[BIOME_LIST_SIZE];
private static ArrayList<BiomeGenBase>[] typeInfoList = new ArrayList[Type.values().length];
private static class BiomeInfo
{
public EnumSet<Type> typeList;
public BiomeInfo(Type[] types)
{
typeList = EnumSet.noneOf(Type.class);
for(Type t : types)
{
typeList.add(t);
}
}
}
static
{
registerVanillaBiomes();
}
/**
* Registers a biome with a specific biome type
*
* @param biome the biome to be registered
* @param type the type to register the biome as
* @return returns true if the biome was registered successfully
*/
public static boolean registerBiomeType(BiomeGenBase biome, Type ... types)
{
if(BiomeGenBase.biomeList[biome.biomeID] != null)
{
for(Type type : types)
{
if(typeInfoList[type.ordinal()] == null)
{
typeInfoList[type.ordinal()] = new ArrayList<BiomeGenBase>();
}
typeInfoList[type.ordinal()].add(biome);
}
if(biomeList[biome.biomeID] == null)
{
biomeList[biome.biomeID] = new BiomeInfo(types);
}
else
{
for(Type type : types)
{
biomeList[biome.biomeID].typeList.add(type);
}
}
return true;
}
return false;
}
/**
* Returns a list of biomes registered with a specific type
*
* @param type the Type to look for
* @return a list of biomes of the specified type, null if there are none
*/
public static BiomeGenBase[] getBiomesForType(Type type)
{
if(typeInfoList[type.ordinal()] != null)
{
return (BiomeGenBase[])typeInfoList[type.ordinal()].toArray(new BiomeGenBase[0]);
}
return new BiomeGenBase[0];
}
/**
* Gets a list of Types that a specific biome is registered with
*
* @param biome the biome to check
* @return the list of types, null if there are none
*/
public static Type[] getTypesForBiome(BiomeGenBase biome)
{
checkRegistration(biome);
if(biomeList[biome.biomeID] != null)
{
return (Type[])biomeList[biome.biomeID].typeList.toArray(new Type[0]);
}
return new Type[0];
}
/**
* Checks to see if two biomes are registered as having the same type
*
* @param biomeA
* @param biomeB
* @return returns true if a common type is found, false otherwise
*/
public static boolean areBiomesEquivalent(BiomeGenBase biomeA, BiomeGenBase biomeB)
{
int a = biomeA.biomeID;
int b = biomeB.biomeID;
checkRegistration(biomeA);
checkRegistration(biomeB);
if(biomeList[a] != null && biomeList[b] != null)
{
for(Type type : biomeList[a].typeList)
{
if(containsType(biomeList[b], type))
{
return true;
}
}
}
return false;
}
/**
* Checks to see if the given biome is registered as being a specific type
*
* @param biome the biome to be considered
* @param type the type to check for
* @return returns true if the biome is registered as being of type type, false otherwise
*/
public static boolean isBiomeOfType(BiomeGenBase biome, Type type)
{
checkRegistration(biome);
if(biomeList[biome.biomeID] != null)
{
return containsType(biomeList[biome.biomeID], type);
}
return false;
}
/**
* Checks to see if the given biome has been registered as being of any type
* @param biome the biome to consider
* @return returns true if the biome has been registered, false otherwise
*/
public static boolean isBiomeRegistered(BiomeGenBase biome)
{
return biomeList[biome.biomeID] != null;
}
public static boolean isBiomeRegistered(int biomeID)
{
return biomeList[biomeID] != null;
}
/**
* Loops through the biome list and automatically adds tags to any biome that does not have any
* This should be called in postInit to make sure all biomes have been registered
*
* DO NOT call this during world generation
*/
public static void registerAllBiomes()
{
for(int i = 0; i < BIOME_LIST_SIZE; i++)
{
if(BiomeGenBase.biomeList[i] != null)
{
checkRegistration(BiomeGenBase.biomeList[i]);
}
}
}
/**
* Automatically looks for and registers a given biome with appropriate tags
* This method is called automatically if a biome has not been registered with any tags,
* And another method requests information about it
*
* NOTE: You can opt out of having your biome registered by registering it as type NULL
*
* @param biome the biome to be considered
*/
public static void makeBestGuess(BiomeGenBase biome)
{
if(biome.theBiomeDecorator.treesPerChunk >= 3)
{
if(biome.isHighHumidity() && biome.temperature >= 1.0F)
{
BiomeDictionary.registerBiomeType(biome, JUNGLE);
}
else if(!biome.isHighHumidity())
{
BiomeDictionary.registerBiomeType(biome, FOREST);
}
}
else if(biome.maxHeight <= 0.3F && biome.maxHeight >= 0.0F)
{
if(!biome.isHighHumidity() || biome.minHeight >= 0.0F)
{
BiomeDictionary.registerBiomeType(biome, PLAINS);
}
}
if(biome.isHighHumidity() && biome.minHeight < 0.0F && (biome.maxHeight <= 0.3F && biome.maxHeight >= 0.0F))
{
BiomeDictionary.registerBiomeType(biome, SWAMP);
}
if(biome.minHeight <= -0.5F)
{
BiomeDictionary.registerBiomeType(biome, WATER);
}
if(biome.maxHeight >= 1.5F)
{
BiomeDictionary.registerBiomeType(biome, MOUNTAIN);
}
if(biome.getEnableSnow() || biome.temperature < 0.2F)
{
BiomeDictionary.registerBiomeType(biome, FROZEN);
}
if(!biome.isHighHumidity() && biome.temperature >= 1.0F)
{
BiomeDictionary.registerBiomeType(biome, DESERT);
}
}
//Internal implementation
private static void checkRegistration(BiomeGenBase biome)
{
if(!isBiomeRegistered(biome))
{
makeBestGuess(biome);
}
}
private static boolean containsType(BiomeInfo info, Type type)
{
return info.typeList.contains(type);
}
private static void registerVanillaBiomes()
{
registerBiomeType(ocean, WATER );
registerBiomeType(plains, PLAINS );
registerBiomeType(desert, DESERT );
registerBiomeType(extremeHills, MOUNTAIN );
registerBiomeType(forest, FOREST );
registerBiomeType(taiga, FOREST, FROZEN);
registerBiomeType(taigaHills, FOREST, FROZEN);
registerBiomeType(swampland, SWAMP );
registerBiomeType(river, WATER );
registerBiomeType(frozenOcean, WATER, FROZEN);
registerBiomeType(frozenRiver, WATER, FROZEN);
registerBiomeType(icePlains, FROZEN );
registerBiomeType(iceMountains, FROZEN );
registerBiomeType(beach, BEACH );
registerBiomeType(desertHills, DESERT );
registerBiomeType(jungle, JUNGLE );
registerBiomeType(jungleHills, JUNGLE );
registerBiomeType(forestHills, FOREST );
registerBiomeType(sky, END );
registerBiomeType(hell, NETHER );
registerBiomeType(mushroomIsland, MUSHROOM );
registerBiomeType(extremeHillsEdge, MOUNTAIN );
registerBiomeType(mushroomIslandShore, MUSHROOM, BEACH);
}
}
@@ -1,70 +0,0 @@
package net.minecraftforge.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.gen.ChunkProviderGenerate;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.structure.MapGenStronghold;
import net.minecraft.world.gen.structure.MapGenVillage;
import net.minecraft.world.biome.WorldChunkManager;
import com.google.common.collect.Lists;
public class BiomeManager
{
public static void addVillageBiome(BiomeGenBase biome, boolean canSpawn)
{
if (!MapGenVillage.villageSpawnBiomes.contains(biome))
{
ArrayList<BiomeGenBase> biomes = new ArrayList<BiomeGenBase>(MapGenVillage.villageSpawnBiomes);
biomes.add(biome);
MapGenVillage.villageSpawnBiomes = biomes;
}
}
public static void removeVillageBiome(BiomeGenBase biome)
{
if (MapGenVillage.villageSpawnBiomes.contains(biome))
{
ArrayList<BiomeGenBase> biomes = new ArrayList<BiomeGenBase>(MapGenVillage.villageSpawnBiomes);
biomes.remove(biome);
MapGenVillage.villageSpawnBiomes = biomes;
}
}
public static void addStrongholdBiome(BiomeGenBase biome)
{
if (!MapGenStronghold.allowedBiomes.contains(biome))
{
MapGenStronghold.allowedBiomes.add(biome);
}
}
public static void removeStrongholdBiome(BiomeGenBase biome)
{
if (MapGenStronghold.allowedBiomes.contains(biome))
{
MapGenStronghold.allowedBiomes.remove(biome);
}
}
public static void addSpawnBiome(BiomeGenBase biome)
{
if (!WorldChunkManager.allowedBiomes.contains(biome))
{
WorldChunkManager.allowedBiomes.add(biome);
}
}
public static void removeSpawnBiome(BiomeGenBase biome)
{
if (WorldChunkManager.allowedBiomes.contains(biome))
{
WorldChunkManager.allowedBiomes.remove(biome);
}
}
}
@@ -1,260 +0,0 @@
package net.minecraftforge.common;
import java.util.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.structure.*;
import net.minecraftforge.oredict.OreDictionary;
public class ChestGenHooks
{
//Currently implemented categories for chests/dispensers, Dungeon loot is still in DungeonHooks
public static final String MINESHAFT_CORRIDOR = "mineshaftCorridor";
public static final String PYRAMID_DESERT_CHEST = "pyramidDesertyChest";
public static final String PYRAMID_JUNGLE_CHEST = "pyramidJungleChest";
public static final String PYRAMID_JUNGLE_DISPENSER = "pyramidJungleDispenser";
public static final String STRONGHOLD_CORRIDOR = "strongholdCorridor";
public static final String STRONGHOLD_LIBRARY = "strongholdLibrary";
public static final String STRONGHOLD_CROSSING = "strongholdCrossing";
public static final String VILLAGE_BLACKSMITH = "villageBlacksmith";
public static final String BONUS_CHEST = "bonusChest";
public static final String DUNGEON_CHEST = "dungeonChest";
private static final HashMap<String, ChestGenHooks> chestInfo = new HashMap<String, ChestGenHooks>();
private static boolean hasInit = false;
static
{
init();
}
private static void init()
{
if (hasInit)
{
return;
}
hasInit = true;
addInfo(MINESHAFT_CORRIDOR, StructureMineshaftPieces.mineshaftChestContents, 3, 7);
addInfo(PYRAMID_DESERT_CHEST, ComponentScatteredFeatureDesertPyramid.itemsToGenerateInTemple, 2, 7);
addInfo(PYRAMID_JUNGLE_CHEST, ComponentScatteredFeatureJunglePyramid.junglePyramidsChestContents, 2, 7);
addInfo(PYRAMID_JUNGLE_DISPENSER, ComponentScatteredFeatureJunglePyramid.junglePyramidsDispenserContents, 2, 2);
addInfo(STRONGHOLD_CORRIDOR, ComponentStrongholdChestCorridor.strongholdChestContents, 2, 4);
addInfo(STRONGHOLD_LIBRARY, ComponentStrongholdLibrary.strongholdLibraryChestContents, 1, 5);
addInfo(STRONGHOLD_CROSSING, ComponentStrongholdRoomCrossing.strongholdRoomCrossingChestContents, 1, 5);
addInfo(VILLAGE_BLACKSMITH, ComponentVillageHouse2.villageBlacksmithChestContents, 3, 9);
addInfo(BONUS_CHEST, WorldServer.bonusChestContent, 10, 10);
ItemStack book = new ItemStack(Item.enchantedBook, 1, 0);
WeightedRandomChestContent tmp = new WeightedRandomChestContent(book, 1, 1, 1);
getInfo(MINESHAFT_CORRIDOR ).addItem(tmp);
getInfo(PYRAMID_DESERT_CHEST).addItem(tmp);
getInfo(PYRAMID_JUNGLE_CHEST).addItem(tmp);
getInfo(STRONGHOLD_CORRIDOR ).addItem(tmp);
getInfo(STRONGHOLD_LIBRARY ).addItem(new WeightedRandomChestContent(book, 1, 5, 2));
getInfo(STRONGHOLD_CROSSING ).addItem(tmp);
//Wish Dungeons would get on the same wave length as other world gen...
ChestGenHooks d = new ChestGenHooks(DUNGEON_CHEST);
d.countMin = 8;
d.countMax = 8;
chestInfo.put(DUNGEON_CHEST, d);
addDungeonLoot(d, new ItemStack(Item.saddle), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.ingotIron), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.bread), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.wheat), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.gunpowder), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.silk), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.bucketEmpty), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.appleGold), 1, 1, 1);
addDungeonLoot(d, new ItemStack(Item.redstone), 50, 1, 4);
addDungeonLoot(d, new ItemStack(Item.record13), 5, 1, 1);
addDungeonLoot(d, new ItemStack(Item.recordCat), 5, 1, 1);
addDungeonLoot(d, new ItemStack(Item.dyePowder, 1, 3), 100, 1, 1);
addDungeonLoot(d, book, 100, 1, 1);
}
static void addDungeonLoot(ChestGenHooks dungeon, ItemStack item, int weight, int min, int max)
{
dungeon.addItem(new WeightedRandomChestContent(item, min, max, weight));
}
private static void addInfo(String category, WeightedRandomChestContent[] items, int min, int max)
{
chestInfo.put(category, new ChestGenHooks(category, items, min, max));
}
/**
* Retrieves, or creates the info class for the specified category.
*
* @param category The category name
* @return A instance of ChestGenHooks for the specified category.
*/
public static ChestGenHooks getInfo(String category)
{
if (!chestInfo.containsKey(category))
{
chestInfo.put(category, new ChestGenHooks(category));
}
return chestInfo.get(category);
}
/**
* Generates an array of items based on the input min/max count.
* If the stack can not hold the total amount, it will be split into
* stacks of size 1.
*
* @param rand A random number generator
* @param source Source item stack
* @param min Minimum number of items
* @param max Maximum number of items
* @return An array containing the generated item stacks
*/
public static ItemStack[] generateStacks(Random rand, ItemStack source, int min, int max)
{
int count = min + (rand.nextInt(max - min + 1));
ItemStack[] ret;
if (source.getItem() == null)
{
ret = new ItemStack[0];
}
else if (count > source.getItem().getItemStackLimit())
{
ret = new ItemStack[count];
for (int x = 0; x < count; x++)
{
ret[x] = source.copy();
ret[x].stackSize = 1;
}
}
else
{
ret = new ItemStack[1];
ret[0] = source.copy();
ret[0].stackSize = count;
}
return ret;
}
//shortcut functions, See the non-static versions below
public static WeightedRandomChestContent[] getItems(String category, Random rnd){ return getInfo(category).getItems(rnd); }
public static int getCount(String category, Random rand){ return getInfo(category).getCount(rand); }
public static void addItem(String category, WeightedRandomChestContent item){ getInfo(category).addItem(item); }
public static void removeItem(String category, ItemStack item){ getInfo(category).removeItem(item); }
public static ItemStack getOneItem(String category, Random rand){ return getInfo(category).getOneItem(rand); }
private String category;
private int countMin = 0;
private int countMax = 0;
//TO-DO: Privatize this once again when we remove the Deprecated stuff in DungeonHooks
ArrayList<WeightedRandomChestContent> contents = new ArrayList<WeightedRandomChestContent>();
public ChestGenHooks(String category)
{
this.category = category;
}
public ChestGenHooks(String category, WeightedRandomChestContent[] items, int min, int max)
{
this(category);
for (WeightedRandomChestContent item : items)
{
contents.add(item);
}
countMin = min;
countMax = max;
}
/**
* Adds a new entry into the possible items to generate.
*
* @param item The item to add.
*/
public void addItem(WeightedRandomChestContent item)
{
contents.add(item);
}
/**
* Removes all items that match the input item stack, Only metadata and item ID are checked.
* If the input item has a metadata of -1, all metadatas will match.
*
* @param item The item to check
*/
public void removeItem(ItemStack item)
{
Iterator<WeightedRandomChestContent> itr = contents.iterator();
while(itr.hasNext())
{
WeightedRandomChestContent cont = itr.next();
if (item.isItemEqual(cont.theItemId) || (item.getItemDamage() == OreDictionary.WILDCARD_VALUE && item.itemID == cont.theItemId.itemID))
{
itr.remove();
}
}
}
/**
* Gets an array of all random objects that are associated with this category.
*
* @return The random objects
*/
public WeightedRandomChestContent[] getItems(Random rnd)
{
ArrayList<WeightedRandomChestContent> ret = new ArrayList<WeightedRandomChestContent>();
for (WeightedRandomChestContent orig : contents)
{
Item item = orig.theItemId.getItem();
if (item != null)
{
WeightedRandomChestContent n = item.getChestGenBase(this, rnd, orig);
if (n != null)
{
ret.add(n);
}
}
}
return ret.toArray(new WeightedRandomChestContent[ret.size()]);
}
/**
* Gets a random number between countMin and countMax.
*
* @param rand A RNG
* @return A random number where countMin <= num <= countMax
*/
public int getCount(Random rand)
{
return countMin < countMax ? countMin + rand.nextInt(countMax - countMin) : countMin;
}
/**
* Returns a single ItemStack from the possible items in this registry,
* Useful if you just want a quick and dirty random Item.
*
* @param rand A Random Number gen
* @return A single ItemStack, or null if it could not get one.
*/
public ItemStack getOneItem(Random rand)
{
WeightedRandomChestContent[] items = getItems(rand);
WeightedRandomChestContent item = (WeightedRandomChestContent)WeightedRandom.getRandomItem(rand, items);
ItemStack[] stacks = ChestGenHooks.generateStacks(rand, item.theItemId, item.theMinimumChanceToGenerateItem, item.theMaximumChanceToGenerateItem);
return (stacks.length > 0 ? stacks[0] : null);
}
//Accessors
public int getMin(){ return countMin; }
public int getMax(){ return countMax; }
public void setMin(int value){ countMin = value; }
public void setMax(int value){ countMax = value; }
}
@@ -1,269 +0,0 @@
package net.minecraftforge.common;
import static net.minecraftforge.common.Configuration.NEW_LINE;
import static net.minecraftforge.common.Configuration.allowedProperties;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.base.Splitter;
public class ConfigCategory implements Map<String, Property>
{
private String name;
private String comment;
private ArrayList<ConfigCategory> children = new ArrayList<ConfigCategory>();
private Map<String, Property> properties = new TreeMap<String, Property>();
public final ConfigCategory parent;
private boolean changed = false;
public ConfigCategory(String name)
{
this(name, null);
}
public ConfigCategory(String name, ConfigCategory parent)
{
this.name = name;
this.parent = parent;
if (parent != null)
{
parent.children.add(this);
}
}
public boolean equals(Object obj)
{
if (obj instanceof ConfigCategory)
{
ConfigCategory cat = (ConfigCategory)obj;
return name.equals(cat.name) && children.equals(cat.children);
}
return false;
}
public String getQualifiedName()
{
return getQualifiedName(name, parent);
}
public static String getQualifiedName(String name, ConfigCategory parent)
{
return (parent == null ? name : parent.getQualifiedName() + Configuration.CATEGORY_SPLITTER + name);
}
public ConfigCategory getFirstParent()
{
return (parent == null ? this : parent.getFirstParent());
}
public boolean isChild()
{
return parent != null;
}
public Map<String, Property> getValues()
{
return ImmutableMap.copyOf(properties);
}
public void setComment(String comment)
{
this.comment = comment;
}
public boolean containsKey(String key)
{
return properties.containsKey(key);
}
public Property get(String key)
{
return properties.get(key);
}
private void write(BufferedWriter out, String... data) throws IOException
{
write(out, true, data);
}
private void write(BufferedWriter out, boolean new_line, String... data) throws IOException
{
for (int x = 0; x < data.length; x++)
{
out.write(data[x]);
}
if (new_line) out.write(NEW_LINE);
}
public void write(BufferedWriter out, int indent) throws IOException
{
String pad0 = getIndent(indent);
String pad1 = getIndent(indent + 1);
String pad2 = getIndent(indent + 2);
write(out, pad0, "####################");
write(out, pad0, "# ", name);
if (comment != null)
{
write(out, pad0, "#===================");
Splitter splitter = Splitter.onPattern("\r?\n");
for (String line : splitter.split(comment))
{
write(out, pad0, "# ", line);
}
}
write(out, pad0, "####################", NEW_LINE);
if (!allowedProperties.matchesAllOf(name))
{
name = '"' + name + '"';
}
write(out, pad0, name, " {");
Property[] props = properties.values().toArray(new Property[properties.size()]);
for (int x = 0; x < props.length; x++)
{
Property prop = props[x];
if (prop.comment != null)
{
if (x != 0)
{
out.newLine();
}
Splitter splitter = Splitter.onPattern("\r?\n");
for (String commentLine : splitter.split(prop.comment))
{
write(out, pad1, "# ", commentLine);
}
}
String propName = prop.getName();
if (!allowedProperties.matchesAllOf(propName))
{
propName = '"' + propName + '"';
}
if (prop.isList())
{
char type = prop.getType().getID();
write(out, pad1, String.valueOf(type), ":", propName, " <");
for (String line : prop.getStringList())
{
write(out, pad2, line);
}
write(out, pad1, " >");
}
else if (prop.getType() == null)
{
write(out, pad1, propName, "=", prop.getString());
}
else
{
char type = prop.getType().getID();
write(out, pad1, String.valueOf(type), ":", propName, "=", prop.getString());
}
}
for (ConfigCategory child : children)
{
child.write(out, indent + 1);
}
write(out, pad0, "}", NEW_LINE);
}
private String getIndent(int indent)
{
StringBuilder buf = new StringBuilder("");
for (int x = 0; x < indent; x++)
{
buf.append(" ");
}
return buf.toString();
}
public boolean hasChanged()
{
if (changed) return true;
for (Property prop : properties.values())
{
if (prop.hasChanged()) return true;
}
return false;
}
void resetChangedState()
{
changed = false;
for (Property prop : properties.values())
{
prop.resetChangedState();
}
}
//Map bouncer functions for compatibility with older mods, to be removed once all mods stop using it.
@Override public int size(){ return properties.size(); }
@Override public boolean isEmpty() { return properties.isEmpty(); }
@Override public boolean containsKey(Object key) { return properties.containsKey(key); }
@Override public boolean containsValue(Object value){ return properties.containsValue(value); }
@Override public Property get(Object key) { return properties.get(key); }
@Override public Property put(String key, Property value)
{
changed = true;
return properties.put(key, value);
}
@Override public Property remove(Object key)
{
changed = true;
return properties.remove(key);
}
@Override public void putAll(Map<? extends String, ? extends Property> m)
{
changed = true;
properties.putAll(m);
}
@Override public void clear()
{
changed = true;
properties.clear();
}
@Override public Set<String> keySet() { return properties.keySet(); }
@Override public Collection<Property> values() { return properties.values(); }
@Override //Immutable copy, changes will NOT be reflected in this category
public Set<java.util.Map.Entry<String, Property>> entrySet()
{
return ImmutableSet.copyOf(properties.entrySet());
}
public Set<ConfigCategory> getChildren(){ return ImmutableSet.copyOf(children); }
public void removeChild(ConfigCategory child)
{
if (children.contains(child))
{
children.remove(child);
changed = true;
}
}
}
@@ -1,927 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import static net.minecraftforge.common.Property.Type.BOOLEAN;
import static net.minecraftforge.common.Property.Type.DOUBLE;
import static net.minecraftforge.common.Property.Type.INTEGER;
import static net.minecraftforge.common.Property.Type.STRING;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PushbackInputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableSet;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.relauncher.FMLInjectionData;
/**
* This class offers advanced configurations capabilities, allowing to provide
* various categories for configuration variables.
*/
public class Configuration
{
private static boolean[] configMarkers = new boolean[Item.itemsList.length];
private static final int ITEM_SHIFT = 256;
private static final int MAX_BLOCKS = 4096;
public static final String CATEGORY_GENERAL = "general";
public static final String CATEGORY_BLOCK = "block";
public static final String CATEGORY_ITEM = "item";
public static final String ALLOWED_CHARS = "._-";
public static final String DEFAULT_ENCODING = "UTF-8";
public static final String CATEGORY_SPLITTER = ".";
public static final String NEW_LINE;
private static final Pattern CONFIG_START = Pattern.compile("START: \"([^\\\"]+)\"");
private static final Pattern CONFIG_END = Pattern.compile("END: \"([^\\\"]+)\"");
public static final CharMatcher allowedProperties = CharMatcher.JAVA_LETTER_OR_DIGIT.or(CharMatcher.anyOf(ALLOWED_CHARS));
private static Configuration PARENT = null;
File file;
private Map<String, ConfigCategory> categories = new TreeMap<String, ConfigCategory>();
private Map<String, Configuration> children = new TreeMap<String, Configuration>();
private boolean caseSensitiveCustomCategories;
public String defaultEncoding = DEFAULT_ENCODING;
private String fileName = null;
public boolean isChild = false;
private boolean changed = false;
static
{
Arrays.fill(configMarkers, false);
NEW_LINE = System.getProperty("line.separator");
}
public Configuration(){}
/**
* Create a configuration file for the file given in parameter.
*/
public Configuration(File file)
{
this.file = file;
String basePath = ((File)(FMLInjectionData.data()[6])).getAbsolutePath().replace(File.separatorChar, '/').replace("/.", "");
String path = file.getAbsolutePath().replace(File.separatorChar, '/').replace("/./", "/").replace(basePath, "");
if (PARENT != null)
{
PARENT.setChild(path, this);
isChild = true;
}
else
{
fileName = path;
load();
}
}
public Configuration(File file, boolean caseSensitiveCustomCategories)
{
this(file);
this.caseSensitiveCustomCategories = caseSensitiveCustomCategories;
}
/**
* Gets or create a block id property. If the block id property key is
* already in the configuration, then it will be used. Otherwise,
* defaultId will be used, except if already taken, in which case this
* will try to determine a free default id.
*/
public Property getBlock(String key, int defaultID) { return getBlock(CATEGORY_BLOCK, key, defaultID, null); }
public Property getBlock(String key, int defaultID, String comment) { return getBlock(CATEGORY_BLOCK, key, defaultID, comment); }
public Property getBlock(String category, String key, int defaultID) { return getBlockInternal(category, key, defaultID, null, 256, Block.blocksList.length); }
public Property getBlock(String category, String key, int defaultID, String comment) { return getBlockInternal(category, key, defaultID, comment, 256, Block.blocksList.length); }
/**
* Special version of getBlock to be used when you want to garentee the ID you get is below 256
* This should ONLY be used by mods who do low level terrain generation, or ones that add new
* biomes.
* EXA: ExtraBiomesXL
*
* Specifically, if your block is used BEFORE the Chunk is created, and placed in the terrain byte array directly.
* If you add a new biome and you set the top/filler block, they need to be <256, nothing else.
*
* If you're adding a new ore, DON'T call this function.
*
* Normal mods such as '50 new ores' do not need to be below 256 so should use the normal getBlock
*/
public Property getTerrainBlock(String category, String key, int defaultID, String comment)
{
return getBlockInternal(category, key, defaultID, comment, 0, 256);
}
private Property getBlockInternal(String category, String key, int defaultID, String comment, int lower, int upper)
{
Property prop = get(category, key, -1, comment);
if (prop.getInt() != -1)
{
configMarkers[prop.getInt()] = true;
return prop;
}
else
{
if (defaultID < lower)
{
FMLLog.warning(
"Mod attempted to get a block ID with a default in the Terrain Generation section, " +
"mod authors should make sure there defaults are above 256 unless explicitly needed " +
"for terrain generation. Most ores do not need to be below 256.");
FMLLog.warning("Config \"%s\" Category: \"%s\" Key: \"%s\" Default: %d", fileName, category, key, defaultID);
defaultID = upper - 1;
}
if (Block.blocksList[defaultID] == null && !configMarkers[defaultID])
{
prop.set(defaultID);
configMarkers[defaultID] = true;
return prop;
}
else
{
for (int j = upper - 1; j > 0; j--)
{
if (Block.blocksList[j] == null && !configMarkers[j])
{
prop.set(j);
configMarkers[j] = true;
return prop;
}
}
throw new RuntimeException("No more block ids available for " + key);
}
}
}
public Property getItem(String key, int defaultID) { return getItem(CATEGORY_ITEM, key, defaultID, null); }
public Property getItem(String key, int defaultID, String comment) { return getItem(CATEGORY_ITEM, key, defaultID, comment); }
public Property getItem(String category, String key, int defaultID) { return getItem(category, key, defaultID, null); }
public Property getItem(String category, String key, int defaultID, String comment)
{
Property prop = get(category, key, -1, comment);
int defaultShift = defaultID + ITEM_SHIFT;
if (prop.getInt() != -1)
{
configMarkers[prop.getInt() + ITEM_SHIFT] = true;
return prop;
}
else
{
if (defaultID < MAX_BLOCKS - ITEM_SHIFT)
{
FMLLog.warning(
"Mod attempted to get a item ID with a default value in the block ID section, " +
"mod authors should make sure there defaults are above %d unless explicitly needed " +
"so that all block ids are free to store blocks.", MAX_BLOCKS - ITEM_SHIFT);
FMLLog.warning("Config \"%s\" Category: \"%s\" Key: \"%s\" Default: %d", fileName, category, key, defaultID);
}
if (Item.itemsList[defaultShift] == null && !configMarkers[defaultShift] && defaultShift >= Block.blocksList.length)
{
prop.set(defaultID);
configMarkers[defaultShift] = true;
return prop;
}
else
{
for (int x = Item.itemsList.length - 1; x >= ITEM_SHIFT; x--)
{
if (Item.itemsList[x] == null && !configMarkers[x])
{
prop.set(x - ITEM_SHIFT);
configMarkers[x] = true;
return prop;
}
}
throw new RuntimeException("No more item ids available for " + key);
}
}
}
public Property get(String category, String key, int defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, int defaultValue, String comment)
{
Property prop = get(category, key, Integer.toString(defaultValue), comment, INTEGER);
if (!prop.isIntValue())
{
prop.set(defaultValue);
}
return prop;
}
public Property get(String category, String key, boolean defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, boolean defaultValue, String comment)
{
Property prop = get(category, key, Boolean.toString(defaultValue), comment, BOOLEAN);
if (!prop.isBooleanValue())
{
prop.set(defaultValue);
}
return prop;
}
public Property get(String category, String key, double defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, double defaultValue, String comment)
{
Property prop = get(category, key, Double.toString(defaultValue), comment, DOUBLE);
if (!prop.isDoubleValue())
{
prop.set(defaultValue);
}
return prop;
}
public Property get(String category, String key, String defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, String defaultValue, String comment)
{
return get(category, key, defaultValue, comment, STRING);
}
public Property get(String category, String key, String[] defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, String[] defaultValue, String comment)
{
return get(category, key, defaultValue, comment, STRING);
}
public Property get(String category, String key, int[] defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, int[] defaultValue, String comment)
{
String[] values = new String[defaultValue.length];
for (int i = 0; i < defaultValue.length; i++)
{
values[i] = Integer.toString(defaultValue[i]);
}
Property prop = get(category, key, values, comment, INTEGER);
if (!prop.isIntList())
{
prop.set(values);
}
return prop;
}
public Property get(String category, String key, double[] defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, double[] defaultValue, String comment)
{
String[] values = new String[defaultValue.length];
for (int i = 0; i < defaultValue.length; i++)
{
values[i] = Double.toString(defaultValue[i]);
}
Property prop = get(category, key, values, comment, DOUBLE);
if (!prop.isDoubleList())
{
prop.set(values);
}
return prop;
}
public Property get(String category, String key, boolean[] defaultValue)
{
return get(category, key, defaultValue, null);
}
public Property get(String category, String key, boolean[] defaultValue, String comment)
{
String[] values = new String[defaultValue.length];
for (int i = 0; i < defaultValue.length; i++)
{
values[i] = Boolean.toString(defaultValue[i]);
}
Property prop = get(category, key, values, comment, BOOLEAN);
if (!prop.isBooleanList())
{
prop.set(values);
}
return prop;
}
public Property get(String category, String key, String defaultValue, String comment, Property.Type type)
{
if (!caseSensitiveCustomCategories)
{
category = category.toLowerCase(Locale.ENGLISH);
}
ConfigCategory cat = getCategory(category);
if (cat.containsKey(key))
{
Property prop = cat.get(key);
if (prop.getType() == null)
{
prop = new Property(prop.getName(), prop.getString(), type);
cat.put(key, prop);
}
prop.comment = comment;
return prop;
}
else if (defaultValue != null)
{
Property prop = new Property(key, defaultValue, type);
prop.set(defaultValue); //Set and mark as dirty to signify it should save
cat.put(key, prop);
prop.comment = comment;
return prop;
}
else
{
return null;
}
}
public Property get(String category, String key, String[] defaultValue, String comment, Property.Type type)
{
if (!caseSensitiveCustomCategories)
{
category = category.toLowerCase(Locale.ENGLISH);
}
ConfigCategory cat = getCategory(category);
if (cat.containsKey(key))
{
Property prop = cat.get(key);
if (prop.getType() == null)
{
prop = new Property(prop.getName(), prop.getString(), type);
cat.put(key, prop);
}
prop.comment = comment;
return prop;
}
else if (defaultValue != null)
{
Property prop = new Property(key, defaultValue, type);
prop.comment = comment;
cat.put(key, prop);
return prop;
}
else
{
return null;
}
}
public boolean hasCategory(String category)
{
return categories.get(category) != null;
}
public boolean hasKey(String category, String key)
{
ConfigCategory cat = categories.get(category);
return cat != null && cat.containsKey(key);
}
public void load()
{
if (PARENT != null && PARENT != this)
{
return;
}
BufferedReader buffer = null;
UnicodeInputStreamReader input = null;
try
{
if (file.getParentFile() != null)
{
file.getParentFile().mkdirs();
}
if (!file.exists() && !file.createNewFile())
{
return;
}
if (file.canRead())
{
input = new UnicodeInputStreamReader(new FileInputStream(file), defaultEncoding);
defaultEncoding = input.getEncoding();
buffer = new BufferedReader(input);
String line;
ConfigCategory currentCat = null;
Property.Type type = null;
ArrayList<String> tmpList = null;
int lineNum = 0;
String name = null;
while (true)
{
lineNum++;
line = buffer.readLine();
if (line == null)
{
break;
}
Matcher start = CONFIG_START.matcher(line);
Matcher end = CONFIG_END.matcher(line);
if (start.matches())
{
fileName = start.group(1);
categories = new TreeMap<String, ConfigCategory>();
continue;
}
else if (end.matches())
{
fileName = end.group(1);
Configuration child = new Configuration();
child.categories = categories;
this.children.put(fileName, child);
continue;
}
int nameStart = -1, nameEnd = -1;
boolean skip = false;
boolean quoted = false;
for (int i = 0; i < line.length() && !skip; ++i)
{
if (Character.isLetterOrDigit(line.charAt(i)) || ALLOWED_CHARS.indexOf(line.charAt(i)) != -1 || (quoted && line.charAt(i) != '"'))
{
if (nameStart == -1)
{
nameStart = i;
}
nameEnd = i;
}
else if (Character.isWhitespace(line.charAt(i)))
{
// ignore space charaters
}
else
{
switch (line.charAt(i))
{
case '#':
skip = true;
continue;
case '"':
if (quoted)
{
quoted = false;
}
if (!quoted && nameStart == -1)
{
quoted = true;
}
break;
case '{':
name = line.substring(nameStart, nameEnd + 1);
String qualifiedName = ConfigCategory.getQualifiedName(name, currentCat);
ConfigCategory cat = categories.get(qualifiedName);
if (cat == null)
{
currentCat = new ConfigCategory(name, currentCat);
categories.put(qualifiedName, currentCat);
}
else
{
currentCat = cat;
}
name = null;
break;
case '}':
if (currentCat == null)
{
throw new RuntimeException(String.format("Config file corrupt, attepted to close to many categories '%s:%d'", fileName, lineNum));
}
currentCat = currentCat.parent;
break;
case '=':
name = line.substring(nameStart, nameEnd + 1);
if (currentCat == null)
{
throw new RuntimeException(String.format("'%s' has no scope in '%s:%d'", name, fileName, lineNum));
}
Property prop = new Property(name, line.substring(i + 1), type, true);
i = line.length();
currentCat.put(name, prop);
break;
case ':':
type = Property.Type.tryParse(line.substring(nameStart, nameEnd + 1).charAt(0));
nameStart = nameEnd = -1;
break;
case '<':
if (tmpList != null)
{
throw new RuntimeException(String.format("Malformed list property \"%s:%d\"", fileName, lineNum));
}
name = line.substring(nameStart, nameEnd + 1);
if (currentCat == null)
{
throw new RuntimeException(String.format("'%s' has no scope in '%s:%d'", name, fileName, lineNum));
}
tmpList = new ArrayList<String>();
skip = true;
break;
case '>':
if (tmpList == null)
{
throw new RuntimeException(String.format("Malformed list property \"%s:%d\"", fileName, lineNum));
}
currentCat.put(name, new Property(name, tmpList.toArray(new String[tmpList.size()]), type));
name = null;
tmpList = null;
type = null;
break;
default:
throw new RuntimeException(String.format("Unknown character '%s' in '%s:%d'", line.charAt(i), fileName, lineNum));
}
}
}
if (quoted)
{
throw new RuntimeException(String.format("Unmatched quote in '%s:%d'", fileName, lineNum));
}
else if (tmpList != null && !skip)
{
tmpList.add(line.trim());
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (buffer != null)
{
try
{
buffer.close();
} catch (IOException e){}
}
if (input != null)
{
try
{
input.close();
} catch (IOException e){}
}
}
resetChangedState();
}
public void save()
{
if (PARENT != null && PARENT != this)
{
PARENT.save();
return;
}
try
{
if (file.getParentFile() != null)
{
file.getParentFile().mkdirs();
}
if (!file.exists() && !file.createNewFile())
{
return;
}
if (file.canWrite())
{
FileOutputStream fos = new FileOutputStream(file);
BufferedWriter buffer = new BufferedWriter(new OutputStreamWriter(fos, defaultEncoding));
buffer.write("# Configuration file" + NEW_LINE + NEW_LINE);
if (children.isEmpty())
{
save(buffer);
}
else
{
for (Map.Entry<String, Configuration> entry : children.entrySet())
{
buffer.write("START: \"" + entry.getKey() + "\"" + NEW_LINE);
entry.getValue().save(buffer);
buffer.write("END: \"" + entry.getKey() + "\"" + NEW_LINE + NEW_LINE);
}
}
buffer.close();
fos.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void save(BufferedWriter out) throws IOException
{
for (ConfigCategory cat : categories.values())
{
if (!cat.isChild())
{
cat.write(out, 0);
out.newLine();
}
}
}
public ConfigCategory getCategory(String category)
{
ConfigCategory ret = categories.get(category);
if (ret == null)
{
if (category.contains(CATEGORY_SPLITTER))
{
String[] hierarchy = category.split("\\"+CATEGORY_SPLITTER);
ConfigCategory parent = categories.get(hierarchy[0]);
if (parent == null)
{
parent = new ConfigCategory(hierarchy[0]);
categories.put(parent.getQualifiedName(), parent);
changed = true;
}
for (int i = 1; i < hierarchy.length; i++)
{
String name = ConfigCategory.getQualifiedName(hierarchy[i], parent);
ConfigCategory child = categories.get(name);
if (child == null)
{
child = new ConfigCategory(hierarchy[i], parent);
categories.put(name, child);
changed = true;
}
ret = child;
parent = child;
}
}
else
{
ret = new ConfigCategory(category);
categories.put(category, ret);
changed = true;
}
}
return ret;
}
public void removeCategory(ConfigCategory category)
{
for (ConfigCategory child : category.getChildren())
{
removeCategory(child);
}
if (categories.containsKey(category.getQualifiedName()))
{
categories.remove(category.getQualifiedName());
if (category.parent != null)
{
category.parent.removeChild(category);
}
changed = true;
}
}
public void addCustomCategoryComment(String category, String comment)
{
if (!caseSensitiveCustomCategories)
category = category.toLowerCase(Locale.ENGLISH);
getCategory(category).setComment(comment);
}
private void setChild(String name, Configuration child)
{
if (!children.containsKey(name))
{
children.put(name, child);
changed = true;
}
else
{
Configuration old = children.get(name);
child.categories = old.categories;
child.fileName = old.fileName;
old.changed = true;
}
}
public static void enableGlobalConfig()
{
PARENT = new Configuration(new File(Loader.instance().getConfigDir(), "global.cfg"));
PARENT.load();
}
public static class UnicodeInputStreamReader extends Reader
{
private final InputStreamReader input;
private final String defaultEnc;
public UnicodeInputStreamReader(InputStream source, String encoding) throws IOException
{
defaultEnc = encoding;
String enc = encoding;
byte[] data = new byte[4];
PushbackInputStream pbStream = new PushbackInputStream(source, data.length);
int read = pbStream.read(data, 0, data.length);
int size = 0;
int bom16 = (data[0] & 0xFF) << 8 | (data[1] & 0xFF);
int bom24 = bom16 << 8 | (data[2] & 0xFF);
int bom32 = bom24 << 8 | (data[3] & 0xFF);
if (bom24 == 0xEFBBBF)
{
enc = "UTF-8";
size = 3;
}
else if (bom16 == 0xFEFF)
{
enc = "UTF-16BE";
size = 2;
}
else if (bom16 == 0xFFFE)
{
enc = "UTF-16LE";
size = 2;
}
else if (bom32 == 0x0000FEFF)
{
enc = "UTF-32BE";
size = 4;
}
else if (bom32 == 0xFFFE0000) //This will never happen as it'll be caught by UTF-16LE,
{ //but if anyone ever runs across a 32LE file, i'd like to disect it.
enc = "UTF-32LE";
size = 4;
}
if (size < read)
{
pbStream.unread(data, size, read - size);
}
this.input = new InputStreamReader(pbStream, enc);
}
public String getEncoding()
{
return input.getEncoding();
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException
{
return input.read(cbuf, off, len);
}
@Override
public void close() throws IOException
{
input.close();
}
}
public boolean hasChanged()
{
if (changed) return true;
for (ConfigCategory cat : categories.values())
{
if (cat.hasChanged()) return true;
}
for (Configuration child : children.values())
{
if (child.hasChanged()) return true;
}
return false;
}
private void resetChangedState()
{
changed = false;
for (ConfigCategory cat : categories.values())
{
cat.resetChangedState();
}
for (Configuration child : children.values())
{
child.resetChangedState();
}
}
public Set<String> getCategoryNames()
{
return ImmutableSet.copyOf(categories.keySet());
}
}
@@ -1,430 +0,0 @@
package net.minecraftforge.common;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.MinecraftException;
import net.minecraft.world.World;
import net.minecraft.world.WorldManager;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.WorldProviderEnd;
import net.minecraft.world.WorldProviderHell;
import net.minecraft.world.WorldProviderSurface;
import net.minecraft.world.WorldServer;
import net.minecraft.world.WorldServerMulti;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.SaveHandler;
import net.minecraftforge.event.world.WorldEvent;
public class DimensionManager
{
private static Hashtable<Integer, Class<? extends WorldProvider>> providers = new Hashtable<Integer, Class<? extends WorldProvider>>();
private static Hashtable<Integer, Boolean> spawnSettings = new Hashtable<Integer, Boolean>();
private static Hashtable<Integer, WorldServer> worlds = new Hashtable<Integer, WorldServer>();
private static boolean hasInit = false;
private static Hashtable<Integer, Integer> dimensions = new Hashtable<Integer, Integer>();
private static ArrayList<Integer> unloadQueue = new ArrayList<Integer>();
private static BitSet dimensionMap = new BitSet(Long.SIZE << 4);
private static ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().<World,World>makeMap();
private static Multiset<Integer> leakedWorlds = HashMultiset.create();
public static boolean registerProviderType(int id, Class<? extends WorldProvider> provider, boolean keepLoaded)
{
if (providers.containsKey(id))
{
return false;
}
providers.put(id, provider);
spawnSettings.put(id, keepLoaded);
return true;
}
/**
* Unregisters a Provider type, and returns a array of all dimensions that are
* registered to this provider type.
* If the return size is greater then 0, it is required that the caller either
* change those dimensions's registered type, or replace this type before the
* world is attempted to load, else the loader will throw an exception.
*
* @param id The provider type ID to unreigster
* @return An array containing all dimension IDs still registered to this provider type.
*/
public static int[] unregisterProviderType(int id)
{
if (!providers.containsKey(id))
{
return new int[0];
}
providers.remove(id);
spawnSettings.remove(id);
int[] ret = new int[dimensions.size()];
int x = 0;
for (Map.Entry<Integer, Integer> ent : dimensions.entrySet())
{
if (ent.getValue() == id)
{
ret[x++] = ent.getKey();
}
}
return Arrays.copyOf(ret, x);
}
public static void init()
{
if (hasInit)
{
return;
}
hasInit = true;
registerProviderType( 0, WorldProviderSurface.class, true);
registerProviderType(-1, WorldProviderHell.class, true);
registerProviderType( 1, WorldProviderEnd.class, false);
registerDimension( 0, 0);
registerDimension(-1, -1);
registerDimension( 1, 1);
}
public static void registerDimension(int id, int providerType)
{
if (!providers.containsKey(providerType))
{
throw new IllegalArgumentException(String.format("Failed to register dimension for id %d, provider type %d does not exist", id, providerType));
}
if (dimensions.containsKey(id))
{
throw new IllegalArgumentException(String.format("Failed to register dimension for id %d, One is already registered", id));
}
dimensions.put(id, providerType);
if (id >= 0)
{
dimensionMap.set(id);
}
}
/**
* For unregistering a dimension when the save is changed (disconnected from a server or loaded a new save
*/
public static void unregisterDimension(int id)
{
if (!dimensions.containsKey(id))
{
throw new IllegalArgumentException(String.format("Failed to unregister dimension for id %d; No provider registered", id));
}
dimensions.remove(id);
}
public static boolean isDimensionRegistered(int dim)
{
return dimensions.containsKey(dim);
}
public static int getProviderType(int dim)
{
if (!dimensions.containsKey(dim))
{
throw new IllegalArgumentException(String.format("Could not get provider type for dimension %d, does not exist", dim));
}
return dimensions.get(dim);
}
public static WorldProvider getProvider(int dim)
{
return getWorld(dim).provider;
}
public static Integer[] getIDs(boolean check)
{
if (check)
{
List<World> allWorlds = Lists.newArrayList(weakWorldMap.keySet());
allWorlds.removeAll(worlds.values());
for (ListIterator<World> li = allWorlds.listIterator(); li.hasNext(); )
{
World w = li.next();
leakedWorlds.add(System.identityHashCode(w));
}
for (World w : allWorlds)
{
int leakCount = leakedWorlds.count(System.identityHashCode(w));
if (leakCount == 5)
{
FMLLog.fine("The world %x (%s) may have leaked: first encounter (5 occurences).\n", System.identityHashCode(w), w.getWorldInfo().getWorldName());
}
else if (leakCount % 5 == 0)
{
FMLLog.fine("The world %x (%s) may have leaked: seen %d times.\n", System.identityHashCode(w), w.getWorldInfo().getWorldName(), leakCount);
}
}
}
return getIDs();
}
public static Integer[] getIDs()
{
return worlds.keySet().toArray(new Integer[worlds.size()]); //Only loaded dims, since usually used to cycle through loaded worlds
}
public static void setWorld(int id, WorldServer world)
{
if (world != null) {
worlds.put(id, world);
weakWorldMap.put(world, world);
MinecraftServer.getServer().worldTickTimes.put(id, new long[100]);
FMLLog.info("Loading dimension %d (%s) (%s)", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
} else {
worlds.remove(id);
MinecraftServer.getServer().worldTickTimes.remove(id);
FMLLog.info("Unloading dimension %d", id);
}
ArrayList<WorldServer> tmp = new ArrayList<WorldServer>();
if (worlds.get( 0) != null)
tmp.add(worlds.get( 0));
if (worlds.get(-1) != null)
tmp.add(worlds.get(-1));
if (worlds.get( 1) != null)
tmp.add(worlds.get( 1));
for (Entry<Integer, WorldServer> entry : worlds.entrySet())
{
int dim = entry.getKey();
if (dim >= -1 && dim <= 1)
{
continue;
}
tmp.add(entry.getValue());
}
MinecraftServer.getServer().worldServers = tmp.toArray(new WorldServer[tmp.size()]);
}
public static void initDimension(int dim) {
WorldServer overworld = getWorld(0);
if (overworld == null) {
throw new RuntimeException("Cannot Hotload Dim: Overworld is not Loaded!");
}
try {
DimensionManager.getProviderType(dim);
} catch (Exception e) {
System.err.println("Cannot Hotload Dim: " + e.getMessage());
return; //If a provider hasn't been registered then we can't hotload the dim
}
MinecraftServer mcServer = overworld.getMinecraftServer();
ISaveHandler savehandler = overworld.getSaveHandler();
WorldSettings worldSettings = new WorldSettings(overworld.getWorldInfo());
WorldServer world = (dim == 0 ? overworld : new WorldServerMulti(mcServer, savehandler, overworld.getWorldInfo().getWorldName(), dim, worldSettings, overworld, mcServer.theProfiler, overworld.getWorldLogAgent()));
world.addWorldAccess(new WorldManager(mcServer, world));
MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world));
if (!mcServer.isSinglePlayer())
{
world.getWorldInfo().setGameType(mcServer.getGameType());
}
mcServer.setDifficultyForAllWorlds(mcServer.getDifficulty());
}
public static WorldServer getWorld(int id)
{
return worlds.get(id);
}
public static WorldServer[] getWorlds()
{
return worlds.values().toArray(new WorldServer[worlds.size()]);
}
public static boolean shouldLoadSpawn(int dim)
{
int id = getProviderType(dim);
return spawnSettings.containsKey(id) && spawnSettings.get(id);
}
static
{
init();
}
/**
* Not public API: used internally to get dimensions that should load at
* server startup
*/
public static Integer[] getStaticDimensionIDs()
{
return dimensions.keySet().toArray(new Integer[dimensions.keySet().size()]);
}
public static WorldProvider createProviderFor(int dim)
{
try
{
if (dimensions.containsKey(dim))
{
WorldProvider provider = providers.get(getProviderType(dim)).newInstance();
provider.setDimension(dim);
return provider;
}
else
{
throw new RuntimeException(String.format("No WorldProvider bound for dimension %d", dim)); //It's going to crash anyway at this point. Might as well be informative
}
}
catch (Exception e)
{
FMLCommonHandler.instance().getFMLLogger().log(Level.SEVERE,String.format("An error occured trying to create an instance of WorldProvider %d (%s)",
dim, providers.get(getProviderType(dim)).getSimpleName()),e);
throw new RuntimeException(e);
}
}
public static void unloadWorld(int id) {
unloadQueue.add(id);
}
/*
* To be called by the server at the appropriate time, do not call from mod code.
*/
public static void unloadWorlds(Hashtable<Integer, long[]> worldTickTimes) {
for (int id : unloadQueue) {
WorldServer w = worlds.get(id);
try {
if (w != null)
{
w.saveAllChunks(true, null);
}
else
{
FMLLog.warning("Unexpected world unload - world %d is already unloaded", id);
}
} catch (MinecraftException e) {
e.printStackTrace();
}
finally
{
if (w != null)
{
MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(w));
w.flush();
setWorld(id, null);
}
}
}
unloadQueue.clear();
}
/**
* Return the next free dimension ID. Note: you are not guaranteed a contiguous
* block of free ids. Always call for each individual ID you wish to get.
* @return the next free dimension ID
*/
public static int getNextFreeDimId() {
int next = 0;
while (true)
{
next = dimensionMap.nextClearBit(next);
if (dimensions.containsKey(next))
{
dimensionMap.set(next);
}
else
{
return next;
}
}
}
public static NBTTagCompound saveDimensionDataMap()
{
int[] data = new int[(dimensionMap.length() + Integer.SIZE - 1 )/ Integer.SIZE];
NBTTagCompound dimMap = new NBTTagCompound();
for (int i = 0; i < data.length; i++)
{
int val = 0;
for (int j = 0; j < Integer.SIZE; j++)
{
val |= dimensionMap.get(i * Integer.SIZE + j) ? (1 << j) : 0;
}
data[i] = val;
}
dimMap.setIntArray("DimensionArray", data);
return dimMap;
}
public static void loadDimensionDataMap(NBTTagCompound compoundTag)
{
if (compoundTag == null)
{
dimensionMap.clear();
for (Integer id : dimensions.keySet())
{
if (id >= 0)
{
dimensionMap.set(id);
}
}
}
else
{
int[] intArray = compoundTag.getIntArray("DimensionArray");
for (int i = 0; i < intArray.length; i++)
{
for (int j = 0; j < Integer.SIZE; j++)
{
dimensionMap.set(i * Integer.SIZE + j, (intArray[i] & (1 << j)) != 0);
}
}
}
}
/**
* Return the current root directory for the world save. Accesses getSaveHandler from the overworld
* @return the root directory of the save
*/
public static File getCurrentSaveRootDirectory()
{
if (DimensionManager.getWorld(0) != null)
{
return ((SaveHandler)DimensionManager.getWorld(0).getSaveHandler()).getWorldDirectory();
}
else if (MinecraftServer.getServer() != null)
{
MinecraftServer srv = MinecraftServer.getServer();
SaveHandler saveHandler = (SaveHandler) srv.getActiveAnvilConverter().getSaveLoader(srv.getFolderName(), false);
return saveHandler.getWorldDirectory();
}
else
{
return null;
}
}
}
@@ -1,111 +0,0 @@
package net.minecraftforge.common;
import java.util.ArrayList;
import java.util.Random;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.util.WeightedRandomItem;
import static net.minecraftforge.common.ChestGenHooks.DUNGEON_CHEST;
public class DungeonHooks
{
private static ArrayList<DungeonMob> dungeonMobs = new ArrayList<DungeonMob>();
/**
* Adds a mob to the possible list of creatures the spawner will create.
* If the mob is already in the spawn list, the rarity will be added to the existing one,
* causing the mob to be more common.
*
* @param name The name of the monster, use the same name used when registering the entity.
* @param rarity The rarity of selecting this mob over others. Must be greater then 0.
* Vanilla Minecraft has the following mobs:
* Spider 100
* Skeleton 100
* Zombie 200
* Meaning, Zombies are twice as common as spiders or skeletons.
* @return The new rarity of the monster,
*/
public static float addDungeonMob(String name, int rarity)
{
if (rarity <= 0)
{
throw new IllegalArgumentException("Rarity must be greater then zero");
}
for (DungeonMob mob : dungeonMobs)
{
if (name.equals(mob.type))
{
return mob.itemWeight += rarity;
}
}
dungeonMobs.add(new DungeonMob(rarity, name));
return rarity;
}
/**
* Will completely remove a Mob from the dungeon spawn list.
*
* @param name The name of the mob to remove
* @return The rarity of the removed mob, prior to being removed.
*/
public static int removeDungeonMob(String name)
{
for (DungeonMob mob : dungeonMobs)
{
if (name.equals(mob.type))
{
dungeonMobs.remove(mob);
return mob.itemWeight;
}
}
return 0;
}
/**
* Gets a random mob name from the list.
* @param rand World generation random number generator
* @return The mob name
*/
public static String getRandomDungeonMob(Random rand)
{
DungeonMob mob = (DungeonMob)WeightedRandom.getRandomItem(rand, dungeonMobs);
if (mob == null)
{
return "";
}
return mob.type;
}
public static class DungeonMob extends WeightedRandomItem
{
public String type;
public DungeonMob(int weight, String type)
{
super(weight);
this.type = type;
}
@Override
public boolean equals(Object target)
{
return target instanceof DungeonMob && type.equals(((DungeonMob)target).type);
}
}
static
{
addDungeonMob("Skeleton", 100);
addDungeonMob("Zombie", 200);
addDungeonMob("Spider", 100);
}
}
@@ -1,286 +0,0 @@
package net.minecraftforge.common;
import java.lang.reflect.*;
import java.util.*;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.block.EnumMobType;
import net.minecraft.block.material.Material;
import net.minecraft.enchantment.EnumEnchantmentType;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.EnumEntitySize;
import net.minecraft.entity.player.EnumStatus;
import net.minecraft.item.EnumAction;
import net.minecraft.item.EnumArmorMaterial;
import net.minecraft.item.EnumToolMaterial;
import net.minecraft.util.EnumArt;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.gen.structure.EnumDoor;
import net.minecraftforge.classloading.FMLForgePlugin;
public class EnumHelper
{
private static Object reflectionFactory = null;
private static Method newConstructorAccessor = null;
private static Method newInstance = null;
private static Method newFieldAccessor = null;
private static Method fieldAccessorSet = null;
private static boolean isSetup = false;
//Some enums are decompiled with extra arguments, so lets check for that
private static Class[][] commonTypes =
{
{EnumAction.class},
{EnumArmorMaterial.class, int.class, int[].class, int.class},
{EnumArt.class, String.class, int.class, int.class, int.class, int.class},
{EnumCreatureAttribute.class},
{EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class},
{EnumDoor.class},
{EnumEnchantmentType.class},
{EnumEntitySize.class},
{EnumMobType.class},
{EnumMovingObjectType.class},
{EnumSkyBlock.class, int.class},
{EnumStatus.class},
{EnumToolMaterial.class, int.class, int.class, float.class, int.class, int.class}
};
public static EnumAction addAction(String name)
{
return addEnum(EnumAction.class, name);
}
public static EnumArmorMaterial addArmorMaterial(String name, int durability, int[] reductionAmounts, int enchantability)
{
return addEnum(EnumArmorMaterial.class, name, durability, reductionAmounts, enchantability);
}
public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY)
{
return addEnum(EnumArt.class, name, tile, sizeX, sizeY, offsetX, offsetY);
}
public static EnumCreatureAttribute addCreatureAttribute(String name)
{
return addEnum(EnumCreatureAttribute.class, name);
}
public static EnumCreatureType addCreatureType(String name, Class typeClass, int maxNumber, Material material, boolean peaceful)
{
return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful);
}
public static EnumDoor addDoor(String name)
{
return addEnum(EnumDoor.class, name);
}
public static EnumEnchantmentType addEnchantmentType(String name)
{
return addEnum(EnumEnchantmentType.class, name);
}
public static EnumEntitySize addEntitySize(String name)
{
return addEnum(EnumEntitySize.class, name);
}
public static EnumMobType addMobType(String name)
{
return addEnum(EnumMobType.class, name);
}
public static EnumMovingObjectType addMovingObjectType(String name)
{
if (!isSetup)
{
setup();
}
return addEnum(EnumMovingObjectType.class, name);
}
public static EnumSkyBlock addSkyBlock(String name, int lightValue)
{
return addEnum(EnumSkyBlock.class, name, lightValue);
}
public static EnumStatus addStatus(String name)
{
return addEnum(EnumStatus.class, name);
}
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, int damage, int enchantability)
{
return addEnum(EnumToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
}
private static void setup()
{
if (isSetup)
{
return;
}
try
{
Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory");
reflectionFactory = getReflectionFactory.invoke(null);
newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class);
newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class);
newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class);
fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class);
}
catch (Exception e)
{
e.printStackTrace();
}
isSetup = true;
}
/*
* Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+
* Also modified for use in decompiled code.
* Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically
*/
private static Object getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws Exception
{
Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
parameterTypes[0] = String.class;
parameterTypes[1] = int.class;
System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes));
}
private static < T extends Enum<? >> T makeEnum(Class<T> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception
{
Object[] parms = new Object[additionalValues.length + 2];
parms[0] = value;
parms[1] = Integer.valueOf(ordinal);
System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] {parms}));
}
public static void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception
{
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false);
fieldAccessorSet.invoke(fieldAccessor, target, value);
}
private static void blankField(Class<?> enumClass, String fieldName) throws Exception
{
for (Field field : Class.class.getDeclaredFields())
{
if (field.getName().contains(fieldName))
{
field.setAccessible(true);
setFailsafeFieldValue(field, enumClass, null);
break;
}
}
}
private static void cleanEnumCache(Class<?> enumClass) throws Exception
{
blankField(enumClass, "enumConstantDirectory");
blankField(enumClass, "enumConstants");
}
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Object... paramValues)
{
return addEnum(commonTypes, enumType, enumName, paramValues);
}
public static <T extends Enum<? >> T addEnum(Class[][] map, Class<T> enumType, String enumName, Object... paramValues)
{
for (Class[] lookup : map)
{
if (lookup[0] == enumType)
{
Class<?>[] paramTypes = new Class<?>[lookup.length - 1];
if (paramTypes.length > 0)
{
System.arraycopy(lookup, 1, paramTypes, 0, paramTypes.length);
}
return addEnum(enumType, enumName, paramTypes, paramValues);
}
}
return null;
}
@SuppressWarnings("unchecked")
public static <T extends Enum<? >> T addEnum(Class<T> enumType, String enumName, Class<?>[] paramTypes, Object[] paramValues)
{
if (!isSetup)
{
setup();
}
Field valuesField = null;
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields)
{
String name = field.getName();
if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards
{
valuesField = field;
break;
}
}
int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/;
if (valuesField == null)
{
String valueType = String.format("[L%s;", enumType.getName().replace('.', '/'));
for (Field field : fields)
{
if ((field.getModifiers() & flags) == flags &&
field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't..
{
valuesField = field;
break;
}
}
}
if (valuesField == null)
{
FMLLog.severe("Could not find $VALUES field for enum: %s", enumType.getName());
FMLLog.severe("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF);
FMLLog.severe("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0'));
FMLLog.severe("Fields:");
for (Field field : fields)
{
String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0');
FMLLog.severe(" %s %s: %s", mods, field.getName(), field.getType().getName());
}
return null;
}
valuesField.setAccessible(true);
try
{
T[] previousValues = (T[])valuesField.get(enumType);
List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
T newValue = (T)makeEnum(enumType, enumName, values.size(), paramTypes, paramValues);
values.add(newValue);
setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(enumType, 0)));
cleanEnumCache(enumType);
return newValue;
}
catch (Exception e)
{
e.printStackTrace();
throw new RuntimeException(e.getMessage(), e);
}
}
static
{
if (!isSetup)
{
setup();
}
}
}
@@ -1,12 +0,0 @@
package net.minecraftforge.common;
public enum EnumPlantType
{
Plains,
Desert,
Beach,
Cave,
Water,
Nether,
Crop
}
@@ -1,25 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
//Preliminary, simple Fake Player class
public class FakePlayer extends EntityPlayer
{
public FakePlayer(World world, String name)
{
super(world, name);
}
public void sendChatToPlayer(String s){}
public boolean canCommandSenderUseCommand(int i, String s){ return false; }
public ChunkCoordinates getPlayerCoordinates()
{
return new ChunkCoordinates(0,0,0);
}
@Override
public void func_110122_a(ChatMessageComponent chatmessagecomponent){}
}
@@ -1,18 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.world.World;
//To be expanded for generic Mod fake players?
public class FakePlayerFactory
{
private static FakePlayer MINECRAFT_PLAYER = null;
public static FakePlayer getMinecraft(World world)
{
if (MINECRAFT_PLAYER == null)
{
MINECRAFT_PLAYER = new FakePlayer(world, "[Minecraft]");
}
return MINECRAFT_PLAYER;
}
}
@@ -1,999 +0,0 @@
package net.minecraftforge.common;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
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 com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultiset;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.event.Event;
/**
* Manages chunkloading for mods.
*
* The basic principle is a ticket based system.
* 1. Mods register a callback {@link #setForcedChunkLoadingCallback(Object, LoadingCallback)}
* 2. Mods ask for a ticket {@link #requestTicket(Object, World, Type)} and then hold on to that ticket.
* 3. Mods request chunks to stay loaded {@link #forceChunk(Ticket, ChunkCoordIntPair)} or remove chunks from force loading {@link #unforceChunk(Ticket, ChunkCoordIntPair)}.
* 4. When a world unloads, the tickets associated with that world are saved by the chunk manager.
* 5. When a world loads, saved tickets are offered to the mods associated with the tickets. The {@link Ticket#getModData()} that is set by the mod should be used to re-register
* chunks to stay loaded (and maybe take other actions).
*
* The chunkloading is configurable at runtime. The file "config/forgeChunkLoading.cfg" contains both default configuration for chunkloading, and a sample individual mod
* specific override section.
*
* @author cpw
*
*/
public class ForgeChunkManager
{
private static int defaultMaxCount;
private static int defaultMaxChunks;
private static boolean overridesEnabled;
private static Map<World, Multimap<String, Ticket>> tickets = new MapMaker().weakKeys().makeMap();
private static Map<String, Integer> ticketConstraints = Maps.newHashMap();
private static Map<String, Integer> chunkConstraints = Maps.newHashMap();
private static SetMultimap<String, Ticket> playerTickets = HashMultimap.create();
private static Map<String, LoadingCallback> callbacks = Maps.newHashMap();
private static Map<World, ImmutableSetMultimap<ChunkCoordIntPair,Ticket>> forcedChunks = new MapMaker().weakKeys().makeMap();
private static BiMap<UUID,Ticket> pendingEntities = HashBiMap.create();
private static Map<World,Cache<Long, Chunk>> dormantChunkCache = new MapMaker().weakKeys().makeMap();
private static File cfgFile;
private static Configuration config;
private static int playerTicketLength;
private static int dormantChunkCacheSize;
private static Set<String> warnedMods = Sets.newHashSet();
/**
* All mods requiring chunkloading need to implement this to handle the
* re-registration of chunk tickets at world loading time
*
* @author cpw
*
*/
public interface LoadingCallback
{
/**
* Called back when tickets are loaded from the world to allow the
* mod to re-register the chunks associated with those tickets. The list supplied
* here is truncated to length prior to use. Tickets unwanted by the
* mod must be disposed of manually unless the mod is an OrderedLoadingCallback instance
* in which case, they will have been disposed of by the earlier callback.
*
* @param tickets The tickets to re-register. The list is immutable and cannot be manipulated directly. Copy it first.
* @param world the world
*/
public void ticketsLoaded(List<Ticket> tickets, World world);
}
/**
* This is a special LoadingCallback that can be implemented as well as the
* LoadingCallback to provide access to additional behaviour.
* Specifically, this callback will fire prior to Forge dropping excess
* tickets. Tickets in the returned list are presumed ordered and excess will
* be truncated from the returned list.
* This allows the mod to control not only if they actually <em>want</em> a ticket but
* also their preferred ticket ordering.
*
* @author cpw
*
*/
public interface OrderedLoadingCallback extends LoadingCallback
{
/**
* Called back when tickets are loaded from the world to allow the
* mod to decide if it wants the ticket still, and prioritise overflow
* based on the ticket count.
* WARNING: You cannot force chunks in this callback, it is strictly for allowing the mod
* to be more selective in which tickets it wishes to preserve in an overflow situation
*
* @param tickets The tickets that you will want to select from. The list is immutable and cannot be manipulated directly. Copy it first.
* @param world The world
* @param maxTicketCount The maximum number of tickets that will be allowed.
* @return A list of the tickets this mod wishes to continue using. This list will be truncated
* to "maxTicketCount" size after the call returns and then offered to the other callback
* method
*/
public List<Ticket> ticketsLoaded(List<Ticket> tickets, World world, int maxTicketCount);
}
public interface PlayerOrderedLoadingCallback extends LoadingCallback
{
/**
* Called back when tickets are loaded from the world to allow the
* mod to decide if it wants the ticket still.
* This is for player bound tickets rather than mod bound tickets. It is here so mods can
* decide they want to dump all player tickets
*
* WARNING: You cannot force chunks in this callback, it is strictly for allowing the mod
* to be more selective in which tickets it wishes to preserve
*
* @param tickets The tickets that you will want to select from. The list is immutable and cannot be manipulated directly. Copy it first.
* @param world The world
* @return A list of the tickets this mod wishes to use. This list will subsequently be offered
* to the main callback for action
*/
public ListMultimap<String, Ticket> playerTicketsLoaded(ListMultimap<String, Ticket> tickets, World world);
}
public enum Type
{
/**
* For non-entity registrations
*/
NORMAL,
/**
* For entity registrations
*/
ENTITY
}
public static class Ticket
{
private String modId;
private Type ticketType;
private LinkedHashSet<ChunkCoordIntPair> requestedChunks;
private NBTTagCompound modData;
public final World world;
private int maxDepth;
private String entityClazz;
private int entityChunkX;
private int entityChunkZ;
private Entity entity;
private String player;
Ticket(String modId, Type type, World world)
{
this.modId = modId;
this.ticketType = type;
this.world = world;
this.maxDepth = getMaxChunkDepthFor(modId);
this.requestedChunks = Sets.newLinkedHashSet();
}
Ticket(String modId, Type type, World world, String player)
{
this(modId, type, world);
if (player != null)
{
this.player = player;
}
else
{
FMLLog.log(Level.SEVERE, "Attempt to create a player ticket without a valid player");
throw new RuntimeException();
}
}
/**
* The chunk list depth can be manipulated up to the maximal grant allowed for the mod. This value is configurable. Once the maximum is reached,
* the least recently forced chunk, by original registration time, is removed from the forced chunk list.
*
* @param depth The new depth to set
*/
public void setChunkListDepth(int depth)
{
if (depth > getMaxChunkDepthFor(modId) || (depth <= 0 && getMaxChunkDepthFor(modId) > 0))
{
FMLLog.warning("The mod %s tried to modify the chunk ticket depth to: %d, its allowed maximum is: %d", modId, depth, getMaxChunkDepthFor(modId));
}
else
{
this.maxDepth = depth;
}
}
/**
* Gets the current max depth for this ticket.
* Should be the same as getMaxChunkListDepth()
* unless setChunkListDepth has been called.
*
* @return Current max depth
*/
public int getChunkListDepth()
{
return maxDepth;
}
/**
* Get the maximum chunk depth size
*
* @return The maximum chunk depth size
*/
public int getMaxChunkListDepth()
{
return getMaxChunkDepthFor(modId);
}
/**
* Bind the entity to the ticket for {@link Type#ENTITY} type tickets. Other types will throw a runtime exception.
*
* @param entity The entity to bind
*/
public void bindEntity(Entity entity)
{
if (ticketType!=Type.ENTITY)
{
throw new RuntimeException("Cannot bind an entity to a non-entity ticket");
}
this.entity = entity;
}
/**
* Retrieve the {@link NBTTagCompound} that stores mod specific data for the chunk ticket.
* Example data to store would be a TileEntity or Block location. This is persisted with the ticket and
* provided to the {@link LoadingCallback} for the mod. It is recommended to use this to recover
* useful state information for the forced chunks.
*
* @return The custom compound tag for mods to store additional chunkloading data
*/
public NBTTagCompound getModData()
{
if (this.modData == null)
{
this.modData = new NBTTagCompound();
}
return modData;
}
/**
* Get the entity associated with this {@link Type#ENTITY} type ticket
* @return the entity
*/
public Entity getEntity()
{
return entity;
}
/**
* Is this a player associated ticket rather than a mod associated ticket?
*/
public boolean isPlayerTicket()
{
return player != null;
}
/**
* Get the player associated with this ticket
*/
public String getPlayerName()
{
return player;
}
/**
* Get the associated mod id
*/
public String getModId()
{
return modId;
}
/**
* Gets the ticket type
*/
public Type getType()
{
return ticketType;
}
/**
* Gets a list of requested chunks for this ticket.
*/
public ImmutableSet getChunkList()
{
return ImmutableSet.copyOf(requestedChunks);
}
}
public static class ForceChunkEvent extends Event {
public final Ticket ticket;
public final ChunkCoordIntPair location;
public ForceChunkEvent(Ticket ticket, ChunkCoordIntPair location)
{
this.ticket = ticket;
this.location = location;
}
}
public static class UnforceChunkEvent extends Event {
public final Ticket ticket;
public final ChunkCoordIntPair location;
public UnforceChunkEvent(Ticket ticket, ChunkCoordIntPair location)
{
this.ticket = ticket;
this.location = location;
}
}
/**
* Allows dynamically loading world mods to test if there are chunk tickets in the world
* Mods that add dynamically generated worlds (like Mystcraft) should call this method
* to determine if the world should be loaded during server starting.
*
* @param chunkDir The chunk directory to test: should be equivalent to {@link WorldServer#getChunkSaveLocation()}
* @return if there are tickets outstanding for this world or not
*/
public static boolean savedWorldHasForcedChunkTickets(File chunkDir)
{
File chunkLoaderData = new File(chunkDir, "forcedchunks.dat");
if (chunkLoaderData.exists() && chunkLoaderData.isFile())
{
;
try
{
NBTTagCompound forcedChunkData = CompressedStreamTools.read(chunkLoaderData);
return forcedChunkData.getTagList("TicketList").tagCount() > 0;
}
catch (IOException e)
{
}
}
return false;
}
static void loadWorld(World world)
{
ArrayListMultimap<String, Ticket> newTickets = ArrayListMultimap.<String, Ticket>create();
tickets.put(world, newTickets);
forcedChunks.put(world, ImmutableSetMultimap.<ChunkCoordIntPair,Ticket>of());
if (!(world instanceof WorldServer))
{
return;
}
dormantChunkCache.put(world, CacheBuilder.newBuilder().maximumSize(dormantChunkCacheSize).<Long, Chunk>build());
WorldServer worldServer = (WorldServer) world;
File chunkDir = worldServer.getChunkSaveLocation();
File chunkLoaderData = new File(chunkDir, "forcedchunks.dat");
if (chunkLoaderData.exists() && chunkLoaderData.isFile())
{
ArrayListMultimap<String, Ticket> loadedTickets = ArrayListMultimap.<String, Ticket>create();
Map<String,ListMultimap<String,Ticket>> playerLoadedTickets = Maps.newHashMap();
NBTTagCompound forcedChunkData;
try
{
forcedChunkData = CompressedStreamTools.read(chunkLoaderData);
}
catch (IOException e)
{
FMLLog.log(Level.WARNING, e, "Unable to read forced chunk data at %s - it will be ignored", chunkLoaderData.getAbsolutePath());
return;
}
NBTTagList ticketList = forcedChunkData.getTagList("TicketList");
for (int i = 0; i < ticketList.tagCount(); i++)
{
NBTTagCompound ticketHolder = (NBTTagCompound) ticketList.tagAt(i);
String modId = ticketHolder.getString("Owner");
boolean isPlayer = "Forge".equals(modId);
if (!isPlayer && !Loader.isModLoaded(modId))
{
FMLLog.warning("Found chunkloading data for mod %s which is currently not available or active - it will be removed from the world save", modId);
continue;
}
if (!isPlayer && !callbacks.containsKey(modId))
{
FMLLog.warning("The mod %s has registered persistent chunkloading data but doesn't seem to want to be called back with it - it will be removed from the world save", modId);
continue;
}
NBTTagList tickets = ticketHolder.getTagList("Tickets");
for (int j = 0; j < tickets.tagCount(); j++)
{
NBTTagCompound ticket = (NBTTagCompound) tickets.tagAt(j);
modId = ticket.hasKey("ModId") ? ticket.getString("ModId") : modId;
Type type = Type.values()[ticket.getByte("Type")];
byte ticketChunkDepth = ticket.getByte("ChunkListDepth");
Ticket tick = new Ticket(modId, type, world);
if (ticket.hasKey("ModData"))
{
tick.modData = ticket.getCompoundTag("ModData");
}
if (ticket.hasKey("Player"))
{
tick.player = ticket.getString("Player");
if (!playerLoadedTickets.containsKey(tick.modId))
{
playerLoadedTickets.put(modId, ArrayListMultimap.<String,Ticket>create());
}
playerLoadedTickets.get(tick.modId).put(tick.player, tick);
}
else
{
loadedTickets.put(modId, tick);
}
if (type == Type.ENTITY)
{
tick.entityChunkX = ticket.getInteger("chunkX");
tick.entityChunkZ = ticket.getInteger("chunkZ");
UUID uuid = new UUID(ticket.getLong("PersistentIDMSB"), ticket.getLong("PersistentIDLSB"));
// add the ticket to the "pending entity" list
pendingEntities.put(uuid, tick);
}
}
}
for (Ticket tick : ImmutableSet.copyOf(pendingEntities.values()))
{
if (tick.ticketType == Type.ENTITY && tick.entity == null)
{
// force the world to load the entity's chunk
// the load will come back through the loadEntity method and attach the entity
// to the ticket
world.getChunkFromChunkCoords(tick.entityChunkX, tick.entityChunkZ);
}
}
for (Ticket tick : ImmutableSet.copyOf(pendingEntities.values()))
{
if (tick.ticketType == Type.ENTITY && tick.entity == null)
{
FMLLog.warning("Failed to load persistent chunkloading entity %s from store.", pendingEntities.inverse().get(tick));
loadedTickets.remove(tick.modId, tick);
}
}
pendingEntities.clear();
// send callbacks
for (String modId : loadedTickets.keySet())
{
LoadingCallback loadingCallback = callbacks.get(modId);
if (loadingCallback == null)
{
continue;
}
int maxTicketLength = getMaxTicketLengthFor(modId);
List<Ticket> tickets = loadedTickets.get(modId);
if (loadingCallback instanceof OrderedLoadingCallback)
{
OrderedLoadingCallback orderedLoadingCallback = (OrderedLoadingCallback) loadingCallback;
tickets = orderedLoadingCallback.ticketsLoaded(ImmutableList.copyOf(tickets), world, maxTicketLength);
}
if (tickets.size() > maxTicketLength)
{
FMLLog.warning("The mod %s has too many open chunkloading tickets %d. Excess will be dropped", modId, tickets.size());
tickets.subList(maxTicketLength, tickets.size()).clear();
}
ForgeChunkManager.tickets.get(world).putAll(modId, tickets);
loadingCallback.ticketsLoaded(ImmutableList.copyOf(tickets), world);
}
for (String modId : playerLoadedTickets.keySet())
{
LoadingCallback loadingCallback = callbacks.get(modId);
if (loadingCallback == null)
{
continue;
}
ListMultimap<String,Ticket> tickets = playerLoadedTickets.get(modId);
if (loadingCallback instanceof PlayerOrderedLoadingCallback)
{
PlayerOrderedLoadingCallback orderedLoadingCallback = (PlayerOrderedLoadingCallback) loadingCallback;
tickets = orderedLoadingCallback.playerTicketsLoaded(ImmutableListMultimap.copyOf(tickets), world);
playerTickets.putAll(tickets);
}
ForgeChunkManager.tickets.get(world).putAll("Forge", tickets.values());
loadingCallback.ticketsLoaded(ImmutableList.copyOf(tickets.values()), world);
}
}
}
static void unloadWorld(World world)
{
// World save fires before this event so the chunk loading info will be done
if (!(world instanceof WorldServer))
{
return;
}
forcedChunks.remove(world);
dormantChunkCache.remove(world);
// integrated server is shutting down
if (!MinecraftServer.getServer().isServerRunning())
{
playerTickets.clear();
tickets.clear();
}
}
/**
* Set a chunkloading callback for the supplied mod object
*
* @param mod The mod instance registering the callback
* @param callback The code to call back when forced chunks are loaded
*/
public static void setForcedChunkLoadingCallback(Object mod, LoadingCallback callback)
{
ModContainer container = getContainer(mod);
if (container == null)
{
FMLLog.warning("Unable to register a callback for an unknown mod %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
return;
}
callbacks.put(container.getModId(), callback);
}
/**
* Discover the available tickets for the mod in the world
*
* @param mod The mod that will own the tickets
* @param world The world
* @return The count of tickets left for the mod in the supplied world
*/
public static int ticketCountAvailableFor(Object mod, World world)
{
ModContainer container = getContainer(mod);
if (container!=null)
{
String modId = container.getModId();
int allowedCount = getMaxTicketLengthFor(modId);
return allowedCount - tickets.get(world).get(modId).size();
}
else
{
return 0;
}
}
private static ModContainer getContainer(Object mod)
{
ModContainer container = Loader.instance().getModObjectList().inverse().get(mod);
return container;
}
public static int getMaxTicketLengthFor(String modId)
{
int allowedCount = ticketConstraints.containsKey(modId) && overridesEnabled ? ticketConstraints.get(modId) : defaultMaxCount;
return allowedCount;
}
public static int getMaxChunkDepthFor(String modId)
{
int allowedCount = chunkConstraints.containsKey(modId) && overridesEnabled ? chunkConstraints.get(modId) : defaultMaxChunks;
return allowedCount;
}
public static int ticketCountAvailableFor(String username)
{
return playerTicketLength - playerTickets.get(username).size();
}
public static Ticket requestPlayerTicket(Object mod, String player, World world, Type type)
{
ModContainer mc = getContainer(mod);
if (mc == null)
{
FMLLog.log(Level.SEVERE, "Failed to locate the container for mod instance %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
return null;
}
if (playerTickets.get(player).size()>playerTicketLength)
{
FMLLog.warning("Unable to assign further chunkloading tickets to player %s (on behalf of mod %s)", player, mc.getModId());
return null;
}
Ticket ticket = new Ticket(mc.getModId(),type,world,player);
playerTickets.put(player, ticket);
tickets.get(world).put("Forge", ticket);
return ticket;
}
/**
* Request a chunkloading ticket of the appropriate type for the supplied mod
*
* @param mod The mod requesting a ticket
* @param world The world in which it is requesting the ticket
* @param type The type of ticket
* @return A ticket with which to register chunks for loading, or null if no further tickets are available
*/
public static Ticket requestTicket(Object mod, World world, Type type)
{
ModContainer container = getContainer(mod);
if (container == null)
{
FMLLog.log(Level.SEVERE, "Failed to locate the container for mod instance %s (%s : %x)", mod, mod.getClass().getName(), System.identityHashCode(mod));
return null;
}
String modId = container.getModId();
if (!callbacks.containsKey(modId))
{
FMLLog.severe("The mod %s has attempted to request a ticket without a listener in place", modId);
throw new RuntimeException("Invalid ticket request");
}
int allowedCount = ticketConstraints.containsKey(modId) ? ticketConstraints.get(modId) : defaultMaxCount;
if (tickets.get(world).get(modId).size() >= allowedCount)
{
if (!warnedMods.contains(modId))
{
FMLLog.info("The mod %s has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum : %d", modId, allowedCount);
warnedMods.add(modId);
}
return null;
}
Ticket ticket = new Ticket(modId, type, world);
tickets.get(world).put(modId, ticket);
return ticket;
}
/**
* Release the ticket back to the system. This will also unforce any chunks held by the ticket so that they can be unloaded and/or stop ticking.
*
* @param ticket The ticket to release
*/
public static void releaseTicket(Ticket ticket)
{
if (ticket == null)
{
return;
}
if (ticket.isPlayerTicket() ? !playerTickets.containsValue(ticket) : !tickets.get(ticket.world).containsEntry(ticket.modId, ticket))
{
return;
}
if (ticket.requestedChunks!=null)
{
for (ChunkCoordIntPair chunk : ImmutableSet.copyOf(ticket.requestedChunks))
{
unforceChunk(ticket, chunk);
}
}
if (ticket.isPlayerTicket())
{
playerTickets.remove(ticket.player, ticket);
tickets.get(ticket.world).remove("Forge",ticket);
}
else
{
tickets.get(ticket.world).remove(ticket.modId, ticket);
}
}
/**
* Force the supplied chunk coordinate to be loaded by the supplied ticket. If the ticket's {@link Ticket#maxDepth} is exceeded, the least
* recently registered chunk is unforced and may be unloaded.
* It is safe to force the chunk several times for a ticket, it will not generate duplication or change the ordering.
*
* @param ticket The ticket registering the chunk
* @param chunk The chunk to force
*/
public static void forceChunk(Ticket ticket, ChunkCoordIntPair chunk)
{
if (ticket == null || chunk == null)
{
return;
}
if (ticket.ticketType == Type.ENTITY && ticket.entity == null)
{
throw new RuntimeException("Attempted to use an entity ticket to force a chunk, without an entity");
}
if (ticket.isPlayerTicket() ? !playerTickets.containsValue(ticket) : !tickets.get(ticket.world).containsEntry(ticket.modId, ticket))
{
FMLLog.severe("The mod %s attempted to force load a chunk with an invalid ticket. This is not permitted.", ticket.modId);
return;
}
ticket.requestedChunks.add(chunk);
MinecraftForge.EVENT_BUS.post(new ForceChunkEvent(ticket, chunk));
ImmutableSetMultimap<ChunkCoordIntPair, Ticket> newMap = ImmutableSetMultimap.<ChunkCoordIntPair,Ticket>builder().putAll(forcedChunks.get(ticket.world)).put(chunk, ticket).build();
forcedChunks.put(ticket.world, newMap);
if (ticket.maxDepth > 0 && ticket.requestedChunks.size() > ticket.maxDepth)
{
ChunkCoordIntPair removed = ticket.requestedChunks.iterator().next();
unforceChunk(ticket,removed);
}
}
/**
* Reorganize the internal chunk list so that the chunk supplied is at the *end* of the list
* This helps if you wish to guarantee a certain "automatic unload ordering" for the chunks
* in the ticket list
*
* @param ticket The ticket holding the chunk list
* @param chunk The chunk you wish to push to the end (so that it would be unloaded last)
*/
public static void reorderChunk(Ticket ticket, ChunkCoordIntPair chunk)
{
if (ticket == null || chunk == null || !ticket.requestedChunks.contains(chunk))
{
return;
}
ticket.requestedChunks.remove(chunk);
ticket.requestedChunks.add(chunk);
}
/**
* Unforce the supplied chunk, allowing it to be unloaded and stop ticking.
*
* @param ticket The ticket holding the chunk
* @param chunk The chunk to unforce
*/
public static void unforceChunk(Ticket ticket, ChunkCoordIntPair chunk)
{
if (ticket == null || chunk == null)
{
return;
}
ticket.requestedChunks.remove(chunk);
MinecraftForge.EVENT_BUS.post(new UnforceChunkEvent(ticket, chunk));
LinkedHashMultimap<ChunkCoordIntPair, Ticket> copy = LinkedHashMultimap.create(forcedChunks.get(ticket.world));
copy.remove(chunk, ticket);
ImmutableSetMultimap<ChunkCoordIntPair, Ticket> newMap = ImmutableSetMultimap.copyOf(copy);
forcedChunks.put(ticket.world,newMap);
}
static void loadConfiguration()
{
for (String mod : config.getCategoryNames())
{
if (mod.equals("Forge") || mod.equals("defaults"))
{
continue;
}
Property modTC = config.get(mod, "maximumTicketCount", 200);
Property modCPT = config.get(mod, "maximumChunksPerTicket", 25);
ticketConstraints.put(mod, modTC.getInt(200));
chunkConstraints.put(mod, modCPT.getInt(25));
}
if (config.hasChanged())
{
config.save();
}
}
/**
* The list of persistent chunks in the world. This set is immutable.
* @param world
* @return the list of persistent chunks in the world
*/
public static ImmutableSetMultimap<ChunkCoordIntPair, Ticket> getPersistentChunksFor(World world)
{
return forcedChunks.containsKey(world) ? forcedChunks.get(world) : ImmutableSetMultimap.<ChunkCoordIntPair,Ticket>of();
}
static void saveWorld(World world)
{
// only persist persistent worlds
if (!(world instanceof WorldServer)) { return; }
WorldServer worldServer = (WorldServer) world;
File chunkDir = worldServer.getChunkSaveLocation();
File chunkLoaderData = new File(chunkDir, "forcedchunks.dat");
NBTTagCompound forcedChunkData = new NBTTagCompound();
NBTTagList ticketList = new NBTTagList();
forcedChunkData.setTag("TicketList", ticketList);
Multimap<String, Ticket> ticketSet = tickets.get(worldServer);
for (String modId : ticketSet.keySet())
{
NBTTagCompound ticketHolder = new NBTTagCompound();
ticketList.appendTag(ticketHolder);
ticketHolder.setString("Owner", modId);
NBTTagList tickets = new NBTTagList();
ticketHolder.setTag("Tickets", tickets);
for (Ticket tick : ticketSet.get(modId))
{
NBTTagCompound ticket = new NBTTagCompound();
ticket.setByte("Type", (byte) tick.ticketType.ordinal());
ticket.setByte("ChunkListDepth", (byte) tick.maxDepth);
if (tick.isPlayerTicket())
{
ticket.setString("ModId", tick.modId);
ticket.setString("Player", tick.player);
}
if (tick.modData != null)
{
ticket.setCompoundTag("ModData", tick.modData);
}
if (tick.ticketType == Type.ENTITY && tick.entity != null && tick.entity.addEntityID(new NBTTagCompound()))
{
ticket.setInteger("chunkX", MathHelper.floor_double(tick.entity.chunkCoordX));
ticket.setInteger("chunkZ", MathHelper.floor_double(tick.entity.chunkCoordZ));
ticket.setLong("PersistentIDMSB", tick.entity.getPersistentID().getMostSignificantBits());
ticket.setLong("PersistentIDLSB", tick.entity.getPersistentID().getLeastSignificantBits());
tickets.appendTag(ticket);
}
else if (tick.ticketType != Type.ENTITY)
{
tickets.appendTag(ticket);
}
}
}
try
{
CompressedStreamTools.write(forcedChunkData, chunkLoaderData);
}
catch (IOException e)
{
FMLLog.log(Level.WARNING, e, "Unable to write forced chunk data to %s - chunkloading won't work", chunkLoaderData.getAbsolutePath());
return;
}
}
static void loadEntity(Entity entity)
{
UUID id = entity.getPersistentID();
Ticket tick = pendingEntities.get(id);
if (tick != null)
{
tick.bindEntity(entity);
pendingEntities.remove(id);
}
}
public static void putDormantChunk(long coords, Chunk chunk)
{
Cache<Long, Chunk> cache = dormantChunkCache.get(chunk.worldObj);
if (cache != null)
{
cache.put(coords, chunk);
}
}
public static Chunk fetchDormantChunk(long coords, World world)
{
Cache<Long, Chunk> cache = dormantChunkCache.get(world);
if (cache == null)
{
return null;
}
Chunk chunk = cache.getIfPresent(coords);
if (chunk != null)
{
for (List<Entity> eList : chunk.entityLists)
{
for (Entity e: eList)
{
e.resetEntityId();
}
}
}
return chunk;
}
static void captureConfig(File configDir)
{
cfgFile = new File(configDir,"forgeChunkLoading.cfg");
config = new Configuration(cfgFile, true);
try
{
config.load();
}
catch (Exception e)
{
File dest = new File(cfgFile.getParentFile(),"forgeChunkLoading.cfg.bak");
if (dest.exists())
{
dest.delete();
}
cfgFile.renameTo(dest);
FMLLog.log(Level.SEVERE, e, "A critical error occured reading the forgeChunkLoading.cfg file, defaults will be used - the invalid file is backed up at forgeChunkLoading.cfg.bak");
}
config.addCustomCategoryComment("defaults", "Default configuration for forge chunk loading control");
Property maxTicketCount = config.get("defaults", "maximumTicketCount", 200);
maxTicketCount.comment = "The default maximum ticket count for a mod which does not have an override\n" +
"in this file. This is the number of chunk loading requests a mod is allowed to make.";
defaultMaxCount = maxTicketCount.getInt(200);
Property maxChunks = config.get("defaults", "maximumChunksPerTicket", 25);
maxChunks.comment = "The default maximum number of chunks a mod can force, per ticket, \n" +
"for a mod without an override. This is the maximum number of chunks a single ticket can force.";
defaultMaxChunks = maxChunks.getInt(25);
Property playerTicketCount = config.get("defaults", "playerTicketCount", 500);
playerTicketCount.comment = "The number of tickets a player can be assigned instead of a mod. This is shared across all mods and it is up to the mods to use it.";
playerTicketLength = playerTicketCount.getInt(500);
Property dormantChunkCacheSizeProperty = config.get("defaults", "dormantChunkCacheSize", 0);
dormantChunkCacheSizeProperty.comment = "Unloaded chunks can first be kept in a dormant cache for quicker\n" +
"loading times. Specify the size (in chunks) of that cache here";
dormantChunkCacheSize = dormantChunkCacheSizeProperty.getInt(0);
FMLLog.info("Configured a dormant chunk cache size of %d", dormantChunkCacheSizeProperty.getInt(0));
Property modOverridesEnabled = config.get("defaults", "enabled", true);
modOverridesEnabled.comment = "Are mod overrides enabled?";
overridesEnabled = modOverridesEnabled.getBoolean(true);
config.addCustomCategoryComment("Forge", "Sample mod specific control section.\n" +
"Copy this section and rename the with the modid for the mod you wish to override.\n" +
"A value of zero in either entry effectively disables any chunkloading capabilities\n" +
"for that mod");
Property sampleTC = config.get("Forge", "maximumTicketCount", 200);
sampleTC.comment = "Maximum ticket count for the mod. Zero disables chunkloading capabilities.";
sampleTC = config.get("Forge", "maximumChunksPerTicket", 25);
sampleTC.comment = "Maximum chunks per ticket for the mod.";
for (String mod : config.getCategoryNames())
{
if (mod.equals("Forge") || mod.equals("defaults"))
{
continue;
}
Property modTC = config.get(mod, "maximumTicketCount", 200);
Property modCPT = config.get(mod, "maximumChunksPerTicket", 25);
}
}
public static ConfigCategory getConfigFor(Object mod)
{
ModContainer container = getContainer(mod);
if (container != null)
{
return config.getCategory(container.getModId());
}
return null;
}
public static void addConfigProperty(Object mod, String propertyName, String value, Property.Type type)
{
ModContainer container = getContainer(mod);
if (container != null)
{
ConfigCategory cat = config.getCategory(container.getModId());
cat.put(propertyName, new Property(propertyName, value, type));
}
}
}
@@ -1,71 +0,0 @@
package net.minecraftforge.common;
public enum ForgeDirection
{
/** -Y */
DOWN(0, -1, 0),
/** +Y */
UP(0, 1, 0),
/** -Z */
NORTH(0, 0, -1),
/** +Z */
SOUTH(0, 0, 1),
/** -X */
WEST(-1, 0, 0),
/** +X */
EAST(1, 0, 0),
/**
* Used only by getOrientation, for invalid inputs
*/
UNKNOWN(0, 0, 0);
public final int offsetX;
public final int offsetY;
public final int offsetZ;
public final int flag;
public static final ForgeDirection[] VALID_DIRECTIONS = {DOWN, UP, NORTH, SOUTH, WEST, EAST};
public static final int[] OPPOSITES = {1, 0, 3, 2, 5, 4, 6};
// Left hand rule rotation matrix for all possible axes of rotation
public static final int[][] ROTATION_MATRIX = {
{0, 1, 4, 5, 3, 2, 6},
{0, 1, 5, 4, 2, 3, 6},
{5, 4, 2, 3, 0, 1, 6},
{4, 5, 2, 3, 1, 0, 6},
{2, 3, 1, 0, 4, 5, 6},
{3, 2, 0, 1, 4, 5, 6},
{0, 1, 2, 3, 4, 5, 6},
};
private ForgeDirection(int x, int y, int z)
{
offsetX = x;
offsetY = y;
offsetZ = z;
flag = 1 << ordinal();
}
public static ForgeDirection getOrientation(int id)
{
if (id >= 0 && id < VALID_DIRECTIONS.length)
{
return VALID_DIRECTIONS[id];
}
return UNKNOWN;
}
public ForgeDirection getOpposite()
{
return getOrientation(OPPOSITES[ordinal()]);
}
public ForgeDirection getRotation(ForgeDirection axis)
{
return getOrientation(ROTATION_MATRIX[axis.ordinal()][ordinal()]);
}
}
@@ -1,184 +0,0 @@
package net.minecraftforge.common;
import java.io.File;
import java.util.Arrays;
import java.util.Map;
import java.util.logging.Level;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.management.PlayerInstance;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.common.network.ForgeConnectionHandler;
import net.minecraftforge.common.network.ForgeNetworkHandler;
import net.minecraftforge.common.network.ForgePacketHandler;
import net.minecraftforge.common.network.ForgeTinyPacketHandler;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoadController;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.WorldAccessContainer;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
import cpw.mods.fml.common.network.NetworkMod;
import static net.minecraftforge.common.ForgeVersion.*;
@NetworkMod(
channels = "FORGE",
connectionHandler = ForgeConnectionHandler.class,
packetHandler = ForgePacketHandler.class,
tinyPacketHandler = ForgeTinyPacketHandler.class
)
public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public static int clumpingThreshold = 64;
public static boolean legacyFurnaceSides = false;
public static boolean removeErroringEntities = false;
public static boolean removeErroringTileEntities = false;
public static boolean disableStitchedFileSaving = false;
public ForgeDummyContainer()
{
super(new ModMetadata());
ModMetadata meta = getMetadata();
meta.modId = "Forge";
meta.name = "Minecraft Forge";
meta.version = String.format("%d.%d.%d.%d", majorVersion, minorVersion, revisionVersion, buildVersion);
meta.credits = "Made possible with help from many people";
meta.authorList = Arrays.asList("LexManos", "Eloraam", "Spacetoad");
meta.description = "Minecraft Forge is a common open source API allowing a broad range of mods " +
"to work cooperatively together. It allows many mods to be created without " +
"them editing the main Minecraft code.";
meta.url = "http://MinecraftForge.net";
meta.updateUrl = "http://MinecraftForge.net/forum/index.php/topic,5.0.html";
meta.screenshots = new String[0];
meta.logoFile = "/forge_logo.png";
Configuration config = null;
File cfgFile = new File(Loader.instance().getConfigDir(), "forge.cfg");
try
{
config = new Configuration(cfgFile);
}
catch (Exception e)
{
System.out.println("Error loading forge.cfg, deleting file and resetting: ");
e.printStackTrace();
if (cfgFile.exists())
cfgFile.delete();
config = new Configuration(cfgFile);
}
if (!config.isChild)
{
config.load();
Property enableGlobalCfg = config.get(Configuration.CATEGORY_GENERAL, "enableGlobalConfig", false);
if (enableGlobalCfg.getBoolean(false))
{
Configuration.enableGlobalConfig();
}
}
Property prop;
prop = config.get(Configuration.CATEGORY_GENERAL, "clumpingThreshold", 64);
prop.comment = "Controls the number threshold at which Packet51 is preferred over Packet52, default and minimum 64, maximum 1024";
clumpingThreshold = prop.getInt(64);
if (clumpingThreshold > 1024 || clumpingThreshold < 64)
{
clumpingThreshold = 64;
prop.set(64);
}
prop = config.get(Configuration.CATEGORY_GENERAL, "legacyFurnaceOutput", false);
prop.comment = "Controls the sides of vanilla furnaces for Forge's ISidedInventroy, Vanilla defines the output as the bottom, but mods/Forge define it as the sides. Settings this to true will restore the old side relations.";
legacyFurnaceSides = prop.getBoolean(false);
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringEntities", false);
prop.comment = "Set this to just remove any TileEntity that throws a error in there update method instead of closing the server and reporting a crash log. BE WARNED THIS COULD SCREW UP EVERYTHING USE SPARINGLY WE ARE NOT RESPONSIBLE FOR DAMAGES.";
removeErroringEntities = prop.getBoolean(false);
if (removeErroringEntities)
{
FMLLog.warning("Enableing removal of erroring Entities USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringTileEntities", false);
prop.comment = "Set this to just remove any TileEntity that throws a error in there update method instead of closing the server and reporting a crash log. BE WARNED THIS COULD SCREW UP EVERYTHING USE SPARINGLY WE ARE NOT RESPONSIBLE FOR DAMAGES.";
removeErroringTileEntities = prop.getBoolean(false);
if (removeErroringTileEntities)
{
FMLLog.warning("Enableing removal of erroring Tile Entities USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
disableStitchedFileSaving = prop.getBoolean(true);
if (config.hasChanged())
{
config.save();
}
}
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
bus.register(this);
return true;
}
@Subscribe
public void modConstruction(FMLConstructionEvent evt)
{
FMLLog.info("Registering Forge Packet Handler");
try
{
FMLNetworkHandler.instance().registerNetworkMod(new ForgeNetworkHandler(this));
FMLLog.info("Succeeded registering Forge Packet Handler");
}
catch (Exception e)
{
FMLLog.log(Level.SEVERE, e, "Failed to register packet handler for Forge");
}
}
@Subscribe
public void preInit(FMLPreInitializationEvent evt)
{
ForgeChunkManager.captureConfig(evt.getModConfigurationDirectory());
}
@Subscribe
public void postInit(FMLPostInitializationEvent evt)
{
ForgeChunkManager.loadConfiguration();
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
NBTTagCompound forgeData = new NBTTagCompound();
NBTTagCompound dimData = DimensionManager.saveDimensionDataMap();
forgeData.setCompoundTag("DimensionData", dimData);
return forgeData;
}
@Override
public void readData(SaveHandler handler, WorldInfo info, Map<String, NBTBase> propertyMap, NBTTagCompound tag)
{
if (tag.hasKey("DimensionData"))
{
DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null);
}
}
}
@@ -1,401 +0,0 @@
package net.minecraftforge.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemAxe;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemSpade;
import net.minecraft.item.ItemStack;
import net.minecraft.network.NetServerHandler;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomItem;
import net.minecraft.world.World;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
public class ForgeHooks
{
static class GrassEntry extends WeightedRandomItem
{
public final Block block;
public final int metadata;
public GrassEntry(Block block, int meta, int weight)
{
super(weight);
this.block = block;
this.metadata = meta;
}
}
static class SeedEntry extends WeightedRandomItem
{
public final ItemStack seed;
public SeedEntry(ItemStack seed, int weight)
{
super(weight);
this.seed = seed;
}
}
static final List<GrassEntry> grassList = new ArrayList<GrassEntry>();
static final List<SeedEntry> seedList = new ArrayList<SeedEntry>();
public static void plantGrass(World world, int x, int y, int z)
{
GrassEntry grass = (GrassEntry)WeightedRandom.getRandomItem(world.rand, grassList);
if (grass == null || grass.block == null || !grass.block.canBlockStay(world, x, y, z))
{
return;
}
world.setBlock(x, y, z, grass.block.blockID, grass.metadata, 3);
}
public static ItemStack getGrassSeed(World world)
{
SeedEntry entry = (SeedEntry)WeightedRandom.getRandomItem(world.rand, seedList);
if (entry == null || entry.seed == null)
{
return null;
}
return entry.seed.copy();
}
private static boolean toolInit = false;
static HashMap<Item, List> toolClasses = new HashMap<Item, List>();
static HashMap<List, Integer> toolHarvestLevels = new HashMap<List, Integer>();
static HashSet<List> toolEffectiveness = new HashSet<List>();
public static boolean canHarvestBlock(Block block, EntityPlayer player, int metadata)
{
if (block.blockMaterial.isToolNotRequired())
{
return true;
}
ItemStack stack = player.inventory.getCurrentItem();
if (stack == null)
{
return player.canHarvestBlock(block);
}
List info = toolClasses.get(stack.getItem());
if (info == null)
{
return player.canHarvestBlock(block);
}
Object[] tmp = info.toArray();
String toolClass = (String)tmp[0];
int harvestLevel = (Integer)tmp[1];
Integer blockHarvestLevel = toolHarvestLevels.get(Arrays.asList(block, metadata, toolClass));
if (blockHarvestLevel == null)
{
return player.canHarvestBlock(block);
}
if (blockHarvestLevel > harvestLevel)
{
return false;
}
return true;
}
public static boolean canToolHarvestBlock(Block block, int metadata, ItemStack stack)
{
if (stack == null) return false;
List info = toolClasses.get(stack.getItem());
if (info == null) return false;
Object[] tmp = info.toArray();
String toolClass = (String)tmp[0];
int harvestLevel = (Integer)tmp[1];
Integer blockHarvestLevel = toolHarvestLevels.get(Arrays.asList(block, metadata, toolClass));
return !(blockHarvestLevel == null || blockHarvestLevel > harvestLevel);
}
public static float blockStrength(Block block, EntityPlayer player, World world, int x, int y, int z)
{
int metadata = world.getBlockMetadata(x, y, z);
float hardness = block.getBlockHardness(world, x, y, z);
if (hardness < 0.0F)
{
return 0.0F;
}
if (!canHarvestBlock(block, player, metadata))
{
float speed = ForgeEventFactory.getBreakSpeed(player, block, metadata, 1.0f);
return (speed < 0 ? 0 : speed) / hardness / 100F;
}
else
{
return player.getCurrentPlayerStrVsBlock(block, false, metadata) / hardness / 30F;
}
}
public static boolean isToolEffective(ItemStack stack, Block block, int metadata)
{
List toolClass = toolClasses.get(stack.getItem());
return toolClass != null && toolEffectiveness.contains(Arrays.asList(block, metadata, toolClass.get(0)));
}
static void initTools()
{
if (toolInit)
{
return;
}
toolInit = true;
MinecraftForge.setToolClass(Item.pickaxeWood, "pickaxe", 0);
MinecraftForge.setToolClass(Item.pickaxeStone, "pickaxe", 1);
MinecraftForge.setToolClass(Item.pickaxeIron, "pickaxe", 2);
MinecraftForge.setToolClass(Item.pickaxeGold, "pickaxe", 0);
MinecraftForge.setToolClass(Item.pickaxeDiamond, "pickaxe", 3);
MinecraftForge.setToolClass(Item.axeWood, "axe", 0);
MinecraftForge.setToolClass(Item.axeStone, "axe", 1);
MinecraftForge.setToolClass(Item.axeIron, "axe", 2);
MinecraftForge.setToolClass(Item.axeGold, "axe", 0);
MinecraftForge.setToolClass(Item.axeDiamond, "axe", 3);
MinecraftForge.setToolClass(Item.shovelWood, "shovel", 0);
MinecraftForge.setToolClass(Item.shovelStone, "shovel", 1);
MinecraftForge.setToolClass(Item.shovelIron, "shovel", 2);
MinecraftForge.setToolClass(Item.shovelGold, "shovel", 0);
MinecraftForge.setToolClass(Item.shovelDiamond, "shovel", 3);
for (Block block : ItemPickaxe.blocksEffectiveAgainst)
{
MinecraftForge.setBlockHarvestLevel(block, "pickaxe", 0);
}
for (Block block : ItemSpade.blocksEffectiveAgainst)
{
MinecraftForge.setBlockHarvestLevel(block, "shovel", 0);
}
for (Block block : ItemAxe.blocksEffectiveAgainst)
{
MinecraftForge.setBlockHarvestLevel(block, "axe", 0);
}
MinecraftForge.setBlockHarvestLevel(Block.obsidian, "pickaxe", 3);
MinecraftForge.setBlockHarvestLevel(Block.oreEmerald, "pickaxe", 2);
MinecraftForge.setBlockHarvestLevel(Block.oreDiamond, "pickaxe", 2);
MinecraftForge.setBlockHarvestLevel(Block.blockDiamond, "pickaxe", 2);
MinecraftForge.setBlockHarvestLevel(Block.oreGold, "pickaxe", 2);
MinecraftForge.setBlockHarvestLevel(Block.blockGold, "pickaxe", 2);
MinecraftForge.setBlockHarvestLevel(Block.oreIron, "pickaxe", 1);
MinecraftForge.setBlockHarvestLevel(Block.blockIron, "pickaxe", 1);
MinecraftForge.setBlockHarvestLevel(Block.oreLapis, "pickaxe", 1);
MinecraftForge.setBlockHarvestLevel(Block.blockLapis, "pickaxe", 1);
MinecraftForge.setBlockHarvestLevel(Block.oreRedstone, "pickaxe", 2);
MinecraftForge.setBlockHarvestLevel(Block.oreRedstoneGlowing, "pickaxe", 2);
MinecraftForge.removeBlockEffectiveness(Block.oreRedstone, "pickaxe");
MinecraftForge.removeBlockEffectiveness(Block.obsidian, "pickaxe");
MinecraftForge.removeBlockEffectiveness(Block.oreRedstoneGlowing, "pickaxe");
}
public static int getTotalArmorValue(EntityPlayer player)
{
int ret = 0;
for (int x = 0; x < player.inventory.armorInventory.length; x++)
{
ItemStack stack = player.inventory.armorInventory[x];
if (stack != null && stack.getItem() instanceof ISpecialArmor)
{
ret += ((ISpecialArmor)stack.getItem()).getArmorDisplay(player, stack, x);
}
else if (stack != null && stack.getItem() instanceof ItemArmor)
{
ret += ((ItemArmor)stack.getItem()).damageReduceAmount;
}
}
return ret;
}
static
{
grassList.add(new GrassEntry(Block.plantYellow, 0, 20));
grassList.add(new GrassEntry(Block.plantRed, 0, 10));
seedList.add(new SeedEntry(new ItemStack(Item.seeds), 10));
initTools();
}
/**
* Called when a player uses 'pick block', calls new Entity and Block hooks.
*/
public static boolean onPickBlock(MovingObjectPosition target, EntityPlayer player, World world)
{
ItemStack result = null;
boolean isCreative = player.capabilities.isCreativeMode;
if (target.typeOfHit == EnumMovingObjectType.TILE)
{
int x = target.blockX;
int y = target.blockY;
int z = target.blockZ;
Block var8 = Block.blocksList[world.getBlockId(x, y, z)];
if (var8 == null)
{
return false;
}
result = var8.getPickBlock(target, world, x, y, z);
}
else
{
if (target.typeOfHit != EnumMovingObjectType.ENTITY || target.entityHit == null || !isCreative)
{
return false;
}
result = target.entityHit.getPickedResult(target);
}
if (result == null)
{
return false;
}
for (int x = 0; x < 9; x++)
{
ItemStack stack = player.inventory.getStackInSlot(x);
if (stack != null && stack.isItemEqual(result) && ItemStack.areItemStackTagsEqual(stack, result))
{
player.inventory.currentItem = x;
return true;
}
}
if (!isCreative)
{
return false;
}
int slot = player.inventory.getFirstEmptyStack();
if (slot < 0 || slot >= 9)
{
slot = player.inventory.currentItem;
}
player.inventory.setInventorySlotContents(slot, result);
player.inventory.currentItem = slot;
return true;
}
//Optifine Helper Functions u.u, these are here specifically for Optifine
//Note: When using Optfine, these methods are invoked using reflection, which
//incurs a major performance penalty.
public static void onLivingSetAttackTarget(EntityLivingBase entity, EntityLivingBase target)
{
MinecraftForge.EVENT_BUS.post(new LivingSetAttackTargetEvent(entity, target));
}
public static boolean onLivingUpdate(EntityLivingBase entity)
{
return MinecraftForge.EVENT_BUS.post(new LivingUpdateEvent(entity));
}
public static boolean onLivingAttack(EntityLivingBase entity, DamageSource src, float amount)
{
return MinecraftForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, amount));
}
public static float onLivingHurt(EntityLivingBase entity, DamageSource src, float amount)
{
LivingHurtEvent event = new LivingHurtEvent(entity, src, amount);
return (MinecraftForge.EVENT_BUS.post(event) ? 0 : event.ammount);
}
public static boolean onLivingDeath(EntityLivingBase entity, DamageSource src)
{
return MinecraftForge.EVENT_BUS.post(new LivingDeathEvent(entity, src));
}
public static boolean onLivingDrops(EntityLivingBase entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
{
return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit, specialDropValue));
}
public static float onLivingFall(EntityLivingBase entity, float distance)
{
LivingFallEvent event = new LivingFallEvent(entity, distance);
return (MinecraftForge.EVENT_BUS.post(event) ? 0.0f : event.distance);
}
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z, EntityLivingBase entity)
{
return block != null && block.isLadder(world, x, y, z, entity);
}
public static void onLivingJump(EntityLivingBase entity)
{
MinecraftForge.EVENT_BUS.post(new LivingJumpEvent(entity));
}
public static EntityItem onPlayerTossEvent(EntityPlayer player, ItemStack item)
{
player.captureDrops = true;
EntityItem ret = player.dropPlayerItemWithRandomChoice(item, false);
player.capturedDrops.clear();
player.captureDrops = false;
ItemTossEvent event = new ItemTossEvent(ret, player);
if (MinecraftForge.EVENT_BUS.post(event))
{
return null;
}
player.joinEntityItemWithWorld(event.entityItem);
return event.entityItem;
}
public static float getEnchantPower(World world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z))
{
return 0;
}
Block block = Block.blocksList[world.getBlockId(x, y, z)];
return (block == null ? 0 : block.getEnchantPowerBonus(world, x, y, z));
}
public static ChatMessageComponent onServerChatEvent(NetServerHandler net, String raw, ChatMessageComponent comp)
{
ServerChatEvent event = new ServerChatEvent(net.playerEntity, raw, comp);
if (MinecraftForge.EVENT_BUS.post(event))
{
return null;
}
return event.component;
}
}
@@ -1,78 +0,0 @@
package net.minecraftforge.common;
import java.util.UUID;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.event.*;
import net.minecraftforge.event.entity.*;
import net.minecraftforge.event.world.WorldEvent;
public class ForgeInternalHandler
{
@ForgeSubscribe(priority = EventPriority.HIGHEST)
public void onEntityJoinWorld(EntityJoinWorldEvent event)
{
if (!event.world.isRemote)
{
ForgeChunkManager.loadEntity(event.entity);
}
Entity entity = event.entity;
if (entity.getClass().equals(EntityItem.class))
{
ItemStack stack = entity.getDataWatcher().getWatchableObjectItemStack(10);
if (stack == null)
{
//entity.setDead();
//event.setCanceled(true);
return;
}
Item item = stack.getItem();
if (item == null)
{
FMLLog.warning("Attempted to add a EntityItem to the world with a invalid item: ID %d at " +
"(%2.2f, %2.2f, %2.2f), this is most likely a config issue between you and the server. Please double check your configs",
stack.itemID, entity.posX, entity.posY, entity.posZ);
entity.setDead();
event.setCanceled(true);
return;
}
if (item.hasCustomEntity(stack))
{
Entity newEntity = item.createEntity(event.world, entity, stack);
if (newEntity != null)
{
entity.setDead();
event.setCanceled(true);
event.world.spawnEntityInWorld(newEntity);
}
}
}
}
@ForgeSubscribe(priority = EventPriority.HIGHEST)
public void onDimensionLoad(WorldEvent.Load event)
{
ForgeChunkManager.loadWorld(event.world);
}
@ForgeSubscribe(priority = EventPriority.HIGHEST)
public void onDimensionSave(WorldEvent.Save event)
{
ForgeChunkManager.saveWorld(event.world);
}
@ForgeSubscribe(priority = EventPriority.HIGHEST)
public void onDimensionUnload(WorldEvent.Unload event)
{
ForgeChunkManager.unloadWorld(event.world);
}
}
@@ -1,44 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
public class ForgeVersion
{
//This number is incremented every time we remove deprecated code/major API changes, never reset
public static final int majorVersion = 8;
//This number is incremented every minecraft release, never reset
public static final int minorVersion = 9;
//This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version
public static final int revisionVersion = 0;
//This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code.
public static final int buildVersion = 0;
public static int getMajorVersion()
{
return majorVersion;
}
public static int getMinorVersion()
{
return minorVersion;
}
public static int getRevisionVersion()
{
return revisionVersion;
}
public static int getBuildVersion()
{
return buildVersion;
}
public static String getVersion()
{
return String.format("%d.%d.%d.%d", majorVersion, minorVersion, revisionVersion, buildVersion);
}
}
@@ -1,37 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
/**
* Allows for custom entity data and logic to be hooked to existing entity classes.
*
* @author cpw, mithion
*
*/
public interface IExtendedEntityProperties {
/**
* Called when the entity that this class is attached to is saved.
* Any custom entity data that needs saving should be saved here.
* @param compound The compound to save to.
*/
public void saveNBTData(NBTTagCompound compound);
/**
* Called when the entity that this class is attached to is loaded.
* In order to hook into this, you will need to subscribe to the EntityConstructing event.
* Otherwise, you will need to initialize manually.
* @param compound The compound to load from.
*/
public void loadNBTData(NBTTagCompound compound);
/**
* Used to initialize the extended properties with the entity that this is attached to, as well
* as the world object.
* Called automatically if you register with the EntityConstructing event.
* @param entity The entity that this extended properties is attached to
* @param world The world in which the entity exists
*/
public void init(Entity entity, World world);
}
@@ -1,50 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityMinecart;
/**
* This class defines a replacement for the default minecart collision code.
* Only one handler can be registered at a time. It it registered with EntityMinecart.registerCollisionHandler().
* If you use this, make it a configuration option.
* @author CovertJaguar
*/
public interface IMinecartCollisionHandler
{
/**
* This basically replaces the function of the same name in EnityMinecart.
* Code in IMinecartHooks.applyEntityCollisionHook is still run.
* @param cart The cart that called the collision.
* @param other The object it collided with.
*/
public void onEntityCollision(EntityMinecart cart, Entity other);
/**
* This function replaced the function of the same name in EntityMinecart.
* It is used to define whether minecarts collide with specific entities,
* for example items.
* @param cart The cart for which the collision box was requested.
* @param other The entity requesting the collision box.
* @return The collision box or null.
*/
public AxisAlignedBB getCollisionBox(EntityMinecart cart, Entity other);
/**
* This function is used to define the box used for detecting minecart collisions.
* It is generally bigger that the normal collision box.
* @param cart The cart for which the collision box was requested.
* @return The collision box, cannot be null.
*/
public AxisAlignedBB getMinecartCollisionBox(EntityMinecart cart);
/**
* This function replaces the function of the same name in EntityMinecart.
* It defines whether minecarts are solid to the player.
* @param cart The cart for which the bounding box was requested.
* @return The bounding box or null.
*/
public AxisAlignedBB getBoundingBox(EntityMinecart cart);
}
@@ -1,10 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.world.World;
public interface IPlantable
{
public EnumPlantType getPlantType(World world, int x, int y, int z);
public int getPlantID(World world, int x, int y, int z);
public int getPlantMetadata(World world, int x, int y, int z);
}
@@ -1,53 +0,0 @@
package net.minecraftforge.common;
import java.util.ArrayList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
/**
*
* This allows for mods to create there own Shear-like items
* and have them interact with Blocks/Entities without extra work.
* Also, if your block/entity supports the Shears, this allows you
* to support mod-shears as well.
*
*/
public interface IShearable
{
/**
* Checks if the object is currently shearable
* Example: Sheep return false when they have no wool
*
* @param item The itemstack that is being used, Possible to be null
* @param world The current world
* @param x The X Position
* @param y The Y Position
* @param z The Z Position
* @return If this is shearable, and onSheared should be called.
*/
public boolean isShearable(ItemStack item, World world, int x, int y, int z);
/**
* Performs the shear function on this object.
* This is called for both client, and server.
* The object should perform all actions related to being sheared,
* except for dropping of the items.
*
* Returns a list of items that resulted from the shearing process.
*
* For entities, they should trust there internal location information
* over the values passed into this function.
*
* @param item The itemstack that is being used, Possible to be null
* @param world The current world
* @param x The X Position
* @param y The Y Position
* @param z The Z Position
* @param fortune The fortune level of the shears being used
* @return A ArrayList containing all items from this shearing. Possible to be null.
*/
public ArrayList<ItemStack> onSheared(ItemStack item, World world, int x, int y, int z, int fortune);
}
@@ -1,31 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import net.minecraft.inventory.IInventory;
/** Inventory ranges mapped by side. This class is implemented by TileEntities
* that provide different inventory slot ranges to different sides.
*/
@Deprecated //A equivalent Interface is now in Minecraft Vanilla will be removed next major MC version
public interface ISidedInventory extends IInventory
{
/**
* Get the start of the side inventory.
* @param side The global side to get the start of range.
*/
@Deprecated
int getStartInventorySide(ForgeDirection side);
/**
* Get the size of the side inventory.
* @param side The global side.
*/
@Deprecated
int getSizeInventorySide(ForgeDirection side);
}
@@ -1,317 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import java.util.ArrayList;
import java.util.Arrays;
import net.minecraft.util.DamageSource;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
/**
* This interface is to be implemented by ItemArmor classes. It will allow to
* modify computation of damage and health loss. Computation will be called
* before the actual armor computation, which can then be cancelled.
*
* @see ItemArmor
*/
public interface ISpecialArmor
{
/**
* Retrieves the modifiers to be used when calculating armor damage.
*
* Armor will higher priority will have damage applied to them before
* lower priority ones. If there are multiple pieces of armor with the
* same priority, damage will be distributed between them based on there
* absorption ratio.
*
* @param player The entity wearing the armor.
* @param armor The ItemStack of the armor item itself.
* @param source The source of the damage, which can be used to alter armor
* properties based on the type or source of damage.
* @param damage The total damage being applied to the entity
* @param slot The armor slot the item is in.
* @return A ArmorProperties instance holding information about how the armor effects damage.
*/
public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot);
/**
* Get the displayed effective armor.
*
* @param player The player wearing the armor.
* @param armor The ItemStack of the armor item itself.
* @param slot The armor slot the item is in.
* @return The number of armor points for display, 2 per shield.
*/
public abstract int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot);
/**
* Applies damage to the ItemStack. The mod is responsible for reducing the
* item durability and stack size. If the stack is depleted it will be cleaned
* up automatically.
*
* @param entity The entity wearing the armor
* @param stack The ItemStack of the armor item itself.
* @param source The source of the damage, which can be used to alter armor
* properties based on the type or source of damage.
* @param damage The amount of damage being applied to the armor
* @param slot The armor slot the item is in.
*/
public abstract void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot);
public static class ArmorProperties implements Comparable<ArmorProperties>
{
public int Priority = 0;
public int AbsorbMax = Integer.MAX_VALUE;
public double AbsorbRatio = 0;
public int Slot = 0;
private static final boolean DEBUG = false; //Only enable this if you wish to be spamed with debugging information.
//Left it in because I figured it'd be useful for modders developing custom armor.
public ArmorProperties(int priority, double ratio, int max)
{
Priority = priority;
AbsorbRatio = ratio;
AbsorbMax = max;
}
/**
* Gathers and applies armor reduction to damage being dealt to a entity.
*
* @param entity The Entity being damage
* @param inventory An array of armor items
* @param source The damage source type
* @param damage The total damage being done
* @return The left over damage that has not been absorbed by the armor
*/
public static float ApplyArmor(EntityLivingBase entity, ItemStack[] inventory, DamageSource source, double damage)
{
if (DEBUG)
{
System.out.println("Start: " + damage + " " + (damage * 25));
}
damage *= 25;
ArrayList<ArmorProperties> dmgVals = new ArrayList<ArmorProperties>();
for (int x = 0; x < inventory.length; x++)
{
ItemStack stack = inventory[x];
if (stack == null)
{
continue;
}
ArmorProperties prop = null;
if (stack.getItem() instanceof ISpecialArmor)
{
ISpecialArmor armor = (ISpecialArmor)stack.getItem();
prop = armor.getProperties(entity, stack, source, damage / 25D, x).copy();
}
else if (stack.getItem() instanceof ItemArmor && !source.isUnblockable())
{
ItemArmor armor = (ItemArmor)stack.getItem();
prop = new ArmorProperties(0, armor.damageReduceAmount / 25D, armor.getMaxDamage() + 1 - stack.getItemDamage());
}
if (prop != null)
{
prop.Slot = x;
dmgVals.add(prop);
}
}
if (dmgVals.size() > 0)
{
ArmorProperties[] props = dmgVals.toArray(new ArmorProperties[dmgVals.size()]);
StandardizeList(props, damage);
int level = props[0].Priority;
double ratio = 0;
for (ArmorProperties prop : props)
{
if (level != prop.Priority)
{
damage -= (damage * ratio);
ratio = 0;
level = prop.Priority;
}
ratio += prop.AbsorbRatio;
double absorb = damage * prop.AbsorbRatio;
if (absorb > 0)
{
ItemStack stack = inventory[prop.Slot];
int itemDamage = (int)(absorb / 25D < 1 ? 1 : absorb / 25D);
if (stack.getItem() instanceof ISpecialArmor)
{
((ISpecialArmor)stack.getItem()).damageArmor(entity, stack, source, itemDamage, prop.Slot);
}
else
{
if (DEBUG)
{
System.out.println("Item: " + stack.toString() + " Absorbed: " + (absorb / 25D) + " Damaged: " + itemDamage);
}
stack.damageItem(itemDamage, entity);
}
if (stack.stackSize <= 0)
{
/*if (entity instanceof EntityPlayer)
{
stack.onItemDestroyedByUse((EntityPlayer)entity);
}*/
inventory[prop.Slot] = null;
}
}
}
damage -= (damage * ratio);
}
if (DEBUG)
{
System.out.println("Return: " + (int)(damage / 25.0F) + " " + damage);
}
return (float)(damage / 25.0F);
}
/**
* Sorts and standardizes the distribution of damage over armor.
*
* @param armor The armor information
* @param damage The total damage being received
*/
private static void StandardizeList(ArmorProperties[] armor, double damage)
{
Arrays.sort(armor);
int start = 0;
double total = 0;
int priority = armor[0].Priority;
int pStart = 0;
boolean pChange = false;
boolean pFinished = false;
if (DEBUG)
{
for (ArmorProperties prop : armor)
{
System.out.println(prop);
}
System.out.println("========================");
}
for (int x = 0; x < armor.length; x++)
{
total += armor[x].AbsorbRatio;
if (x == armor.length - 1 || armor[x].Priority != priority)
{
if (armor[x].Priority != priority)
{
total -= armor[x].AbsorbRatio;
x--;
pChange = true;
}
if (total > 1)
{
for (int y = start; y <= x; y++)
{
double newRatio = armor[y].AbsorbRatio / total;
if (newRatio * damage > armor[y].AbsorbMax)
{
armor[y].AbsorbRatio = (double)armor[y].AbsorbMax / damage;
total = 0;
for (int z = pStart; z <= y; z++)
{
total += armor[z].AbsorbRatio;
}
start = y + 1;
x = y;
break;
}
else
{
armor[y].AbsorbRatio = newRatio;
pFinished = true;
}
}
if (pChange && pFinished)
{
damage -= (damage * total);
total = 0;
start = x + 1;
priority = armor[start].Priority;
pStart = start;
pChange = false;
pFinished = false;
if (damage <= 0)
{
for (int y = x + 1; y < armor.length; y++)
{
armor[y].AbsorbRatio = 0;
}
break;
}
}
}
else
{
for (int y = start; y <= x; y++)
{
total -= armor[y].AbsorbRatio;
if (damage * armor[y].AbsorbRatio > armor[y].AbsorbMax)
{
armor[y].AbsorbRatio = (double)armor[y].AbsorbMax / damage;
}
total += armor[y].AbsorbRatio;
}
damage -= (damage * total);
total = 0;
if (x != armor.length - 1)
{
start = x + 1;
priority = armor[start].Priority;
pStart = start;
pChange = false;
if (damage <= 0)
{
for (int y = x + 1; y < armor.length; y++)
{
armor[y].AbsorbRatio = 0;
}
break;
}
}
}
}
}
if (DEBUG)
{
for (ArmorProperties prop : armor)
{
System.out.println(prop);
}
}
}
public int compareTo(ArmorProperties o)
{
if (o.Priority != Priority)
{
return o.Priority - Priority;
}
double left = ( AbsorbRatio == 0 ? 0 : AbsorbMax * 100.0D / AbsorbRatio);
double right = (o.AbsorbRatio == 0 ? 0 : o.AbsorbMax * 100.0D / o.AbsorbRatio);
return (int)(left - right);
}
public String toString()
{
return String.format("%d, %d, %f, %d", Priority, AbsorbMax, AbsorbRatio, (AbsorbRatio == 0 ? 0 : (int)(AbsorbMax * 100.0D / AbsorbRatio)));
}
public ArmorProperties copy()
{
return new ArmorProperties(Priority, AbsorbRatio, AbsorbMax);
}
}
}
@@ -1,220 +0,0 @@
package net.minecraftforge.common;
import java.lang.reflect.Constructor;
import java.util.*;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.crash.CrashReport;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeHooks.GrassEntry;
import net.minecraftforge.common.ForgeHooks.SeedEntry;
import net.minecraftforge.event.EventBus;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.EntityEvent;
import net.minecraftforge.oredict.OreDictionary;
public class MinecraftForge
{
/**
* The core Forge EventBusses, all events for Forge will be fired on these,
* you should use this to register all your listeners.
* This replaces every register*Handler() function in the old version of Forge.
* TERRAIN_GEN_BUS for terrain gen events
* ORE_GEN_BUS for ore gen events
* EVENT_BUS for everything else
*/
public static final EventBus EVENT_BUS = new EventBus();
public static final EventBus TERRAIN_GEN_BUS = new EventBus();
public static final EventBus ORE_GEN_BUS = new EventBus();
private static final ForgeInternalHandler INTERNAL_HANDLER = new ForgeInternalHandler();
/** Register a new plant to be planted when bonemeal is used on grass.
* @param block The block to place.
* @param metadata The metadata to set for the block when being placed.
* @param weight The weight of the plant, where red flowers are
* 10 and yellow flowers are 20.
*/
public static void addGrassPlant(Block block, int metadata, int weight)
{
ForgeHooks.grassList.add(new GrassEntry(block, metadata, weight));
}
/**
* Register a new seed to be dropped when breaking tall grass.
*
* @param seed The item to drop as a seed.
* @param weight The relative probability of the seeds,
* where wheat seeds are 10.
*/
public static void addGrassSeed(ItemStack seed, int weight)
{
ForgeHooks.seedList.add(new SeedEntry(seed, weight));
}
/**
*
* Register a tool as a tool class with a given harvest level.
*
* @param tool The custom tool to register.
* @param toolClass The tool class to register as. The predefined tool
* clases are "pickaxe", "shovel", "axe". You can add
* others for custom tools.
* @param harvestLevel The harvest level of the tool.
*/
public static void setToolClass(Item tool, String toolClass, int harvestLevel)
{
ForgeHooks.toolClasses.put(tool, Arrays.asList(toolClass, harvestLevel));
}
/**
* Register a block to be harvested by a tool class. This is the metadata
* sensitive version, use it if your blocks are using metadata variants.
* By default, this sets the block class as effective against that type.
*
* @param block The block to register.
* @param metadata The metadata for the block subtype.
* @param toolClass The tool class to register as able to remove this block.
* You may register the same block multiple times with different tool
* classes, if multiple tool types can be used to harvest this block.
* @param harvestLevel The minimum tool harvest level required to successfully
* harvest the block.
* @see MinecraftForge#setToolClass for details on tool classes.
*/
public static void setBlockHarvestLevel(Block block, int metadata, String toolClass, int harvestLevel)
{
List key = Arrays.asList(block, metadata, toolClass);
ForgeHooks.toolHarvestLevels.put(key, harvestLevel);
ForgeHooks.toolEffectiveness.add(key);
}
/**
* Remove a block effectiveness mapping. Since setBlockHarvestLevel
* makes the tool class effective against the block by default, this can be
* used to remove that mapping. This will force a block to be harvested at
* the same speed regardless of tool quality, while still requiring a given
* harvesting level.
*
* @param block The block to remove effectiveness from.
* @param metadata The metadata for the block subtype.
* @param toolClass The tool class to remove the effectiveness mapping from.
* @see MinecraftForge#setToolClass for details on tool classes.
*/
public static void removeBlockEffectiveness(Block block, int metadata, String toolClass)
{
List key = Arrays.asList(block, metadata, toolClass);
ForgeHooks.toolEffectiveness.remove(key);
}
/**
* Register a block to be harvested by a tool class.
* By default, this sets the block class as effective against that type.
*
* @param block The block to register.
* @param toolClass The tool class to register as able to remove this block.
* You may register the same block multiple times with different tool
* classes, if multiple tool types can be used to harvest this block.
* @param harvestLevel The minimum tool harvest level required to successfully
* harvest the block.
* @see MinecraftForge#setToolClass for details on tool classes.
*/
public static void setBlockHarvestLevel(Block block, String toolClass, int harvestLevel)
{
for (int metadata = 0; metadata < 16; metadata++)
{
List key = Arrays.asList(block, metadata, toolClass);
ForgeHooks.toolHarvestLevels.put(key, harvestLevel);
ForgeHooks.toolEffectiveness.add(key);
}
}
/**
* Returns the block harvest level for a particular tool class.
*
* @param block The block to check.
* @param metadata The metadata for the block subtype.
* @param toolClass The tool class to check as able to remove this block.
* @see MinecraftForge#setToolClass for details on tool classes.
* @return The harvest level or -1 if no mapping exists.
*/
public static int getBlockHarvestLevel(Block block, int metadata, String toolClass)
{
ForgeHooks.initTools();
List key = Arrays.asList(block, metadata, toolClass);
Integer harvestLevel = ForgeHooks.toolHarvestLevels.get(key);
return (harvestLevel == null ? -1 : harvestLevel);
}
/**
* Remove a block effectiveness mapping. Since setBlockHarvestLevel
* makes the tool class effective against the block by default, this can be
* used to remove that mapping. This will force a block to be harvested at
* the same speed regardless of tool quality, while still requiring a given
* harvesting level.
*
* @param block The block to remove effectiveness from.
* @param toolClass The tool class to remove the effectiveness mapping from.
* @see MinecraftForge#setToolClass for details on tool classes.
*/
public static void removeBlockEffectiveness(Block block, String toolClass)
{
for (int metadata = 0; metadata < 16; metadata++)
{
List key = Arrays.asList(block, metadata, toolClass);
ForgeHooks.toolEffectiveness.remove(key);
}
}
/**
* Method invoked by FML before any other mods are loaded.
*/
public static void initialize()
{
System.out.printf("MinecraftForge v%s Initialized\n", ForgeVersion.getVersion());
FMLLog.info("MinecraftForge v%s Initialized", ForgeVersion.getVersion());
Block filler = new Block(0, Material.air)
{
@SideOnly(Side.CLIENT) public void func_94332_a(IconRegister register){}
};
Block.blocksList[0] = null;
Block.opaqueCubeLookup[0] = false;
Block.lightOpacity[0] = 0;
filler.setUnlocalizedName("ForgeFiller");
for (int x = 256; x < 4096; x++)
{
if (Item.itemsList[x] != null)
{
Block.blocksList[x] = filler;
}
}
boolean[] temp = new boolean[4096];
System.arraycopy(EntityEnderman.carriableBlocks, 0, temp, 0, EntityEnderman.carriableBlocks.length);
EntityEnderman.carriableBlocks = temp;
EVENT_BUS.register(INTERNAL_HANDLER);
OreDictionary.getOreName(0);
//Force these classes to be defined, Should prevent derp error hiding.
new CrashReport("ThisIsFake", new Exception("Not real"));
}
public static String getBrandingVersion()
{
return "Minecraft Forge "+ ForgeVersion.getVersion();
}
}
@@ -1,409 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import java.util.ArrayList;
import net.minecraftforge.common.Property.Type;
public class Property
{
public enum Type
{
STRING,
INTEGER,
BOOLEAN,
DOUBLE;
private static Type[] values = {STRING, INTEGER, BOOLEAN, DOUBLE};
public static Type tryParse(char id)
{
for (int x = 0; x < values.length; x++)
{
if (values[x].getID() == id)
{
return values[x];
}
}
return STRING;
}
public char getID()
{
return name().charAt(0);
}
}
private String name;
private String value;
public String comment;
private String[] values;
private final boolean wasRead;
private final boolean isList;
private final Type type;
private boolean changed = false;
public Property()
{
wasRead = false;
type = null;
isList = false;
}
public Property(String name, String value, Type type)
{
this(name, value, type, false);
}
Property(String name, String value, Type type, boolean read)
{
setName(name);
this.value = value;
this.type = type;
wasRead = read;
isList = false;
}
public Property(String name, String[] values, Type type)
{
this(name, values, type, false);
}
Property(String name, String[] values, Type type, boolean read)
{
setName(name);
this.type = type;
this.values = values;
wasRead = read;
isList = true;
}
/**
* Returns the value in this property as it's raw string.
*
* @return current value
*/
public String getString()
{
return value;
}
/**
* Returns the value in this property as an integer,
* if the value is not a valid integer, it will return -1.
*
* @return The value
*/
public int getInt()
{
return getInt(-1);
}
/**
* Returns the value in this property as an integer,
* if the value is not a valid integer, it will return the
* provided default.
*
* @param _default The default to provide if the current value is not a valid integer
* @return The value
*/
public int getInt(int _default)
{
try
{
return Integer.parseInt(value);
}
catch (NumberFormatException e)
{
return _default;
}
}
/**
* Checks if the current value stored in this property can be converted to an integer.
* @return True if the type of the Property is an Integer
*/
public boolean isIntValue()
{
try
{
Integer.parseInt(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
/**
* Returns the value in this property as a boolean,
* if the value is not a valid boolean, it will return the
* provided default.
*
* @param _default The default to provide
* @return The value as a boolean, or the default
*/
public boolean getBoolean(boolean _default)
{
if (isBooleanValue())
{
return Boolean.parseBoolean(value);
}
else
{
return _default;
}
}
/**
* Checks if the current value held by this property is a valid boolean value.
* @return True if it is a boolean value
*/
public boolean isBooleanValue()
{
return ("true".equals(value.toLowerCase()) || "false".equals(value.toLowerCase()));
}
/**
* Checks if the current value held by this property is a valid double value.
* @return True if the value can be converted to an double
*/
public boolean isDoubleValue()
{
try
{
Double.parseDouble(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
/**
* Returns the value in this property as a double,
* if the value is not a valid double, it will return the
* provided default.
*
* @param _default The default to provide if the current value is not a valid double
* @return The value
*/
public double getDouble(double _default)
{
try
{
return Double.parseDouble(value);
}
catch (NumberFormatException e)
{
return _default;
}
}
public String[] getStringList()
{
return values;
}
/**
* Returns the integer value of all values that can
* be parsed in the list.
*
* @return Array of length 0 if none of the values could be parsed.
*/
public int[] getIntList()
{
ArrayList<Integer> nums = new ArrayList<Integer>();
for (String value : values)
{
try
{
nums.add(Integer.parseInt(value));
}
catch (NumberFormatException e){}
}
int[] primitives = new int[nums.size()];
for (int i = 0; i < nums.size(); i++)
{
primitives[i] = nums.get(i);
}
return primitives;
}
/**
* Checks if all of the current values stored in this property can be converted to an integer.
* @return True if the type of the Property is an Integer List
*/
public boolean isIntList()
{
for (String value : values)
{
try
{
Integer.parseInt(value);
}
catch (NumberFormatException e)
{
return false;
}
}
return true;
}
/**
* Returns the boolean value of all values that can
* be parsed in the list.
*
* @return Array of length 0 if none of the values could be parsed.
*/
public boolean[] getBooleanList()
{
ArrayList<Boolean> tmp = new ArrayList<Boolean>();
for (String value : values)
{
try
{
tmp.add(Boolean.parseBoolean(value));
}
catch (NumberFormatException e){}
}
boolean[] primitives = new boolean[tmp.size()];
for (int i = 0; i < tmp.size(); i++)
{
primitives[i] = tmp.get(i);
}
return primitives;
}
/**
* Checks if all of current values stored in this property can be converted to a boolean.
* @return True if it is a boolean value
*/
public boolean isBooleanList()
{
for (String value : values)
{
if (!"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value))
{
return false;
}
}
return true;
}
/**
* Returns the double value of all values that can
* be parsed in the list.
*
* @return Array of length 0 if none of the values could be parsed.
*/
public double[] getDoubleList()
{
ArrayList<Double> tmp = new ArrayList<Double>();
for (String value : values)
{
try
{
tmp.add(Double.parseDouble(value));
}
catch (NumberFormatException e) {}
}
double[] primitives = new double[tmp.size()];
for (int i = 0; i < tmp.size(); i++)
{
primitives[i] = tmp.get(i);
}
return primitives;
}
/**
* Checks if all of the current values stored in this property can be converted to a double.
* @return True if the type of the Property is a double List
*/
public boolean isDoubleList()
{
for (String value : values)
{
try
{
Double.parseDouble(value);
}
catch (NumberFormatException e)
{
return false;
}
}
return true;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
/**
* Determines if this config value was just created, or if it was read from the config file.
* This is useful for mods who auto-assign there blocks to determine if the ID returned is
* a configured one, or a automatically generated one.
*
* @return True if this property was loaded from the config file with a value
*/
public boolean wasRead()
{
return wasRead;
}
public Type getType()
{
return type;
}
public boolean isList()
{
return isList;
}
public boolean hasChanged(){ return changed; }
void resetChangedState(){ changed = false; }
public void set(String value)
{
this.value = value;
changed = true;
}
public void set(String[] values)
{
this.values = values;
changed = true;
}
public void set(int value){ set(Integer.toString(value)); }
public void set(boolean value){ set(Boolean.toString(value)); }
public void set(double value){ set(Double.toString(value)); }
}
@@ -1,47 +0,0 @@
package net.minecraftforge.common;
import net.minecraft.block.Block;
import net.minecraft.block.BlockChest;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.BlockDropper;
import net.minecraft.block.BlockPistonBase;
import net.minecraft.world.World;
import static net.minecraftforge.common.ForgeDirection.*;
public class RotationHelper {
private static final ForgeDirection[] UP_DOWN_AXES = new ForgeDirection[] { UP, DOWN };
public static ForgeDirection[] getValidVanillaBlockRotations(Block block)
{
return block instanceof BlockChest ? UP_DOWN_AXES : VALID_DIRECTIONS;
}
public static boolean rotateVanillaBlock(Block block, World worldObj, int x, int y, int z, ForgeDirection axis)
{
if (worldObj.isRemote)
{
return false;
}
if (block instanceof BlockChest && (axis == UP || axis == DOWN))
{
return rotateBlock(worldObj, x, y, z, axis, 0x7);
}
if (block instanceof BlockPistonBase || block instanceof BlockDropper || block instanceof BlockDispenser)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7);
}
return false;
}
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask)
{
int rotMeta = worldObj.getBlockMetadata(x, y, z);
int masked = rotMeta & ~mask;
ForgeDirection orientation = ForgeDirection.getOrientation(rotMeta & mask);
ForgeDirection rotated = orientation.getRotation(axis);
worldObj.setBlockMetadataWithNotify(x,y,z,rotated.ordinal() & mask | masked,3);
return true;
}
}
@@ -1,44 +0,0 @@
package net.minecraftforge.common;
import java.io.File;
import net.minecraft.world.chunk.storage.IChunkLoader;
import net.minecraft.world.storage.IPlayerFileData;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.MinecraftException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.storage.WorldInfo;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.WorldServer;
//Class used internally to provide the world specific data directories.
public class WorldSpecificSaveHandler implements ISaveHandler
{
private WorldServer world;
private ISaveHandler parent;
private File dataDir;
public WorldSpecificSaveHandler(WorldServer world, ISaveHandler parent)
{
this.world = world;
this.parent = parent;
dataDir = new File(world.getChunkSaveLocation(), "data");
dataDir.mkdirs();
}
@Override public WorldInfo loadWorldInfo() { return parent.loadWorldInfo(); }
@Override public void checkSessionLock() throws MinecraftException { parent.checkSessionLock(); }
@Override public IChunkLoader getChunkLoader(WorldProvider var1) { return parent.getChunkLoader(var1); }
@Override public void saveWorldInfoWithPlayer(WorldInfo var1, NBTTagCompound var2) { parent.saveWorldInfoWithPlayer(var1, var2); }
@Override public void saveWorldInfo(WorldInfo var1){ parent.saveWorldInfo(var1); }
@Override public IPlayerFileData getSaveHandler() { return parent.getSaveHandler(); }
@Override public void flush() { parent.flush(); }
@Override public String getWorldDirectoryName() { return parent.getWorldDirectoryName(); }
@Override
public File getMapFileFromName(String name)
{
return new File(dataDir, name + ".dat");
}
}
@@ -1,49 +0,0 @@
package net.minecraftforge.common.network;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login;
import net.minecraft.server.MinecraftServer;
import cpw.mods.fml.common.network.IConnectionHandler;
import cpw.mods.fml.common.network.Player;
public class ForgeConnectionHandler implements IConnectionHandler {
@Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
{
}
@Override
public String connectionReceived(NetLoginHandler netHandler, INetworkManager manager)
{
return null;
}
@Override
public void connectionOpened(NetHandler netClientHandler, String server, int port, INetworkManager manager)
{
}
@Override
public void connectionOpened(NetHandler netClientHandler, MinecraftServer server, INetworkManager manager)
{
}
@Override
public void connectionClosed(INetworkManager manager)
{
}
@Override
public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login)
{
}
}
@@ -1,20 +0,0 @@
package net.minecraftforge.common.network;
import net.minecraftforge.common.ForgeDummyContainer;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkModHandler;
public class ForgeNetworkHandler extends NetworkModHandler
{
public ForgeNetworkHandler(ForgeDummyContainer container)
{
super(container,container.getClass().getAnnotation(NetworkMod.class));
configureNetworkMod(container);
}
@Override
public boolean acceptVersion(String version)
{
return true;
}
}
@@ -1,187 +0,0 @@
package net.minecraftforge.common.network;
import java.util.Arrays;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
import com.google.common.base.Throwables;
import com.google.common.collect.MapMaker;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.Ints;
import com.google.common.primitives.UnsignedBytes;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.network.FMLNetworkException;
public abstract class ForgePacket
{
public static final String CHANNEL_ID = "FORGE";
enum Type
{
/**
* Registers a dimension for a provider on client
*/
REGISTERDIMENSION(DimensionRegisterPacket.class);
private Class<? extends ForgePacket> packetType;
private ConcurrentMap<INetworkManager, ForgePacket> partTracker;
private Type(Class<? extends ForgePacket> clazz)
{
this.packetType = clazz;
}
ForgePacket make()
{
try
{
return this.packetType.newInstance();
}
catch (Exception e)
{
Throwables.propagateIfPossible(e);
FMLLog.log(Level.SEVERE, e, "A bizarre critical error occured during packet encoding");
throw new FMLNetworkException(e);
}
}
private ForgePacket consumePart(INetworkManager network, byte[] data)
{
if (partTracker == null)
{
partTracker = new MapMaker().weakKeys().weakValues().makeMap();
}
if (!partTracker.containsKey(network))
{
partTracker.put(network, make());
}
ForgePacket pkt = partTracker.get(network);
ByteArrayDataInput bdi = ByteStreams.newDataInput(data);
int chunkIdx = UnsignedBytes.toInt(bdi.readByte());
int chunkTotal = UnsignedBytes.toInt(bdi.readByte());
int chunkLength = bdi.readInt();
if (pkt.partials == null)
{
pkt.partials = new byte[chunkTotal][];
}
pkt.partials[chunkIdx] = new byte[chunkLength];
bdi.readFully(pkt.partials[chunkIdx]);
for (int i = 0; i < pkt.partials.length; i++)
{
if (pkt.partials[i] == null)
{
return null;
}
}
return pkt;
}
}
private Type type;
private byte[][] partials;
public static Packet250CustomPayload[] makePacketSet(ForgePacket packet)
{
byte[] packetData = packet.generatePacket();
if (packetData.length < 32000)
{
return new Packet250CustomPayload[]
{
new Packet250CustomPayload(CHANNEL_ID,
Bytes.concat(new byte[]
{
UnsignedBytes.checkedCast(0), //IsMultipart: False
UnsignedBytes.checkedCast(packet.getID())
},
packetData))
};
}
else
{
byte[][] chunks = new byte[packetData.length / 32000 + 1][];
for (int i = 0; i < packetData.length / 32000 + 1; i++)
{
int len = Math.min(32000, packetData.length - i* 32000);
chunks[i] = Bytes.concat(new byte[]
{
UnsignedBytes.checkedCast(1), //IsMultipart: True
UnsignedBytes.checkedCast(packet.getID()), //Packet ID
UnsignedBytes.checkedCast(i), //Part Number
UnsignedBytes.checkedCast(chunks.length), //Total Parts
},
Ints.toByteArray(len), //Length
Arrays.copyOfRange(packetData, i * 32000, len + i * 32000));
}
Packet250CustomPayload[] ret = new Packet250CustomPayload[chunks.length];
for (int i = 0; i < chunks.length; i++)
{
ret[i] = new Packet250CustomPayload(CHANNEL_ID, chunks[i]);
}
return ret;
}
}
public static ForgePacket readPacket(INetworkManager network, byte[] payload)
{
boolean multipart = UnsignedBytes.toInt(payload[0]) == 1;
int type = UnsignedBytes.toInt(payload[1]);
Type eType = Type.values()[type];
byte[] data = Arrays.copyOfRange(payload, 2, payload.length);
if (multipart)
{
ForgePacket pkt = eType.consumePart(network, data);
if (pkt != null)
{
return pkt.consumePacket(Bytes.concat(pkt.partials));
}
return null;
}
else
{
return eType.make().consumePacket(data);
}
}
public ForgePacket()
{
for (Type t : Type.values())
{
if (t.packetType == getClass())
{
type = t;
continue;
}
}
if (type == null)
{
throw new RuntimeException("ForgePacket constructor called on ungregistered type.");
}
}
public byte getID()
{
return UnsignedBytes.checkedCast(type.ordinal());
}
public abstract byte[] generatePacket();
public abstract ForgePacket consumePacket(byte[] data);
public abstract void execute(INetworkManager network, EntityPlayer player);
}
@@ -1,26 +0,0 @@
package net.minecraftforge.common.network;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.Packet250CustomPayload;
import cpw.mods.fml.common.network.FMLPacket;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.Player;
public class ForgePacketHandler implements IPacketHandler {
@Override
public void onPacketData(INetworkManager network, Packet250CustomPayload packet, Player player)
{
ForgePacket pkt = ForgePacket.readPacket(network, packet.data);
// Part of an incomplete multipart packet
if (pkt == null)
{
return;
}
pkt.execute(network, (EntityPlayer)player);
}
}
@@ -1,15 +0,0 @@
package net.minecraftforge.common.network;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet131MapData;
import cpw.mods.fml.common.network.ITinyPacketHandler;
public class ForgeTinyPacketHandler implements ITinyPacketHandler {
@Override
public void handle(NetHandler handler, Packet131MapData mapData)
{
}
}
@@ -1,69 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common.network.packet;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.network.ForgePacket;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
/**
* This class offers the ability for servers to register dimensions on client.
*/
public class DimensionRegisterPacket extends ForgePacket
{
/** The dimension ID to register on client */
public int dimensionId;
/** The provider ID to register with dimension on client */
public int providerId;
// nullary constructor required by ForgePacket.make()
public DimensionRegisterPacket() {}
public DimensionRegisterPacket(int dimensionId, int providerId)
{
this.dimensionId = dimensionId;
this.providerId = providerId;
}
@Override
public byte[] generatePacket()
{
ByteArrayDataOutput dat = ByteStreams.newDataOutput();
dat.writeInt(this.dimensionId);
dat.writeInt(this.providerId);
return dat.toByteArray();
}
@Override
public ForgePacket consumePacket(byte[] data)
{
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
dimensionId = dat.readInt();
providerId = dat.readInt();
return this;
}
@Override
public void execute(INetworkManager network, EntityPlayer player)
{
if (!(player instanceof EntityPlayerMP))
{
if (!DimensionManager.isDimensionRegistered(dimensionId))
{
DimensionManager.registerDimension(dimensionId, providerId);
}
}
}
}
@@ -1,130 +0,0 @@
package net.minecraftforge.event;
import static org.objectweb.asm.Opcodes.*;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import com.google.common.collect.Maps;
public class ASMEventHandler implements IEventListener
{
private static int IDs = 0;
private static final String HANDLER_DESC = Type.getInternalName(IEventListener.class);
private static final String HANDLER_FUNC_DESC = Type.getMethodDescriptor(IEventListener.class.getDeclaredMethods()[0]);
private static final ASMClassLoader LOADER = new ASMClassLoader();
private static final HashMap<Method, Class<?>> cache = Maps.newHashMap();
private final IEventListener handler;
private final ForgeSubscribe subInfo;
public ASMEventHandler(Object target, Method method) throws Exception
{
handler = (IEventListener)createWrapper(method).getConstructor(Object.class).newInstance(target);
subInfo = method.getAnnotation(ForgeSubscribe.class);
}
@Override
public void invoke(Event event)
{
if (handler != null)
{
if (!event.isCancelable() || !event.isCanceled() || subInfo.receiveCanceled())
{
handler.invoke(event);
}
}
}
public EventPriority getPriority()
{
return subInfo.priority();
}
public Class<?> createWrapper(Method callback)
{
if (cache.containsKey(callback))
{
return cache.get(callback);
}
ClassWriter cw = new ClassWriter(0);
MethodVisitor mv;
String name = getUniqueName(callback);
String desc = name.replace('.', '/');
String instType = Type.getInternalName(callback.getDeclaringClass());
String eventType = Type.getInternalName(callback.getParameterTypes()[0]);
/*
System.out.println("Name: " + name);
System.out.println("Desc: " + desc);
System.out.println("InstType: " + instType);
System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback));
System.out.println("Event: " + eventType);
*/
cw.visit(V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[]{ HANDLER_DESC });
cw.visitSource(".dynamic", null);
{
cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;");
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, instType);
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, eventType);
mv.visitMethodInsn(INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback));
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
cw.visitEnd();
Class<?> ret = LOADER.define(name, cw.toByteArray());
cache.put(callback, ret);
return ret;
}
private String getUniqueName(Method callback)
{
return String.format("%s_%d_%s_%s_%s", getClass().getName(), IDs++,
callback.getDeclaringClass().getSimpleName(),
callback.getName(),
callback.getParameterTypes()[0].getSimpleName());
}
private static class ASMClassLoader extends ClassLoader
{
private ASMClassLoader()
{
super(ASMClassLoader.class.getClassLoader());
}
public Class<?> define(String name, byte[] data)
{
return defineClass(name, data, 0, data.length);
}
}
}
@@ -1,11 +0,0 @@
package net.minecraftforge.event;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(value = RUNTIME)
@Target(value = TYPE)
public @interface Cancelable{}
@@ -1,21 +0,0 @@
package net.minecraftforge.event;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
@Cancelable
public class CommandEvent extends Event
{
public final ICommand command;
public final ICommandSender sender;
public String[] parameters;
public Throwable exception;
public CommandEvent(ICommand command, ICommandSender sender, String[] parameters)
{
this.command = command;
this.sender = sender;
this.parameters = parameters;
}
}
-155
View File
@@ -1,155 +0,0 @@
package net.minecraftforge.event;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Base Event class that all other events are derived from
*/
public class Event
{
@Retention(value = RUNTIME)
@Target(value = TYPE)
public @interface HasResult{}
public enum Result
{
DENY,
DEFAULT,
ALLOW
}
private boolean isCanceled = false;
private final boolean isCancelable;
private Result result = Result.DEFAULT;
private final boolean hasResult;
private static ListenerList listeners = new ListenerList();
private static final Map<Class, Map<Class, Boolean>> annotationMap = new ConcurrentHashMap<Class, Map<Class, Boolean>>();
public Event()
{
setup();
isCancelable = hasAnnotation(Cancelable.class);
hasResult = hasAnnotation(HasResult.class);
}
private boolean hasAnnotation(Class annotation)
{
Class me = this.getClass();
Map<Class, Boolean> list = annotationMap.get(me);
if (list == null)
{
list = new ConcurrentHashMap<Class, Boolean>();
annotationMap.put(me, list);
}
Boolean cached = list.get(annotation);
if (cached != null)
{
return cached;
}
Class cls = me;
while (cls != Event.class)
{
if (cls.isAnnotationPresent(annotation))
{
list.put(annotation, true);
return true;
}
cls = cls.getSuperclass();
}
list.put(annotation, false);
return false;
}
/**
* Determine if this function is cancelable at all.
* @return If access to setCanceled should be allowed
*/
public boolean isCancelable()
{
return isCancelable;
}
/**
* Determine if this event is canceled and should stop executing.
* @return The current canceled state
*/
public boolean isCanceled()
{
return isCanceled;
}
/**
* Sets the state of this event, not all events are cancelable, and any attempt to
* cancel a event that can't be will result in a IllegalArgumentException.
*
* The functionality of setting the canceled state is defined on a per-event bases.
*
* @param cancel The new canceled value
*/
public void setCanceled(boolean cancel)
{
if (!isCancelable())
{
throw new IllegalArgumentException("Attempted to cancel a uncancelable event");
}
isCanceled = cancel;
}
/**
* Determines if this event expects a significant result value.
*/
public boolean hasResult()
{
return hasResult;
}
/**
* Returns the value set as the result of this event
*/
public Result getResult()
{
return result;
}
/**
* Sets the result value for this event, not all events can have a result set, and any attempt to
* set a result for a event that isn't expecting it will result in a IllegalArgumentException.
*
* The functionality of setting the result is defined on a per-event bases.
*
* @param value The new result
*/
public void setResult(Result value)
{
result = value;
}
/**
* Called by the base constructor, this is used by ASM generated
* event classes to setup various functionality such as the listener's list.
*/
protected void setup()
{
}
/**
* Returns a ListenerList object that contains all listeners
* that are registered to this event.
*
* @return Listener List
*/
public ListenerList getListenerList()
{
return listeners;
}
}
Loaded 100 of 650 files, more files were not shown because too many files have changed in this diff. Show more