Compare commits

..
1223 Commits
Author SHA1 Message Date
425eff39ff Update to 1.18.2
Co-authored-by: sciwhiz12 <[email protected]>
Co-authored-by: Marc Hermans <[email protected]>
Co-authored-by: LexManos <[email protected]>
Co-authored-by: Curle <[email protected]>
Signed-off-by: SizableShrimp <[email protected]>
2022-03-01 14:16:46 -08:00
sciwhiz12 34291c1fb2 1.18.x Omnibus (#8239) 2022-03-01 18:59:37 +00:00
ichttt 4011c3fb07 Bump modlauncher and securejarhandler version (#8489) 2022-02-28 14:31:10 -08:00
LexManos 104daf8ef0 Update license headers to compact SPDX format.
License has not changed, this is just more compact and doesn't include years.
Bump version for RB.
2022-02-28 13:41:23 -08:00
LexManos d9a04b881a Remove - from allowed characters in mod ids.
The Java Module System does not allow them in module ids.
Closes #8488
2022-02-28 13:23:53 -08:00
gigaherz ae62362d49 Fix static initializer crash when loading BakedRenderable. 2022-02-28 22:03:31 +01:00
sciwhiz12 2f8c3ea738 Fix regressions for onAddedTo/RemovedFromWorld and related events (#8434) 2022-02-28 17:23:19 +00:00
SizableShrimp f0c2554b1c [1.18] Integrate the gametest framework with Forge (#8225)
Signed-off-by: SizableShrimp <[email protected]>
2022-02-25 01:06:32 +00:00
sciwhiz12 bb547a5748 Re-add missing Shulker patch for EntityTeleportEvent (#8481) 2022-02-25 00:51:00 +00:00
sciwhiz12 5dd3842b77 Fix entity type in conversion event to Drowned (#8479) 2022-02-25 00:49:48 +00:00
Sara Freimer 2ab4685149 Add VanillaGameEvent to allow for globally listening to vanilla's GameEvents (#8472) 2022-02-22 15:12:06 -08:00
Sara Freimer edbc07ed22 Provide damage source context to Item#onDestroyed(ItemEntity) (#8473) 2022-02-22 14:38:53 -08:00
Sara Freimer e225dbc8d1 Add missing shear and elytra game events (#8471) 2022-02-22 14:24:14 -08:00
sciwhiz12 117be913da Fix comment for permission handler config setting (#8466) 2022-02-22 14:21:47 -08:00
Brennan Ward 512d4d7271 Apply nullable annotations to LootingLevelEvent (#8422) 2022-02-22 14:20:29 -08:00
LexManos a9237cff75 Fix Mob Spawner logic with CustomSpawnRules. Closes #8398 2022-02-22 14:18:52 -08:00
Take Weiland bc24487d0e Fix LivingDropsEvent not having all drops for foxes (#8387) 2022-02-15 09:41:06 -08:00
Take Weiland c3e0b071a2 Add missing Locale parameter to String.format calls, Fixes getArmorResource functionality on some locaales. (#8463) 2022-02-15 09:27:10 -08:00
Take Weiland 21787234f4 Allow items to hide parts of their tooltips by default (#8358) 2022-02-15 09:23:18 -08:00
Marc Hermans a9958b19db Prevent 1.x Branches being treated as Pull Requests. (#8443) 2022-02-12 09:28:14 -08:00
Take Weiland b25d9562f2 Fix RegistryObject not working if created after registry events (#8383) 2022-02-08 13:05:38 -08:00
Marc Hermans 2765c0d8d9 Add support for tagging StructureFeatures (#8408) 2022-02-08 12:48:57 -08:00
Take Weiland 82a20911cb Re-added the patch for LivingExperienceDropEvent and enable it for dragons (#8388) 2022-02-08 12:39:01 -08:00
Sara Freimer f19f7e4670 Implement getPickupSound on ForgeFlowingFluid (#8374) 2022-02-08 12:24:47 -08:00
Frinn38 e10f5c637e Add getCodec method in ForgeRegistry (#8333) 2022-02-08 12:12:28 -08:00
eerussianguy 4bfe562f14 Fix #8298 (MobBucketItem) and add test mod (#8313) 2022-02-08 11:55:25 -08:00
Joseph Tarbit 5e64ef9ecb Deprecate IForgeAbstractMinecart::getCartItem (#8283) 2022-02-08 11:38:25 -08:00
Take Weiland dda1be91ea Fix HoeItem patch incorrectly applied during migration. (#8384) 2022-02-08 11:28:22 -08:00
Take Weiland 4f4849b60c Fix issues with client only commands in combination with server only commands not using MC's command system. (#8452) 2022-02-08 11:24:55 -08:00
Dipo 3b754fef5e Fix FoliagePlacerType and TreeDecoratorType registry (#8394) 2022-02-04 01:28:55 +00:00
Take Weiland 5e295f2485 Fix PlayerChangeGameModeEvent (#8441) 2022-02-04 00:08:41 +00:00
Dennis C 5c9258491f Fix comparison of custom ParticleRenderTypes leading to broken particle effects. (#8385) 2022-01-30 14:26:03 +00:00
LexManos af87677516 Fix cases where null is potentially sent to Screen events. Closes #8432 2022-01-27 23:38:08 -08:00
mezz a68c886ea2 Ensure ScreenEvent doesn't accept null screens (#8296) 2022-01-27 19:47:58 -08:00
Bagel b129e385cc Update cobblestone tags (#8292) 2022-01-27 19:39:44 -08:00
Marc Hermans fdc921923c Prevent release of custom payload packet buffer on the server side. (#8181) 2022-01-27 19:33:45 -08:00
SizableShrimp 476e20ae96 Make MinecraftLocator respect non-MOD FML Mod Types Fixes #8344 (#8346) 2022-01-22 10:26:14 -08:00
Joseph B d63516f2ac Fix vanilla worlds being marked experimental (#8415) 2022-01-22 03:46:44 +00:00
KnightMiner fd522d38b0 Simplify usage of IItemRenderProperties::getArmorModel (#8349) 2022-01-22 00:37:55 +01:00
Take Weiland 5f0d4abf23 Hide mod update notification while screen is still fading in (#8386) 2022-01-21 22:38:46 +01:00
LexManos 8e3e8b2120 Revert "Hooks to allow registering and managing custom DFU schemes and types. (#8242)" 2022-01-20 15:39:47 -08:00
Marc Hermans 72fd6808d8 Provide NPE protection against out of order init of the TYPES and REF (#8410) 2022-01-20 14:58:48 -08:00
Brennan Ward 2c35d04495 Add ShieldBlockEvent (#8261) 2022-01-20 13:43:22 -08:00
gigaherz f704d65d5a Add renderable API to allow easier rendering of OBJ and other custom models, from Entity and BlockEntity renderers. (#8259)
This is a redesign of a discarded section of my initial model system rewrite, back in 1.14.
In order to use it with the OBJ loader, you can use OBJLoader.INSTANCE.loadModel to get the OBJModel, and then call OBJModel#bakeRenderable() to get a SimpleRenderable object to render with.

The SimpleRenderable support animation, by providing different transformation matrices for each part in the MultipartTransforms.

Additionally, a BakedRenderable helper exists to turn an arbitrary BakedModel into a renderable.

After trying to get the B3D loader to work, I decided it wasn't worth the trouble and marked it for removal instead.
2022-01-20 13:30:39 -08:00
sciwhiz12 6c6a4817e7 Merge values of defaulted optional tags, Fixes issue where multiple mods declare the same optional tag. (#8250) 2022-01-20 12:26:54 -08:00
Girafi ef3408c1eb Added new 1.18 biomes to the BiomeDictionary (#8246) 2022-01-20 12:21:45 -08:00
Marc Hermans 0ea593c50e Hooks to allow registering and managing custom DFU schemes and types. (#8242) 2022-01-20 12:20:39 -08:00
Take Weiland 643b972e97 Ping data compression (#8169) 2022-01-20 11:51:40 -08:00
Joseph B 93ce9e72f7 Expand the LevelStem codec to allow dimension jsons to specify that the dimension's chunk generator should use the overworld/server's seed (#7955) 2022-01-20 11:46:08 -08:00
coehlrich f1bafce275 Add Client Commands (#7754) 2022-01-20 11:32:55 -08:00
SuperMartijn642 75408c1a70 Remove references to the now-broken BlockEntity#save(CompoundTag) method (#8235) 2022-01-19 19:27:34 +00:00
cpw 00fafb07ce update McModLauncher libraries to newer versions...
Signed-off-by: cpw <[email protected]>
2022-01-17 21:46:45 -05:00
cpw e49a347aea add extra keystore properties
Signed-off-by: cpw <[email protected]>
2022-01-16 18:29:05 -05:00
cpw 2c8ca313a0 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-16 23:26:56 +00:00
cpw fe7dcdf637 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-16 23:26:35 +00:00
cpw 15daa2955d TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-16 23:05:42 +00:00
cpw 03af8a53a2 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-16 23:05:18 +00:00
cpw c7e4e4b5b4 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-16 23:03:39 +00:00
cpw d477425f70 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-16 23:02:55 +00:00
cpw a3449f2866 fix crowdin key
Signed-off-by: cpw <[email protected]>
2022-01-15 14:46:27 -05:00
cpw 2a1f98aec2 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-15 19:43:05 +00:00
cpw bc9bd40d03 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-15 19:42:19 +00:00
cpw 58344b0b15 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-15 19:42:08 +00:00
cpw edcc8b3c97 fix secondary branches builds
Signed-off-by: cpw <[email protected]>
2022-01-15 14:21:01 -05:00
OrionDevelopment d494ba9be4 TeamCity change in 'MinecraftForge / MinecraftForge' project: parameters of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:58:23 +00:00
OrionDevelopment b92f56503e TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:57:37 +00:00
OrionDevelopment 5a9be79785 TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:56:12 +00:00
OrionDevelopment 225c2125c6 TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:55:02 +00:00
OrionDevelopment e2a932108e TeamCity change in 'MinecraftForge / MinecraftForge' project: parameters of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:54:11 +00:00
OrionDevelopment ec38717702 TeamCity change in 'MinecraftForge / MinecraftForge' project: parameters of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:50:32 +00:00
OrionDevelopment 3009f5350c TeamCity change in 'MinecraftForge / MinecraftForge' project: VCS roots of 'Build - Secondary Branches' build configuration were updated 2022-01-15 18:48:59 +00:00
Marc Hermansandcpw a24dd3c8ee Remove primary branches from building on secondary branch configuration and publish crowdin data. (#8397)
* Remove the normalized branch names also from the filter.

* Add the additional publishing arguments to get the crowdin information.

* TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed

* Fix the configuration.

* Remove the required patch and use the base script.

* Make a note about the reference.

Co-authored-by: cpw <[email protected]>
2022-01-15 12:45:09 -05:00
cpw 3fae26a470 TeamCity change in 'MinecraftForge / MinecraftForge' project: project parameters were changed 2022-01-15 17:20:24 +00:00
Marc Hermans a44ac01aee Correct the build configuration to support a setup. (#8395)
* Add a setup task and publish the correct versions.

* Reconfigure build task and disable the normal build and test cycle on everything but pull requests, run an assemble there.

* Fix the derp in the build configuration.
2022-01-15 11:44:42 -05:00
Marc Hermans b09f8d0fc8 Enable the TeamCity CI pipeline (#8368)
* Setup the build.gradle

* Setup the teamcity toolchain.

* Revert the usage of the local build of GU.

* Automatically add it now, it will always exist and is added to maven automatically by GU.

* Implement the branch filter and move the constant for the minimal changelog tag to a constant in the extension.

* Adding the JDK and Gradle version to the build script.
2022-01-15 10:39:09 -05:00
Take Weiland 57a916bf09 Fix and improve Ingredient invalidation (#8361) 2022-01-14 15:05:57 +00:00
Alex O'Neill 15d3df2818 Rework world persistence hooks to fix the double registry injection when loading single player worlds. (#8234) 2022-01-11 18:00:04 -08:00
SuperMartijn642 63a42bad98 Update tags for new 1.17 and 1.18 content (#7891) 2022-01-10 16:15:50 -08:00
Dennis C 28d3c491a0 Fix TerrainParticle rendering black under certain conditions (#8378) 2022-01-10 00:55:57 +00:00
cech12 551296813e Allow modded tools to work on glow lichen (#8371) 2022-01-09 21:23:03 +00:00
sciwhiz12 62b99be117 Fix custom climbable blocks not sending a death message (#8372)
Fixes #8370
2022-01-09 21:18:27 +00:00
Sara Freimer 6683e9e660 Provide access to the blockstate in BucketPickup#getPickupSound for multiply-logged blocks (#8357) 2022-01-08 21:20:09 +00:00
Sara Freimer 3b9df7df1b Fix clients being unable to deserialize tags for custom registries (#8352) 2022-01-08 20:47:28 +00:00
Bagel a9a8d7ed8c Fix particles going fullbright for a few frames when first spawning (#8291) 2022-01-08 20:28:22 +00:00
Take Weiland 80770898c6 Also create parent directories when creating config files (#8364) 2022-01-08 18:44:11 +00:00
JTK222 335cb5edc4 Fix crash with PermissionsAPI (#8330)
Fixes a crash in singleplayer, when the internal server didn't shut down correctly between world loads.
2022-01-02 18:43:07 +00:00
sciwhiz12 7259887176 Re-add missing default spawn lists in features (#8285)
Fixes #8265
Fixes #8301
2021-12-27 16:23:43 +00:00
JTK222 0320c185b5 Fixed incorrect generic in PermissionAPI (#8317) 2021-12-22 13:22:16 +00:00
JTK222andLexManos 2f5f696b68 Redo of the whole PermissionAPI (#7780)
Co-authored-by: LexManos <[email protected]>
2021-12-20 18:34:57 +00:00
JTK222 d33e9c8251 Fix misplaced patch in SpreadingSnowyDirtBlock.
Fixes #8308.
2021-12-19 18:28:24 +00:00
Sara Freimer 21c50da8ec Add RenderArmEvent to make overriding just the arm rendering not require copying nearly as much vanilla code (#8254) 2021-12-13 13:58:16 -08:00
Bagel e2a205d2e7 Add MobEffect tags (#8231) 2021-12-13 13:32:04 -08:00
Dennis C 950e7b032a Log missing or unsupported dependencies (#8218) 2021-12-13 11:48:43 -08:00
sciwhiz12 d1a55a147e Fix datagen test for sounds definitions provider (#8249) 2021-12-13 11:32:53 -08:00
Vincent Lee 1fd8b1a4b8 Fix wrong stage being declared in transition to common (#8267) 2021-12-13 11:14:02 -08:00
Curle 41ea5b195b Update to 1.18.1
Co-Authored by:
- Curle
_ Orion
2021-12-10 20:00:29 +01:00
Marc Hermans 14e152579b [CVE-2021-44228]: Update Log4J to fix the security issue inside it. (#8268) 2021-12-10 01:23:30 -08:00
Jared dcf7bb1af2 Fix KeyMappings only checking if they conflict with themselves. (#8256) 2021-12-08 00:09:25 +00:00
Dennis C 456a48b12a Fix ChunkWatchEvent not being fired (#8253) 2021-12-05 19:39:59 +00:00
Jonathan Coates aceb878a64 Call handleUpdateTag for BlockEntities again (#8237) 2021-12-04 01:30:13 +00:00
Joseph B f451e21f39 Fix test worldgen data (#8248) 2021-12-03 22:10:09 +00:00
LexManos c6ac740d31 Allow Forge Registries to return key information for overridden objects. Fixes #8230 2021-12-02 12:15:19 -08:00
Curle dbf98d3888 Save Chunk capabilities to the chunk, rather than recursively to the capabilities. 2021-12-02 19:16:47 +00:00
gigaherz 1b7bdc3ec6 Fix LevelChunk capability attach crash.
Fix client chunks not having capability providers attached.
Add capability attach tests.
2021-12-02 16:24:23 +01:00
gigaherz d414e31f08 Make HandshakeConsumer public again.
Fixes #8241
2021-12-02 15:15:20 +01:00
Curle b2036e9d23 Complete TODO in ShapedRecipe patch causing logspam related to minecraft:air 2021-12-02 00:43:25 +00:00
Curle abe4afe152 Add missing biomes back to the BiomeDictionary 2021-12-02 00:43:00 +00:00
Curle e7ad43c993 Readd Mixin 0.8.5 to fix modules issues. 2021-12-01 22:11:42 +00:00
Curle 7631600b53 Readd PoseStack field to RenderTooltipEvent. 2021-12-01 16:55:29 +00:00
Curle 530a1e8eb0 Fix custom loot serializers using wrong registry names 2021-12-01 01:21:21 +00:00
LexManos 54b2c18fcf Fix DungeonHooks not returning correct values. Fixes dungeons in world spawning pigs. 2021-11-30 17:14:56 -08:00
LexManos eb1a9b57c6 Fix dedicated server install. Closes #8226
Fix example mod
Fix obf issue with records. Closes #8228
Fix dependencies beingg out of sync from vanilla. Closes #8227
Disable mixin due to module incompatibility.
2021-11-30 16:22:58 -08:00
gigaherz 5b6d54555e Fix mod resources not loading.
Add BreakingItemParticle.java.patch which I forgot to commit during the porting.
2021-11-30 21:44:35 +01:00
40a174310d Initial port to 1.18
Co-authored-by: David Quintana <[email protected]>
Co-authored-by: SizableShrimp <[email protected]>
2021-11-30 17:42:18 +00:00
LexManos be0a6819ac Bump version for final RB of 1.17's lifecycle. Move on to 1.18! 2021-11-30 08:54:18 -08:00
LexManos 82a7ee1416 Fix LiquidBlock's fluid field not being redirected to the supplier getFluid. Closes #7922 2021-11-30 08:43:37 -08:00
sciwhiz12 b4feee8046 [1.17.x Omnibus] Fix typos and javadocs across code base (#8144) 2021-11-25 13:09:56 -08:00
AterAnimAvis df8954869a Fix /forge setdimension command arguments not parsing/suggesting correctly. 2021-11-25 12:27:26 -08:00
uSkizzik 8a552136a2 Fix Spectating Part Entity (MC-46486) (#8206) 2021-11-25 12:17:15 -08:00
Paint_Ninja 34ec627457 Use HttpClient for VersionChecker (#8148) 2021-11-25 12:14:11 -08:00
Harley O'Connor 28dd76ebbf Changed control flow of post mouse events to allow listening to events handled by vanilla. (#8133) 2021-11-25 12:03:05 -08:00
sciwhiz12 b639bcb5c7 Deprecate durability bar methods in Item extension (#8214)
To retain compatibility with existing mods, the vanilla methods redirect
to the extension methods for now.

Users should now use and override the vanilla methods as directed in
the javadocs of the now-deprecated methods, as the extension methods
will be removed in the future.

Fixes #8201
2021-11-25 20:09:40 +01:00
sciwhiz12 7538cf5501 Reorder image tooltip component to match vanilla (#8213)
Fixes #8212
2021-11-25 19:58:55 +01:00
Sekwah 1112819fc8 Fix render pipeline lighting issue with small cubes (#8158)
This will also allow other mods which need to calculate small normalised vectors to be able to use the default classes without needing to write their own, while not effecting any side effects created by how the base game uses this function.
2021-11-25 11:14:12 +01:00
ChampionAsh5357 cdd38270e9 Fixes infinite loop when dismounting in EntityMountEvent (#8114) 2021-11-24 18:03:12 -08:00
ichttt 20e309c339 Fix onChunkUnloaded not gettting called correctly (#8103) 2021-11-24 13:53:51 -08:00
Take Weiland 5f87bde00e Fix death message for tamed animals not having proper cause of death. (#8196) 2021-11-23 17:11:03 -08:00
DaemonUmbra a4e574fa6b Fix potential issue with BackgroundScanHandler for users with slow disc IO (#8176) 2021-11-23 17:05:45 -08:00
TelepathicGrunt ec7cb00f86 Make WorldEvent.Load run for Overworld before chunk creation like other dimensions (#8167) 2021-11-23 17:02:23 -08:00
Robert Kämpf ebe375dac0 Deprecate net.minecraftforge.common.util.Constants and inner classes to encourage usage of vanilla constants (#8140) 2021-11-23 16:47:43 -08:00
SuperMartijn642 4a2572d545 [1.17.x] Change expected type of LootTable fields to arrays (#8194)
#8184 reverted some LootTable patches, including the types of fields `f_79023_` and `f_79024_`. However, `ForgeLootTableProvider` still expects a list, however the type of the fields is an array now.
This PR changes the expected type in `ForgeLootTableProvider` to an array as well.
2021-11-21 10:26:31 -08:00
MelanX 55db597baa Apply window resizing to all gui layers (#8207) 2021-11-21 13:28:56 +01:00
Minecraftschurli c24d05173f [1.17.x] make ScrollPanel better usable by modders (#8179) 2021-11-20 16:54:12 +01:00
LexManos d711982a1c Update installer to 2.1.+ so we don't have to bump it in the future. 2021-11-12 17:25:37 -08:00
ChampionAsh5357 8a38416e0f Remove Old LootPool Patches (#8184) 2021-11-10 12:17:53 -08:00
ichttt a784bdb0d0 Remove the remnants of the selective reload listener (#8072) 2021-11-09 14:30:45 -08:00
Minecraftschurli dc9a7f6ad5 Fix the hopefully last issue with GAMELIBRARY loading (#8162) 2021-11-09 14:27:17 -08:00
uSkizzik 417798f2eb Fix part entities not working at all (#8177) 2021-11-09 14:16:40 -08:00
Dennis C 394e76eed3 Pass IModelData through IForgeBakedModel#getModelData() before asking the BakedModel for the particle texture (#8106) 2021-10-31 12:26:32 +01:00
Dennis C 9e476551be Fix blocks with flammable material catching fire from lava when they are marked as non-flammable (#8160) 2021-10-20 12:15:43 -07:00
Alex O'Neill 1dc421e6a4 Add BiomeDictionary#hasType(String) (#8157) 2021-10-20 12:10:13 -07:00
Silver_David e431bb1caa Add "forge:enchanting_materials" tag in place of Lapis in the Enchanting Table (#8149) 2021-10-20 12:08:53 -07:00
ChampionAsh5357 8bd517ca91 Fix Breaking waterlogged blocks occasionally displays air for a frame Closes #7253 (#8128) 2021-10-20 12:01:48 -07:00
Dennis C 69ddf58600 Add accessor to an unmodifiable view of the fullPots map in FlowerPotBlock (#8108) 2021-10-20 11:57:33 -07:00
ChampionAsh5357 1e040c9f1f Fix Behavior With Unknown Items in Recipes (#8105) 2021-10-20 11:56:23 -07:00
LexManos 11bdf592c8 Disable jenkins cache system until a functional system is in place. 2021-10-17 16:28:45 -07:00
Take Weiland f4a827ab01 Fix another crash with new tooltip events (#8155)
* Fix another crash with new tooltip events
* Add ItemStack context to ghost recipe tooltip events
* Expand Tooltip Event test mod to add a screen to test all tooltip render methods
2021-10-18 00:22:42 +02:00
ChampionAsh5357 827ca83cfd Add entity source to PotionAddedEvent (#8147) 2021-10-14 20:13:18 -07:00
Dipo e9f8acd191 Add helper methods to generate blockstate and models for button, pressure plate, sign to BlockStateProvider/ModelProvider (#8139) 2021-10-14 20:11:20 -07:00
Max Becker febfd5ab62 Fix Entity#onAddedToWorld not being called for non-player entities server-side (#8134) 2021-10-14 20:09:16 -07:00
Alex O'Neill 4ca2a8058f Add ATs for world generation extensibility, focusing on NoiseBasedChunkGenerator, NoiseSampler, NoiseBasedAquifer, and Beardifier (#8087) 2021-10-14 20:07:08 -07:00
Unbekannt1998 4acafcccfd Make AdvancementProvider extensible by modders (#8120) 2021-10-14 20:00:18 -07:00
LexManos 937b719e24 Skip loading jars with neither a manifest, nore a mods.toml.
Deprecate helper functions related to ModFile/Metadata.
Mark ModFileFactory as to be removed from our usage.
It may be useful for other loaders, but introduces a weird level of indirection that makes things a pain.
If there are consumers of this API please leave feedback before the next major mc version so we can be sure to provide something useful.
2021-10-13 12:51:16 -07:00
LexManos 2b5bfd923c Fix mods with both a manifest and a mods.toml have mismatched module names. 2021-10-13 12:19:22 -07:00
Take Weiland 249aaa5806 Fix missing toolTip methods in Screen (#8154) 2021-10-13 14:02:31 +02:00
Take Weiland 46f57e6a9a Fix render tooltip render patch (#8153) 2021-10-13 10:06:25 +02:00
LexManos cfd79130de Attempt to fix non-mods.toml jar files. Closes #8136 #8146 #8152
Make jenkins copy gradle cache to address concurrent build issues.
2021-10-12 18:49:14 -07:00
Take Weiland 6a25c99097 Tooltip event rewrite (#8038)
Redesigns the tooltip events, and adds a feature where mods can register factories for ClientTooltipComponents, which are used for custom rendering in tooltips. The old events are maintained for binary compatibility.
2021-10-11 20:37:14 +02:00
Dennis C 95be0d87d9 Add ForgeSpawnEggItem to lazily handle EntityTypes (#8044) 2021-10-07 23:50:18 -07:00
Dennis C 6125ec3bc8 Reimplement IForgeBlockEntity#onLoad() hook (#7946) 2021-10-07 13:31:56 -07:00
gigaherz 9944a8252a Implement GUI Stacking feature. (#8130)
You can now use `mc.pushGuiLayer` and `mc.popGuiLayer` to manage the layers.
mc.setScreen behaves such that if called with a non-null screen it replaces the entire stack, and if called with null it closes the entire stack.
2021-10-04 19:15:56 -07:00
gigaherz fd544dd414 Add ability for people to add custom pack finders (RepositorySources) (#8121)
Added AddPackFindersEvent which lets you add additional resource/data pack sources to the game.
Added PathResourcePack as a utility to allow easy providing of a subfolder in a mod as a resource pack.
2021-10-04 15:10:05 -07:00
Take Weiland c00777e6ea Added EntityEvent.EnteringSection event to replace EnteringChunk event. (#8078) 2021-10-04 14:43:07 -07:00
OneLemonyBoi b2cea78006 Prevent Block/Entity data side leak on integrated servers by copying custom data before writing. #8111 2021-10-04 12:40:58 -07:00
sciwhiz12 79272361f0 Re-implement linear filtering text render types (#8052)
* Re-implement linear filtering text render types

Implements and closes #7996
2021-10-03 20:05:19 +02:00
percivalalb fe4be54774 Fix breaking block particles not respecting IModelData (#8065)
The sprite used for the block particles needs updating after the constructor otherwise it defaults to the texture sprite returned from passing ModelData.INSTANCE to get IForgeBakedModel#getParticleIcon. Calling updateSprite fetches the real IModelData instance for that blockstate/pos and sets the texture to the desired one
2021-10-03 20:03:28 +02:00
Sydney eecb8cc783 Fix Signs breaking with custom WoodTypes (#8132) 2021-10-03 20:00:07 +02:00
LexManos 5e2e404828 Bump SJH version. Closes #8127
Attempt addressing loading libraries during dev time, and bump SPI version introducing GAMELIBRARY type. #7976 #7957 #8090
2021-10-01 13:21:00 -07:00
LexManos 96303f6570 Capability rework to get rid of @CapabilityInject and use CapabilityToken as the identifier, deprecated old system for removal in 1.18. (#8116) 2021-09-30 22:54:23 -07:00
OneLemonyBoi 166feefc02 Fix pet death message being sent when pet death event is canceled. (#8110) 2021-09-27 12:59:06 -07:00
Rikka0_0小六花 cd67762bee [1.17.x] implements canConnectRedstone(), Redstone dust now defers to the blockstate for determining connectivity (#8014) 2021-09-27 12:26:17 -07:00
sciwhiz12 347a0b3c0d Prevent call to Item#initializeClient when in datagen (#8097)
When running under data-generation, the Minecraft singleton is unavailable
even though the operating env is under the CLIENT dist. Adding this check
prevents crashes from devs unaware of this, as most uses of
IItemRenderProperties (usually for a custom BEWLR) make use of the
Minecraft singleton and therefore will cause NPEs if not guarded against.

A similar thing happens in MobEffect and Block.
2021-09-24 23:10:34 +02:00
sciwhiz12 be1698bb15 Move ItemStack#forgeInit call earlier to allow earlier capability queries (#8096) 2021-09-19 16:35:55 -07:00
sciwhiz12 a3e9d7a397 Remove incorrect FallingBlock patch (#8092)
The patch accidentally replaces the minimum build height (set by the
dimension via e.g. datapacks) with 0, causing falling blocks placed
below Y level 0 to never fall.

Fixes #8091
2021-09-18 19:42:30 -07:00
sciwhiz12 b2dbe9de51 Fix inverted hooks for PermissionsChangedEvent (#8089)
Because IEventBus#post returns true on cancellation and the patched-in
hooks inverts the return of the ForgeHooks method, if the player
whose permission level is being changed is online and the event is not
cancelled, the permission change _is_ cancelled.

The fix is inverting the patched-in hooks and the default return value
of the ForgeHooks method, so that the permission change is cancelled
only if the player is online, the event is fired, and the event is cancelled.

Fixes #8088
2021-09-18 14:58:27 -07:00
Marc Hermans a31adc2823 Add the missing patch for ItemStack for last build. (#8085) 2021-09-17 13:26:05 -07:00
Marc Hermans 30a33f5c3e Support Lazy capabilities on itemstacks, for better ItemStack copy performance. (#7945) 2021-09-17 11:23:12 -07:00
gigaherz b01a217f45 Fix EntityJoinWorldEvent not firing as expected: (#8033)
- Fix entities loaded from disk not getting the event.
- Fix vehicles with passengers getting the event twice.
2021-09-16 17:11:04 -07:00
sciwhiz12 69136fce19 Re-add patch to release buffer in custom payload packet (#8042) 2021-09-16 16:54:25 -07:00
noeppi_noeppi ee21224fff Propagate all arguments passed to the server start scripts to the game (#8060) 2021-09-16 16:52:55 -07:00
ichttt 804f390064 Remove old Log4j thread cache invalidation (#8068) 2021-09-16 16:37:16 -07:00
LexManos ca2023fa80 Fix pick-block for items that map to multiple blocks. Closes #8080 2021-09-15 12:09:03 -07:00
gigaherz 4e562664f4 Update nashorn to 15.3, which fixes crashing when run on Java 17.
Please note that due to https://bugs.mojang.com/browse/MCL-18306, the vanilla launcher will not let you use Java 17 yet without workarounds.
2021-09-15 01:54:08 +02:00
SizableShrimp c8d3ad1d1c Add mixin full release to install list. (#8076) 2021-09-11 22:20:40 -07:00
sciwhiz12 b7379953d5 Add new tool action for shield blocking, replacing IForgeItem#isShield (#8055) 2021-09-08 13:14:47 -07:00
sciwhiz12 9d7f5dd32a Add workaround for pairs of ' being stripped (#8050)
Fixes #7396, where if a translated string with balanced pairs of single
quote characters passes through ForgeI18n, the quotes are stripped
because of ExtendedMessageFormat. This is most notable in languages
where `'` is used frequently, like Canadian French from the bug report.

Note that unbalanced pairs cause an IllegalArgumentException in
ExtendedMessageFormat, which means the message is not affected.
2021-09-08 11:36:00 -07:00
sciwhiz12 049ed79e7b Re-add missing patch for IForgeItem#getEquipmentSlot (#8041) 2021-09-08 11:20:12 -07:00
Mysticdrew 675bf8bde2 Added PlayerPermissionChangedEvent(#8023) 2021-09-08 10:39:27 -07:00
DavidQF555 8dc58ad469 Changed Monster Requirement to Mob in RangedBowAttackGoal (#7960) 2021-09-08 10:22:28 -07:00
noeppi_noeppi 827c963d7e Add shebang to run.sh in server files (#8058) 2021-09-02 14:23:53 -07:00
LexManos 2ac616b293 Fix incorrect parameter being sent to AbstractContainerScreen#getSlotColor. 2021-09-02 10:45:01 -07:00
sciwhiz12 dcfbc08504 Patch ModSorter to include forge mod in forgeAndMC list (#8043) 2021-09-01 07:26:29 -07:00
Sara Freimer 19f470ee8c Fix GuiUtils#drawContinuousTexturedBox making assumptions about what shader is currently active, and fix buttons and header not showing on LoadingErrorScreen (#8022) 2021-08-31 17:51:42 +02:00
iTitus a96d078a7a Fix ScrollPanel render calls and usage (#8012) 2021-08-31 16:57:08 +02:00
sciwhiz12 b375da6962 Fix all layers of ItemLayerModel being fullbright (#8039)
Fixes #8007
2021-08-31 11:33:27 +02:00
Cyborgmas d17f10d80c Cleanup Tag Loading, this migrates thins to more of a vanilla style. (#7898) 2021-08-30 14:58:30 -07:00
cech12 a336e443f7 Add Shears ToolActions (#7997)
Make shear interactions extend to subclasses
Add Shears actions for beehive harvesting, pumpkin carving and trip wire disarming
2021-08-30 13:42:37 -07:00
SizableShrimp c5a1c90366 Fix broken fmlonly installer and promote it to page gen (#8029)
Update gradle wrapper to 7.2
2021-08-27 02:03:40 -07:00
Cyborgmas 95c0aa1e98 Minor resource pack related fixes (#7884) 2021-08-23 10:52:17 -07:00
LexManos 559b801cc4 Fix misaligned patch causing monsters to not spawn in nether fortresses correctly. 2021-08-21 18:30:13 -07:00
Take Weiland aa97ddad8b Add RegisterCapabilitiesEvent (#8021) 2021-08-20 12:38:43 -07:00
Commoble d612dc3a6d Move static ITEM_TIER_ORDERING_JSON resourcelocation declaration from anonymous class into outer class to work around eclipse compiler error. (#8018) 2021-08-19 14:31:05 -07:00
SizableShrimp 9165d4c3a1 Fix entities not spawning in structures (#8020)
This affects swamp huts, pillager outposts, ocean monuments, and nether fortresses
2021-08-18 22:44:26 -07:00
Commoble 12d0f96fc2 Add support for forge's "remove" list to tag datagenerators (#7911) 2021-08-18 13:49:29 -07:00
Sirttas bec9d6f534 Add hook to allow items to customize the attack sweep range. (#7981) 2021-08-18 13:05:19 -07:00
Jonathan Coates 892c3669e0 Track the active mod within DeferredWorkQueue (#7973) 2021-08-18 12:46:33 -07:00
StrikerRocker (Tharik Sherief) ce13efbac9 Allow to check spawner block entity in events (#7941) 2021-08-18 02:15:57 -07:00
Cyborgmas 1018b077dc Remove neutral mob patches as the bug was fixed upstream. (#8001) 2021-08-17 22:02:38 -07:00
malte0811 9746db5129 Ensure that all render targets in a PostChain use the same format (#7978)
closes #6995
2021-08-15 16:18:34 +02:00
SizableShrimp c4de1f33ba Fix update checker to use runtime minecraft version (#8000) 2021-08-12 01:44:29 -07:00
vemerion a8a4623d24 Correct incorrect arguments for render hand event (#7987) 2021-08-10 18:53:14 -07:00
David Quintana 10b51f257f Redesign the tool system to rely on the new vanilla tags. (#7970)
Changed:
- ToolType is replaced with ToolAction, which can selectively represent which actions are supported by an item.
- Added a canPerformAction method to query ToolActions.
- Renamed canHarvestBlock to isCorrectToolForDrops to match vanilla.
- Added TierSortingRegistry, which can be used to add custom tiers and supports sorting between vanilla or with other mods.

How to use:

For the breaking system there's 2 methods:
- getDestroySpeed decides if an item *can* mine the block fast. Override if you have multiple tags or your item isn't a DiggerItem.
- isCorrectToolForDrops decides if an item will get drops. Returning false will also slow down mining, regardless of getDestroySpeed. Override if you have type-dependant tiers or your item isn't a DiggerItem.

For the tier system mods can just call `TierSortingRegistry.registerTier(tier, "name", List.of(lesser tiers), List.of(better tiers));` to register their tiers.
There's helper methods to query tiers such as TierSortingRegsitry.isCorrectTierForDrops.

The ToolActions solve 2 problems:
1. distinguishing which kind of digger an item can be
2. querying if the item can perform specific secondary actions.
Any item can override `canPerformAction` to customize which actions it performs.
2021-08-10 15:45:08 -07:00
LexManos 52d7df06da Fixed reference to registryAccess in dimension fix, and marked for removal in next MC version. Closes #7961 2021-08-10 13:10:50 -07:00
LexManos fcc819584a Bump BootStrapLauncher, and make sure Capability providers call parent revive. 2021-08-10 00:11:20 -07:00
Sirttas 4721d4c461 Fix custom ingredients not being read correctly over the network. (#7980) 2021-08-09 12:09:24 -07:00
Silver_David dbdc345d4a Add a OnDatapackSyncEvent, useful as a notification for modders to send extra data to the client (#7912) 2021-08-06 10:18:12 -07:00
Choonster TheMage 14c6fc3388 Add access transformer to make Features.Decorators class public (#7974) 2021-08-06 09:42:27 -07:00
LexManos 33419ed5b1 Fix NullPointerException in DetercorRailBlock patch. 2021-08-04 01:43:38 -07:00
LexManos 9ec1e24dc5 Remove entity.remove(keepData) functions because Mojang changed entity removal mechanics.
If a modder wishes to use the capabilities from a invalid entity. They must manually call reviveCaps/invalidateCaps themselves.
2021-08-04 01:08:04 -07:00
LexManos 06804675be Add forceSystemNanoTime config option to the client.
Normally glfwGetTime is used, but in some cases it may have performance issues.
2021-08-04 01:05:02 -07:00
Johannes Jäger 2f43f9910d Rename potion registry fields to match the mojang names (#7939) 2021-08-02 15:32:14 -07:00
bl4ckscor3 ea9a72af85 Fix patch issue that removed SimpleWaterloggedBlock from BaseRailBlock (#7937) 2021-08-02 14:58:06 -07:00
Striker Rocker 9a92363e15 Fix EntityInteractSpecific Event not being fired in server (#7936) 2021-08-02 14:34:42 -07:00
ChampionAsh5357 94389d0efd Add BlockEntityRenderer registering to RegisterRenderers (#7975) 2021-08-02 01:00:16 +02:00
DaemonUmbra 9080886c1a Fix installer issue with spaces in paths. (#7972) 2021-07-31 22:02:41 -07:00
Alex O'Neill 13ca55f34d Remove unused config entries. (#7954) 2021-07-30 17:43:45 -07:00
Alex O'Neill 5dbea18e30 Re-add call to Ingredient#invalidateAll() (#7953) 2021-07-30 17:42:52 -07:00
DaemonUmbra 30cfd848d8 Remove Generic from ProjectileImpactEvent (#7959)
Generification of this event was half-done and has been aborted, leaving the generic parameter in place just creates confusion and crashes
2021-07-29 19:10:35 -07:00
gigaherz 80d08dbf3a Introduce RegisterShadersEvent to register shaders with the proper timing (runs every client resource reload).
Fix ShaderInstance to allow resourcelocations with namespaces as input.
Fix shader parsing to respect resource domains.
Fix ForgeRenderTypes to use the right shader in each situation.
Add custom forge shader for unlit translucent entity rendering, equivalent to the vanilla entity translucent shader.
2021-07-30 01:48:20 +02:00
SizableShrimp 7d4c238165 Fix userdev mod deps on the classpath (#7919) 2021-07-27 22:43:36 -07:00
iTitus 0ea9401d90 Fix typo in FluidBlockWrapper (#7931) 2021-07-26 15:22:37 -07:00
LexManos 4bdfd8674d Fix rounding related errors with small entity pathfinding. Closes #7730 2021-07-26 14:24:24 -07:00
eerussianguy 3e9e0a6447 Add modder-friendly way to edit the boat model / texture in custom boats (#7897) 2021-07-26 10:54:51 +02:00
Commoble 76da41dd46 Fix EntityRendererEventsTest crashing dedicated server when running forge_test_server in forgedev (#7930) 2021-07-25 22:48:28 +02:00
gigaherz 6ddf56ef15 Added RegisterClientReloadListenersEvent which lets you register reload listeners with appropriate timing.
Added new entity rendering events.
- EntityRenderersEvent.RegisterLayerDefinitions: Used to register layer definitions for entity models.
- EntityRenderersEvent.RegisterRenderers: Used to register entity renderers.
- EntityRenderersEvent.AddLayers: Called during resource reload after all renderers have been constructed and it's safe to add layers.
Removed RenderingRegistry, which is now not necessary.
Removed a few unused things.
Fixes #7920
2021-07-25 12:06:36 +02:00
SuperMartijn642 eeec737188 Pass the 'includeName' flag to the ItemTossEvent (#7894) 2021-07-24 16:52:19 +02:00
Cyborgmas 119ac8f4ab remove old direct GL call (#7907) 2021-07-24 16:45:11 +02:00
Cyborgmas bdf0d9cf22 1.17 Fix InitGuiEvent (#7906) 2021-07-24 16:40:51 +02:00
SuperMartijn642 bd58ced0e4 Expose RenderStateShard inner classes (#7895)
In 1.17, all of the inner classes of `RenderStateShard` (`RenderStateShard.OverlayStateShard`, `RenderStateShard.WriteMaskStateShard`, etc.) have been changed to protected. These classes are needed however to create new `RenderType.CompositeRenderType`'s using `RenderType.CompositeState.CompositeStateBuilder`.
Since these are protected inner classes, their constructors also can't be directly be obtained using `ObfuscationReflectionHelper`.

Currently, any mod using custom `RenderType`'s will have to either:
- add their own access transformer for the inner classes, or
- extend `RenderStateShard` to access `RenderStateShard`'s inner classes, and extend `RenderType` to access `RenderType.CompositeRenderType`

This PR changes the visibility of `RenderStateShard`'s inner classes to public in Forge's `accesstransformer.cfg`.
2021-07-24 16:39:00 +02:00
Cyborgmas 5af6649435 added back attribute patches (#7886) 2021-07-24 16:30:21 +02:00
LexManos 695e1fbb94 Bump SecureJarHandler, and fix life cycle event's deferred work being on the incorrect thread/boot classloader. 2021-07-23 17:25:47 -07:00
LexManos b027a92dd2 Bump SecureJarHandler to fix package meta issue. Closes #7881
Fix version.json having duplicate libraries.
2021-07-22 14:52:17 -07:00
be5446b91c Update to 1.17
Update to Official classnames
Patchwork
Make the game compile and run
Merge in the new HUD overlay API
Merge in the new render properties API
PEEL
Use Gradle 7.2 snapshot to fix eclipse integration bug in 7.1, Would use 7.0 but FG needs 7.1 for some reason.
New FML installer
Update to 1.17.1

Co-authored-by: LexManos <[email protected]>
Co-authored-by: SizableShrimp <[email protected]>
Co-authored-by: cpw <[email protected]>
Co-authored-by: Curle <[email protected]>
Co-authored-by: Unnoen <[email protected]>
Co-authored-by: covers1624 <[email protected]>
Co-authored-by: DaemonUmbra <[email protected]>
Co-authored-by: gigaherz <[email protected]>
Signed-off-by: SizableShrimp <[email protected]>
2021-07-22 19:57:02 +01:00
LexManos 064ae6961b New 1.16.5 RB. 2021-07-21 18:25:45 -07:00
SizableShrimp 22d609ed6c ForgeGradle 5.1 and Gradle 7, which allows development on J16. Runtime still targets J8. (#7877) 2021-07-21 14:21:09 -07:00
LexManos 315bbb74ff Work around javac scoping issue. 2021-07-19 21:55:46 -07:00
LexManos 4e4d31b68c Fix LAN worlds where registry entries have been removed. 2021-07-19 21:15:26 -07:00
William Bradford Larcombe 1a17fa6129 Fix FakePlayers having null connection and add FakePlayer test mod (#7733) 2021-07-19 12:54:42 -07:00
AterAnimAvis ca9df21258 Use '{assets_root}' rather than task output path for userdev config (#7873)
Signed-off-by: AterAnimAvis <[email protected]>
2021-07-17 18:23:30 +02:00
Silk 93d7fa54fc Fix missing userdev config for datagen runs (#7871)
Signed-off-by: TheSilkMiner <[email protected]>
2021-07-17 13:14:38 +02:00
Bailey Hollingsworth f235d80d9f Adds a damage float in Lightning Entity and patches Entity to use it. (#7849) 2021-07-16 20:12:40 -07:00
Mike Garay be34dd89a9 Patch several mob classes to let them use modded versions of their ranged weapons (#7845) 2021-07-16 20:12:33 -07:00
AwesomeSyd239 6663f23e13 Add Fishing bobber projectile impact event (#7842) 2021-07-16 19:41:51 -07:00
OneLemonyBoi f9f7ef2580 Removes misapplied patch in Entity (#7841) 2021-07-16 19:38:56 -07:00
OneLemonyBoi 86352e9c19 Removes misleading Nullable annotation from canCreatureSpawn (#7840) 2021-07-16 19:38:06 -07:00
OneLemonyBoi 8c8b31435b Corrects the assigning of mob kills, Fixes MC-121048 (#7836) 2021-07-16 19:37:12 -07:00
OneLemonyBoi 16b3e2780e Updates MouseHelper to allow for Horizontal Scroll to be recognized as Vertical Scroll (#7834) 2021-07-16 19:31:14 -07:00
Take Weiland 1121f18413 Fix entities losing their scoreboard data when they are unloaded (#7826) 2021-07-16 19:24:29 -07:00
Take Weiland 96804fb4df [1.16] Allow blocks other than beds or respawn anchors to act as respawn points (#7824) 2021-07-16 19:23:36 -07:00
LexManos 03a6dbb405 Regen patches 2021-07-16 19:12:38 -07:00
Won-Ton 77e8c72589 Add AT entries for DimensionSettings to make them easier for mods to work with (#7817) 2021-07-16 18:03:56 -07:00
cech12 043e49a694 New hook to allow Trapdoors be climbable for custom ladders (#7816) 2021-07-16 18:01:27 -07:00
King Lemming 5169f1f6fe Convenience change for potion enumeration - does not change patch size in any meaningful way! (#7811) 2021-07-16 17:56:08 -07:00
Mike Garay 2bd83b26aa Adds knockback attribute to players and updated knockback calculation to PlayerEntity#attack (#7806) 2021-07-16 17:52:58 -07:00
Sekwah e6c1814122 Fix mod menu URL click bounds (#7804) 2021-07-16 17:51:11 -07:00
Daniel Houck 7f2892de7e Fix vanilla rotation/mirroring issues (#7803)
Patch minecraft to fix MC-227255 and MC-134110, which are block
rotation and mirroring issues.  I noticed this from problems with
Structurize, but this probably affects any other mods that allow
rotating or mirroring structures (as well as vanilla structure blocks).
2021-07-16 17:50:29 -07:00
PersonTheCat 439ba462d6 Synchronize ResourcePackList#addPackFinder (#7799) 2021-07-16 17:48:10 -07:00
mikewk 7c6ae3e61e Fixes tryFluidTransfer_Internal to respect the FluidStack drainable when draining fluidSource. (#7782) 2021-07-16 17:45:39 -07:00
Take Weiland f9b894ecbf Add IRecipeType parameter to burn time hooks (#7771) 2021-07-16 17:37:41 -07:00
Andy Dingley df53db351e Use MobGriefingEvent for PiglinEntity when determining whether Piglins want to pick up items. (#7762) 2021-07-16 17:35:24 -07:00
Andy Dingley 9aa04c8036 [1.16.x] Remove redundant mobgriefing check in SmallFireaballEntity. (#7761) 2021-07-16 17:33:59 -07:00
Queekusme 626496cec0 Changed AbstractFurnaceTileEntity's canBurn and burn functions to use IRecipe's 'assemble' instead of 'getResultItem' (#7756) 2021-07-16 17:33:02 -07:00
covers1624 022482a3bd Bypass chunk future chain when processing loads and getChunk called. (#7697) 2021-07-16 17:26:45 -07:00
DaemonUmbra dd228a9ac1 Removed sidedness from PacketBuffer methods. (#7236)
Affected methods:
* readLongArray (x2)
* readSectionPos
* readString (no-arg variant)
2021-07-16 17:25:11 -07:00
Silk a6d1646591 Add data generators for sounds.json (#6982) 2021-07-16 17:24:16 -07:00
Take Weiland 39f9f393db Add custom TextureAtlasSprite loaders (#7822)
Adds a system for mods to specify custom texture loaders which can be requested by the resource pack through a metadata section in the .mcmeta file. Due to technical reasons, png file is still required for MC to identify a texture as existing, even if the loader doesn't use it.
2021-07-16 01:55:43 +02:00
Commoble d35784eb14 Fix PlayerGameModeEventTest and ForgeWorldTypeTest so they don't crash the dedicated server when running forge_test_server in forgedev (#7869) 2021-07-15 16:40:07 -07:00
LexManos 31fb15c88d Add userdev to run config. 2021-07-13 18:15:54 -07:00
Take Weiland 29f175743b Add truncation to FMLStatusPing to work around protocol limits (#7818) 2021-06-16 19:23:20 -07:00
SizableShrimp 33499db93f Remove ModelResourceLocation patch for SAS entry (#7813) 2021-06-09 09:35:03 -07:00
Take Weiland 84381553a9 Fix jar file path detection if the path contains a "!" (#7790) 2021-06-08 13:26:01 -07:00
mrp-v2 2a7dde3d2e Add method to get the number of elements in a model builder (#7792) 2021-06-08 12:49:25 -07:00
Take Weiland aa4f24c915 Fix vanilla packet splitter remote detection and add advancement packet splitting (#7802) 2021-06-08 12:47:37 -07:00
Nightenom 1d87831773 Add option for linear filtering of text texture (#7645) 2021-06-08 21:33:31 +02:00
mrp-v2 65e99f9b58 Use empty model instead of missing model for non-existant layers in multilayer models (#7750)
Fixes issues when using multi-layer models as part of composite models
2021-06-08 21:07:33 +02:00
LexManos b98991dc70 Add debug logging to packet compression encoder.
Should make figuring out who is sending large packets easier.
Disable with -Pforge.disablePacketCompressionDebug=true
2021-06-03 10:29:49 -07:00
LexManos 435e65eb18 Removed signature line from mod list screen. #7500 2021-05-23 11:08:45 -07:00
Curle 8211a5048a Reinstate the MinecartCollisionHandler field to AbstractMinecartEntity (#7748) Closes #7506. 2021-05-17 13:51:23 -07:00
Curle 167f14f4a1 Fix PlayerEvent.BreakSpeed's pos being nullable. (#7747) Closes #7615. 2021-05-17 13:46:11 -07:00
Curle f332642409 Fix OBJ Loader data gen string (#7746) Closes #7616 2021-05-17 13:43:37 -07:00
noeppi_noeppi 77d41023b5 Add an event similar to PlayerEvent.NameFormat but for the name shown in the tab list. (#7740) 2021-05-17 13:17:01 -07:00
Curle da2594289c Fix filling buckets with fluids without bucket items consuming the fluid (#7745) Closes #7670 2021-05-17 13:10:27 -07:00
David Quintana 6f3da80b5a Work around crash while loading flatworld with modded structures. (#7764)
* Work around crash while loading flatworld with modded structures.

* Maybe fix issue with gradle daemon leaking memory and slowing down CI builds.
2021-05-14 00:11:46 +02:00
gigaherz 474b47ea51 Update Forge to Gradle 6.9 2021-05-12 23:33:33 +02:00
Trikzon b6ce4fb066 Add barrels and barrels/wooden block and item tag (#7676) 2021-04-30 10:53:19 -07:00
KnightMiner 1406f2bf1f Fix shears not properly breaking tripwire (MC-129055) (#7718) 2021-04-30 10:52:02 -07:00
JoJoModding 5125775992 Fix Line endings in tooltips not handled properly in multiplayer screen Closes #7738 (#7739) 2021-04-30 10:42:15 -07:00
Sydney 929c7b7a0b Fix cats, phantoms and pillagers saying they're at BlockPos.ZERO during LivingSpawnEvent.CheckSpawn (#7722) 2021-04-23 13:27:56 -07:00
mrp-v2 7bf02e7dcd [1.16] Add missing Multipart Blockstate Builder feature: Nested condition groups (#7677) 2021-04-22 22:55:18 -07:00
Dennis C 9d0d249eaf Pass BlockPos to BlockParticleData used for "fall impact" particle (#7705) 2021-04-22 22:53:58 -07:00
sciwhiz12 c4b1df1fc7 Check version ranges of optional dependencies when present (#7710)
If an optional dependency is present, but it does not conform to the version range,
it will now error out in the same fashion as missing required dependencies, instead
of a more cryptic error down the line due to a missing method/class/field/etc.

Implements and closes #7696
2021-04-22 22:52:24 -07:00
Take Weiland b3f253df61 Fix ClientVisualization crashing on systems without monitors (#7719) 2021-04-22 22:45:38 -07:00
atkarimarton dc099069fa Fix Furnace Minecarts going faster then vanilla (#7725) 2021-04-22 22:29:33 -07:00
AterAnimAvis e80c785563 Update for Forge's new maven (#7723) 2021-04-22 22:28:18 -07:00
cpw 1f9611204f A bloody quote FFS
Signed-off-by: cpw <[email protected]>
2021-04-18 11:35:05 -04:00
cpw 0120f6274d Update for new maven
Signed-off-by: cpw <[email protected]>
2021-04-18 11:28:54 -04:00
cpw c0e74bc8a8 Fix broken java9hacks for j16 handling..
Signed-off-by: cpw <[email protected]>
2021-04-02 14:27:25 -04:00
SizableShrimp 80feb0aeb2 Add generic EntityTeleportEvent (#7694) 2021-03-29 18:05:13 -07:00
covers1624 f47429717d Restore SS version, fixes findFieldInstanceChecks 2021-03-22 16:51:53 +10:30
Take Weiland 0239a736ec Fix sign textures being stitched onto every texture atlas (#7690) 2021-03-17 10:04:07 -07:00
LexManos 5c488c9007 Fix AT order, missed exec line and bump for RB. 2021-03-15 15:06:12 -07:00
Take Weiland 53c039680c Fix wrong eye height when entity size changes (esp. baby animals) (#7628) 2021-03-15 14:08:40 -07:00
Take Weiland 7379e8b9a4 Allow ITeleporter to override the vanilla teleport sound (#7682) 2021-03-15 14:02:20 -07:00
SizableShrimp 2a0d9e8dac Fix datapack exception related to EnumArgument with siblings (#7686)
Invalid enum constants are now properly thrown as a CommandSyntaxException
2021-03-15 13:20:08 -07:00
kaydogz aacba8e38e Add support for custom WoodTypes (#7623) 2021-03-15 12:28:45 -07:00
LexManos f4fd1c2f16 Use JGit instead of GrGit now that jcenter is going away.
Update missed mapped name in MDK.
2021-03-15 12:18:51 -07:00
gigaherz 813f3d630d Bump nashorn wrapper version. 2021-03-13 19:56:17 +01:00
gigaherz 76cea5a7da Fix yet another copypasta. 2021-03-13 19:56:17 +01:00
diesieben07 e33f794298 Fix incorrectly replaced SRG names 2021-03-13 19:56:14 +01:00
AterAnimAvis 72d05d17a9 Fix potential Deadlock when using custom Item entities. (#7532)
Be careful when adding Entities during Chunk Load (#7519)
2021-03-12 10:50:05 -08:00
gigaherz 19f9b309a6 Fix copypasta. 2021-03-12 02:54:10 +01:00
Curle 5b53616a47 Automatically fix some issues with configurations deemed invalid for simple reasons (#7671) 2021-03-11 16:11:05 -08:00
gigaherz 5f9e6f3b56 Add coremod that injects bouncer methods to work around name conflicts with official names.
Fixes a binary break.
2021-03-11 21:57:47 +01:00
gigaherz 0ad8e2c27f Bump SpecialSource 2021-03-11 19:29:20 +01:00
David Quintana 55f29764f8 Bulk update license year, and use replacement variable so that the current year is always used. 2021-03-10 23:41:00 +01:00
David Quintana a4f7087b92 Introduce a new feature that lets mods know if optional mods and optional network channels are present in the remote.
Allow connections from forge versions that don't have the vanilla splitter.
2021-03-10 23:40:59 +01:00
LexManos a95b968c13 Regenerate patches with relative headers. This should lower conflicts in future PRs.
Convert Forge to use Official mappings.
Mojang released their obfuscation mappings but we have not used them up until now due to wanting to get their license to be more explicitly permissive.
It is clear that their intent is to allow us to use their names for developing mods like this.
See the full wording, and our interpretation here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
2021-03-09 14:21:48 -08:00
LexManos 802298d99d Update to FG4, and Gradle 6.8. 2021-03-09 13:27:46 -08:00
Take Weiland 5363dc5d99 Support splitting vanilla packets that are too large on forge<->forge connections (#7485)
Currently only for SUpdateRecipesPacket and STagsListPacket that blow up with huge datapacks
2021-03-04 12:14:52 -08:00
Sara Freimer 9602c22083 Fix a few places where the vanilla method was being called instead of the forge one (#7535)
Cleanup javadocs references slightly, fix a couple spots not using the proper forge hooks, and remove a couple unneeded patches
Update deprecation comment on isAir
2021-03-03 12:50:32 -08:00
FireController#1847 17500032ae Add Opacity to ForgeHooksClient#renderMainMenu (#7660) 2021-03-02 21:28:48 -08:00
Marc Hermans 65bc41281f Add support for caching of configuration values. (#7608) 2021-02-24 18:36:51 -08:00
Kovak ba15737fe3 Added entity attribute setup and creation events 2021-02-15 18:40:32 -08:00
KnightMiner 58f93263e2 Fix updateItemStackNBT not properly being called (#7646)
Re-added ItemStack delegate redirect transformer
2021-02-15 17:28:35 -08:00
Sara Freimer d97f28141c Fix a few FluidUtil issues that were causing DispenseFluidContainer to not function properly (#7422) 2021-02-15 17:08:05 -08:00
ichttt 0340664dbf Add a way to specify a custom background texture with namespaces in the Creative GUI. (#7404) 2021-02-15 16:46:23 -08:00
DaemonUmbra d2cfda3fb4 Fixed Configs not correcting when hot-loaded from changes on disk (#7427) 2021-02-15 16:39:59 -08:00
FledgeShiu 48225e1bea Reduce default logging markers in the MDK. Modders can re-enable these for better debugging. (#7432)
Modders PLEASE read your damn log, and fix the errors we point out. Spamming modpacks with stack traces is just lazy programming.
2021-02-15 16:39:02 -08:00
sciwhiz12 37ea725749 Deprecate Forge's setdimension command, vanilla execute command can do this now. (#7459) 2021-02-15 16:19:13 -08:00
LeBossMax2 733b812c7b Fix ItemTextureQuadConverter.convertTexture generating wrong quads, fixes #7620 (#7650) 2021-02-16 00:38:21 +01:00
Sangar 9ab29ea8fe Added MultipartBakedModel.getModelData(). (#7595)
This allows custom IBakedModel implementations to use the IModelData provided by their IBakedModel.getModelData() when used in the context of a multipart model.
2021-02-16 00:22:24 +01:00
Cyborgmas fe26b77e3b fix global cache not being a block render type (#7648) 2021-02-16 00:15:33 +01:00
Alex O'Neill b8eca88f75 Allow mods to use additional custom LootParameter when querying existing loot tables (#7515) 2021-02-15 14:52:00 -08:00
Sydney e039531497 Add ForgeHooks.canEntitySpawn to Cat, Phantom, and Patrol spawners. (#7569) 2021-02-15 13:40:03 -08:00
Max Becker 9017e24b40 Fix/Replace player visibility event (#7573) 2021-02-15 13:25:54 -08:00
AterAnimAvis 75570079ae Fix: Clear the last error from glfwInit to prevent vanilla from throwing an exception later in the chain when glfw errors. (#7587) 2021-02-15 13:16:09 -08:00
seymourimadeit e2167140db Fix MC-181464 persisting for modded shields (#7602) 2021-02-15 12:56:34 -08:00
malte0811 a89ce2d6f1 FIx race condition in LazyOptional (#7611) 2021-02-15 12:11:27 -08:00
Dennis C 007cd42ec6 [1.16.5] Fix shaders breaking almost every overlay that uses textures, fixes #7575 (#7624) 2021-02-14 19:11:46 -08:00
TelepathicGrunt d16a8d6d5d Disable syncing of Feature and Biome registries (#7639) 2021-02-14 19:05:11 -08:00
Drullkus 69321a363e Add IExtensibleEnum to GrassColorModifier (#7641) 2021-02-14 19:04:31 -08:00
Sydney 0e1ee4b1d2 Log stacktraces in NettyPacketEncoder. (#7654) 2021-02-14 18:36:09 -08:00
Dennis C cc1a9be2b4 Lower logging level for datafixer warning to debug (#7636) 2021-02-10 11:05:01 -08:00
Sara Freimer 1d7da4c595 Reintroduce forge's chunk manager to allow mods to force chunks with either a block position or entity (UUID) "owner" and have them properly persist between restarts (#7642) 2021-02-09 14:19:07 -08:00
Sara Freimer 1ac432c594 Fix two places where querying an object for the new "valid" capability from a capability invalidation listener could cause the object to return the old invalid capability. (#7643) 2021-02-09 13:28:02 -08:00
Cyborgmas 276871d5a3 Fix config spec in cases of enum class discrepancies (#7635) 2021-02-09 13:21:23 -08:00
Take Weiland 8460227ddf Fix onBlockAdded being called twice for ItemEntity placing non-TE blocks (#7607) 2021-02-09 13:02:08 -08:00
Jon f450d4025d Prevent NullPointerException when adding new loot pool. (#7605) 2021-02-09 12:59:48 -08:00
brandon3055 93a815957d Added generic multi part entity API (#7554) 2021-02-09 12:53:25 -08:00
Cyborgmas 84b7cdc1cd Fix IAngerable entities crashing when reading nbt on client (#7618) 2021-02-06 19:41:12 -08:00
Silk 83fee0b3d4 [1.16.x] Add loot table ID in Global Loot Modifiers (#7428) 2021-02-02 13:32:02 +01:00
Sara Freimer aeaebf5785 Add a block tag to allow mods to blacklist blocks endermen should not be able to place blocks on top of, similar to how vanilla hardcodes against them being able to place things on bedrock (#7548) 2021-01-29 18:02:08 -08:00
HellFirePvP d88e660cbb Fix translucent model parts of MultiLayerModels rendering as missing models due to differing rendertypes when rendering block model (#7579)
Signed-off-by: HellFirePvP <[email protected]>
2021-01-29 18:01:16 -08:00
Sara Freimer ab949c7cca Fix existing file tag provider support looking in the wrong folder for custom tag types (#7576) 2021-01-29 17:34:54 -08:00
Cyborgmas 7728dde36b Propery re-encode registries (#7629) 2021-01-28 13:07:11 -08:00
Cyborgmas 004ab59e6f Properly encode registries. (#7626) 2021-01-27 17:22:58 -08:00
Cyborgmas 7bfd2b8f34 Inject vanilla dimensions inside worlds missing them (#7599) 2021-01-27 16:00:28 -08:00
LexManos f169c99348 Introduce a new field_to_instanceof transformer to reduce some simple patches. 2021-01-26 16:32:13 -08:00
LexManos d3d3bdc769 Fix broken build. 2021-01-25 18:52:46 -08:00
Max Becker 0a0f3232ea Add modded biomes to overworld biome list (#7360) 2021-01-25 18:36:46 -08:00
LexManos 50d75a27e1 Fix dynamic registries not getting ids assigned correctly from old worlds in specific unordered value insertions. Closes #7586 2021-01-25 18:17:51 -08:00
KnightMiner 19f8d2a793 Optionally add a milk fluid to the vanilla bucket (#7294)
Fixes the previous broken code that was supposed to make mod registered milk returned by the vanilla bucket by allowing mods to enable a milk fluid.
2021-01-17 16:05:24 -05:00
LexManos f173bde812 1.16.5 Initial Update. 2021-01-15 11:33:11 -08:00
LexManos dd10933ab0 Update Coremods, ASM, and include standalone Nashorn to load on J15. 2021-01-14 15:48:53 -08:00
LexManos 9ffa44f254 Introduce a new field_to_instanceof transformer to reduce some simple patches. 2021-01-14 02:52:52 -08:00
LexManos d8f41adf39 Update Coremods, ASM, and include standalone Nashorn to load on J15. 2021-01-12 13:22:13 -08:00
Ian Rehwinkel c3e84646db Added IWeatherParticleRenderHandler to allow a mod to take control over weather particles and sounds. (#7522) 2021-01-07 12:24:40 -08:00
covers1624 2094f99640 Allow Chunk loading Tickets to opt-into forcing chunk ticks. (#7525) 2021-01-07 12:13:47 -08:00
malte0811 94f3bdaa69 Fix crash when mods add goals to skeleton horses (MC-206338) (#7509) 2021-01-07 12:04:50 -08:00
Take Weiland 7220e9d0b0 Set WM_CLASS and WM_INSTANCE_NAME for early progress window (#7534) 2021-01-07 12:03:46 -08:00
Alex O'Neill 020102d87f Make UnboundedMapCodec more lenient in decoding dimensions. Fixes MC-197860 (#7527) 2021-01-05 19:17:24 -08:00
LexManos f101700969 Fix FML's Config Sync packet not allowing same length filenames in encoder and decoder. Closes #7584 2021-01-05 11:50:05 -08:00
LexManos c4b148b84b Prevent NPE and deprecated MissingMappings.getMappings function. Closes #6252 2021-01-05 11:47:00 -08:00
LexManos b6a9274870 Fix entities not correctly being able to be ridden under water. 2021-01-03 03:02:32 -08:00
Jonathan Coates 830d9699e3 Fix crash when beehive is broken by fake player (#7566) 2020-12-28 13:56:44 -08:00
Alex O'Neill fc68b81b21 Add supplier variant to AbstractBlock.Properties#lootFrom (#7563) 2020-12-28 13:42:15 -08:00
Take Weiland 2904772b16 Fix ModFileResourcePack.getAllResourceLocations ignoring resourceNamespace. (#7562)
Fixes #7405
2020-12-28 13:39:44 -08:00
Take Weiland e120b57032 Fix missing serializers when deserializing global loot modifiers (#7561) 2020-12-28 13:37:32 -08:00
Take Weiland b86b56260d Fix VanillaConnectionNetworkFilter sending out invalid entity properties packets without an entity ID (#7560) 2020-12-28 13:34:31 -08:00
Richard Freimer b222b23557 Make shear interactions extend to subclasses (#7544) 2020-12-28 13:10:35 -08:00
sciwhiz12 8ec4253068 Add a SoundType subclass that uses suppliers (#7538) 2020-12-28 13:09:03 -08:00
sciwhiz12 74ca88b7be Fix compound ingredient in shapeless recipes (#7537) Fixes #7530 2020-12-28 13:03:48 -08:00
Alex O'Neill a1119cd77a Fix potential NPE in ForgeHooks.onItemPlaceIntoWorld when passing in null player. (#7505) 2020-12-28 12:18:52 -08:00
mrp-v2 545723dc8c Fix modded PointOfInterestType's not populating blockstate map when registered (#7503) 2020-12-28 12:17:51 -08:00
poopoodice b64f4780c5 Add new LivingConversionEvent to control mobs turning into other mobs. (#7386) 2020-12-28 12:03:11 -08:00
KnightMiner 1c98b29087 Add ItemAttributeModifierEvent (#7484) 2020-12-28 11:59:09 -08:00
Brennan Ward 33880331d2 Fix RightClickBlock ALLOW not being implemented (#7426) 2020-12-28 11:54:30 -08:00
LexManos 74a43877e4 Quiet down errors related to modders not changing their update urls from the default. 2020-12-26 11:39:14 -08:00
LexManos 7542fbea48 Make mod data packs able to be disabled. It'll break things, but that's on you. Closes #6776 2020-12-26 11:38:45 -08:00
tterrag 2d9a1bc6f9 Add generated resource tracking to ExistingFileHelper 2020-12-12 12:33:56 -05:00
tterrag a57a240c13 Fix BlockStateProvider item models not knowing about block models
Add tests for this case
2020-12-10 21:37:13 -05:00
Richard Freimer b7fb6484d7 Override invalidateCaps instead of remove for vanilla TE capability invalidation (#7536)
Properly invalidate patched in vanilla TE caps in invalidateCaps instead of remove so that they get invalidated on chunk unload
2020-12-08 11:54:29 -08:00
Richard Freimer 1a539ffebc Make TEs invalidate capabilities when the chunk they are in unloads (#7529)
Fixed LazyOptional potentially notifying invalidation listeners multiple times.
2020-12-05 12:05:32 -08:00
Kevin G 27220a5ad8 Fixed entity navigation to stop entities spinning - MC-94054 (#7520) 2020-12-05 11:54:03 -08:00
Unbekannt1998 e975fc8252 Fix wrong function call in BlockStateProvider::horizontalFaceBlock (#7514) 2020-12-05 11:52:44 -08:00
tterrag d85ea5a3b0 Fix datagen order of multipart conditions being unstable 2020-11-28 21:10:49 -05:00
Alex O'Neill ccb7345084 Fix forge config option for default world type not applying unless you change the default world type (#7521) 2020-11-28 03:56:44 +01:00
David Quintana 93c00b67d9 Implement feature for mods to define new world types (#7448)
* Mods can now register world types via a new forge registry, and optionally register a settings screen to tweak them.
  * The default world type for dedicated servers and singleplayer world creation is configurable via forge's common config.
2020-11-28 00:57:15 +01:00
IzzelAliz cd393bbfdc Fix dimType not encode to registries (#7513) 2020-11-24 09:14:10 -08:00
Richard Freimer fd045d4628 Add support for referencing forge's resources and specifying existing mods to data generators (#7456) 2020-11-22 22:45:13 -05:00
cpw 47e076071b Fix #6692
Thanks @AterAnimAvis for help and suggestions

Signed-off-by: cpw <[email protected]>
2020-11-22 17:00:48 -05:00
Cyborgmas a73e003dd3 Fix translucent blocks not rendering properly when moved by pistons on fabulous (#7441) 2020-11-21 11:57:33 -08:00
LexManos 949984268d Bump version for RB. 2020-11-20 12:53:44 -08:00
Take Weiland 114acfca3b Fix food bar not rendering when non-living entities are mounted (#7446) 2020-11-20 10:24:43 -08:00
Alex O'Neill 56e538e8a9 Fix MC-194811 - Removing structures causes chunk save errors. 2020-11-20 10:23:50 -08:00
Take Weiland fa46f3dd49 Fix concurrency issue in StartupMessageManager (#7483) 2020-11-20 10:17:00 -08:00
Alex O'Neill 6ec5a8f2c1 Fix forge registry types that have private constructors (BlockStateProviderType, BlockPlacerType, FoliagePlacerType, TreeDecoratorType) (#7482) 2020-11-20 10:11:15 -08:00
cpw 49b596dda3 Fix problem where the absence of forge and MC in later loading triggered a weird crash.
Signed-off-by: cpw <[email protected]>
2020-11-15 11:08:34 -05:00
cpw 0c5ced1bbf Fix NPE problem when modid is mismatched.
Signed-off-by: cpw <[email protected]>
2020-11-13 20:41:20 -05:00
cpw 4a09a2420d Return the processed modlist data to the upstream system, not the raw unprocessed data. Should resolve the problem
that mixin complains about missing info when it's in a "crashed" situation.

Signed-off-by: cpw <[email protected]>
2020-11-13 19:12:43 -05:00
Cyborgmas 0ff8a596fc Fix dims on servers not loading the first run (#7445) 2020-11-11 01:09:35 -08:00
Take Weiland bca20ace4e Allow for custom argument types by filtering them on vanilla connections (#7463) 2020-11-10 12:24:25 -08:00
Brennan Ward f3b53001c9 Add Player context to AnvilUpdateEvent (#7442) 2020-11-10 12:05:47 -08:00
Jonathan Coates 15bac0eeaa Don't overwrite PlayerAdvancement's player with a fake one (#7454)
If a FakePlayer is constructed with the same UUID/GameProfile as a
currently active player, the player object within PlayerAdvancement is
set to the fake player.

As fake players cannot receive advancements (see grantCriterion), this
prevents the actual player from receiving any advancements until they
change dimension/relog.
2020-11-10 11:55:42 -08:00
Curle 1782973a29 Add BannerBlock.forColor to SAS to fix banner.toItem() on servers. 2020-11-10 11:38:20 -08:00
Boy132 9a4a501a95 Call Harvest check event even if the block doesn't require any tool (#7414) 2020-11-10 11:36:32 -08:00
LexManos 9bbfbd5479 Use linked collections to stabilize order when adding new registry entries. 2020-11-10 11:24:57 -08:00
Dennis C 8c68731838 Render local player when the renderViewEntity is not the local player (#7216) 2020-11-10 11:13:49 -08:00
cpw 0d7f507f4e Some help in ExtensionPoint regarding DISPLAYTEST. Let's improve those tick rates!
Signed-off-by: cpw <[email protected]>
2020-11-07 23:11:45 -05:00
cpw f78b943bdf Handle erroring during early mod construction phases, and actually report that into the error UI
by doing armslength exception handling and propagation.

Signed-off-by: cpw <[email protected]>
2020-11-07 22:30:19 -05:00
cpw 160f3f88f9 Support backwards loading 1.16.3 mods in 1.16.4, because we are able to do that. Tweak loading a bit to be smarter about dependency errors of various kinds.
Signed-off-by: cpw <[email protected]>
2020-11-07 20:48:02 -05:00
David Quintana 45e38859ed Add FluidStack codec, and a test mod that verifies its behaviour matches the existing write/read logic.
Add missing license headers.
2020-11-07 21:10:18 +01:00
cpw 38a5400a8c Update event bus version (should be 3.0.5)
Tweak MDK to automatically populate recommended values for things like forge version, loader version and minecraft version.

Signed-off-by: cpw <[email protected]>
2020-11-06 21:11:26 -05:00
diesieben07 acd18455c2 Workaround for modded attributes on vanilla entities logging warnings on vanilla clients
Switch to a handler-based approach per packet class, simplify patch, add some docs

Add license header and docs

Switch to a network handler based approach

Switch to a network handler based approach

revert build gradle change

Simplify Packet patch

Add license header to IForgePacket

Revert ForgeHooks changes

Less hacky and more generic way to filter packets for vanilla connections

_Actually_ Order SAS.
It's early

Order SAS

simplify vanilla connection check

Remove unneeded import change
2020-11-03 18:47:04 -05:00
cpw 5a7facc20f Fix early sorting bug that meant the file deduping was causing an error, to, well, not cause it, so we can get to an error screen.
Signed-off-by: cpw <[email protected]>
2020-11-02 14:57:23 -05:00
LexManos f54998a6b7 1.16.4 Initial Update 2020-11-02 10:42:45 -08:00
LexManos 7d00d015f3 Fix Biomes not properly copying over ids loaded from the save to the new Dynamic Registry. 2020-11-01 20:30:38 -08:00
David Quintana fed7beab89 Introduce custom loader additions to the model data generators. (#7450)
Currently implemented loaders:
* OBJ
* Composite
* Multi-layer
* Item layers (vanilla item/generated but with fullbright texture support)
* Bucket
* Separate Perspective
2020-11-02 02:09:49 +01:00
cpw cf3e9d1e0c actually rollback on error in registry events.
Signed-off-by: cpw <[email protected]>
2020-11-01 19:51:56 -05:00
cpw 749c9063af Fix config parse failure causing crash in building exception message. fixes #7438
Signed-off-by: cpw <[email protected]>
2020-11-01 17:09:00 -05:00
Tobias Hotz 1af6632a29 Auto-detect ansi support for log4j2
move to fml.loading subpackage

Add license header
2020-11-01 17:03:12 -05:00
cpw 7e79243bca Return client resources even if no data pack found on server. Closes #6225 (Pull request)
Signed-off-by: cpw <[email protected]>
2020-11-01 17:02:56 -05:00
cpw 36f9c804d9 Update modlauncher. fixes #7452
Signed-off-by: cpw <[email protected]>
2020-11-01 16:05:02 -05:00
malte0811 06fe9ccda0 Fix (NonNull)Lazy.Concurrent using a global lock (#7403)
* Fix Lazy.Concurrent using a global lock, thus preventing multiple threads from resolving independent Lazy's at the same time
* Use Lazy with an added null check to implement NonNullLazy
2020-10-29 18:09:20 +01:00
David Quintana 53eedb0f10 Update forge mappings to 20201028-1.16.3 (#7435) 2020-10-29 01:11:57 +01:00
Alex O'Neill 6e0e67b14d Fix breaking changes from the Biome rename PR #7434 (#7439) 2020-10-27 09:00:53 -07:00
sciwhiz12 22f7f4649b Reimplement nametag distance attribute, fix attribute translation keys (#7387) 2020-10-26 16:52:36 -07:00
Alex O'Neill 8a77681574 Fix data pack biomes failing to load in SingleBiomeProvider (#7434) 2020-10-26 15:06:53 -07:00
cpw 6982c5dd56 Add in proper handling of equals and hashcode for modjar urls. Fixes very slow loading on windows.
Signed-off-by: cpw <[email protected]>
2020-10-26 18:00:14 -04:00
cpw 7205c30ece Force 8.0.5 ML
Signed-off-by: cpw <[email protected]>
2020-10-26 08:51:05 -04:00
cpw 80baad974e Restore FingerprintViolationEvent with appropriate THIS IS F*CKING DEAD DELET WARNINGS.
Also, notify in UI if using legacy JDK without capability to read out security data from mod jars.

Signed-off-by: cpw <[email protected]>
2020-10-26 07:31:49 -04:00
cpw ae160cad12 Add signature reporting for mods, using new signature capture from ModLauncher. Need to figure out
how to reflect Minecraft's JAR signatures into here.

Signed-off-by: cpw <[email protected]>
2020-10-25 22:26:16 -04:00
cpw 6ff6277efa Rollback registries to vanilla state if something happens during loading, so subsequent activities can still run and not generate false reports..
Signed-off-by: cpw <[email protected]>
2020-10-25 11:33:43 -04:00
LexManos 74f9ef838a Fix mcp_snapshot mapping issue causing unneeded patches. Closes #7424 2020-10-20 12:32:19 -07:00
David Quintana 395f89c973 Fix resource leak in the OBJ loader. 2020-10-20 13:24:12 +02:00
SilverDavid 8536521b7b Fix issue with ITeleporter allowing easier use of vanilla logic. (#7317) 2020-10-16 12:09:53 -07:00
Richard Freimer b1659300e0 Adds tag support for Enchantments, Potions, and TileEntityTypes (#7379) 2020-10-15 12:45:25 -07:00
LexManos 93226bbcff Resuscitate BiomeDictionary using RegistryKeys instead of biome references. 2020-10-15 12:43:18 -07:00
Ocelot 51fa230e7b Add event for player changing game mode (#7355) 2020-10-15 10:15:06 -07:00
cpw 5f292895cb Fix RCON multipacket responses not actually understanding UTF8.
Signed-off-by: cpw <[email protected]>
2020-10-12 14:10:57 -04:00
cpw 9cfe741cea Fix RCON not sending newlines in output for multiline. Fixes https://bugs.mojang.com/browse/MC-7569, a very old bug that is really annoying if you use RCON.
Signed-off-by: cpw <[email protected]>
2020-10-11 21:48:55 -04:00
ChampionAsh5357 bed38d4253 Fix Texture Presence String (#7408) 2020-10-10 09:45:18 -07:00
LexManos 37f226eda5 Fix typo causing potential error in vine growth. Closes #7406
Sort missing registry dumps by name, making it easier to read.
2020-10-09 12:56:26 -07:00
David Quintana 59b4affbe7 Fixed conditional advancement loading when using the "advancements" array.
Added automatic generation of conditional advancements from the criteria in the conditional recipe entries.
Added advancement name calculation from the recipe ID.
2020-10-09 15:47:32 +02:00
Flanks255 5477a36656 Additions to the mdk build.gradle to accommodate datagens. (#7398) 2020-10-08 14:03:41 -07:00
DaemonUmbra 5648336893 Added Basic Class-Level SAS Capability to checkSAS, added Vector4f to SAS (#7385) 2020-10-08 14:02:48 -07:00
Richard Freimer f5b53d5d10 Add hooks to allow modification of structures spawn lists (#7344) 2020-10-07 13:04:03 -07:00
Richard Freimer 10448c1ac9 Add back patches to Screen allowing for item tooltips to be auto wrapped again (#7378)
Only deals with the methods receiving an ItemStack or ITextComponent(s), the methods that take IReorderingProcessor(s) are left alone.
2020-10-06 21:38:27 +02:00
Mumfrey 5243275db2 Bump mixin version to 0.8.2 2020-10-05 15:34:07 +01:00
cpw 3041c2022b Add in extra debug logging
Signed-off-by: cpw <[email protected]>
2020-10-04 17:45:28 -04:00
cpw 09be003d61 Remove redundant call to CrashReport generator - Vanilla is doing a crashreport for itself at startup now.
Add a UUID into crashreport that is also logged in all channels at crash report generation time. This will allow to associate crash reports and the logs.

Signed-off-by: cpw <[email protected]>
2020-10-04 16:40:38 -04:00
cpw 3fe5ddd68f Fix doc README and answer lex's question
Signed-off-by: cpw <[email protected]>
2020-10-04 15:50:58 -04:00
cpw 935cb6782d Modify how ModLoadingStage handles dispatch to Registry Events. Stops the objectholder spam and generally improves performance on larger packs.
Signed-off-by: cpw <[email protected]>
2020-10-04 15:50:15 -04:00
DaemonUmbra 9b421b54a7 Added "Bukkit Plugin" to InvalidModIdentifier (#7384) 2020-10-02 16:40:06 -07:00
Richard Freimer 6e23030595 Fix vanilla Campfire smoke bug. MC-201374 (#7381) 2020-10-02 16:34:17 -07:00
sciwhiz12 78d69db79e Fix toggleable keybindings still being active while in GUI Fixes #7370 (#7373) 2020-10-02 16:28:21 -07:00
Max Becker 9177ac1b2e Fix modded EntityClassifications not being useable in the codec. (#7337) 2020-10-02 15:06:48 -07:00
cech12 248d207dbc Support effective materials of vanilla AxeItem (#7351) 2020-09-28 11:01:59 -07:00
LexManos 03082c361a Prep new RB. 2020-09-23 23:48:57 -07:00
ichttt 65372e3123 Fix grass disappearing when alwaysSetupTerrainOffThread is true (#7291) 2020-09-23 23:43:07 -07:00
Alex O'Neill 0f923fa51f Accessors for inspecting and removal of biome generation settings. Fixed carvers still being immutable. (#7339) 2020-09-23 23:39:25 -07:00
LexManos d1e3567c6b Revive BiomeManager and BiomeLayer hooks. 2020-09-23 23:35:40 -07:00
Richard Freimer af75547d37 Fix a few minor issues with custom tag types and fix OptionalNamedTags (#7316) 2020-09-23 20:12:11 -07:00
Take Weiland 37be3aff2d Fix ToggleableKeyBinding differences to vanilla. (#7338) 2020-09-23 15:10:01 -07:00
Take Weiland b9b17d8331 Fix forge light pipeline applying block offsets twice (#7323) 2020-09-23 14:34:38 -07:00
Yunus 2a433a5c8c Updated build badge versions to 1.16.3 in readme (#7325) 2020-09-23 14:25:59 -07:00
ichttt e344fd08a5 Add a better license error screen (#7350) 2020-09-23 14:16:36 -07:00
Tyler Hancock 0484f695fb Fixed container item being consumed in brewing stand. #7307 (#7314) 2020-09-22 12:14:08 -07:00
sciwhiz12 e55bd86dff Fix parse results of CommandEvent being disregarded (#7303) 2020-09-22 12:06:01 -07:00
Nightenom b1247df4dc [1.16] Fix possible crash when using rendering regionCache (#7207) 2020-09-22 11:58:19 -07:00
Alex O'Neill 91dda36b08 [1.16] Reimplement ICloudRenderHandler, ISkyRenderHandler and IWeatherRenderHandler (#6994) 2020-09-22 11:41:07 -07:00
Alex O'Neill ac19d1bf2b Make Biome.Climate and BiomeAmbiance fields accessible (#7336) 2020-09-17 17:57:58 -07:00
cpw e0e0302ece Use mixin 0.8.1. Should fix problems with mixin not working properly with latest modlauncher.
Signed-off-by: cpw <[email protected]>
2020-09-17 16:41:46 -04:00
Sebastian Hartte 6eb3e20abb Sets the empty/fill sounds for vanilla fluids.
Use Fluid's fillSound rather than emptySound when filling buckets.
2020-09-15 22:06:17 +02:00
Cyborgmas 738491c25d Add MatrixStack-aware alternatives to the methods in GuiUtils (#7127) 2020-09-15 21:46:58 +02:00
Justin Wiblin 2686b7a9ab Fix json biomes not setting registry name correctly for the BiomeLoadingEvent. (#7329) 2020-09-15 09:51:45 -07:00
David Quintana 4b93e3a224 Fix inconsistencies in how the values from the model are passed into the baked model.
This puts them in line with vanilla, as intended.
2020-09-15 16:17:57 +02:00
Yunus 873c490470 Reimplemented drawHoveringText (#7268) 2020-09-15 15:22:50 +02:00
LexManos 11e3281b3f New BiomeLoadingEvent that allows modders to edit biomes as they are being deserialized. 2020-09-14 17:43:01 -07:00
LexManos ce6c664acd Bump MCP version for lambda issue. 2020-09-11 08:55:13 -07:00
LexManos c75eb9e7cf 1.16.3 Update
Also included a bunch of warning cleanups.
2020-09-10 12:01:45 -07:00
Redstone_Dubstep 2353cd982a Fix tile entities being replaced when not needed. (#7318) 2020-09-10 11:54:48 -07:00
malte0811 dbcf8bd075 Fix exception when getting rendering box for tile entities with no collision boxes. (#7301) 2020-09-10 11:02:06 -07:00
cpw 9f3141ea16 More crash reporting tweaks. Don't crash when trying to show warnings. Also, put the exception name in the error screen on the second line!
Signed-off-by: cpw <[email protected]>
2020-09-09 19:04:19 -04:00
Take Weiland c382527ba2 Fix Minecart speed cap on rail being initialized to 0 (#7315) 2020-09-09 10:09:00 -07:00
Richard Freimer 45f8dc5245 Add support for custom tag types (#7289) 2020-09-08 19:10:36 -07:00
cpw 43391c009c More crash report tweaks. Put a button to open the generated crash report on the error screen, tweak formatting of crash report, and add the enhanced stack trace data (transformers et al)
Signed-off-by: cpw <[email protected]>
2020-09-08 20:05:45 -04:00
ChampionAsh5357 15733a18e4 New hook for better custom scaffolding movement (#7261) 2020-09-08 14:00:09 -07:00
Cyborgmas f68344cd7c Fixed crash with zip paths (#7300) 2020-09-08 13:47:39 -07:00
mrp-v2 e421ea164c Fix custom teleporters NPE (#7296) 2020-09-08 13:29:07 -07:00
Cyborgmas 178e3d244a Prevent duplicate wrapper tags from crashing (#7283) 2020-09-08 13:25:23 -07:00
Tschipp bd5e107628 Add partialTicks to RenderNameplateEvent (#7277) 2020-09-08 13:24:02 -07:00
NoahBeech a477671c03 Fixing logic in getCurrentRailPosition to correctly identify the rail… (#7276) 2020-09-08 13:23:18 -07:00
Edwin Mindcraft 887bc37209 [1.16.x] Fixes for Bamboo, Enchantments and Conduits, small adjustments to bring some patches closer to the vanilla code. (#7239) 2020-09-08 13:03:36 -07:00
sciwhiz12 47f05a4fcd Bump resource pack version to 6 (#7299) 2020-09-08 13:02:28 -07:00
sciwhiz12 47ba5b7a89 Remove dead ForgeHooks.canToolHarvestBlock function. (#7262) 2020-09-08 13:01:26 -07:00
ChampionAsh5357 05480843cd Re-implement DrawHighlightEvent$HighlightEntity Firing (#7233) 2020-09-08 12:50:06 -07:00
ichttt 0e1ed8c936 Reimplement FarmlandWaterManager (#7213) 2020-09-08 12:25:48 -07:00
Cyborgmas edf41bda19 Add dataprovider for Global Loot Modifiers (#6960) 2020-09-08 12:11:08 -07:00
ichttt 051416b823 Fix crash when dumping crash report for an exception that has a null cause (#7308) 2020-09-08 12:00:55 -07:00
cpw 84fe2cbcc4 Tweak crash report dump to visit all the causes up to the top.
Signed-off-by: cpw <[email protected]>
2020-09-06 21:29:21 -04:00
cpw 4ff0d246ce Fix ExplodedDirectoryLocator visiting non-existent paths. Closes #7203
Also, bump modlauncher to 7.0.1 to fix resources.

Signed-off-by: cpw <[email protected]>
2020-09-06 19:38:58 -04:00
cpw 9051021474 Fix some potential issues in crash dumping during mod loading
Signed-off-by: cpw <[email protected]>
2020-09-06 18:07:53 -04:00
cpw cc473be332 Park the polling thread for a bit, if we're not the one driving the task list forwards. This allows for the actual driver to work on low cpu count machines.
Signed-off-by: cpw <[email protected]>
2020-09-06 17:55:03 -04:00
cpw b1f73a0760 Use new enumeration mechanism in ModLauncher, to allow getResources to work. This enables serviceloader-in-mods, and other stuff that might need to visit multiple mod jars. Also, tweaked the visitor code slightly, may result in a trivial performance change. Closing #7302 as it's not really relevant any more.
Signed-off-by: cpw <[email protected]>
2020-09-06 17:54:05 -04:00
cpw de03eb6e3c Fix compiler issue in eclipse properly
Signed-off-by: cpw <[email protected]>
2020-09-03 12:09:29 -04:00
sciwhiz12 bef8c2da3d Fix crash caused by previous commit (#7298) 2020-09-03 08:40:40 -04:00
LexManos 3820d1b66f Dirty casting hacks to fix eclipse compiler inference issue. I'm sorry cpw. 2020-09-02 21:15:16 -07:00
tterrag 7dbae7ea4a Fix broken ExistingFileHelper import
Add licenses to some new files
2020-09-02 23:37:46 -04:00
tterrag be5885155c Add validation via resources for tag providers (#7271)
BREAKING CHANGE: Moved ExistingFileHelper to common package
Remove various workarounds from forge tag providers
2020-09-02 23:18:22 -04:00
cpw 5dac065994 Move the "modloading" thread activity onto _our_ worker pool. It turns out that the vanilla worker pool can deadlock during stitching if it's insufficiently large, if modloader "waitForTransition" is also a worker member of that pool.
Closes #7293 (to reproduce issue easily, modify Util.func_240979_a_ and change the values in the MathHelper.clamp call). I've verified that 3 and below for "max" cause the problem. (I didn't test a whole range of values, just sufficient to reproduce problem and verify fix). Note that setting it to zero (and using the "direct executor" that's inaccessible in normal operation) works as well with this fix.

Signed-off-by: cpw <[email protected]>
2020-09-01 14:36:02 -04:00
cpw 1d7db95539 Fix missed debugging code. Read the config from the config.
Signed-off-by: cpw <[email protected]>
2020-08-31 22:26:53 -04:00
cpw de24783152 Fix up slight registry change and other 1.16.2 stuffs.
Signed-off-by: cpw <[email protected]>
2020-08-31 21:30:53 -04:00
cpw bfeec0c7bd Merge branch '1.16.1' into 1.16.x
# Conflicts:
#	patches/minecraft/net/minecraft/client/Minecraft.java.patch
#	patches/minecraft/net/minecraft/item/crafting/Ingredient.java.patch
#	src/main/java/net/minecraftforge/fml/client/ClientModLoader.java
#	src/main/java/net/minecraftforge/registries/GameData.java
2020-08-31 21:15:56 -04:00
cpw 2e42340dfa Fix up all the things. Removed SidedProvider because it served no real purpose anymore.
Signed-off-by: cpw <[email protected]>
2020-08-31 21:00:44 -04:00
cpw 16b82bb97b Merge branch '1.16.x' into 1.16.1
# Conflicts:
#	src/main/java/net/minecraftforge/fml/ModList.java
#	src/main/java/net/minecraftforge/fml/client/ClientModLoader.java
2020-08-30 21:44:51 -04:00
cpw d76ee4edd7 Redo event dispatch, removes a bunch of nonsense, and tries to integrate with the vanilla CF system where possible
Signed-off-by: cpw <[email protected]>
2020-08-30 21:39:06 -04:00
ichttt cf09f3eeb9 Add particle culling (#6981) 2020-08-30 16:05:16 -07:00
LexManos d8eaeabf3c Wrap vanilla's 'default' biome registry in ForgeRegistry.
This should allow registering mod dimensions like in 1.16.1, while the data driven system is fleshed out.
2020-08-26 09:49:41 -07:00
David Quintana 600e68cace Clarify in the LazyOptional which methods carry the lazyness over to the returned value and which don't. (#6750)
For consistency, this meant making a few changes:
- Renamed the existing lazy mapping method to lazyMap, to indicate that it doesn't run the mapping immediately.
- Added a new implementation of map(), which returns Optional<T>, and resolves the value in the process.
- Changed filter() to return Optional, since there's no way to filter lazily.
- Added a new method resolve(), which helps convert the custom LazyOptional class into a standard Optional, for use
with library methods that expect Optional<T>.

* Update License headers.
2020-08-25 03:11:28 +02:00
sciwhiz12 625cd746ef Add user-friendly exceptions when config loading fails (#7214) 2020-08-21 14:27:12 -07:00
Max Becker fc000fe913 Replace EntityHeight event with EntitySize event (#6858) 2020-08-21 11:53:37 -07:00
Davide Albiero e3db429763 [1.16] ForgeEventFactory#canCreateFluidSource reintroduced (#7181) 2020-08-21 11:37:43 -07:00
Cyborgmas e803006360 Cleanup and expand Forge tags (#7004) 2020-08-21 11:30:21 -07:00
sciwhiz12 07ffc890e5 Fix modproperties property in mods.toml causing exception (#7192) 2020-08-21 11:25:40 -07:00
Philip T 5a20705f05 Log info about server list warning (#7209)
Make it easier to figure out what mods are missing or have to be marked as client/server side only.
2020-08-21 11:15:44 -07:00
mcenderdragon aaa1deeef2 Fix ItemStack#isDamageable is not calling Item#isDamagable (#7221) 2020-08-21 11:06:38 -07:00
Take Weiland 50197b1fa5 Improve performance and cleanup code for DelegatingResourcePack (#7228) 2020-08-21 10:48:48 -07:00
Cyborgmas 797791c2af Fix small logging issues with loading pack.png for mods (#7265) 2020-08-21 10:24:49 -07:00
Take Weiland c2de232703 Fix config iteration order (#7230) 2020-08-21 10:23:20 -07:00
LexManos 9118c3dd24 Cleanup Forge's build script, fix some unneeded patches.
Add checkExcscheckAll tasks.
2020-08-21 02:47:04 -07:00
ChampionAsh5357 c6d512afe8 Readding DifficultyChangeEvent hooks (#7240) 2020-08-20 21:35:09 -07:00
malte0811 5037adede9 Improve startup time by caching the manifest data for mod jars (#7256) 2020-08-20 21:29:02 -07:00
Yunus a5aca97e31 Removed HarvestDropsEvent (#7193) 2020-08-18 22:47:38 -07:00
Cyborgmas edca0c7293 Remove forge optional tags in favor of Vanilla's new system. (#7246) 2020-08-18 22:22:34 -07:00
LexManos 132cc3659d New method for creating modded tag references, fix connecting to vanilla servers. 2020-08-14 12:04:55 -07:00
LexManos 680c4062f4 Fix creating nether portals. 2020-08-14 12:04:17 -07:00
sean e1efab0452 Print mod file name on InvalidModFileException (#7241) 2020-08-13 19:16:53 -07:00
Yunus bd428de4fa Updated MDK and README for 1.16.2 (#7243) 2020-08-13 12:22:58 -07:00
Cyborgmas 978b3c7fb1 Fix server connection, misapplied patch (#7245) 2020-08-13 12:22:17 -07:00
LexManos fe43088c96 Initial 1.16.2 Update 2020-08-13 00:35:08 -07:00
David Quintana a3c4ffd2c1 Fix ModelRegistryEvent firing every time resources reload instead of just once. 2020-08-09 22:04:44 +02:00
David Quintana a8e68328c4 Move ModelRegistryEvent invocation to when the model loading is about to start.
Freeze the ModelLoaderRegistry right after this event happens, just before model loading actually begins.
This means ModelRegistryEvent is now the correct place to register loaders, as it was intended.
This is a slight breaking change, but any mod that used FMLClientSetupEvent before will need to be updated regardless due to the existing race condition.
2020-08-08 03:00:15 +02:00
Take Weiland 8bad5b1f13 Fix wrong BlockState param passed into canSustainPlant from FarmlandBlock (#7212) 2020-08-03 17:19:12 -07:00
sciwhiz12 54b4089afd Add harvest levels for hoes and new 1.16 blocks for pickaxes Fixes #7187 (#7189) 2020-08-03 17:06:36 -07:00
sciwhiz12 493608e1b5 Fix debug world not generating modded blocks (#6926) 2020-08-03 17:00:31 -07:00
ChampionAsh5357 0984777c98 New IForgeBlock#getToolModifiedState hook allow better control over tools interacting with blocks. (#7176) 2020-08-03 16:49:26 -07:00
Xerousso 97a2b9a448 Added new hook to allow Biomes to control their Edge biomes (#7000) 2020-08-03 16:21:13 -07:00
brandon3055 399bc6c9c3 Add support for custom elytra (#7202) 2020-08-03 15:55:10 -07:00
Take Weiland 20702456ac Re-introduce "outdated" notification on Mods button in main menu (#7123) 2020-08-03 15:11:06 -07:00
sciwhiz12 b4a6d186de Fix RenderTickEvent using wrong partial ticks value when game is paused. Fixes #6991 (#7208) 2020-08-03 11:53:21 -07:00
tterrag 8f9e52c260 Implement forge IBakedModel methods in vanilla wrapper models 2020-07-29 23:10:40 -04:00
LexManos e62805f1d7 Fix another case of swallowed errors not shutting down mods. 2020-07-28 16:44:29 -07:00
cpw ff752ab14b Revert "Properly shutdown FMLModContainer's event bus when an error in a lifecycle event is detected."
This reverts commit 30bad1e2

Signed-off-by: cpw <[email protected]>
2020-07-28 19:17:35 -04:00
cpw 19a38f5cb9 Revert "Shut down all other mod handlers if the loading cycle errors. This prevents other mods from throwing errors and being blamed for initial cause. This is a temporary hack until cpw re-writes the mod event dispatcher."
This reverts commit 7592bbe8

Signed-off-by: cpw <[email protected]>
2020-07-28 19:17:29 -04:00
LexManos 7592bbe87e Shut down all other mod handlers if the loading cycle errors.
This prevents other mods from throwing errors and being blamed for initial cause.
This is a temporary hack until cpw re-writes the mod event dispatcher.
2020-07-28 14:39:53 -07:00
LexManos 30bad1e26d Properly shutdown FMLModContainer's event bus when an error in a lifecycle event is detected. 2020-07-28 12:01:15 -07:00
LexManos 5104824a1b Enable EventBus type check during ForgeDev, and add IModBusEvent marker to ModelRegistryEvent. 2020-07-28 10:24:52 -07:00
LexManos 4ffcdaa6da Make license toml entry optional during 1.16.1
There are to many existing mods to make this required.
Yes, we are technically before a RB and can do breaking changes. However this is too large.
2020-07-28 00:16:18 -07:00
cpw 95d2b6ae89 Missed one event. NewRegistry needs the marker.
Signed-off-by: cpw <[email protected]>
2020-07-27 21:13:53 -04:00
cpw d21c05b9ea Update MDK license to default to All rights reserved, and offer a link to chooseyourlicense.com as a place to research appropriate licenses.
Note: the license field _is_ backwards compatible and will simply be ignored on older forge versions.
Signed-off-by: cpw <[email protected]>
2020-07-27 21:06:48 -04:00
cpw 97dfcbc52b Update coremods and spi, include mandatory license field in metadata. Added at top level of mods.toml file.
Signed-off-by: cpw <[email protected]>
2020-07-27 20:21:39 -04:00
cpw 532d153d33 Update modlauncher, eventbus, accesstransformers and more to use a newer mechanism for generating ASM.
Introduced IModBusEvent as a marker interface for events on the ModBus. Expect exceptions if you use
the modbus for events not listened there.

Signed-off-by: cpw <[email protected]>
2020-07-27 19:40:43 -04:00
Raycoms 849e718a42 Fix rail 180 rotations (#7177) 2020-07-27 16:35:15 -07:00
Jamie Mansfield 720966544d Fire AnimalTameEvent for cats (#7172) Closes #7171 2020-07-27 16:00:14 -07:00
LexManos 7717795f42 Fix Biome generation error. 2020-07-27 15:56:04 -07:00
Paul Becker daa817bbdf Fix SleepingTimeCheckEvent not being fired in initial sleep test. (#7005) 2020-07-27 14:35:13 -07:00
Yunus fba168051a Fix ClimberPathNavigator spinning when width is small. Closes #6993 (#6997) 2020-07-27 14:30:16 -07:00
Tschipp 941b9a1d1f Re-added PlayerEvent.NameFormat (#6992) 2020-07-27 14:16:35 -07:00
Xerousso 27798c5804 Fixed modded overworld biomes not spawning [1.16.x] (#6990) 2020-07-27 14:10:42 -07:00
Cyclonit 9d84b5df31 Added EntityLeaveWorldEvent (#6984) 2020-07-27 14:06:01 -07:00
Amber 00797fdb3a Re-implement moddable flammabilities (#6983) 2020-07-27 14:02:45 -07:00
Yunus 8d617767ad Updated versions in README and removed flocker.tv mentions (#6978) 2020-07-27 13:42:06 -07:00
Take Weiland c9f9fd01b5 Re-add patch for PlayerSetSpawnEvent (#6977) 2020-07-27 13:41:35 -07:00
sciwhiz12 2450693f7d Fix ChunkDataEvents using different data tags (#6961) Fixes #6957 2020-07-27 13:40:22 -07:00
Joseph Tarbit cf7784ac4b Post SoundLoadEvent on mod bus instead of forge bus (#6955) 2020-07-27 13:26:51 -07:00
cpw e3137213e5 Remove startupquery. Currently wasn't functional, and 1.16 has out of band state loading in all cases, so the complex functionality there is no longer needed. Going to research using the Lifecycle indicator from DFU as a proxy/replacement. Probably with some codec FUN.
Signed-off-by: cpw <[email protected]>
2020-07-21 21:26:02 -04:00
LexManos 7b43b9f8c0 Run Forge's data generators to sync 1.16 vanilla changes. 2020-07-21 17:34:23 -07:00
cpw daa85d3c5b Don't show the early launcher GUI when running data. It's not needed and prevents use on automated builds.
Need to investigate why a bunch of tags seem to be being blown away by rerunning on forge.

Signed-off-by: cpw <[email protected]>
2020-07-21 20:12:33 -04:00
cpw 9e8c4c3a58 Add mixin
Signed-off-by: cpw <[email protected]>
2020-07-21 19:55:57 -04:00
Cyborgmas 24f3ef5ffe Load Modded Datapacks in DatapackScreen, before world creation (#6913) 2020-07-20 15:56:21 -07:00
tterrag a3edfd3748 Fix inconsistencies with model/blockstate datagen 2020-07-18 18:34:35 -04:00
Max Becker 96b9a057b7 Filter duplicate mod files from mod file scan data (#6855) 2020-07-17 10:35:38 -07:00
LexManos 638d1d31de Fixed Forge commands. Closes #6973 Closes #6974 Closes #6976 2020-07-16 14:08:13 -07:00
Jared 00013865b0 Added an event for registering commands. closes #6968 (#6969) 2020-07-15 12:30:41 -07:00
Tyler Hancock 6722e7a428 Make all functions in Style common. (#6931) 2020-07-13 17:15:32 -07:00
seymourimadeit 0f56b4c4ee Mark Raid.WaveMembers as an extensible enum. (#6878) 2020-07-13 15:40:37 -07:00
LexManos 201349f8de Fix checkPatches task. Closes #6956
Fix patched in method using srg name. Closes #6965
Fix capabilities not being collected for ClientWorld. Closes #6966
Fix TagEmptyCondition using client side copy of tags instead of server. Closes #6949
Fix ExtendedButton using narrator text. Closes #6958, Closes #6959
Fix misaligned patch in RepairContainer. Closes #6950, Closes #6953
Fix LivingJumpEvent not being fired for players jumping horses. Closes #6929
Remove extra getToughness method in ArmorItem. Closes #6970
Remove GetCollisionBoxesEvent. Closes #6921
2020-07-13 15:17:37 -07:00
Richard Freimer 065ebde57e Fix race condition with DeferredRegister for custom registries (#6951) 2020-07-10 14:08:22 -07:00
sciwhiz12 6b3f2f46fa Remove hooks into beacon base/payments. Vanilla uses tags now for extensibility. (#6948) 2020-07-10 10:49:42 -07:00
Jared e4ffbeb329 Expose the DataPackRegistries instance to the AddReloadListenerEvent (#6933) 2020-07-08 14:24:01 -07:00
sciwhiz12 60ee0bcdb3 Fix canRepair not being set true as default (#6936)
Closes #6934 and #6935
2020-07-08 14:13:07 -07:00
David Quintana 2a2306d6e1 Fix misaligned patch causing LivingEquipmentChangeEvent to never be posted. 2020-07-08 16:54:47 +02:00
David Quintana fc3fa13bf3 Fix particles sometimes "losing" the lightmap and drawing fullbright. 2020-07-08 12:01:27 +02:00
Justin aab8adb884 Add simple patch checker and cleanup patches (#6851)
* Add simple patch checker and cleanup patches

* Address comments
 * move task implementation
 * genPatches is now finalized by checkPatches
 * the S2S artifacts are automatically removed
 * added class and method access checking
2020-07-06 14:30:10 -07:00
Richard Freimer 2ad347b043 Fix the modifier combined name for keybinds displaying two pluses outside of forgedev #6901 (#6902) 2020-07-06 14:26:54 -07:00
Richard Freimer d26e285e09 Fix harvest level and tool type not actually getting set #6906 (#6922) 2020-07-06 14:12:36 -07:00
Richard Freimer 91a2b02590 Reimplement ITeleporter Patches (#6886) 2020-07-06 13:45:22 -07:00
Mysterious_Dev a567ddaa10 Add function to add items with the same behavior as the pumpkin for enderman (#6890) 2020-07-06 13:34:01 -07:00
Richard Freimer 68e71009f3 Custom Item integration with Piglins (#6914) 2020-07-06 13:30:17 -07:00
ichttt 0227bfe9ee Some dead code cleanup, and re-implement some bed hooks. (#6903) 2020-07-06 13:19:53 -07:00
Take Weiland df57e0a1ba Fix missing null checks in ForgeIngameGui (#6907) 2020-07-06 13:06:31 -07:00
sciwhiz12 68ea1b654c Fix swap offhand keybind not working in GUIs (#6920) 2020-07-06 12:43:05 -07:00
Cyborgmas ff86201523 New AddReloadListenerEvent that gathers server side data reload handlers. (#6849) 2020-07-06 12:41:57 -07:00
David Quintana 8e5138da27 Attempt to use a more compatible method to initialize stencil support.
In case the separate attachments don't work for everyone, there's a new setting to choose the combined attachment.
2020-07-03 14:40:21 +02:00
David Quintana a690a7526a Fix multi-layer item rendering. 2020-07-03 05:54:46 +02:00
David Quintana 517bbc8b5b Update copyright year to 2020. 2020-07-02 19:49:11 +02:00
David Quintana ce3d8b40cf Model system improvements:
- Port some things I did in 1.14 which I couldn't do in 1.15 due to breaking changes.
- Fix multi-layer block models not working (1.16 RenderType doesn't override toString the same way anymore)
- Implement multi-layer item rendering.
- Improve CompositeModel submodel data passing.
2020-07-02 19:16:40 +02:00
Cyborgmas 45152c6073 Pass matrixstack in tooltip render events (#6885) 2020-07-02 14:43:41 +02:00
SuperMartijn642 46c9dec421 Include model data in getQuads call (#6884)
The model data wasn't included when getting quads from specific sides, but was when getting quads for side = null.
2020-07-02 14:43:23 +02:00
tterrag a0b0e6788d Fix improper handling of baked lighting in forge light pipeline
Closes #6812
2020-07-02 01:53:52 -04:00
pupnewfster b00c91af3c Fix FMLServerAboutToStartEvent being fired too late on the integrated server https://github.com/MinecraftForge/MinecraftForge/issues/6859 2020-07-01 21:59:03 -04:00
ichttt d11a582a25 Fix miss-aligned patch ItemEntity (#6895) 2020-07-01 11:14:16 -07:00
MelanX bf1a0461cb Add hoe tool type (#6872) 2020-06-30 13:17:57 -07:00
ichttt 4aa53dbb00 Fix loading screen color and text (#6824) 2020-06-30 13:16:51 -07:00
Curle a79e4b3722 Allow any armor to have custom knockback resistance (#6877) 2020-06-30 13:09:12 -07:00
Take Weiland d1016f752e Add senderUUID to ClientChatReceivedEvent (#6881) 2020-06-30 12:57:23 -07:00
LexManos ab29145328 Re-write checkATs function and automate making Items/Blocks public. 2020-06-29 19:33:34 -07:00
cpw 99e7fad655 Reorganize modloading on the dediserver. This removes the DedicatedServer parameter from the FMLDedicatedServerSetupEvent.
Code for customizing the server instance should be moved to the ServerAboutToStartEvent or similar, where the server instance
is available.

This reorganization means that mods will load fully before the server is even constructed, or the server properties loaded. We also move the EULA right to the front so we don't have to wait for bootstrap.

This should fix the problems with mods which customize world data and other things.

Signed-off-by: cpw <[email protected]>
2020-06-29 22:09:37 -04:00
Cyborgmas d5aa0c4a91 Fix datagen resolving tags and exploding. (#6865) 2020-06-29 16:39:04 -07:00
Matthew Messinger 20d231bbed Fix Language.javaLocale parsing (#6862) 2020-06-29 16:37:21 -07:00
Take Weiland 5db6f158f8 Fix IItemHandler wrappers for chests not updating both chests (#6875) 2020-06-29 15:58:22 -07:00
LexManos 88d02712db Fix missed patch in PlayerList and EntitySelectioonContext. Closes #6846 Closes #6850 2020-06-29 13:57:10 -07:00
ichttt 7858abe96d Make Type classes safe to use in concurrent loading (#6825) 2020-06-29 13:29:32 -07:00
Richard Freimer b0e35f358e Fix access levels being hardcoded to private via patch overriding AT entry (#6848) 2020-06-29 13:09:04 -07:00
LexManos 80d2730fec Fix tag related issues when connecting to a vanilla server. 2020-06-29 12:42:32 -07:00
LexManos 3b64ea6305 Fix Forge's internal handler being registered in wrong place.
Fix double call to loader end.
2020-06-28 15:08:03 -07:00
David Quintana 5f1a7326c7 Add a model loader that lets mods specify different models for different perspectives.
Allow custom models to reference vanilla item models as child models.
2020-06-28 00:32:50 +02:00
LexManos af9bb9641b Fix swim speed being incorrect. Closes #6845
Fix BreakSpeedEvent having null position. Closes #6844
Add MatrixStack to BackgroundDrawnEvent. Closes #6843
Fix some patches that should of been ATs. Closes #6839
Add getter to ServerPlayer to access client's language calue if sent. Closes #6829
Some patch cleanup.
2020-06-26 16:55:04 -07:00
LexManos fc6b38d7f2 Fix blocks being harvested with incorrect tools. 2020-06-26 15:40:05 -07:00
Cyborgmas 4887a5e0e7 fix misapplied patch
also sneak in an import patch removal
2020-06-26 18:40:02 -04:00
LexManos 97d4652f5f Make installer use MCPConfig version to identify MC assets. 2020-06-26 12:52:50 -07:00
cpw 41a6d70aee Tweak the server startup a bit, make sure methods that can't work because they run before a server exists explode saying so.
Also fix other launch profiles.

Signed-off-by: cpw <[email protected]>
2020-06-26 14:27:32 -04:00
LexManos 99917e569c Fix dedicated server loading by constructing mods before data packs are created. 2020-06-26 09:56:23 -07:00
David Quintana 30227a1e28 Fix create method.
Fix test mods not loading correctly.
2020-06-26 17:20:21 +02:00
David Quintana a1110b92d0 Reintroduce missed patch in EntityClassification. 2020-06-26 16:43:01 +02:00
Cyborgmas 438e3886cc Include a getter for the matrix stack in OverlayEvent (#6834) 2020-06-26 15:55:33 +02:00
Cyborgmas fa6ca9c275 Fix block render types not being properly applied to item entities (#6832) 2020-06-26 15:22:57 +02:00
its_meow 71baebcc93 [1.16.x] Allow GlobalEntityTypeAttributes' EntityType -> AttributeModifierMap to be added to (#6822)
* Make GlobalEntityTypeAttributes map able to be added to

* Split get patch into two lines

* Favor Forge's map over vanilla
2020-06-26 15:03:56 +02:00
Cyborgmas e7b5dcb149 Fixed creative screen arrows (#6827) 2020-06-26 14:58:48 +02:00
Yunus 29e52e963d Added call to method for tooltip with FontRenderer (#6831) 2020-06-26 14:57:26 +02:00
Curle 3dc8d2b293 Retarget Block.Properties patch to the new AbstractBlock, reintroduce harvestLevel and harvestTool fields (#6819)
* Retarget Block.Properties patch to the new AbstractBlock, reintroduces the harvestLevel and harvestTool fields.

* Slight adjustment to fix the lootTableSupplier.
2020-06-26 14:35:36 +02:00
Yunus 29be40adec Fixed sneaking while swimming (#6817) 2020-06-26 14:25:32 +02:00
Cyborgmas 272ea75aab Fixed tooltip rendering issues (#6815) 2020-06-26 14:24:58 +02:00
Cyborgmas cbac95de0f Fixed villager trades having non-applicable enchants
Also added an AT at lex's request
2020-06-25 22:30:44 -04:00
Yunus 87d89fb09a Updated MDK mods.toml versions (#6808) 2020-06-25 18:42:28 -07:00
Dominik Baumann 7bca3684bd Add missing patch to ScreenShotHelper (#6809)
Adds the missed patch back
2020-06-25 18:42:17 -07:00
Cyborgmas 6cfc88e707 Fix block drops (#6810) 2020-06-25 18:42:11 -07:00
Cyborgmas 8179a504cb Fix locate command (#6811) 2020-06-25 18:42:01 -07:00
LexManos baf32612db Rework BlockSnapshot and fix client notifications. Closes #6807 2020-06-25 18:41:38 -07:00
LexManos 9cf9305fd0 Bump MCPConfig version. 2020-06-25 16:24:35 -07:00
cpw 4700973dff Update to 1.16.1 and fix a couple more patch problems
Signed-off-by: cpw <[email protected]>
2020-06-25 18:28:48 -04:00
cpw 648d53ffe1 Fix some patching derps from 1.15 merge
Signed-off-by: cpw <[email protected]>
2020-06-25 18:16:38 -04:00
cpw c7ed9f690e Clean up legacy cruft
Signed-off-by: cpw <[email protected]>
2020-06-25 17:55:54 -04:00
Anthony Anderson ca2ed1ff7a Final patching
Signed-off-by: cpw <[email protected]>
2020-06-25 17:55:54 -04:00
covers1624 80eb12e59d Compiling fixes - IN GAME! 2020-06-25 17:55:52 -04:00
tterrag 631230b298 Patching and updates 2020-06-25 17:55:40 -04:00
cpw 6d15febdb3 Setup and import of 1.16 YEET 2020-06-25 17:55:38 -04:00
covers1624 56397043bb Allow RayTraceContext to be constructed with a null entity. (#6708) 2020-06-25 17:54:00 -04:00
Yanny 469527890f Replace explicit shears reference in vanilla loot tables with tag for modded shears. (#6765) 2020-06-25 17:53:58 -04:00
hanetzer 2ffdfb9582 Fix cache file sorting issue on linux (#6793) 2020-06-25 17:52:38 -04:00
Cyborgmas 4178885e29 Fire jump event for horses when ridden (#6802) 2020-06-25 17:52:36 -04:00
cpw 20f78ac724 Modify how modfiles load slightly, for better decoupling.
Signed-off-by: cpw <[email protected]>
2020-06-25 17:51:27 -04:00
Take Weiland b117722d84 Throw an exception from DeferredRegister when trying to register entries after registry event has fired (#6789) 2020-06-25 17:51:27 -04:00
DaemonUmbra 2acf2110ef Potential userProperties Fix (#6740) 2020-06-18 14:24:26 -07:00
Take Weiland 6345f2670c Add system for dimensions to be marked for deletion (#6515) 2020-06-15 09:37:08 -07:00
LexManos 9114bec81d Fix dedicated server issue in some implementations of Block.getPickBlock. Closes #6566 2020-06-12 17:28:05 -07:00
LexManos 9ac626d2a9 Fire SpecialSpawn event for mobs spawners. Closes #6700 2020-06-12 16:53:01 -07:00
LexManos 457909b6d5 Remove the yellow coloring on hover in ExtendedButton to match vanilla behavior. Closes #6714 Closes #6713 2020-06-12 16:36:58 -07:00
LexManos 07b62b77e6 Fix entity pathing not matching vanilla. Closes #6755 2020-06-12 16:24:27 -07:00
DaemonUmbra e374f62037 Fixed --server argument crashing the client (#6754)
Closes #6753
Moving the fadeOutStart setter above the callback invocation prevents re-entry into the block (which would result in an infinite loop and a StackOverflowException) if the callback causes a render tick (which creating a new ConnectionScreen does).
2020-06-12 15:46:52 -07:00
brandon3055 0209daec36 Fixed ItemStack comparison ignoring capabilities when stack nbt is null. (#6764) 2020-06-12 15:43:38 -07:00
Vincent Lee 1b89f931eb Supply matrixstack to IRenderHandler where possible. Closes #6439 (#6537) 2020-06-12 15:42:44 -07:00
Take Weiland a3e4b75c59 Fix StartupQuery not working more than once on the client (#6699) 2020-06-12 15:36:00 -07:00
DaemonUmbra 45b90a0d45 Added ProjectileImpactEvent.FireworkRocket (#6758) 2020-06-12 15:33:44 -07:00
LexManos fd9bf64d53 Add custom registry type support to DeferredRegister. (#6742)
It's still a hard dependency because it requires a class reference.
But there is not a sane way to test registry types without a class reference.
2020-06-12 15:28:43 -07:00
Take Weiland 5dbea9ea8d Fix "overlayMessage" rendering in ForgeIngameGui being different than vanilla (#6748) 2020-06-07 08:47:59 -07:00
David Quintana 28f7b5d885 Implement loader for ItemLayerModel.
Add support for specifying which layers are fullbright.
Fix improper generation of model edge. - Thanks to iChun and KnightMiner for the fix suggestions.
2020-06-04 16:04:09 +02:00
LexManos 0c0603dc91 Remove dead test classes. 2020-06-03 17:46:30 -07:00
LexManos f24991f3bb Add --flat argument to data generators to not create data in mod specific directores.
Useful For Forge's test mods mainly.
Standardized data gen cache file's folder separators.
Added ItemModelProvider to BlockStateProvider for cleaner datagen code.
Added .gitattributes to fix datagen json's line endings correct on windows.
2020-06-03 16:57:07 -07:00
cpw a39f1cbe1a Improve the DistExecutor API and introduce some "almost completely" safe mechanisms to handle sided lambdas.
In general, use sided lambdas safely by embedding them in a separately loaded class. There's a whole twitch stream
dedicated to investigating this problem. See link in DistExecutor if you're interested.

Signed-off-by: cpw <[email protected]>
2020-05-24 17:40:52 -04:00
tterrag 6fd01a13ee Fix typo in new registry fields' names
Note: this is technically a breaking change. If you for some reason added code referencing these two fields in the last few hours, sorry.
2020-05-23 21:24:30 -04:00
tterrag 6829324f5a Fix server startup query info not including new text 2020-05-23 16:22:29 -04:00
tterrag eb9c966095 Improve look of notification GUI, improve StartupQuery API 2020-05-23 16:05:10 -04:00
tterrag f0bab0fb38 Add forge registries for applicable new registry types
Expose constructors for all forge registry entries
Also, remove deprecation on ItemCameraTransforms/TransformType
2020-05-23 13:42:56 -04:00
LexManos d5cb0935e9 Bump version for new RB. 2020-05-15 12:33:32 -07:00
LexManos d4f79882f9 Update MCP Mappings. 2020-05-15 12:17:25 -07:00
ichttt 8d3685439e fix test mod and add warning comment to framebuffer (#6698) 2020-05-15 20:25:57 +02:00
LexManos 68cf703435 Fix FireBlock using flammability instead of spread speed when looking for places to spread. Closes #6646 2020-05-15 10:59:57 -07:00
LexManos bcdd04d549 Fix incorrect argument passed in RenderPipeline potentially causing crash. #6677 2020-05-15 10:53:35 -07:00
Funwayguy ec7d9d4179 Re-added patch to enable stencil buffer in net.minecraft.client.shader.Framebuffer
Add test for the stencil buffer feature. Only tests that it doesn't crash when enabling, for now. - giga
2020-05-15 19:49:55 +02:00
TheSilkMiner 765da1aca8 Allow Music Discs to be created with SoundEvent delegates. (#6523) 2020-05-15 10:38:19 -07:00
Edwin Mindcraft 7fa42ca064 Use IProperty#getName when generating blockstate jsons (#6582)
Close #6520
2020-05-15 13:28:10 -04:00
David Quintana c23ea1e733 Model system fixes:
- Add "origin" key to determine what origin to use. This will default to the existing (broken) behaviour to avoid breaking changes.
- Fix interaction of transforms with variant transforms (transformation ordering).
- Fix OBJ loader ignoring "diffuseLighting" attribute from the json.
  This attribute will continue not being used if "ambientToFullbright" is on (default) to avoid breaking changes.
2020-05-15 19:25:26 +02:00
LexManos 0f48e851a3 Fixed typo in registry alias writing causing infinite loop. Closes #6689 2020-05-15 09:38:20 -07:00
LexManos 549007a4a6 Fixed Partivle.onGround not updating correctly due to decompile error. Closes #6595 2020-05-15 09:37:51 -07:00
covers1624 932e7c84b3 Remove duplicate post of ChunkEvent.Load. (#6697) 2020-05-15 07:45:37 -07:00
Cyborgmas 999b5df933 Fix LevelChange event not firing after enchanting (#6693) 2020-05-14 13:22:12 -07:00
ichttt 29396b6235 Fix server config directory remaining locked when integrated server is shut down. (#6644) 2020-05-12 15:11:45 -07:00
Alex Thomson 4ce32c3663 Fix exclusion of coremods not filtering correctly when the mods directory is a symbolic link. (#6600) 2020-05-12 15:02:01 -07:00
Jais Djurhuus-Kempel 8084cc5499 Allow Bees to use custom hives. (#6656) 2020-05-12 14:29:32 -07:00
Tom Boshoven 988fc97af1 Fixed tile entities persisting when switching between states that don't have TEs without changing the block. (#6674) 2020-05-12 14:21:28 -07:00
Jamie Mansfield 5f082045b0 Fixed CropGrowEvents not firing for Bamboo (#6680) 2020-05-12 14:18:36 -07:00
Jamie Mansfield abc98ba56b Fix vanilla screens escape key not matching done button behavior (#6682) 2020-05-12 14:18:03 -07:00
ShetiPhian e35c5c9ae4 Fixed FluidTank.drain calling onContentsChanged when simulating (#6684) 2020-05-12 14:17:17 -07:00
LexManos 926fa5d5a6 Fix infinite loading screen when resources error. Closes #6592 & #6593 2020-05-12 14:08:05 -07:00
covers1624 99d8fa1a6b Fix IForgeBlock.removedByPlayer not firing on the client. (#6638) 2020-05-11 15:28:38 -07:00
cpw 1a317a7306 Update to newer eventbus, with typetools compatibility with jvms up to j14. No guarantees on actual game compatibility however.
Signed-off-by: cpw <[email protected]>
2020-05-10 20:34:57 -04:00
Jamie Mansfield fa01ba3221 Fixed informational /forge commands being repeated to all ops when logging is enabled. Closes #6330 2020-05-06 13:49:15 -07:00
Jamie Mansfield 766019e1fc Fix ModListScreen escape key not matching done button behavior. Closes #6672 2020-05-06 13:41:43 -07:00
David Quintana a7e4cdcc49 Patch the bucket logic to not hardcode some checks to WATER. Fixes not being able to place custom fluids into modded fluid-loggable blocks that accept fluids other than water. 2020-05-06 13:30:20 +02:00
David Quintana 6551ccc247 Avoid discarding the bottom 4 bits of the lightmap coords. It turns out vanilla relies on those bits. Fixes some blocks being darker than they should be in certain circumstances. 2020-05-04 01:13:43 +02:00
Jacob Smith c3e4d303e9 Fix issue with providing a null ItemStack to onPlayerDestroyItem (#6633) 2020-05-03 13:48:17 -07:00
Brennan Ward 9e763a8334 Allow overriding of tool level requirements when harvesting a block, via the HarvestCheck event. (#6632) 2020-05-03 13:40:34 -07:00
Richard Freimer 035c01e222 Fixed Hoppers not inserting fully into custom contains with slots that can hold more then max stack (#6631) 2020-05-03 13:34:26 -07:00
Corey Frenette 1fa88ebd56 Fixed ChunkDataEvent.Save being fired with a null world if chunk isn't fully generated when unloaded. (#6628) 2020-05-03 13:27:06 -07:00
Tyler Hancock 4fce4eb10b Fix vanilla loot table resource leak. (#6622) 2020-05-03 13:23:09 -07:00
Tyler Hancock 2e694d3a6d Change recipe condition log level to debug. (#6621) 2020-05-03 13:22:22 -07:00
CAS-ual-TY e8966a05f5 Fix milk buckets removing potion effects without filters. (#6609) 2020-05-03 13:17:43 -07:00
Dion van der Hak a377727ac4 Added missing localization for swim speed, and reach distance attributes (#6585) 2020-05-03 13:13:56 -07:00
Vincent Lee 385fb64ab7 Allow colors of tooltip to be specified in GuiUtils.drawHoveringText tooltip methods (#6579) 2020-05-03 13:09:28 -07:00
ichttt f2216f4e25 Fix config comments referencing disallowed enum values. (#6542) 2020-05-03 12:56:47 -07:00
David Quintana 0fc1ea01d1 Remove redundant call to modifyLoot. Closes #6657 2020-04-28 19:22:48 +02:00
tterrag ea23cd4779 Fix various issues with the loading screen and datagen
Fix NPE on datagen startup
Fix early loading GUI hanging and never terminating after datagen
Add loading GUI messages for datagen
2020-04-28 00:00:45 -04:00
Take Weiland 903a400132 Fix BackgroundScanHandler crashing on servers (#6660) 2020-04-27 11:06:34 -07:00
cpw 940f3ed731 Remove silly icon override. Squirrels are fun y'all..
Signed-off-by: cpw <[email protected]>
2020-04-27 09:55:14 -04:00
tterrag 9d8817b5db Rename window icon image to avoid conflict, fix not using vanilla icon 2020-04-27 01:09:34 -04:00
tterrag 10204f8d82 Fix VariantList calling deprecated bake method 2020-04-26 23:48:51 -04:00
LexManos 746d702058 Fix resource packs not being sorted properly. Closes #6287 2020-04-26 20:05:56 -07:00
LexManos 3c5728f070 Fix Automatic Event Subscriber not detecting mod id defaults, and fix test mods. 2020-04-26 19:04:37 -07:00
cpw 8c8ef2d9e1 Use forge logo as short term window Icon, fix Buffer cast problems for new JDK stupid.
Signed-off-by: cpw <[email protected]>
2020-04-26 21:42:18 -04:00
cpw 6a25490d7f Handle message display a bit better, try to make the UI tick a bit better.. Still a problem with
a modelbake right at the end, happening on the window flip.

Signed-off-by: cpw <[email protected]>
2020-04-26 21:03:43 -04:00
RogueLogix 6a0b16817d Move ClientVisualization to secondary thread 2020-04-26 16:06:44 -07:00
RogueLogix 677e2104a0 move handOffWindow down near start() 2020-04-26 15:41:53 -07:00
cpw 438c969fef merge early startup into main window if used. It seems to work well.. Also ticks window on main thread, so mac compatible now.
Signed-off-by: cpw <[email protected]>
2020-04-26 18:24:48 -04:00
cpw 4af0bfd661 Update jenkinsfile and gradle for new versions of things..
Signed-off-by: cpw <[email protected]>
2020-04-25 17:54:50 -04:00
LexManos 03c2a3d3a8 Fix potential NPEs in RegistryObject.orElseThrow/isPresent/ifPresent Closes #6647 2020-04-24 19:18:57 -07:00
David Quintana 9a6d1c390e Add tickRate setter to the ForgeFlowingFluid Properties builder. 2020-04-23 14:57:06 +02:00
cpw 0512a47eba Fix recursion mess in PlayerAdvancement loading, by using an alternative based on a toposorted list of all advancements.
It seems to be fully equivalent in testing, but there may be corner cases, so there is a config to disable, though disabling
may break servers, especially those chunkloading fake players.

Signed-off-by: cpw <[email protected]>
2020-04-19 21:36:44 -04:00
LexManos 699a5c3c18 Revert defualt jvm args. 2020-04-15 10:09:49 -07:00
LexManos 5a552b9f8d Fixed dev time compilation using J9+ producing incorrect bytecode. 2020-04-14 23:54:32 -07:00
David Quintana aa5b9d12ea Add "type" field to global loot modifier jsons. (#6554)
* Add "type" field to global loot modifier jsons and fix tests.
To avoid binary breaking, "type" defaults to be the same as the filename.
* Fix license headers.
2020-04-12 21:27:11 +02:00
tterrag a3b1007633 Fix child annotations not inheriting member name, cleanup 2020-04-11 01:57:40 -04:00
tterrag bdd0af5280 Fix element type of scanned child annotations 2020-04-11 01:19:25 -04:00
Patrick Ocampo 5e554530ac Fixed PlantType not extending IExtensibleEnum, Closes #6286 2020-04-08 17:17:38 -07:00
valoeghese 713c24d916 Added hook to allow modded Hill Biomes (#6571) 2020-04-08 17:12:04 -07:00
tterrag c359a38d9f Improve performance of VertexBufferConsumer by inlining element locs 2020-04-07 21:44:29 -04:00
tterrag d84a88d78d Revive forge lighting pipeline, disabled by default for now
Remove a lot of light value convolution by using 0..1 for nearly everything
Fix a lot of TODOs that are needed for the lighting pipeline to function
Potential fix for #6425
2020-04-07 21:44:15 -04:00
tterrag cf9b1b2193 Fix Tag serializing empty optionals, improve RegistryObject error msg 2020-04-05 00:48:56 -04:00
tterrag 25605505d5 Remove SideOnly from WoodType methods 2020-04-04 15:35:41 -04:00
LexManos 0d2a0deef3 Cleanup IForgeTagBuilder code style. 2020-04-01 11:34:36 -07:00
tterrag b6dc5381ca Move global loot test data files out of generated folder 2020-03-31 20:15:55 -04:00
tterrag 559bacbd98 Add support for optional tag values to Tag.Builder
Add optional tag values to data gen test
Fix data gen test not running by correcting gui_light value
2020-03-31 20:15:09 -04:00
tterrag 19444ffa18 Fix a few issues with BufferBuilder
Fix vanilla bug that caused the byte order of the buffer from getNextBuffer to be incorrect
Fix missing modification to nextElementBytes in putBulkData
2020-03-31 19:55:09 -04:00
tterrag db3d202c4e Deprecate ModelBuilder#gui3d, add ModelBuilder#guiLight 2020-03-30 00:15:08 -04:00
naqaden 2f5172f907 Add renderer to RenderNameplateEvent (#6562) 2020-03-27 16:22:01 -07:00
dags f6cb5268a2 Defer writing the server.properties file until after mods have loaded to prevent config loss (#6545) 2020-03-27 16:19:34 -07:00
hnOsmium0001 fcee09cab2 Fix ownership leak in ItemStackHandler (#6580)
- Triggered by invoking ItemStackHandler#extractItem with `simulate=true`
2020-03-27 16:10:21 -07:00
cpw dd1d8737ad Fix cycle happening in noteblock even though we're setting the new value as well..
Signed-off-by: cpw <[email protected]>
2020-03-20 20:05:23 -04:00
cpw 3e48066021 Add a progress message for atlas textures. Fills a big time gap on bigger packs.
Signed-off-by: cpw <[email protected]>
2020-03-20 17:34:46 -04:00
Managarmr 0d16042705 Remove ArrowEntity patch, vanilla fixed MC-107941 2020-03-17 02:41:36 -07:00
LexManos 52b8070692 Fix Forge's tps and gen commands. 2020-03-15 16:27:58 -07:00
LexManos 23541ab175 Update gradle wrapper
Update MCPConfig to version that bypasses javac compiler bugs
Fix Global loot test compile errors.
2020-03-15 13:55:03 -07:00
tterrag c7a17946a5 Fix loading text not rendering after mojang logo appears 2020-03-15 03:39:04 -04:00
tterrag 208ca23515 Fix loading GUI corrupting matrix state 2020-03-15 03:27:43 -04:00
cpw 6329c0fcf2 Somewhat restore the loading screen overlay. It seems that once the mojang logo and progress bar
start running, I can no longer write to the window, even though I am obviously trying to..

Signed-off-by: cpw <[email protected]>
2020-03-14 23:28:45 -04:00
Nightenom 202ae50820 Add projection matrix to RenderWorldLastEvent (#6536) 2020-03-11 00:00:21 -07:00
Draco18s 58e5f33fad Global Loot Functions (#6401) 2020-02-26 22:13:36 -08:00
DaemonUmbra 2ce4f5ece5 Updated ForgeDev MCP Mapping Version (#6532) 2020-02-25 19:45:14 -08:00
cpw aca45340bf Fix up alarming security crisis with network handling that allowed for wrong code execution on the server, resulting in CRASHED SERVERS. AWFUL stuff.
Also fixed a silly log message from the login handler.

This change introduces a mechanism to direct certain packets to only process on one side or another. Invalid sidedness will result in the connection being terminated.

Signed-off-by: cpw <[email protected]>
2020-02-23 22:15:34 -05:00
Julian Dunskus 30d4520c6b Make TransformationHelper.slerp for quaternions public (#6528) 2020-02-23 18:32:33 +01:00
DaemonUmbra daff482092 Fixed Conduit and Beacon Activation on Vanilla Servers (#6438) 2020-02-17 11:01:38 -08:00
Richard Freimer a740044e21 Fix ITeleporter being ignored when teleporting from the end to the overworld (#6505)
* Fix custom teleporters triggering end credits when returning from the end
* Fix setdimension command ignoring position
2020-02-17 17:16:46 +01:00
Vincent Lee 1a4955f9fd Fix missing call to itemstack TER (#6445) 2020-02-14 22:43:31 +01:00
Vincent Lee 2c4042c17c Fix missed modeldata passing in BlockModelRenderer (#6442) 2020-02-14 22:33:27 +01:00
Robert Skalko e95ba8a3dc Fix NPE when players rejoin the server in a dimension that was deleted (#6511) 2020-02-14 12:34:41 -08:00
Rigner 63cb030cba Fix a wrong RenderState name MC-167447 (#6501) 2020-02-14 12:12:52 -08:00
Daniël Goossens 743fc70a7f Fix client not informing server when it attempts to interact with things, and is canceled by a client side handler. 2020-02-14 12:04:38 -08:00
ewewukek c14ffa3264 Fix wrong arguments passed to ForgeHooksClient.renderSpecificFirstPersonHand() (#6496) 2020-02-14 12:03:08 -08:00
malte0811 3f292d5d42 Fixed ChunkWatchEvent.(Un)Watch not firing correctly (#6453) 2020-02-14 12:02:47 -08:00
Unnoen 886e89ccb2 Update version and support data on README. (#6429) 2020-02-14 12:02:00 -08:00
Joseph Tarbit 977428e42c Fixed Food not using effect suppliers, to better support delayed initialization and registry replacements. (#6411) 2020-02-14 12:00:40 -08:00
Parker Hawke 1c02312ae6 Fixed displaying item names when only more sensitive version changes (#6402) 2020-02-14 11:55:27 -08:00
David Quintana 8fbd84515f Fix gui_light for forge's item parent models. 2020-02-14 19:03:11 +01:00
Richard Freimer f93289e01c Allows custom blocks to define if they should use the fluid overlay instead of the flowing texture when in a fluid (#6493) 2020-02-06 23:53:37 +01:00
LexManos 982ed69776 Fix a small patch misalignment. 2020-02-03 13:21:18 -08:00
Richard Freimer 1f46169e1e Add FluidStack support to the Forge packet buffer. (#6353) (#6485) 2020-02-03 12:46:14 -08:00
Richard Freimer 7bac75f370 Make Minecarts work with modded powered/activator rails. (#6486)
Re-adds functionality for rails to have different maximum speeds.
2020-02-03 12:45:36 -08:00
ichttt 06d9b6531c Revert game data to frozen on disconnect from a remote server or when terminating a local server. Closes #6487 (#6497) 2020-02-03 12:21:10 -08:00
David Quintana 2991e767dd Remove unintended changes. 2020-02-02 23:05:04 +01:00
David Quintana a901d80dd5 Implement fluid overlay texture rendering for custom fluids. 2020-02-02 23:02:56 +01:00
DaemonUmbra d86f58a0df Fixed Attacks/Punches not Registering (#6481)
Replaced incorrect magic number with constant
2020-01-29 22:12:04 -08:00
Vincent Lee 0ad574257e Clean up a bunch of render events (#6444)
* Delete RenderHandEvent as RenderSpecificHandEvent can do everything it does and more. Rename RenderSpecificHandEvent to RenderHandEvent as it's now the only hand rendering event.
* Pass MatrixStack and IRenderTypeBuffer into the event whenever they are available. If they're available, that means we're in a batching environment and the modder should not be using the tessellator or other buffers on their own, or they risk "Already building" crashes.
2020-01-30 00:46:22 +01:00
Bartosz Skrzypczak 4839d18c73 Fix NullPointerException on java 8u242 in dev environment. (#6473)
Java 8u242 no longer re-initializes internal sys_paths and usr_paths fields in loadLibrary when they are null, so the value can't be set to null.
2020-01-29 13:55:07 -08:00
Vincent Lee e539e7ecbb Fix incorrectly ported patch for restoreBlurMipmap (#6450) 2020-01-29 13:13:08 -08:00
Daniël Goossens 1b618fae90 Fix RightClickBlock code differences between client and server implementation (#6451) 2020-01-29 13:11:50 -08:00
Yamahari f12a93fe1e Defer material getting for ChestTileEntityRenderer into seperate function (#6465) 2020-01-29 13:05:12 -08:00
Cadiboo 617159c825 Small Forge config fixes (#6466) 2020-01-29 13:04:35 -08:00
LexManos c72d6e9122 Fix ChunkDataEvent.Load not firing, it now fires in the aync thread. Be careful. Closes #6471 2020-01-29 12:18:13 -08:00
LexManos 69ae178bf4 Fix incorrect keybinding modifiers patch. Closes #6478 2020-01-29 11:57:10 -08:00
LexManos d391299340 Fix PlayerChangedDimensionEvent using incorrect from dimension argument in ServerPlayerEntity.teleport. Closes #6457 2020-01-29 11:56:38 -08:00
LexManos 40091678a8 Fix default mod resources loosing it's sort order. 2020-01-29 11:31:31 -08:00
LexManos 2b43aa6301 Fix WakeupEvent patch misalign. Closes #6474 2020-01-29 11:31:02 -08:00
mcenderdragon 44d9fff2b4 [1.15] Reimplemented the ITeleporter interface (#6404) 2020-01-29 09:18:07 -08:00
David Quintana 509a28efd3 Hook "gui_light" value from the model into the IBakedModel implementations.
Apply some of the suggestions from the 1.14 models PR.
2020-01-23 22:54:54 +01:00
LexManos c4e000dbe7 1.15.2 Initial Update 2020-01-22 13:44:03 -08:00
ichttt 0bcc2e3fbd Cleanup fml packages removing old deprecated classes related to GUIs/Configs and fix HoverChecker (#6437)
Fixed ModListWidget name to avoid confusion and collision.
Delete CheckBox, as vanilla has it's own CheckBox now which looks much better
Rename ModConfigEvent.ConfigReloading to ModConfigEvent.Reloading
2020-01-22 14:09:58 -07:00
Daniël Goossens e6c440a4f7 Fixed parameter name issue in ISTER rename. #6461 (#6468) 2020-01-22 13:38:13 -07:00
LexManos 575af22cee Fix default widget foreground color. 2020-01-22 11:56:05 -08:00
Daniël Goossens dea08be906 Updated method names referencing ItemStackTileEntityRenderer (#6461) 2020-01-22 12:26:34 -07:00
Cadiboo 0f27975f77 Fix Widget Foreground Color not allowing pure black (#6460) 2020-01-22 12:25:35 -07:00
Wyn Price 2d30419a31 Fixed rounding issue with entity navigation fix (#6455) (#6456) 2020-01-22 12:24:20 -07:00
Brennan Ward 68ce113c5b Fixed RenderTypeLookup loosing mappings for registry replacements. (#6452) 2020-01-22 12:23:42 -07:00
Take Weiland ad7e4e95ae Use extended version of getLightValue in all places (#6433) 2020-01-22 12:22:35 -07:00
Scotteh 345387645e [1.15.x] Added entity nameplate rendering event hook (#6416) 2020-01-22 12:22:04 -07:00
tterrag 380366e25f Remove emissive items hook, add small utility for bakedquad lighting 2020-01-20 22:44:26 -05:00
David Quintana 1936eb1f36 Fix breaking overlay weirdness. applyBakedNormals was not transforming the baked normals when applying them. Fixes #6432 2020-01-16 03:29:46 +01:00
Daniël Goossens 088fc6b67f [1.15] Add new InputEvent.ClickInputEvent, addresses #5802 (#6047) 2020-01-15 16:30:01 -08:00
David Quintana 983a47a7d6 Fix dark spots in fullbright quad rendering.
Fix multi-layer model not declaring dependency on the particle texture.
Fix mistake in 2c054fca which I didn't intend to push when I did.
2020-01-13 23:20:46 +01:00
David Quintana c1840abb0a Fix multi-layer model loader to actually work in a sane way. No more "base" model involved, and now transforms and overrides work as expected. 2020-01-13 19:38:52 +01:00
David Quintana 2c054fca76 Attempt to fix fullbright lighting.
Fix lightmap value calculation.
2020-01-13 13:19:36 +01:00
tterrag d5b94aa9c8 Add constructor for FishBucketItem that accepts suppliers 2020-01-09 17:26:11 -05:00
David Quintana c4c760bfb3 Fix QuadTransformer normal processing. 2020-01-07 23:52:51 +01:00
Choonster TheMage dd0260c476 Fix validation in RotationBuilder#angle (fixes #6323) (#6408) 2020-01-07 14:21:12 -08:00
Richard Freimer ca62702ff9 Add support for custom nether portal frame blocks (#6389) 2020-01-07 14:20:37 -08:00
RANKSHANK 0d50b4c39f InputEvent.RawMouseEvent fix (#6395) 2020-01-07 13:19:46 -08:00
DaemonUmbra c37e44efb6 Fixed Big Mushrooms not generating (#6390)
Removed vanilla negation from Forge logic that negated the vanilla logic it was replacing
also ran datagen to update the dirt tag to reflect changes that were previously made in the datagen code
2020-01-07 13:15:11 -08:00
tterrag df04ae11ef Fix dyes tag containing dye items instead of tags
Update generated data
2020-01-05 19:03:49 -05:00
Choonster TheMage 6e8b976089 [1.15.x] Remove unused parameter from ElementBuilder#rotation (fixes #6321) (#6407) 2020-01-05 14:29:45 -05:00
tterrag bc878ddf19 Refactor BlockStateProvider to encapsulate a BlockModelProvider
Make most protected methods of data generators public
2020-01-05 14:27:20 -05:00
tterrag 3096608d4a Fix crash when building BakedQuadBuilder
Add javadocs and move sprite to constructor where possible
2020-01-05 13:36:06 -05:00
tterrag 7c99b756f9 Fix incorrect check for missing texture in DynamicBucketModel 2020-01-04 23:50:17 -05:00
tterrag 90035ab084 Remove custom vertex format from BakedQuad 2020-01-04 23:36:56 -05:00
David Quintana b6c12f5fff A few more binary-breaking changes, before it's too late:
- Move CompositeModel out of its package.
- Move a few inner classes from the OBJ loader.
- Rename the bucket model and fluid model classes to match the naming convention.
- Remove BiomeEvent.* and WorldTypeEvent.InitBiomeGens as they are not currently implemented and they haven't been in the previous version either.
2020-01-04 17:18:28 +01:00
David Quintana 4b9920bcb3 Cherry-pick ca819e09 from the 1.14.x branch. Removes a patch from NativeImage which was invalid. 2020-01-04 17:18:27 +01:00
LexManos 1e053298be Fix the particle renderer not setting GL state between each type. MC-168672 2020-01-02 19:02:42 -08:00
David Quintana ca031ca33f Fix CompositeModel not respecting "display" transforms.
Remove leftovers from discarded feature.
2020-01-02 06:21:43 +01:00
David Quintana ecb56054bc Allow model jsons to override the material library used by OBJ models.
Fix model loader test mod resources.
Update licenses.
2020-01-01 17:15:49 +01:00
tterrag 53747b0cb5 Apply baked-in lightmap data to rendering
- Fix ForgeHooksClient.fillNormal injecting data to lightmap
- Fix OBJModel not filling lightmap data
- Fix NewModelLoaderTest blockitem not linking with block
2019-12-30 16:12:14 -05:00
David Quintana e1b0a8c153 Fix LightUtil.unpack to set the 4th component to 1 when expanding an xyz position into a 4-component vector.
Add TRSRTransformer test mod.
Fix signature of the bindTileEntityRenderer method, to account for covariance.
2019-12-29 17:16:27 +01:00
David Quintana fc189c9aaf More model/rendering fixes:
- Breaking change: Change ClientRegistry.bindTileEntityRenderer to a factory, so mods don't have to manually specify the dispatcher.
- Breaking change: Delete obsolete SimpleModelState (the class was duplicated by mistake, see SimpleModelTransform) and ICustomModelState (part of the old loader API).
- Breaking change: Rename getTextureDependencies to getTextures, for consistency.
- Reinstate the getRenderLayer method, fixed appropriately to return the new RenderType value.
- Fix OBJ loader applying the model transform in the wrong reference frame.
- Fix vanilla bug in TransformationMatrix#func_227986_a_
- Fix QuadTransformer logic.
- Added new method to IModelConfiguration to retrieve the owner IUnbakedModel, needed in order to construct ItemOverrideLists when baking custom models.
- Reintroduce multi-layer model through the new model loader system.
2019-12-29 02:13:58 +01:00
David Quintana e8ce61d4cd New batch of Model/rendering fixes:
- PerspectiveMapWrapper did not pass IModelData through to the wrapped model.
- CompositeModel did not store the returned textures from getTextureDependencies.
- VertexFormat used COLOR instead of UV to detect UV presence.
- QuadTransformer would crash due to index out of bounds.
- Small cleanup of TransformationHelper
2019-12-24 13:12:38 +01:00
David Quintana ac61018806 Fix obj models having all faces in the same mesh, breaking material assignments and visibility in the process.
Reintroduce lost patch from the model loader, which would cause the custom values to be missing from generated models.
2019-12-20 18:14:09 +01:00
tterrag 18e97a487d Fix diffuse lighting being baked into models, fixes dark items 2019-12-19 23:13:28 -05:00
David Quintana c3b1f47754 Fix item quads not using the existing vertex color when applying tint colors. 2019-12-20 04:50:40 +01:00
David Quintana 503d277033 Fix bucket model. Some mask textures were not added to the repository, and the bucket override generation was broken.
Fix OBJ loading crash due to a float value being parsed as int.
Fixes 6377
2019-12-20 02:44:27 +01:00
bl4ckscor3 40de19f16e Fix game crashing when modded entities are present (#6364) 2019-12-19 00:56:01 -05:00
ichttt 83ebdcd8f2 Fix warning screen about missing minecraft registry entries (#6363) 2019-12-18 21:02:20 -08:00
Richard Freimer 47a1f7529a Fix capabilities becoming inaccessible on returning from end (#6368) 2019-12-18 20:40:36 -08:00
ichttt 747cb0f151 Some code cleanup for 1.15 (#6362) 2019-12-18 20:39:41 -08:00
tterrag 30b530836a Fix MainMenuScreen patch 2019-12-17 21:10:49 -05:00
tterrag 49596dcacc Mod list GUI detail pass
- Make padding consistent on all elements
- Properly horizontally center the "Search" text
- Update and resize forge/mcp logos
- Enable linear filtering on logo rendering by default
  - Can be disabled with the "logoBlur" mods.toml property
2019-12-17 20:58:26 -05:00
ichttt 5df687dddc Fix mod list screen (#6367) 2019-12-17 20:03:11 -05:00
David Quintana 599a754b60 Fix items in ground being too small, we were applying perspectives twice.
Restore forge patch and fix a tiny mistake in it.
2019-12-18 00:46:29 +01:00
Tobias Hotz eaac0c17a4 Fix keybinds not loading/saving correctly 2019-12-17 18:30:51 -05:00
tterrag faaebe7a07 Remove uvlock hook, fixes broken stair/fence/etc models 2019-12-17 17:37:39 -05:00
tterrag 6256ba336e Update fallback spec version 2019-12-17 17:15:09 -05:00
tterrag 5987d917b8 Update to 1.15.1 2019-12-17 14:37:34 -05:00
David Quintana 738abbb360 Finish converting the code from javax.vecmath to the vanilla vector classes. Forge is now vecmath-free! 2019-12-17 19:14:52 +01:00
tterrag 1558362583 Remove deprecations 2019-12-17 04:50:13 -05:00
tterrag 5b67354e24 Fix incorrect item lighting 2019-12-16 23:46:45 -05:00
tterrag dec91dec68 Revert fluid change to use Material, fixes server crash 2019-12-16 23:22:13 -05:00
1933d05e36 Update to 1.15
Due to the massive rendering changes, certain features, such as emissive item rendering and the forge block rendering/lighting pipeline are currently disabled.

Co-authored-by: David Quintana <[email protected]>
Co-authored-by: tterrag <[email protected]>
Co-authored-by: Unnoen <[email protected]>
2019-12-17 03:38:12 +01:00
King Lemming 9e5ecaaf75 Added a couple of raytraceresult.getType() != MISS checks in places where they were absent. This corrects a couple of vanilla oversights and also greatly reduces Forge bus event spam for arrows and llama spit. (#6355)
Signed-off-by: King Lemming <[email protected]>
2019-12-15 14:39:41 -08:00
Luke Tonon 3701ec06d0 Restored canRiderInteract boolean in IForgeEntity (#6347) 2019-12-10 11:56:07 -08:00
Daniël Goossens 5d0fb2967c Split DrawBlockHighlightEvent into subevents to make usage clearer, addresses #2190 (#6269) 2019-12-10 11:46:01 -08:00
tterrag 5c88451f6f Allow classpath locator to discover jars via FMLModType attribute 2019-12-05 22:56:05 -05:00
cpw cfc53c939e Tidy up some output and also add libraries from the modfile detection into the transforming classloader.
Signed-off-by: cpw <[email protected]>
2019-12-05 22:47:39 -05:00
tterrag 3ba78225c3 Fix swapped yaw/pitch in camera setup event 2019-12-02 19:10:59 -05:00
liach d8e6181058 Restore camera setup render event (#6335) 2019-12-02 14:54:46 -08:00
DaemonUmbra bb4e78da90 Fixed invocation of Vanilla spawn logic (#6334)
Forge's replacement of the Vanilla logic gets inverted, so the Vanilla logic inside that replacement must be inverted to correct for this.
(Fixes #6332)
2019-12-02 14:54:00 -08:00
bl4ckscor3 4dd32d6f72 Add item tag 'beacon_payment' for items that can activate a beacon (#6328) 2019-12-02 14:52:45 -08:00
Luke Tonon 68b0075fe6 Added FENCES_WOODEN and FENCE_GATES_WOODEN tags as fuels in AbstractFurnaceTileEntity (#6327) 2019-12-02 14:36:30 -08:00
Paul Becker f9686cf098 New SleepFinishedTimeEvent allowing control of world time when waking up. (#6043) 2019-12-02 14:08:14 -08:00
tterrag ca28877fd5 Fix EntityLootTables not calling addTables 2019-11-25 01:49:24 -05:00
tterrag c18d26c7d8 Make EntityLootTables reusable for modders 2019-11-25 01:03:24 -05:00
nikita488 241db39cea Fix emissive items not working 2019-11-24 19:08:46 -05:00
cpw 31da9a4878 Fix the hang on startup problem when windows' broken device enumeration
causes a huge glfwInit slowdown. Log a message too when this is detected.

See https://github.com/glfw/glfw/issues/1284, https://stackoverflow.com/questions/10967795/directinput8-enumdevices-sometimes-painfully-slow,
https://discourse.libsdl.org/t/win-10-initing-joystick-causes-45s-hang-in-sdl-dinput-joystickdetect/23293

Signed-off-by: cpw <[email protected]>
2019-11-23 15:37:56 -05:00
Richard Freimer 0e65f20f22 Add hooks to make it easier to add custom TNT blocks (#6290) 2019-11-20 19:19:34 -08:00
DaemonUmbra d8d70e8b35 Add tags supports_beacon and supports_conduit and modify Beacon and Conduit to use these tags (#6266) 2019-11-20 19:15:13 -08:00
bl4ckscor3 5d62261082 Fix RawMouseEvent not being cancelable (#6310) 2019-11-12 15:12:25 -08:00
Richard Freimer a72b774acf Fix DyeColor referencing incorrect Tag path. Fixes #6301 (#6303) 2019-11-12 15:11:43 -08:00
DaemonUmbra b1042f2c3c Modify StonecutterContainer to allow shift-click insertion of any block with a valid recipe rather than limiting to blocks in an Immutable List (#6268) 2019-11-12 15:10:52 -08:00
tterrag 124c78b926 Fix #6305 lighting optimization using the wrong method 2019-11-07 16:56:54 -05:00
tterrag 7332bf91d5 Add support for modded warm ocean biomes in bonemeal code 2019-11-07 10:39:33 -05:00
tterrag 33307fb1bd Optimize SectionLightStorage#cancelSectionUpdates loop 2019-11-05 14:55:43 -05:00
Daniël Goossens 1ef8b75cbb Add LeftClickEvent trigger to onPlayerDamageBlock (#6046) 2019-11-05 11:12:02 -08:00
DaemonUmbra f4a85e5f03 Fixed an NPE caused by missing registries. (#6292)
Missing registries in this case being registries renamed without proper remapping or created by mods that were removed.
2019-11-05 11:10:32 -08:00
DaemonUmbra 7f8b30aed3 Made the slash optional in fml confirm/cancel. (#6282) 2019-11-05 11:10:19 -08:00
LexManos b8ea220925 Fix registry snapshots not reading aliases correctly. Closes #6298 2019-11-05 11:10:03 -08:00
cpw 1e1644f6d4 A few tweaks to things. Make the mods command a bit better, make the
IndexedMessageCodec actually log which network channel it got back packets
on. Also, improve the custom directorymodlocator with actual custom names,
finally, allow up to 99 log rollovers, up from 7 default (this means a
repeatedly crashing server is less likely to roll out the log of the first
crash).

Signed-off-by: cpw <[email protected]>
2019-11-03 12:33:07 -05:00
tterrag fab4ce894a Fix BlockStateProvider#horizontalBlock emitting rotations >=360 2019-11-01 17:10:06 -04:00
Camilo f2f7ab80f6 Added some more biome types to BiomeDictionary (#6250) 2019-11-01 11:26:08 -07:00
DaemonUmbra c044f3b0c4 Replaced getTypes invocation in ensureHasTypes with a direct reference to types, preventing infinite recursion (#6284)
The direct reference is checked via ternary and reports if the set is empty, this is likely to result in log spam if modders don't assign types to their biomes
2019-11-01 11:24:00 -07:00
tterrag ebd463e92f Fix lang generator escaping newlines, add lang generator test 2019-10-30 15:25:03 -04:00
tterrag 69ba974960 Escape control chars and unicode when writing out lang datagen 2019-10-30 15:01:25 -04:00
tterrag dbee8a24d8 Allow LanguageProvider helpers to accept suppliers of subtypes 2019-10-28 21:23:01 -04:00
tterrag 2373dab982 Expose private helper methods in BlockLootTables to subclasses 2019-10-28 19:28:16 -04:00
Wyn Price 1ebfef5ec9 Fixed vanilla bug in entity navigation to stop entities spinning (MC-94054) (#6091) 2019-10-28 14:13:14 -07:00
Paul Becker ff7a2fe4d6 Reimplement usage of Item#doesSneakBypassUse() (#6114) 2019-10-28 13:24:15 -07:00
cpw 862289cf56 Handle logging during shutdown better on the server, by not
closing the logfile before the server itself has shutdown.

Signed-off-by: cpw <[email protected]>
2019-10-26 16:55:15 -04:00
cpw e3068d7db2 Fix NPE in modlauncher when there is no mods dir yet.
Signed-off-by: cpw <[email protected]>
2019-10-25 07:27:55 -04:00
DaemonUmbra 29ad7a39de Fixed NPEs caused by uninitialized lists in ModDirTransformerDiscoverer (#6277) 2019-10-24 23:06:27 -07:00
LexManos 3484200f80 Make Loot Table data generators more reusable for modders. 2019-10-24 22:09:08 -07:00
tterrag acaa470dea Add Blockstate and Model data providers (#6241) 2019-10-24 22:33:24 -04:00
cpw 3bf6c17bb8 Allow pack locators to load from the mods folder.
Regular mods are now automatically de-duped based on the version number -
the highest version file of a "root mod id" is now selected automatically.

Signed-off-by: cpw <[email protected]>
2019-10-23 21:30:17 -04:00
AfterRebelion ca8a418364 Exclude Cobblestone slabs and wall recipes (#6230) 2019-10-22 15:31:35 -07:00
Wyn Price 6422310453 Fixed forge rendering pipeline and shape based light occulsion. (#6178) 2019-10-22 15:29:27 -07:00
Wyn Price ebf489be8c Fix shouldCauseReequipAnimation not affecting anything (#6256) 2019-10-22 15:08:06 -04:00
cpw c8967fa176 Expose the registrationchange event to simple channel (not that anyone should care, but who knows?)
Also, Context.getNetworkManager should have been public. Derp.

Signed-off-by: cpw <[email protected]>
2019-10-18 09:32:44 -04:00
cpw 51d08ad8ab Fix clientside chunk load event spam. Was an offset patch.. Also fire unload on the client side too.
Signed-off-by: cpw <[email protected]>
2019-10-18 00:03:09 -04:00
cpw dc664ba597 Add in an event to expose the standard MC channel stuff to network
event channels that care about such things. Mods using simplechannel
don't need to care.

Also, put a sync wrapper around crashreportextender, so it doesn't
die sometimes randomly during startup.

Signed-off-by: cpw <[email protected]>
2019-10-17 20:28:39 -04:00
Daniël Goossens 8e74ba8c24 Fix #6244 RightClickBlock#getUseBlock and #getUseItem being ignored (#6246) 2019-10-17 19:13:16 -04:00
David Quintana ec3e8c2039 Fix vanilla models with parents not loading properly from forge blockstates. 2019-10-16 23:11:23 +02:00
ichttt 6cbd418703 Include a profile icon for the launcher json (#6222) 2019-10-15 15:00:03 -07:00
ichttt 6c8342b74e Fixed loading error/warning screen not showing (#6218) 2019-10-15 14:59:41 -07:00
James Mitchell c345dfb0c6 Fixed MC-162953 bounds checks in NativeImage (#6216) 2019-10-15 14:58:16 -07:00
JoJoModding 8adc546d92 Allow mods actually to have their own usable config gui (#6208) 2019-10-15 14:56:27 -07:00
iChun 25a9e477cb Fix error logging in FMLUserdevLaunchProvider.setup (#6206) 2019-10-15 14:55:45 -07:00
bl4ckscor3 886de4ee43 Fix shear sound not playing (#6202) 2019-10-15 14:55:26 -07:00
ichttt c98abaaa42 Fix some config checks still using the old fields (#6193) 2019-10-15 14:54:47 -07:00
Philipp a8bd5e7ece Add onCropsGrow event to KelpTopBlock (#6171) 2019-10-15 14:33:07 -07:00
Justin a328364999 Fix mod info panel rendering incorrectly on some systems with HiDPI displays (pesky macs) (#6170) 2019-10-15 14:31:41 -07:00
FireController1847 94cbf72e39 Re-add PlayerGiveXpEvent & PlayerChangeLevelEvent (#6165) 2019-10-14 10:37:44 -07:00
Max Becker 8248eb6ea1 Skip background for hidden effect instances (#6197) 2019-10-14 10:33:45 -07:00
cpw 408104dbaf Bump modlauncher version to 4.1
Signed-off-by: cpw <[email protected]>
2019-10-13 14:21:24 -04:00
Wyn Price 5978670897 Fixed IModelData not being cleared when tile entity is removed (#6115) 2019-10-10 23:07:52 -04:00
Vincent Lee 01d14004a9 Allow modded IParticleRenderTypes to be rendered (#6221) 2019-10-10 23:05:16 -04:00
tterrag 940bbc4e91 Better sanity checks in ModelDataManager 2019-10-10 16:02:36 -04:00
Vincent Lee 7070bd0340 Make customClientFactory optional again (#6191) 2019-10-10 11:23:27 -07:00
David Quintana 5e9380ab85 Fix forge blockstates and custom model loading (#6154)
* Reimplement forge blockstates variant through the use of a pseudo-model that handles the model loading, retexturing, custom data, etc. on behalf of the blockstates loader. This model gets injected into the model registry with an autogenerated unique name, to not collide with other model locations.
* Fix model loaders not being properly initialized by calling the reload method from the loader register function. In 1.12, registering a reload listener caused the listener to be called right away from the register method. This is not true anymore.
2019-10-08 00:18:29 +02:00
cpw 9c759294c6 Add a super early GUI for showing pre-game launch messages from FML. NOTE: this cannot show on MAC because MAC can't handle
off-thread GUIs in any way shape or form, and we need the main thread to do real work.

Fix forge fading in wrongly.

Signed-off-by: cpw <[email protected]>
2019-10-05 17:03:02 -04:00
David Quintana b294f4d894 New round of fluid system fixes: (#6175)
- Fix race condition lazy-initializing flowing fluid block data.
- Fix typo in ItemTextureQuadConverter that prevents certain animated textures from being used in the fluid bucket.
- Fix calls to onContentsChanged in FluidTank.
- Fix FluidUtil.tryEmptyContainer logic when simulating.
- Fix EmptyFluidHandler.fill returning the wrong number.
2019-10-05 19:49:26 +02:00
tterrag ca980a56bc Combine all hidden mod resource packs into a single sortable pack
Fix mod datapacks sorting under vanilla
2019-10-04 18:36:33 -04:00
cpw 8482293b40 Split server and client side pack locators apart and move them to their
respective behavioural components. This should facilitate fixing the
server pack data pack ordering, as well as other new features of mod
resource packs.

Signed-off-by: cpw <[email protected]>
2019-10-04 15:24:15 -04:00
LexManos dc5a06aab4 Fix dimension types being incorrect when connecting to a non-Forge server. Closes #6203 2019-10-04 10:36:50 -07:00
cpw 35bd69808c Fix the stupid derp that broke singleplayer dims. Don't send the dim packet
to the local client - it is not needed because obviously not. Seems to have
fixed the problem. Probably infinity new bugs by this.

Signed-off-by: cpw <[email protected]>
2019-10-04 07:27:11 -04:00
tterrag 4f12261080 Move OnlyIn patches on DyeColor to SAS file
Also fix broken cobblestone stairs recipe
2019-10-04 02:26:54 -04:00
tterrag fbdfc0f95c Expose DyeColor#colorValue, remove OnlyIn from all DyeColor methods 2019-10-04 01:40:28 -04:00
cpw 48735c3946 Properly propagate the DimensionType information from server to client
at client connection time. This means the client now knows about the
dimensiontype properly and can access the ModDimension information on
the client.

Signed-off-by: cpw <[email protected]>
2019-10-02 21:54:02 -04:00
Ruben Taelman c985225d0c Fix FluidTank with empty contents throwing error if drained (#6196) 2019-10-01 19:57:05 -07:00
Matthew Messinger 48ff897ed1 Move opening initial screen to after startup and events are enabled (#6139)
This allows events to be fired for the initial opening of the main menu
Also fixes MC-145102
2019-10-01 19:56:03 -07:00
Wyn Price 9db568d49d Changed all calls of BlockState#getSoundType to use the sensitive version. (#6120) 2019-10-01 19:54:23 -07:00
Draco18s 896e785994 Patch Sweet Berry Bush to have Crop Growth Event Hook (#6094) 2019-10-01 19:52:24 -07:00
tterrag 78cdb705d4 Allow structure processors to process entities 2019-09-28 18:18:24 -04:00
cpw 136452840d Remove forced ANSI terminal - it breaks the Eclipse terminal output.
As a result, we can now support coloured log output again, by default.

Regen run configs to get the change (you should do this every update, you
know :D)

Signed-off-by: cpw <[email protected]>
2019-09-28 16:05:50 -04:00
tterrag b3631b707c Make patched-in StairsBlock constructor public
Also fix supplier generic being too narrow in DeferredRegister#register
2019-09-27 17:56:30 -04:00
cpw f4bab8b8c1 Integrate modlauncher changes for mixin.
Signed-off-by: cpw <[email protected]>
2019-09-27 17:42:24 -04:00
tterrag 2392a4c184 Fix new flower pot ctor not being usable with deferred register 2019-09-25 18:01:43 -04:00
tterrag 476b7056fb Usability improvements to RegistryObject/DeferredRegister 2019-09-25 18:01:39 -04:00
tterrag d510978446 Add constructor to StairsBlock that accepts a state supplier 2019-09-24 21:05:23 -04:00
LexManos 583ff81dba Fix server jar manifest path. 2019-09-23 18:42:54 -07:00
tterrag 01a862db30 Fix sea level not being available on client, move hook to Dimension 2019-09-23 13:08:26 -04:00
tterrag dfbd61436b Add template arg to StructureProcessor#process 2019-09-22 23:35:12 -04:00
LexManos f03745ce45 Fix timezone issue with the installer. 2019-09-23 02:46:43 +00:00
LexManos 48cf910626 Bump binpatcher and jarsplitter versions to address Java differences on older JDKs. 2019-09-22 17:30:29 -07:00
tterrag 0492b25335 Allow modded dimensions to customise World#getSeaLevel 2019-09-22 16:47:56 -04:00
tterrag 6d9cb0a646 Fix jigsaw blocks not mirroring properly 2019-09-22 16:47:44 -04:00
tterrag 571ecafdbc Fix type bound on GameRegistry.findRegistry being too narrow 2019-09-21 16:19:23 -04:00
tterrag dee844e232 Add IExtensibleEnum#init, extend FillerBlockType/PlacementBehaviour 2019-09-21 15:57:32 -04:00
cpw 07bcff5067 Tag the deprecation of DeferredWorkQueue. I think this is causing confusion
as to scope. Its functionality will be tied to the events in future -
so mods can request the deferred work through methods on the Mod Lifecycle
events directly. The API will be coming soon.

Signed-off-by: cpw <[email protected]>
2019-09-17 21:41:08 -04:00
cpw 7fa3594c04 Fixed the problem where an error would cause the main thread to continue
even though there were still parallel threads running. Also, handle exceptions
in the AutomaticEventSubscriber rather than leaking them to the Parallel processor.

Actually closes #6148
Signed-off-by: cpw <[email protected]>
2019-09-17 21:41:08 -04:00
tterrag 6fda1e968d Make FlowerPotBlock extensible and reusable for mods
- Change static lookup map to an instance variable
- Add an instance variable for the "empty pot" for the current block
- Keep one instance of the lookup map between the empty pot and all its full versions
- Convert everything to use delegates
2019-09-17 19:57:58 -04:00
Brennan Ward af8074cc39 Post tag event directly from reloader thread (#6164) 2019-09-17 14:39:36 -07:00
cpw 71a4828809 Some tweaks around the code base. A functional consumer for networking - return a bool from your consumer function, rather than setPacketHandled.
Tweak the server modloading behaviour to try and be a bit clearer that a mod errored.

Signed-off-by: cpw <[email protected]>
2019-09-16 20:14:25 -04:00
Brennan Ward 79ce18ac3e Update furnace fuels to not recreate it's list every query, and update when tags are reloaded. Add Tag update events. (#6140) 2019-09-16 14:04:32 -07:00
Nightenom bb83e11a7c Maintain default behavior for Item#canPlayerBreakBlockWhileHolding() (#6128) 2019-09-16 13:36:43 -07:00
Unnoen 0f888dde49 Update README badges to fix wrong version. (#6141) 2019-09-16 13:21:17 -07:00
MrCrayfish f4215d121c Reimplemented "MouseEvent" as RawMouseEvent for 1.14.X (#6144) 2019-09-16 13:03:10 -07:00
Take Weiland 60eecb98a6 Fix patch for vanilla spawning in WorldEntitySpawner (#6130) 2019-09-12 11:10:51 -07:00
LexManos 3cc76a3f60 Fix Entity.getPersistentData function name. Closes #6131
Bump spec version for first 1.14.4 RB.
2019-09-12 09:12:30 -07:00
Justin ffdeeb95b7 Fix ParticleFactoryRegisterEvent not firing (#6126) 2019-09-12 09:01:43 -07:00
David Quintana 58335d7bc0 Minor fixes to the fluids (#6150)
* Fixed vanilla rendering of fluids to take into account the alpha bits of the color, and fix usages accordingly.
* Fixed missing texture derp.
2019-09-12 17:33:19 +02:00
David Quintana b0c9d7cce9 Some (sadly breaking) improvements to the Fluid API (#6110)
* Some (sadly breaking) improvements to the API, after feedback and concerns provided by users:
  - Moved calculation of the translation key to the FluidAttributes constructor, so that builders can be shared between still & flowing sub-fluids.
  - Moved biome-based coloring to a dedicated FluidAttributes.Water variant, which is not used by default.
  - Added logic to automatically gather fluid textures into the list of textures to bake.
  - Patched BucketItem and FlowingFluidBlock to avoid eager access to the fluid objects.
  - Added a ForgeFlowingFluid class, as a more user-friendly way to construct a new FlowingFluid.
2019-09-11 16:00:32 +02:00
LexManos 281ef5a152 Add new DeferredRegistry helper, and change RegistryObject to update when overrides are registered. 2019-09-10 16:02:07 -07:00
LexManos 9183c2fa0d Delay Block loot table name generation until needed, as calling early will result in an empty name as the block is not registered yet. 2019-09-10 16:00:57 -07:00
LexManos 389751beae Fix slimes splitting more times then they should. Closes #6138 2019-09-09 15:30:11 -07:00
tterrag 2b4e3bcf54 Fix a couple places not calling forge getLightValue 2019-09-08 23:32:27 -04:00
tterrag 3dce85c49f Properly fix missing attribute issue, add vanilla bug ID 2019-09-08 02:23:16 -04:00
tterrag 185ce79a68 Fix vanilla typo causing errors when client is missing entity attributes 2019-09-08 02:05:01 -04:00
tterrag f777aba227 Remove StructureArgument to work around vanilla issue, clean up custom arguments 2019-09-08 02:01:17 -04:00
tterrag 5efa373d7f Fix SCommandListPacket underflowing buffer when encountering a missing argument type 2019-09-08 01:33:21 -04:00
cpw b6cd19b4ae Fix problem with network connections timing out frequently. Turns out
there's a race condition - and the extra work forge does causes it to
happen much more frequently than vanilla (though I'm sure it's a vanilla
issue). Closes #6124, #5767 and probably lots more.

Signed-off-by: cpw <[email protected]>
2019-09-07 18:42:50 -04:00
tterrag fc5573333d Make /locate command support modded structures 2019-09-07 01:09:42 -04:00
tterrag 55fe7c470f Make STRUCTURE_FEATURE registry a slave map of the FEATURE registry
Also convert Feature.STRUCTURES to a slave map
2019-09-06 23:42:19 -04:00
LexManos 3ef1d6919c Fix REGISTER packet encode/decode issues.
Changed ForgeConfig values to return the default value if the config is not loaded, and exposed the value objects as a internal config.
2019-09-05 15:38:14 -07:00
LexManos e1863383ff Fix naming conflicts with official names. 2019-09-04 22:33:17 -07:00
LexManos 4dc34b7d5b Fix item used stat not triggering properly on last item in the stack. 2019-09-03 19:58:57 -07:00
LexManos 2c8c022034 Add a bunch of tags from the omnibus.
Fix test imports. And update patches for line numbers.
2019-09-03 18:51:09 -07:00
bl4ckscor3 b5b43a5a36 Add spawn reason to spawn events (#6096) 2019-09-03 15:15:48 -07:00
Wire Segal c09fe57031 Add collisionExtendsVertically hook to allow modded blocks that extend collision into the block above similar to fences. (#6092) 2019-09-03 14:50:27 -07:00
Daniël Goossens 68524ddde9 Fixed PlayerInteractEvent.LeftClickBlock useItem/useBlock (#6045) 2019-09-03 14:41:46 -07:00
Daniël Goossens 55bdd4d937 Readded IForgeItem#getHighlightTip hook. (#6036) 2019-09-03 14:30:41 -07:00
mcenderdragon 3f089e3add Added gravity as attribute to Entities (#5630) 2019-09-03 13:20:44 -07:00
ichttt ddb90a69d3 Fix CME on chunk unload in FarmlandTicketManager (#5998) 2019-09-03 12:59:35 -07:00
cpw bdce8d0494 Add a modfolderfactory. Fix up login payload exposure.
Signed-off-by: cpw <[email protected]>
2019-09-01 14:40:39 -04:00
cpw 734a3d76aa Peel IModLocator into the SPI package and extract a small IModFile
interface as well. This allows building external IModLocator
implementations.

Signed-off-by: cpw <[email protected]>
2019-09-01 11:31:09 -04:00
cpw a4aa85259e Add in some client only player connectivity events. Closes #5536
Signed-off-by: cpw <[email protected]>
2019-08-31 13:55:46 -04:00
cpw ea1c7a7339 Add in MC REGISTER nonsense. Shut up #5730
Tweak network a bit to fix initialization order stupidity. (Constants don't
load classes!)

Signed-off-by: cpw <[email protected]>
2019-08-31 13:55:46 -04:00
Tobias Hotz 185f7344fa move default log level for debug file to debug instead of trace, and remove millis from console and GUI. Also remove unused config xmls 2019-08-31 13:55:46 -04:00
GirafiStudios 26e4bf92a0 Added getters for FMLPlayMessages.SpawnEntity 2019-08-31 13:55:46 -04:00
cpw 68cb017be1 Move indexFor and biConsumer into FMLHandshakeHandler and expose them publicly, so mods can add additional
login messages. Closes #6087

Signed-off-by: cpw <[email protected]>
2019-08-31 13:55:45 -04:00
David Quintana 68ff1afac1 Hookup BlockEvent.FluidPlaceBlockEvent (#6103) 2019-08-31 14:15:08 +02:00
cpw 0d448a5e4f Update libs to 1.0 versions, bump grgit, and fix tag search behaviour that resulted.
Signed-off-by: cpw <[email protected]>
2019-08-29 23:39:49 -04:00
David Quintana d9f6659f2c Fluid rework derp fixes. (#6098)
* Fix nulls returning from non-null methods, and null-check of non-nullable values.
* Fix missed computation of the isEmpty flag in FluidStack
* Cleanup getAmount/isEmpty calls.
* Remove redundant suppliers. That info is readily available from the vanilla Fluid / FluidState.
2019-08-29 21:09:42 +02:00
Vincent Lee bae2ee0420 Minor model system cleanup/documentation (#6089) 2019-08-28 21:33:49 -07:00
ichttt 799e864d93 Fix Digging particle sometimes using the wrong block pos to get additional model data (#6077) 2019-08-28 21:33:15 -07:00
DaemonUmbra aa38f62bae Change fml.modloading.brokenfile.optifine to not imply that Forge is responsible for Forge-Optifine compatibility. (#6080) 2019-08-28 21:32:33 -07:00
ichttt 06c3e255b3 Add a config comment that lists the available constants of enums (#6079) 2019-08-28 21:28:21 -07:00
bl4ckscor3 d5e20b13b9 Restore PotionShiftEvent (#6042) 2019-08-28 21:15:55 -07:00
Daniël Goossens c83d4d29e4 Added new InputEvent.MouseScrollEvent, fixes #5811 (#6037) 2019-08-28 21:13:31 -07:00
Brennan Ward ee1c06085b Add Villager Trading Events (#6016) 2019-08-28 20:34:07 -07:00
BlakeBr0 336d53b692 Strip side annotations from CropsBlock.getSeedsItem (#6013) 2019-08-28 20:14:41 -07:00
Wyn Price 95c58ba75c Updated constants to 1.14 (#6012) 2019-08-28 20:13:47 -07:00
valoeghese 56857cf5e7 Added hook to allow biomes to specify custom river variants. (#5969) 2019-08-28 20:12:52 -07:00
Vincent Lee 838998b885 Add particle factory registration event (#6018) 2019-08-28 18:42:17 -07:00
David Quintana a9b3b48273 Make FluidStacks non-nullable, and implement some TODOs. 2019-08-29 03:18:42 +02:00
David Quintana a788e8a475 Fix license headers so gradlew build is happy. 2019-08-29 03:18:42 +02:00
David Quintana b7e1cc5f6b Fluid API rework (#5983)
- Moved forge fluids into FluidAttributes companion object to the vanilla Fluid. By gigaherz
- Redesigned the Fluid API to be closer to the Items API. By King Lemming
Co-authored-by: King Lemming <[email protected]>
2019-08-29 03:18:41 +02:00
LexManos e784a7f606 Recipe system cleanup. (#6014) 2019-08-29 03:18:41 +02:00
Managarmr 3e9bc3c434 Fix regular arrows giving off particles after a world reload (MC-107941) (#6061) 2019-08-28 18:12:47 -07:00
ichttt dd340b8ef2 Fix coremod not redirecting to the correct method (#6078) 2019-08-28 17:49:46 -07:00
LexManos 7deb479676 Fix blocks being placed in adventure mode. Closes #6085
Add early error for setting invalid world directory. Closes #6084
Fix PlayerTickEvent not firing when dead, even if player isn't removed from world yet. Closes #6074
Fix PlayerDestroyItemEvent not firing for some cases. Closes #6067
2019-08-28 12:57:25 -07:00
LexManos 1ab40e0b3f Fix Javac generics breakage. 2019-08-20 15:40:36 -07:00
LexManos 283c3d1664 Prevent worlds from unloading while players are in out-of-world states by tracking all worlds references by every player in the server's player list. 2019-08-20 15:31:08 -07:00
LexManos 5291ea7270 Add Argument serializer for ModIdArgument. EnumArgument can't as vanilla doesn't support extra data. 2019-08-20 15:29:26 -07:00
LexManos 0c1c1b65e1 Sort server.properties while writing. 2019-08-20 15:27:31 -07:00
LexManos b0787e9f40 Fix chunk load failure when entering End portal Closes #6068 2019-08-19 19:46:00 -07:00
LexManos dc0eacb80f Fix Configs not generating correctly on first load Closes #6069 2019-08-19 19:45:32 -07:00
Vincent Lee 8c04651301 Add hook to load custom mrls/rls not attached to a block or item. (#6010) 2019-08-15 11:03:57 -07:00
bl4ckscor3 94621fecd1 Cover more cases for RightClickBlock event and restore onItemUseFirst (#6009) 2019-08-15 10:34:59 -07:00
kirderf1 5e392e3300 Make DimensionManager.SavedEntry save sky light consistently (#6019) 2019-08-15 10:17:28 -07:00
LexManos 88595dd26b Fix extract inheritance not using proper classpath and update buildscript for FG asm changes. 2019-08-14 16:13:15 -07:00
cpw 4323c6d845 Grrr. Stupid error. Sorry lex: I fixed it.
Signed-off-by: cpw <[email protected]>
2019-08-05 08:56:42 -04:00
cpw 81ec8b99ac Actually reload config when it changes on disk. Closes #5541 and #5959
Signed-off-by: cpw <[email protected]>
2019-08-04 22:37:43 -04:00
cpw 1af7b7603d Move fml's PlayerEvent and TickEvent to forge. Update
`import net.minecraftforge.fml.common.gameevent.PlayerEvent;`
to
`import net.minecraftforge.event.entity.player.PlayerEvent;`
and
`import net.minecraftforge.fml.common.gameevent.TickEvent;`
to
`import net.minecraftforge.event.TickEvent;`

Signed-off-by: cpw <[email protected]>
2019-08-04 22:34:14 -04:00
cpw 0fd8fa2211 Bump modlauncher to 3.2.x. Add a sender modid and document IMC. Closes #5746
Signed-off-by: cpw <[email protected]>
2019-08-04 22:19:02 -04:00
cpw 5048739b7f Turned minecraft into a proper Mod, with a "dummy" language provider.
Also fixed the "translations" not being available early if an exception occurs
by force loading the forge and MC ones. Closes #5984

Signed-off-by: cpw <[email protected]>
2019-08-04 20:16:01 -04:00
DaemonUmbra 44f3f9e2d0 Fix a crash I caused by misunderstanding formatToString (#6007) 2019-08-02 18:48:46 -07:00
LexManos ed1c55508f Fix userdev setup by moving SAS concept to FG. 2019-08-02 18:03:27 -07:00
its_meow 50e411b82a Add piston events (#5798) 2019-08-02 14:12:21 -07:00
its_meow a8a0306f98 Fix AT for EntitySpawnPlacementRegistry.register 2019-08-02 14:06:05 -07:00
desht 19b7d26bc2 Make ParticleManager.IParticleMetaFactory public (#5926) 2019-08-02 14:05:32 -07:00
JoJoModding c7940e70ed Add button to open mods folder (#5986) 2019-08-02 14:00:54 -07:00
DaemonUmbra 58ede2c80a Change ModLoadingException to display ModID instead of ModInfo instance identifier. (#5999) 2019-08-02 13:44:56 -07:00
henkelmax e83e00520f Fixed PlayerInteractEvents not working (#5976) 2019-08-02 13:44:17 -07:00
Gamebuster 9a50c208f0 Fixed Buttons in the error screen are incorrectly rendered if they are extremely long Closes #5687 (#5924) 2019-08-02 13:42:58 -07:00
Gamebuster 7acb380ba8 Fix LazyOptional throwing NPE to consumers when owners null. (#5772) 2019-08-02 13:42:13 -07:00
LexManos 48fa2f458c Make Villager profession unlocalized name use modids when not 'minecraft' Closes #5977
Fixed trees able to be generated through water. Closes #6000
Change Block#toString to use getRegistryName instead of getNameForObject Closes #5937
Allow Cooking Recipes to deserialize results with stack sizes. Closes #5960
2019-08-02 13:37:02 -07:00
LexManos 318fc6ffe8 Fixed DimensionType.getRegistryName() returning null Closes #5992
Fixed RegisterDimensionEvent not firing for new worlds. Closes #5987
2019-07-31 22:43:46 -07:00
LexManos b009cedc0c Introduce new Side Annotation Stripper system to semi-automate the shipment of Sided methods and cleanup patches.
New forge:checkSAS task to validate this config file. Closes #5995
2019-07-31 21:15:39 -07:00
ichttt c6dd475610 Move world unload patch to tick function to prevent duplicate unloading, fix log message in dim manager, fix javadoc for unload method (#5964) 2019-07-30 16:39:05 -07:00
bl4ckscor3 61285a098a fix melon and pumpkin seeds being peaceable on more than just farmland (#5980) 2019-07-30 16:35:23 -07:00
Paul Becker 995a8b8d35 Fixed possible ClassCastException with dye-able armor. (#5985) 2019-07-30 16:30:12 -07:00
cpw 5d33697cb1 Fix naming for dev launch providers - they're in MCP..
Signed-off-by: cpw <[email protected]>
2019-07-29 20:19:50 -04:00
cpw ae09fc6b6d Register a config command. Currently one subcommand: showfile, which
when passed a modid and a type (CLIENT, COMMON or SERVER) will display
a link in the caller's chat to open that file in the OS file viewer of choice.

Signed-off-by: cpw <[email protected]>
2019-07-28 21:09:15 -04:00
cpw cd826f7bcf Load default configs from the defaultconfig directory by default. (Can
be overridden in the fml.toml config file if desired).

Will load any type of config tracked file from there - client, common, server
or custom tracked file. This means you can ship defaults for your pack
in a defaultconfig directory. I am thinking about ways to force a specific
config override for an existing config.

Signed-off-by: cpw <[email protected]>
2019-07-28 13:44:18 -04:00
cpw 283ece29e8 Fix vanilla bug that hardcore death doesn't clean up properly, leaving
a running server and a broken GUI. Vanilla bug MC-148865

Signed-off-by: cpw <[email protected]>
2019-07-27 12:47:59 -04:00
LexManos 1918148b8e Fixed network ticking player entity while it is dead. And explicitly prevent overworld from unloading. Closes #5978 2019-07-27 02:35:06 -07:00
cpw e17714583f Crash report extended to show ModLauncher FML and Forge data.
Signed-off-by: cpw <[email protected]>
2019-07-26 20:02:21 -04:00
cpw 4c05c63a04 Fix potion transformer to look up the right name depending on context.
Signed-off-by: cpw <[email protected]>
2019-07-26 00:35:03 -04:00
cpw 0bdc2d04b4 Added a coremod, shush, don't tell Lex.
Seriously, this is how to do targeted changes to specific classes.

In this case, adding a fieldtomethod redirect for EffectInstance.potion
to allow substitution.

Signed-off-by: cpw <[email protected]>
2019-07-25 23:02:05 -04:00
LexManos 57d4d60a33 Fix Slimes not splitting on death Closes #5973 2019-07-25 17:59:57 -07:00
LexManos 731e1920d2 Fix @ObjectHolderRegistry not properly detecting vanilla class level references. Closes #5958 2019-07-25 17:59:08 -07:00
LexManos 7411b444d3 Fixed missed patch causing blocks to not dropping EXP and BreakEvent to not fire. 2019-07-24 11:15:23 -07:00
David Quintana ae3d002ac6 Fix & Improve state comparison when checking vanilla block replacements (#5922) 2019-07-22 19:23:20 -07:00
LexManos 1bd70ac5ab Keep player cap data until they have revived. Closes #5956 2019-07-22 15:45:38 -07:00
cpw c90b1732e9 Fix objloader registering at wrong time. Closes #5847. Added test
class as suggested in the issue.

Note: most tests are commented out at the present time, pending
rework. Tests that work, work.

Signed-off-by: cpw <[email protected]>
2019-07-20 21:04:00 -04:00
cpw fcd9582133 Fix datafixer exception catch: Closes #5951
Signed-off-by: cpw <[email protected]>
2019-07-20 19:59:08 -04:00
cpw 9d82d822db Fix error when ModsDiscoverer visits a non existent mods dir.
Closes cpw/modlauncher#30

Signed-off-by: cpw <[email protected]>
2019-07-20 19:37:54 -04:00
cpw 186d91c03f Merge branch 'pull/5948' into 1.14.x 2019-07-20 19:35:26 -04:00
cpw eec5809097 Realms' removal has removed the need for additional jar transformation.
Signed-off-by: cpw <[email protected]>
2019-07-20 19:33:54 -04:00
cpw 4582a29ec1 Make I18N format errors less spammy, also remove single apostrophes from
current translations in en_us.json. Other langs may still have problems.

Closes #5952
Signed-off-by: cpw <[email protected]>
2019-07-20 19:14:17 -04:00
JoJoModding 2f83234ccb Fix spam during startup (#5957) 2019-07-20 14:55:21 -07:00
ichttt bef52c945b Fix forge 1.14.4 startup in obfed enviroment (#5955) 2019-07-20 12:59:23 -07:00
Thomas Aunvik 1de4ad735b Updated Example Version Range for 1.14.4 (#5950)
* Updated Example Version Range for 1.14.4

* Also changed loader version and version range
2019-07-20 12:06:06 -04:00
LexManos 00fc29d40d Fix javac compile issues. 2019-07-19 23:27:31 -07:00
cpw 27afdc8a27 Provisional update to 1.14.4. Missing a lot of playerinteractionmanager patches because everything moved and I'm tired.
Fix up immediate problems.

bump to 28.
2019-07-20 00:35:40 -04:00
cpw eff42f6066 Update mappings to 20190719 in prep for 1.14.4..
Signed-off-by: cpw <[email protected]>
2019-07-19 11:55:30 -04:00
Barteks2x b99453d568 Fix RegistryObject when used with generic registry entry classes 2019-07-19 12:06:16 +02:00
CJ Miller 9f5ce12754 Remove OnlyIn Client Distribution from Effect and EffectType methods. (#5925) 2019-07-18 14:15:31 -07:00
LexManos cb21e95e0b Change default BrewingRecipe to use an Ingredient for the input instead of ItemStack. Closes #5944
Add AT for GameRules.register Closes #5946
Fix Forge Blockstate loader model path is inconsistent with vanilla blockstates Closes #5892
Fix client crashing when opting not to load a world when there's missing blocks Closes #5886
2019-07-18 14:13:20 -07:00
LexManos e6f032db1b Fix CheckSpawn event logic for natural spawns. 2019-07-16 22:38:11 -07:00
LexManos 86e9425638 Fixed item breaking particles not capturing current state of the ItemStack. Closes #5934 2019-07-16 16:02:52 -07:00
ewewukek 53ac33a84c Fix RenderSpecificHandEvent firing with wrong hand stack (#5927) 2019-07-16 12:42:33 -07:00
its_meow 5cf2af569f [1.14.x] Fix text positioning issues caused by scaling loading screen (#5932) 2019-07-16 12:41:21 -07:00
LexManos a46b7cb67a Fixed PlayerSleepInBedEvent pos is always null Closes #5936
Fixed decompile error causing Endless Loop in ModelBackery if model errors exist.
Fixed NPEs related to teleporting players without portals.
2019-07-16 11:52:51 -07:00
LexManos 3d78f30d18 Add simple concurrency protection to Server world list. Closes #5938 and #5739 2019-07-16 09:59:33 -07:00
cpw ad64d383e1 Update modlauncher to the 3.x series.
Signed-off-by: cpw <[email protected]>
2019-07-14 22:48:30 -04:00
tterrag1098 0a7f5ff9fa Rework GuiModList mod info to use custom scrolling panel impl 2019-07-10 20:13:33 -07:00
LexManos ce28c5794d Cleanup Forge's Access Transformer, and add ATs for Block.Properties#noDrop, and AxeItem/PickaxeItem. Closes #5866 and Closes #5921 2019-07-10 17:39:19 -07:00
LexManos e55c7c889b Fix race condition in client mouse handler. Closes #5888 2019-07-10 17:35:53 -07:00
LexManos 0633e8218f Added LootPool.Builder#bonusRolls setter. Closes #5887 2019-07-09 18:21:05 -07:00
LexManos 0fdfe1fd59 Implemented Item.get/setDamage hooks. Closes #5899 2019-07-09 18:03:19 -07:00
LexManos 2cc264645b Implement Item.isRepairable in Crafting and Grindstone. Closes #5917 2019-07-09 18:02:47 -07:00
LexManos 983e0a93db Re-implement state.onBlockExploded() Closes #5914 2019-07-09 17:07:09 -07:00
Vincent Lee d88e4fbf36 Add general damage hook for items. Closes #5502 (#5670) 2019-07-08 20:43:02 -07:00
LexManos f79da3edf7 Fix syntax error in IRenderHandler. 2019-07-08 20:14:41 -07:00
LexManos 8742d74e93 Pass tick counter to custom render handlers (#5744) 2019-07-08 19:55:47 -07:00
Cadiboo ff80ab6a23 Fire Loading event (#5795) 2019-07-08 19:49:47 -07:00
Dirk "YouDirk" Lehmann 8c37d642fe Fix logoFile not working properly (#5775) 2019-07-08 19:49:31 -07:00
ichttt 06a30e9f23 Adds some explanatory javadocs and check world in ModelDataManager (#5762) 2019-07-08 19:47:18 -07:00
Antoine Lucas 650e7dc16e Add InputEvent documentation (#5698) 2019-07-08 19:47:06 -07:00
ichttt d41fad51c2 Add IModelData to getParticleTexture (#5756) 2019-07-08 19:46:32 -07:00
ichttt 0463949ac3 Fixed BakedModelWrapper not delegating new methods (#5761) 2019-07-08 19:45:27 -07:00
Sargun Vohra 5f0fd4b706 Throw exception when a mod returns null from a dispatched capability provider (#5646) 2019-07-08 19:45:10 -07:00
Benjamin K 201c368325 Add isServer and isClient methods to LogicalSide (#5606)
* Add helper methods to LogicalSide.

* Fix backwards docs.
2019-07-08 19:44:35 -07:00
Cadiboo 3fe08f149d Added documentation to ObfuscationReflectionHelper adn deprecated index based functions. (#5893) 2019-07-08 19:44:21 -07:00
LexManos 61bea2bfda Fixed EntityJoinWorldEvent not being fired when player is added to ServerWorld. #5827
Fixed wrong example path for the access transformer in the MDK build.gradle. #5891
Added getters for mouse x/y velocity and if the middle-mouse button is being held down. #5776
Modify issue template for better clarity. #5874
Fixed grindstone not using ItemStack-sensitive getMaxDamage. #5831
Added ParticleManager.registerFactory to Forge's AT. #5896
Fixed NPE in SidedInvWrapper when side was null. #5787
Moved EndermanEntity.setAttackTarget super call to allow LivingSetAttackTargetEvent the ability to override default behavior. #5778
Added field to make "Looking at" debug info maximum distance configurable #5714
2019-07-08 18:42:12 -07:00
DaemonUmbra f720140481 Disable Config Button when no mods are selected (#5905)
Closes #5889
2019-07-08 15:56:49 -07:00
Tedstar 66a2d38ab8 Fix MC-258 on mod list screen, enable sorting, minor tweaks. (#5846) 2019-07-08 15:50:05 -07:00
DaemonUmbra bed266f310 Fixed #5895: Shearing via Displenser drops Shears (#5906) 2019-07-08 15:47:34 -07:00
Cloudhunter 719f08ea5e Fix link applying to whole component in chat if component starts with link (#5909) 2019-07-08 15:46:49 -07:00
Suppergerrie2 3992ea5c59 Added harvestLevel and harvestTool setter to the Block.Properties. (#5916) 2019-07-08 15:45:53 -07:00
LexManos a01c1cdc3a Fix installer realms issue on server.
Uptake EventBus changes to fix some potential dead locks.
2019-07-05 13:26:23 -07:00
m00nl1ght-dev 7a8ae9f56b Fix old entity not being removed on dimension change (#5833) 2019-07-04 13:03:45 -07:00
primetoxinz 765efc3c72 Update TextureStitchEvent.Pre to give access to the list of ResourceLocations that will be loaded as textures. (#5870) 2019-07-03 12:26:51 -07:00
LexManos bc23c1ddb2 Add installer processor to deobfuscate Mincraft's Realms library.
This task will processes the current realms library from the json, so the installer must be re-ran every time they update it.
2019-07-03 01:08:20 -07:00
David Quintana 87e2fcb4e5 Redirect a method to the recipe book container, to allow modded screens to have a recipe book. (#5873) 2019-07-02 13:05:03 -07:00
Take Weiland 478b7e7ccc Fix WorldEvent.Unload not firing on the client (fixes #5880) (#5884) 2019-07-02 12:58:45 -07:00
Take Weiland 0574db134c Fix TickEvent.PlayerTickEvent firing twice for tick end (fixes #5878) (#5885) 2019-07-02 12:57:06 -07:00
LexManos 358211ca66 Fix type cast issues in ForgeConfig values. Closes #5894
Added config value set and save functions.
By default mod configs are auto-saved, so you do not need to call save unless you create your own Config object.
2019-07-02 11:54:59 -07:00
cpw c8e5007913 Remove legacy StartupProgress.
Implement properly scalable progress thanks to @gigaherz. Closes #5863.
Implement API for pushing messages to the startup screen from mods.
Add memory display.

Signed-off-by: cpw <[email protected]>
2019-06-30 23:48:54 -04:00
cpw 943fedb073 Update coremods to newer version, with support for new targets.
Signed-off-by: cpw <[email protected]>
2019-06-29 17:05:18 -04:00
LexManos 13ae8e41ee Fix duplicate WorldEvent.Unload call in client key handler.
Add recipe generator to replace vanilla recipes with Forge tags.
2019-06-27 17:23:23 -07:00
LexManos ac8b196b8c Fix dimension save data invalid cache being to aggressive. 2019-06-27 10:57:03 -07:00
ある 2c3183bdae Fix garbled "µs" (#5818) 2019-06-26 13:23:47 -07:00
LexManos 53349603e2 Fix fmluserdevdata not being a valid launch target. 2019-06-25 18:16:10 -07:00
LexManos c284de366b Split userdev data entry point into it's own provider to fix duplicate mod issue. 2019-06-25 18:03:51 -07:00
tterrag e81c330694 Fix configs correcting numeric values when the primitive type differs
Fix configs with range not clamping the corrected value, and instead
just replacing with the default

Closes #5855
2019-06-25 19:56:31 -04:00
Ben Staddon 790da699dd Fix item placement losing NBT data in creative mode (#5757) 2019-06-25 13:59:10 -07:00
MajorTuvok 7915397377 Add extension to write entry id's to PacketBuffer's (#5812) 2019-06-25 13:55:24 -07:00
Someone b2a5d34679 Add isItemValid check for ItemStackHandler (#5850) 2019-06-25 13:50:08 -07:00
Johannes 73bb18e78b Fix leather armor dye recipe (#5836) 2019-06-25 13:48:49 -07:00
Tedstar 9701148819 [1.14.x] Replace dye items in Forge tags. (#5843) 2019-06-25 13:44:54 -07:00
Unnoen f1dbc8b117 Update readme and issue template. (#5773) 2019-06-25 13:38:32 -07:00
bl4ckscor3 b8131e6e67 implement Ingredient.getSerializer for custom ingredients (#5813) 2019-06-25 10:25:33 -07:00
LexManos f4598a97f7 Fix vines and scaffolding not being climbable.
Fix powered rails not spreading power correctly. Closes: #5854
2019-06-24 20:05:50 -07:00
LexManos c90d42973d Fix misaligned ServerWorld initCapabilities patch. 2019-06-24 19:37:02 -07:00
LexManos ff0bb8c83c Initial 1.14.3 update. 2019-06-24 19:01:03 -07:00
cpw e5acea60e6 Fix too many registries being sent from server to client
Signed-off-by: cpw <[email protected]>
2019-06-23 19:54:55 -04:00
tterrag 216b536967 Remove OnlyIn on TagCollection#getOwningTags
Fixes Block#getTags crashing on servers
2019-06-23 18:36:27 -04:00
cpw 0a819da0e7 Reorganize sided event dispatch slightly. Dispatch model and entityrenderer
functions at more appropriate times.

Signed-off-by: cpw <[email protected]>
2019-06-23 16:01:20 -04:00
cpw bdad2af27b Tweak for lowercase handling.
Signed-off-by: cpw <[email protected]>
2019-06-23 14:51:58 -04:00
cpw 60513446fa Merge branch 'pull/5793' into 1.14.x 2019-06-23 14:42:32 -04:00
cpw be415091cd Fix crash when crashing during modloading. Fix GuiModList being weird.
Signed-off-by: cpw <[email protected]>
2019-06-23 14:37:05 -04:00
cpw 9067dbf6a0 Process the main modloading work on the async thread, but still
do deferred work on the main thread by passing in the executor.

Signed-off-by: cpw <[email protected]>
2019-06-23 12:26:45 -04:00
tterrag 359be1a880 Clean up config comments, make comment array nonnull 2019-06-23 02:57:00 -04:00
tterrag 99624bf3b5 Fix forge event bus never starting up 2019-06-23 02:17:51 -04:00
tterrag 252b94a110 Automatically add range to config comments 2019-06-23 02:17:28 -04:00
cpw 448d996a45 First pass of adding text to the loading progress UI. It deliberately uses the very primitive STB
generated font, so can only render basic ASCII text, and also only renders pre-defined strings,
as translations aren't available either.

Signed-off-by: cpw <[email protected]>
2019-06-22 23:39:00 -04:00
JoJoDeveloping b9e5dfd286 Add mod failure identification 2019-06-23 03:14:05 +02:00
cpw d966746fbf Moved some events to the Mod's event bus. You'll need to update which bus
you're listening to for these. (The Mod event bus is the only one actively
dispatching events during model loading).

ModelRegistryEvent, ModelBakeEvent, TextureStitchEvent.Pre, TextureStitchEvent.Post, ColourHandlerEvent.Block, ColourHandlerEvent.Item

Signed-off-by: cpw <[email protected]>
2019-06-22 20:36:07 -04:00
cpw 89baeb3d5d Fix StartupQuery, and put tests back.
Signed-off-by: cpw <[email protected]>
2019-06-22 19:58:10 -04:00
cpw 89006458a2 Fix stupid bug introduced with the refactor..
Signed-off-by: cpw <[email protected]>
2019-06-22 19:08:49 -04:00
cpw 389bc1ecea Tidy up mod loading a bit more, and also crash if the [[mods]] list isn't
a list.

Signed-off-by: cpw <[email protected]>
2019-06-22 12:52:22 -04:00
cpw 1e0437208b Merge remote-tracking branch 'origin/1.14.x' into 1.14.x 2019-06-22 12:33:46 -04:00
cpw 256bd01e0c Fix server side loading, tweak mods command.
Signed-off-by: cpw <[email protected]>
2019-06-22 12:31:27 -04:00
tterrag ef7b035f02 Fix ModelDataTest 2019-06-21 23:35:08 -04:00
cpw 83a0dc2ef9 Merge remote-tracking branch 'origin/1.14.x' into 1.14.x 2019-06-21 22:42:33 -04:00
cpw c10174d50d Update mappings, move mod initialization to the async loader.
Signed-off-by: cpw <[email protected]>
2019-06-21 22:42:16 -04:00
tterrag 5a3b375147 Fix #5612 add entity to ISelectionContext 2019-06-21 21:15:56 -04:00
tterrag 656ff25ae1 Fix #5768 add access to MainWindow object in RenderGameOverlayEvent 2019-06-21 20:29:04 -04:00
tterrag 19059b054e Fix #5810 incorrect cullface on some models 2019-06-21 20:23:32 -04:00
tterrag 45bc487fc0 Fix #5686 ArmorLayer still calls deprecated getArmorResource 2019-06-21 19:48:00 -04:00
tterrag 9c74a31ca2 Fix bad patch breaking armor dyeing 2019-06-21 19:47:23 -04:00
tterrag 8c3e511538 Make sure test mods load, fix BlockstateRetextureTest 2019-06-21 19:35:32 -04:00
tterrag 5fb948fb35 Fix #5805 ModelBakeEvent does not fire 2019-06-21 19:34:58 -04:00
LexManos a14c2233e0 Fix lighting not being sent to client when large amounts of blocks change at once. Closes #5839
Remove RecipeType/VanillaRecipeTypes, as 1.14 has a vanilla system for this.
2019-06-19 18:10:02 -07:00
LexManos f01b87fac7 Fix some compile errors in test classes. 2019-06-19 18:07:58 -07:00
LexManos 40bdde2043 Fix Vanilla resources loading from classpath, instead of the extra jar. Causing issues in dev time, and Forge replacements. Closes #5824 2019-06-17 14:08:16 -07:00
LexManos 0a8a601877 Add temporary hard crash when mods error until we can load our error screen. 2019-06-16 00:48:38 -07:00
LexManos 002e29958e Make ReverseTagWrapper unmodifiable, fix error in log when mods folder doesn't exist initial scan. 2019-06-16 00:47:40 -07:00
cpw 604987a005 Skip running the datagenerator on unrequested mods.
Add a run config for the data task for modders to use

Signed-off-by: cpw <[email protected]>
2019-06-16 00:47:50 -04:00
cpw 7e3e6b1969 Remove paulscode hack. It is not needed in 1.14, since paulscode is
no longer used.

Signed-off-by: cpw <[email protected]>
2019-06-15 21:51:51 -04:00
cpw d821514372 Modify lex's data handler to use proper mod lifecycle event mechanisms
instead. New Lifecycle Event for requesting data harvesting. Mods will
be constructed, the registry will fire, and then a new Data event will
fire. Submit new data tag files to the data gatherer if you wish.
The game will shutdown after this. No other mod elements will happen.

Signed-off-by: cpw <[email protected]>
2019-06-15 21:24:45 -04:00
cpw 37a896fe1b Add params for the exception message
Signed-off-by: cpw <[email protected]>

tweak logging

Signed-off-by: cpw <[email protected]>
2019-06-15 19:47:08 -04:00
LexManos e1cdb2e558 Expose the data entry point and generate Forge's Tags using it. 2019-06-13 20:58:03 -07:00
LexManos c30b27fcfe Add reverse tag cache, to make looking up tags for items/blocks/etc.. less costly. 2019-06-12 19:28:10 -07:00
marcus8448 9542f51cd0 Update Example Mod (#5781) 2019-06-12 16:49:20 -07:00
its_meow a7b56f0975 Fix AT for EntitySpawnPlacementRegistry.register (#5799) 2019-06-12 16:17:25 -07:00
Johannes ed3dc8c7d3 Implement getValue in ClearableRegistry fixing DimensionArgument. (#5809)
Fix DimensionArgument
2019-06-12 16:16:32 -07:00
SquidDev ed6ce87c22 Fix RenderSpecificHandEvent firing with wrong hand (#5789) 2019-06-12 01:05:27 -04:00
kashike 4bd7427b70 Use dragon_immune block tag instead of manually checking blocks (#5792) 2019-06-12 01:04:13 -04:00
tterrag 0b1196db3f Fix #5806 sheep drop shears instead of wool
lol
2019-06-12 00:57:27 -04:00
tterrag b25ed7ef91 Fix incorrect method used in ShrubFeature patch 2019-06-12 00:51:45 -04:00
tterrag dc95130526 Rework AbstractTreeFeature patches to reduce impact and avoid name conflicts 2019-06-12 00:48:11 -04:00
tterrag d5ee80a70a Add IContainerFactory for reading custom container data on the client 2019-06-10 18:14:49 -04:00
LexManos 5dc944c1c3 Fix Fishing and Mineshaft Minecarts loot tables erroring. #5785
Fix Client block breaking speed not matching the server. #5790
Fix Village Siege event location, and MC-154328 preventing Sieges starting. #5800
Fix EntityJoinWorldEvent not firing on client, or some server code paths. #5786
2019-06-10 14:03:51 -07:00
tterrag da22fd40bf Adjust NetworkEvent#enqueueWork to match vanilla logic
In singleplayer our packet work could get delayed until the next tick,
breaking the expectation of packet read order. Fixes that using
NetworkHooks.openGui would result in missing inventory data on the client
2019-06-10 00:13:27 -04:00
LexManos 1434419e47 Fix gameDir argument error on dedicated server. 2019-06-09 11:19:01 -07:00
tterrag 3385e62aa7 Add forge registries for most vanilla registries
Made all registry names consistent with their vanilla counterparts
Also added a system for legacy registry names, so no data will be lost
Cleaned up formatting in GameData and ForgeRegistries
2019-06-09 04:23:39 -04:00
tterrag 40f2276e88 Add registry flag for syncing 2019-06-09 00:55:42 -04:00
tterrag 35cd89c00c Fix issues preventing test mods loading 2019-06-09 00:19:29 -04:00
tterrag 892fea3df9 Add forge registry for container types, expose ScreenManager.registerFactory 2019-06-09 00:19:17 -04:00
cpw 2d32929dc5 Don't NPE during construction of ModLoadingException..
Signed-off-by: cpw <[email protected]>
2019-06-08 14:30:15 -04:00
LexManos 728b4857c3 Fix misobfed methods due to mapping conflict. 2019-06-08 09:22:03 -07:00
cpw 9fa4641cb0 Update mappings
Signed-off-by: cpw <[email protected]>
2019-06-08 10:45:28 -04:00
tterrag fc04a65a0f Fix block activation not occurring serverside
Missing block of code from the old patch caused it to be skipped
2019-06-08 01:32:53 -04:00
tterrag a93d7d20ee Rework model patches/classes for new bake signature 2019-06-08 01:02:29 -04:00
LexManos b74b72e44c Fix NamespacedWrapper not delegating a new getter. Fixing data loading spam at world start.
Update red/yellow/green tags with new vanilla item names.
Reenabled test source directory in project and made ModelDataTest compile.
2019-06-07 19:34:16 -07:00
cpw 850c73b73f and userdev
Signed-off-by: cpw <[email protected]>
2019-06-07 17:34:25 -04:00
cpw d736e26e0c Fix realms class name
Signed-off-by: cpw <[email protected]>
2019-06-07 17:32:33 -04:00
3191 changed files with 101543 additions and 108007 deletions

No files matched your search

+7
View File
@@ -14,3 +14,10 @@
*.cfg text eol=lf
*.py text eol=lf
*.jks binary
# Disable autocrlf on generated files, they always generate with LF
src/generated/**/.cache/cache text eol=lf
src/generated/**/*.json text eol=lf
src/generated_test/**/.cache/cache text eol=lf
src/generated_test/**/*.json text eol=lf
-4
View File
@@ -1,4 +0,0 @@
<!-- Thank you for reporting! -->
<!-- Please go to the forum first for support with crashes and issues. -->
<!-- http://www.minecraftforge.net/forum/forum/18-support-bug-reports/ -->
+13
View File
@@ -0,0 +1,13 @@
---
name: Feature request
about: Want to request a feature?
title: ''
labels: Feature
assignees: ''
---
<!-- Please note, feature requests that are submitted as GitHub issues here are rarely implemented. -->
<!-- If you'd like to see something in Forge, you should be ready to implement it as a PR. -->
<!-- If you're not sure, open a Draft PR or discuss it in the Discord server. -->
<!-- Discord: https://discord.gg/UvedJ9m -->
+26
View File
@@ -0,0 +1,26 @@
---
name: Issue report
about: Visit the forum first for issues with crashes.
title: ''
labels: Triage
assignees: ''
---
<!-- Thank you for reporting! -->
<!-- For support with crashes and issues, please create a post on the forum instead: -->
<!-- https://www.minecraftforge.net/forum/forum/18-support-bug-reports/ -->
**Minecraft Version:** {Minecraft version}
**Forge Version:** {Forge version. *Version number, not latest/rb*}
**Logs:** {Link(s) to GitHub Gist with full latest.log and/or crash report}
**Steps to Reproduce:**
1. Do this
2. Then do that
3. ...
**Description of issue:**
+10 -6
View File
@@ -9,29 +9,35 @@
#idea
/.idea
/*/out
/classes
*.iml
#gradle
/build
/.gradle
/mdk/.gradle
/mdk/build
/*/build
/*/.gradle
#occupational hazards
# Projects repo, either ignore it, or ignore patches.
/projects/mcp/
/projects/clean/
/projects/forge/
/projects/fmlonly/
#/patches/*
#occupational hazards
/projects/**/build/
/projects/**/out/
/projects/**/run/
/projects/**/*.launch
/repo/
/buildSrc
src/generated/resources/.cache/
#Patch rejects
/patches-/
*.patch.rej
/projects/*/rejects/
# FML changelog
changelog.txt
@@ -39,5 +45,3 @@ changelog.txt
*.7z
/logs/
gradle.properties
!/mdk/gradle.properties
+104
View File
@@ -0,0 +1,104 @@
<?xml version="1.0"?>
<project>
<modelVersion>4.0.0</modelVersion>
<name>MinecraftForge_Forge Config DSL Script</name>
<groupId>MinecraftForge_Forge</groupId>
<artifactId>MinecraftForge_Forge_dsl</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>configs-dsl-kotlin-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<repositories>
<repository>
<id>jetbrains-all</id>
<url>https://download.jetbrains.com/teamcity-repository</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>teamcity-server</id>
<url>https://teamcity.minecraftforge.net/app/dsl-plugins-repository</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>JetBrains</id>
<url>https://download.jetbrains.com/teamcity-repository</url>
</pluginRepository>
</pluginRepositories>
<build>
<sourceDirectory>${basedir}</sourceDirectory>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration/>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>teamcity-configs-maven-plugin</artifactId>
<version>${teamcity.dsl.version}</version>
<configuration>
<format>kotlin</format>
<dstDir>target/generated-configs</dstDir>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>configs-dsl-kotlin</artifactId>
<version>${teamcity.dsl.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.teamcity</groupId>
<artifactId>configs-dsl-kotlin-plugins</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-script-runtime</artifactId>
<version>${kotlin.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
+136
View File
@@ -0,0 +1,136 @@
import jetbrains.buildServer.configs.kotlin.v2019_2.*
import jetbrains.buildServer.configs.kotlin.v2019_2.projectFeatures.githubIssues
/*
The settings script is an entry point for defining a TeamCity
project hierarchy. The script should contain a single call to the
project() function with a Project instance or an init function as
an argument.
VcsRoots, BuildTypes, Templates, and subprojects can be
registered inside the project using the vcsRoot(), buildType(),
template(), and subProject() methods respectively.
To debug settings scripts in command-line, run the
mvnDebug org.jetbrains.teamcity:teamcity-configs-maven-plugin:generate
command and attach your debugger to the port 8000.
To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View
-> Tool Windows -> Maven Projects), find the generate task node
(Plugins -> teamcity-configs -> teamcity-configs:generate), the
'Debug' option is available in the context menu for the task.
*/
version = "2021.2"
project {
buildType(Build)
buildType(BuildSecondaryBranches)
buildType(PullRequests)
params {
text("docker_jdk_version", "17", label = "Gradle version", description = "The version of the JDK to use during execution of tasks in a JDK.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
text("docker_gradle_version", "7.4", label = "Gradle version", description = "The version of Gradle to use during execution of Gradle tasks.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
text("git_main_branch", "1.18.x", label = "Git Main Branch", description = "The git main or default branch to use in VCS operations.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
text("git_branch_spec", """
+:refs/heads/(main*)
+:refs/heads/(master*)
+:refs/heads/(develop|release|staging|main|master)
+:refs/heads/(1.*)
""".trimIndent(), label = "The branch specification of the repository", description = "By default all main branches are build by the configuration. Modify this value to adapt the branches build.", display = ParameterDisplay.HIDDEN, allowEmpty = true)
text("github_repository_name", "MinecraftForge", label = "The github repository name. Used to connect to it in VCS Roots.", description = "This is the repository slug on github. So for example `MinecraftForge` or `MinecraftForge`. It is interpolated into the global VCS Roots.", display = ParameterDisplay.HIDDEN, allowEmpty = false)
text("env.PUBLISHED_JAVA_ARTIFACT_ID", "forge", label = "Published artifact id", description = "The maven coordinate artifact id that has been published by this build. Can not be empty.", allowEmpty = false)
text("env.PUBLISHED_JAVA_FML_ARTIFACT_ID", "fmlonly", label = "Published fmlonly artifact id", description = "The maven coordinate artifact id for fml only that has been published by this build. Can not be empty.", allowEmpty = false)
text("env.PUBLISHED_JAVA_FML_ARTIFACT_VERSION", "0.0.0-SNAPSHOT", label = "Published fmlonly artifact version", description = "The version for fml only that has been published by this build. Can not be empty.", allowEmpty = false)
text("env.PUBLISHED_JAVA_GROUP", "net.minecraftforge", label = "Published group", description = "The maven coordinate group that has been published by this build. Can not be empty.", allowEmpty = false)
//These are references and not actually keys
password("env.CROWDIN_KEY", "credentialsJSON:a3102dbe-805d-4177-9f54-3d2c2eb08fd5", display = ParameterDisplay.HIDDEN)
password("env.KEYSTORE_URL", "credentialsJSON:a7ae1c82-8058-4061-8d12-7f6bc2618d2e", display = ParameterDisplay.HIDDEN)
password("env.KEYSTORE_PASSWORD", "credentialsJSON:d7b964e3-a1fd-47a8-b892-6f601fe47479", display = ParameterDisplay.HIDDEN)
text("additional_publishing_gradle_parameters", "-PcrowdinKey=%env.CROWDIN_KEY% -PkeystoreKeyPass=%env.KEYSTORE_PASSWORD% -PkeystoreStorePass=%env.KEYSTORE_PASSWORD% -Pkeystore=%env.KEYSTORE_URL%", label = "Additional gradle parameters for publish", description = "Contains the additional gradle parameters used during publishing.", display = ParameterDisplay.HIDDEN, allowEmpty = true)
checkbox("should_execute_build", "false", label = "Should build", description = "Indicates if the build task should be executed.", display = ParameterDisplay.HIDDEN,
checked = "true", unchecked = "false")
checkbox("should_execute_test", "false", label = "Should build", description = "Indicates if the build task should be executed.", display = ParameterDisplay.HIDDEN,
checked = "true", unchecked = "false")
}
features {
githubIssues {
id = "MinecraftForge_MinecraftForge__IssueTracker"
displayName = "MinecraftForge/MinecraftForge"
repositoryURL = "https://github.com/MinecraftForge/MinecraftForge"
}
}
}
object Build : BuildType({
templates(AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_BuildMainBranches"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"), AbsoluteId("MinecraftForge_BuildUsingGradle"), AbsoluteId("MinecraftForge_PublishProjectUsingGradle"), AbsoluteId("MinecraftForge_TriggersStaticFilesWebpageGenerator"))
id("MinecraftForge_MinecraftForge__Build")
name = "Build"
description = "Builds and Publishes the main branches of the project."
features {
feature {
id = "trigger_fml_only_files_generator"
type = "triggerBuildFeature"
param("triggers", "MinecraftForge_FilesGenerator_GeneratePages")
param("parameters", """
env.PUBLISHED_JAVA_FML_ARTIFACT_ID~env.PUBLISHED_JAVA_ARTIFACT_ID
env.PUBLISHED_JAVA_FML_ARTIFACT_VERSION~env.PUBLISHED_JAVA_ARTIFACT_VERSION
env.PUBLISHED_JAVA_GROUP
""".trimIndent())
}
}
})
object BuildSecondaryBranches : BuildType({
templates(AbsoluteId("MinecraftForge_ExcludesBuildingDefaultBranch"), AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_BuildMainBranches"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"), AbsoluteId("MinecraftForge_BuildUsingGradle"))
id("MinecraftForge_MinecraftForge__BuildSecondaryBranches")
name = "Build - Secondary Branches"
description = "Builds and Publishes the secondary branches of the project."
params {
text("git_branch_spec", """
+:refs/heads/(*)
-:refs/heads/noci*
""".trimIndent(), label = "The branch specification of the repository", description = "By default all main branches are build by the configuration. Modify this value to adapt the branches build.", display = ParameterDisplay.HIDDEN, allowEmpty = true)
}
vcs {
branchFilter = """
+:*
-:1.*
-:<default>
""".trimIndent()
}
})
object PullRequests : BuildType({
templates(AbsoluteId("MinecraftForge_BuildPullRequests"), AbsoluteId("MinecraftForge_SetupGradleUtilsCiEnvironmen"), AbsoluteId("MinecraftForge_BuildWithDiscordNotifications"), AbsoluteId("MinecraftForge_SetupProjectUsingGradle"), AbsoluteId("MinecraftForge_BuildUsingGradle"))
id("MinecraftForge_MinecraftForge__PullRequests")
name = "Pull Requests"
description = "Builds pull requests for the project"
params {
checkbox("should_execute_build", "true", label = "Should build", description = "Indicates if the build task should be executed.", display = ParameterDisplay.HIDDEN,
checked = "true", unchecked = "false")
text(
"gradle_build_task",
"assemble",
label = "Gradle build task to execute during build",
description = "Determines the build task that is executed to build the project.",
display = ParameterDisplay.HIDDEN,
allowEmpty = false
)
}
vcs {
branchFilter = """
+:*
-:1.*
-:<default>
""".trimIndent()
}
})
-38
View File
@@ -1,38 +0,0 @@
sudo: required
dist: trusty
language: java
jdk: oraclejdk8
env:
- BUILD_NUMBER=9999
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
- rm -f $HOME/.gradle/caches/minecraft/deobfedDeps/providedDummy.jar
- rm -f $HOME/.gradle/caches/minecraft/deobfedDeps/compileDummy.jar
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- $TRAVIS_BUILD_DIR/build/localCache/Forge/
before_install: chmod +x gradlew
install:
- ./gradlew --refresh-dependencies
- ./gradlew ciWriteBuildNumber
script:
- travis_wait ./gradlew build -x createExe -S
- ./gradlew -p projects/Forge test -S -i
notifications:
email: false
# skip building travis on 1.13+ - it doesn't work there
branches:
except:
- 1.13-pre
- 1.13.x
- 1.14.x
- /^noci-.*$/
-22
View File
@@ -1,22 +0,0 @@
Contributing to Forge
=====================
1) Keep patches to Minecraft classes minimal. If you need a lot of things done, you may either add to relevant forge classes or make a new class.
2) An example mod must be provided for all PRs adding events/hooks to Forge. Whether it's a full mod using your proposed hooks, or just a pastebin containing a simple example, an example mod is required. Please also explain in detail what your new hook does.
3) Follow Forge coding guidelines (braces on newlines, spaces instead of tabs, etc)
For more information, refer to [the wiki](https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge)
Contributor License Agreement
=============================
- You grant Forge a license to use your code contributed to the primary codebase (everything **not** under patches) in Forge, under the LGPLv2.1 license.
- You assign copyright ownership of your contributions to the patches codebase (everything under patches) to Forge, where it will be licensed under the LGPLv2.1 license.
Additionally, while 1.9.4 is being maintained, you will be asked to acknowledge these two additional clauses.
- You grant Forge a license to use your code contributed to the primary codebase (everything **not** under patches) in Forge, under the MinecraftForge license.
- You grant assign copyright ownership of your contributions to the patches codebase (everything under patches) to Forge, where it will be licensed under the MinecraftForge license.
"Forge" is Forge Development LLC, a legally incorporated entity in Oregon, USA.
-9
View File
@@ -1,9 +0,0 @@
# On the Contribution of an RF-lite Energy System: "Energy"
Forge has acquired an Energy system, after many years of debate on the topic. The prevalence of the RF API has warranted the inclusion of a similar (but simpler) implementation to forge for 1.10.2 and onwards.
Those who wish to use an RF like API, feel free to use it. If you don't want to think about Energy, but know you need it, you can use it *if you wish*. If you want to interoperate with other energy systems, feel free to use this to broker with them.
# On Diversity in Energy Systems
Forge has always supported diversity in energy-like systems. If you have a burning desire to simulate electricity flow in all it's glory, we fully support you and look forward to playing your mod. If you wish to have pneumatic power, we have no objections, and would love to see your wonderful creations. If you have a power system of your own devising that is simply beyond our imagination, please, blow us away.
# On Modder Obligations
As a modder, you are under *no* obligation to use or support the forge Energy system. If anyone, user, mod-pack maker or even us, tells you otherwise, refer them to this statement. The Forge energy system is not intended to supplant diversity in energy systems. It is not intended to be one-size-fits-all. The choice to support it, is the choice of the modder.
Vendored
+31 -16
View File
@@ -6,8 +6,8 @@ pipeline {
}
agent {
docker {
image 'gradlewrapper:latest'
args '-v gradlecache:/gradlecache'
image 'gradle:7-jdk16'
//args '-v forgegc:/home/gradle/.gradle_cache/'
}
}
environment {
@@ -18,11 +18,6 @@ pipeline {
}
stages {
stage('fetch') {
steps {
checkout scm
}
}
stage('notify_start') {
when {
not {
@@ -39,11 +34,23 @@ pipeline {
)
}
}
/*
stage('pull_cache') {
steps {
sh 'cp -r /home/gradle/.gradle_cache/jdks/ /home/gradle/.gradle/jdks/'
sh 'cp -r /home/gradle/.gradle_cache/wrapper/ /home/gradle/.gradle/wrapper/'
sh 'cp -r /home/gradle/.gradle_cache/caches/ /home/gradle/.gradle/caches/'
}
}
*/
stage('setup') {
steps {
sh './gradlew ${GRADLE_ARGS} --refresh-dependencies --continue setup'
withGradle {
sh './gradlew ${GRADLE_ARGS} --refresh-dependencies --continue setup'
}
script {
env.MYVERSION = sh(returnStdout: true, script: './gradlew :forge:properties -q | grep "version:" | awk \'{print $2}\'').trim()
env.MYVERSION = sh(returnStdout: true, script: './gradlew :forge:properties -q | grep "^version:" | cut -d" " -f2').trim()
env.FMLONLY_VERSION = sh(returnStdout: true, script: './gradlew :fmlonly:properties -q | grep "^version:" | cut -d" " -f2').trim()
}
}
}
@@ -64,15 +71,23 @@ pipeline {
}
}
environment {
FORGE_MAVEN = credentials('forge-maven-forge-user')
CROWDIN = credentials('forge-crowdin')
KEYSTORE = credentials('forge-jenkins-keystore-old')
KEYSTORE_KEYPASS = credentials('forge-jenkins-keystore-old-keypass')
KEYSTORE_STOREPASS = credentials('forge-jenkins-keystore-old-keypass')
}
steps {
sh './gradlew ${GRADLE_ARGS} :forge:publish -PforgeMavenUser=${FORGE_MAVEN_USR} -PforgeMavenPassword=${FORGE_MAVEN_PSW} -PkeystoreKeyPass=${KEYSTORE_KEYPASS} -PkeystoreStorePass=${KEYSTORE_STOREPASS} -Pkeystore=${KEYSTORE} -PcrowdinKey=${CROWDIN}'
sh 'curl --user ${FORGE_MAVEN} http://files.minecraftforge.net/maven/manage/promote/latest/net.minecraftforge.forge/${MYVERSION}'
withCredentials([usernamePassword(credentialsId: 'maven-forge-user', usernameVariable: 'MAVEN_USER', passwordVariable: 'MAVEN_PASSWORD')]) {
withGradle {
sh './gradlew ${GRADLE_ARGS} publish -PkeystoreKeyPass=${KEYSTORE_KEYPASS} -PkeystoreStorePass=${KEYSTORE_STOREPASS} -Pkeystore=${KEYSTORE} -PcrowdinKey=${CROWDIN}'
}
}
}
post {
success {
build job: 'filegenerator', parameters: [string(name: 'COMMAND', value: "promote net.minecraftforge:forge ${env.MYVERSION} latest")], propagate: false, wait: false
build job: 'filegenerator', parameters: [string(name: 'COMMAND', value: "promote net.minecraftforge:fmlonly ${env.FMLONLY_VERSION} latest")], propagate: false, wait: false
}
}
}
stage('test_publish_pr') { //Publish to local repo to test full process, but don't include credentials so it can't sign/publish to maven
@@ -83,7 +98,9 @@ pipeline {
CROWDIN = credentials('forge-crowdin')
}
steps {
sh './gradlew ${GRADLE_ARGS} :forge:publish -PcrowdinKey=${CROWDIN}'
withGradle {
sh './gradlew ${GRADLE_ARGS} publish -PcrowdinKey=${CROWDIN}'
}
}
}
}
@@ -91,9 +108,7 @@ pipeline {
always {
script {
archiveArtifacts artifacts: 'projects/forge/build/libs/**/*.*', fingerprint: true, onlyIfSuccessful: true, allowEmptyArchive: true
//junit 'build/test-results/*/*.xml'
//jacoco sourcePattern: '**/src/*/java'
if (env.CHANGE_ID == null) { // This is unset for non-PRs
discordSend(
title: "${DISCORD_PREFIX} Finished ${currentBuild.currentResult}",
+2 -16
View File
@@ -1,16 +1,2 @@
Minecraft Forge
Copyright (c) 2016-2019.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation version 2.1
of the License.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Minecraft Forge - Forge Development LLC
SPDX-License-Identifier: LGPL-2.1-only
-127
View File
@@ -1,127 +0,0 @@
# FML
Entrypoint : ```FMLServiceProvider.onLoad```
- Verify environment
-- Check all libraries are present: ```accesstransformer```, ```coremod```, ```deobfuscator```
-- Check versions are suitable: ```modlauncher```, ```accesstransformer```, ```coremod```, ```deobfuscator```
- Find deobfuscated and patched MC
-- If not found, trigger job to generate that (loaded later at FMLLaunchProvider.launch)
Injected arguments:
- ```mods``` : CSV list of mod files to load
- ```modlist``` : JSON formatted list of mod files in a maven-like repository format
Entrypoint : ```FMLServiceProvider.initializer```
- Setup paths
-- ```mods``` folder
-- ```config``` folder
- FML config file read (JSON?)
- Trigger initial loading
Entrypoint : ```FMLLaunchProvider.launch```
- Launches the patched and deobfuscated game
- - If that wasn't found it'll be generated from the vanilla jar and patch/deobf files (see above)
- Possible we'll use an alternative launch for the development environment
(A goal is that we pre-generate this JAR during forge installation or modpack installation)
## Loading
- First we discover all mods
- - IModLocator instances present in system are found and queried to compile a master list of all mod artifacts of the three types
- LANGPROVIDERs are added to the supported language system : IModLanguageProvider
- The MODS from the list have their META-INF/mods.json file queried for mod instances to load
- - MODS are cross-referenced for their language being available
- - MODS are cross-referenced for their libraries being available
- - MODS are cross-referenced for their MOD dependencies being available
- - MODS with META-INF/coremods.json specification are loaded into the COREMOD system
- - MODS with META-INF/accesstransformer.json are loaded into the ACCESSTRANSFORMER system
- - MODS are enqueued to the background loading system
- FMLLaunchProvider will be triggered from the ModLauncher to start the game
## Game loading
- Events triggered from loadGame will launch various phases of modloading as before
-- Deprecation of old "FML" events in favour of Forge events
-- If a mod hasn't completed scanning there might be a pause waiting for it to complete before loading (testing indicates this should be a very rare occurrence and isn't worse than existing status quo where all scanning and loading is on-thread)
### ```IModLocator```
Finds mods from various sources of various types
manifest is queried for type: FMLModType
- MOD : this file will be scanned as a mod. This is default if nothing is present
- LIBRARY : this file will be added to the classpath and no further processing is done
- LANGPROVIDER : this file will be loaded as a language provider
#### ```ModsFolderLocator```
- scans for jar files from mods folder
-- able to load all types
-- loads in all environments
-- maybe able to do runtime name transformation for dev time?
Standard mechanism to find and load mods
#### ```ExplodedDirectoryLocator```
- loads a directory as a mod
-- only able to load mods
-- should only load in dev env
Intended as a mechanism to allow development of mods easily by pointing at a compiled output directory
#### ```ArgumentModsLocator``` : NYI
- loads mods from the arguments on the command line
-- able to load all types
-- loads in all environments
### ```IModLanguageProvider```
Provides mod and language provider services
- Provides a means to transform a Mod File (from the IModLocator) into a list of modcontainer objects based on mods.json
- Scanning work will be done in background threads
- Language providers can be provided as JARs via the modlocator for ease of distribution
#### ```FMLModLanguageProvider```
This is the standard Java @Mod implementation provider
- provided by default (always supported)
- All scanning for @Mod will be done in the background thread
#### ```ScalaModLanguageProvider```
This is the scala language provider. It'll be provided separately as a JAR mod download.
- API contract will need definition
Other languages? Kotlin? Alternative Scala versions? Javascript?
## Coremods
Coremods are now forcefully separated into _injection_ and _runtime_ phases.
### Injection
Injection is the act of intercepting the loading of a class and modifying the inbound class with alterations such as additions, replacements and deletions
Injections will be written using Javascript. Two functions are required: a function providing the list of injection sites, and the function to transform the injection site.
All injection sites will need to be pre-specified by the coremod in their metadata. Lookup services should be provided in the Javascript API.
Javascript API for common coremod injection tasks needs to be developed, to allow common best-practice tooling for these complex tasks.
Runtime coremod code (code that has been injected) is Java as usual.
## Background loading thread
Early in loading, a background thread is triggered which will perform scanning tasks for common resources, such as @Mod instances and other annotations. This thread will also be responsible for loading any cached resources, either those defined at build time or pre-computed from previous runs. It may also be tasked with writing those precomputed resources.
There will be a IPreLoaderJobProvider that will allow extension of the scope of these tasks
-37
View File
@@ -1,37 +0,0 @@
# How to install Forge: For Players
Go to [the Forge website](http://files.minecraftforge.net)
and select the minecraft version you wish to get forge for from the list.
You can download the installer for the *Recommended Build* or the
*Latest build* there. Latest builds may have newer features but may be
more unstable as a result. The installer will attempt to install forge
into your vanilla launcher environment, where you can then create a new
profile using that version and play the game!
For support and questions, visit [the Support Forum](http://www.minecraftforge.net/forum/forum/18-support-bug-reports/).
Here is a short video from Rorax showing how to install and setup Forge:
[![HOWTO Install Forge](https://img.youtube.com/vi/lB3ArN_-3Oc/0.jpg)](https://www.youtube.com/watch?v=lB3ArN_-3Oc)
# How to install Forge: For Modders
[See the "Getting Started" section in the Forge Documentation](http://mcforge.readthedocs.io/en/latest/gettingstarted/).
# How to install Forge: For those wishing to work on Forge itself
If you wish to actually inspect Forge, submit PRs or otherwise work
with Forge itself, you're in the right place!
[See the guide to setting up a Forge workspace](http://mcforge.readthedocs.io/en/latest/forgedev/).
## Pull requests
[See the "Making Changes and Pull Requests" section in the Forge documentation](http://mcforge.readthedocs.io/en/latest/forgedev/#making-changes-and-pull-requests).
### Contributor License Agreement
We require all contributors to acknowledge the [Forge Contributor
License Agreement](https://cla-assistant.io/MinecraftForge/MinecraftForge). Please ensure you have a valid email address
associated with your github account to do this. If you have previously
signed it, you should be OK.
+1459 -961
View File
File diff suppressed because it is too large. Load diff
+3
View File
@@ -0,0 +1,3 @@
/.gradle/
/build/
/out/
+9
View File
@@ -0,0 +1,9 @@
repositories {
maven { url = 'https://maven.minecraftforge.net/' }
mavenCentral()
}
dependencies {
implementation 'org.ow2.asm:asm:9.1'
implementation 'org.ow2.asm:asm-tree:9.1'
implementation 'net.minecraftforge:srgutils:0.4.+'
}
@@ -0,0 +1,64 @@
package net.minecraftforge.forge.tasks
import groovy.json.JsonBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.ClassReader
import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.FieldNode
import org.objectweb.asm.tree.MethodNode
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
abstract class BytecodeFinder extends DefaultTask {
@InputFile abstract RegularFileProperty getJar()
@OutputFile abstract RegularFileProperty getOutput()
BytecodeFinder() {
output.convention(project.layout.buildDirectory.dir(name).map { it.file("output.json") })
}
@TaskAction
protected void exec() {
Util.init()
def outputFile = output.get().asFile
if (outputFile.exists())
outputFile.delete()
pre()
jar.get().asFile.withInputStream { i ->
new ZipInputStream(i).withCloseable { zin ->
ZipEntry zein
while ((zein = zin.nextEntry) != null) {
if (zein.name.endsWith('.class')) {
def node = new ClassNode(Opcodes.ASM9)
new ClassReader(zin).accept(node, 0)
process(node)
}
}
}
}
post()
outputFile.text = new JsonBuilder(getData()).toPrettyString()
}
protected process(ClassNode node) {
if (node.fields != null) node.fields.each { process(node, it) }
if (node.methods != null) node.methods.each { process(node, it) }
}
protected pre() {}
protected process(ClassNode parent, FieldNode node) {}
protected process(ClassNode parent, MethodNode node) {}
protected post() {}
protected abstract Object getData()
}
@@ -0,0 +1,267 @@
package net.minecraftforge.forge.tasks
import net.minecraftforge.srgutils.IMappingFile
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.Opcodes
abstract class CheckATs extends DefaultTask {
@InputFile abstract RegularFileProperty getInheritance()
@InputFiles abstract ConfigurableFileCollection getAts()
@InputFile @Optional abstract RegularFileProperty getMappings()
@TaskAction
protected void exec() {
def mappings = mappings.map { IMappingFile.load(it.asFile) }.getOrNull()
Util.init()
def parse = { line ->
def idx = line.indexOf('#')
def comment = idx == -1 ? null : line.substring(idx)
if (idx != -1) line = line.substring(0, idx - 1)
def (modifier, cls, desc) = (line.trim() + ' ').split(' ', -1)
def key = cls + (desc.isEmpty() ? '' : ' ' + desc)
return [modifier, cls, desc, comment, key]
}
def accessLevel = { access ->
if ((access & Opcodes.ACC_PUBLIC) != 0) return 3
if ((access & Opcodes.ACC_PROTECTED) != 0) return 2
if ((access & Opcodes.ACC_PRIVATE) != 0) return 0
return 1
}
def accessStr = { access ->
if (access.endsWith('-f') || access.endsWith('+f'))
return 4
switch (access.toLowerCase()) {
case 'public': return 3
case 'protected': return 2
case 'default': return 1
case 'private': return 0
default: return -1
}
}
def json = inheritance.get().asFile.json()
ats.each { f ->
TreeMap lines = [:]
def group = null
for (def line : f.readLines()) {
if (line.isEmpty()) continue
if (line.startsWith('#group ')) {
def (modifier, cls, desc, comment, key) = parse.call(line.substring(7))
if (desc != '*' && desc != '*()' && desc != '<init>')
throw new IllegalStateException('Invalid group: ' + line)
group = [modifier: modifier, cls: cls, desc: desc, comment: comment,
existing: [] as Set,
children: [] as TreeSet,
group: true
]
if (lines.containsKey(key))
throw new IllegalStateException('Duplicate group: ' + line)
lines[key] = group
} else if (group != null) {
if (line.startsWith('#endgroup')) {
group = null
} else {
def (modifier, cls, desc, comment, key) = parse.call(line)
group['existing'].add(key)
}
} else if (line.startsWith('#endgroup')) {
throw new IllegalStateException('Invalid group ending: ' + line)
} else if (line.startsWith('#')) {
//Nom
} else {
def (modifier, cls, desc, comment, key) = parse.call(line)
if (lines.containsKey(key)) {
println('Duplicate: ' + line)
continue
}
lines[key] = [modifier: modifier, cls: cls, desc: desc, comment: comment, group: false]
}
}
// Process Groups, this will remove any entries outside the group that is covered by the group
for (def key : new ArrayList<>(lines.keySet())) {
def entry = lines.get(key)
if (entry != null && entry['group']) {
def cls = entry['cls']
def jcls = json.get(cls.replaceAll('\\.', '/'))
if (jcls == null) {
lines.remove(key)
println('Invalid Group: ' + key)
} else if ('*' == entry['desc']) {
if (!jcls.containsKey('fields')) {
lines.remove(key)
println('Invalid Group, Class has no fields: ' + key)
} else {
jcls['fields'].each { field, value ->
def fkey = cls + ' ' + field
if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) {
if (lines.containsKey(fkey)) {
lines.remove(fkey)
} else if (!entry['existing'].contains(fkey)) {
println('Added: ' + fkey)
}
entry['children'].add(fkey)
} else if (lines.containsKey(fkey)) {
lines.remove(fkey)
println('Removed: ' + fkey)
}
}
entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) }
}
} else if ('*()' == entry['desc']) {
if (!jcls.containsKey('methods')) {
lines.remove(key)
println('Invalid Group, Class has no methods: ' + key)
} else {
jcls['methods'].each{ mtd, value ->
if (mtd.startsWith('<clinit>') || mtd.startsWith('lambda$'))
return
key = cls + ' ' + mtd.replace(' ', '')
if (accessLevel.call(value['access']) < accessStr.call(entry['modifier'])) {
if (lines.containsKey(key)) {
lines.remove(key)
} else if (!entry['existing'].contains(key)) {
println('Added: ' + key)
}
entry['children'].add(key)
} else if (lines.containsKey(key)) {
lines.remove(key)
println('Removed: ' + key)
}
}
entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) }
}
} else if ('<init>' == entry['desc']) { //Make all public non-abstract subclasses
json.each{ tcls,value ->
if (!value.containsKey('methods') || ((value['access'] & Opcodes.ACC_ABSTRACT) != 0))
return
def parents = [] as Set
def parent = tcls
while (parent != null && json.containsKey(parent)) {
parents.add(parent)
def p = json[parent]
parent = p == null ? null : p['superName']
}
if (parents.contains(cls.replaceAll('\\.', '/'))) {
value['methods'].each{ mtd, v ->
if (mtd.startsWith('<init>')) {
def child = tcls.replaceAll('/', '\\.') + ' ' + mtd.replace(' ', '')
if (accessLevel.call(v['access']) < 3) {
if (lines.containsKey(child)) {
lines.remove(child)
} else if (!entry['existing'].contains(child)) {
println('Added: ' + child)
}
entry['children'].add(child)
} else if (lines.containsKey(child)) {
lines.remove(child)
println('Removed: ' + child)
}
}
}
}
}
entry['existing'].stream().findAll{ !entry['children'].contains(it) }.each{ println('Removed: ' + it) }
}
}
}
// Process normal lines, remove invalid and remove narrowing
for (def key : new ArrayList<>(lines.keySet())) {
def entry = lines.get(key)
if (entry != null && !entry['group']) {
def cls = entry['cls']
def jcls = json.get(cls.replaceAll('\\.', '/'))
if (jcls == null) {
lines.remove(key)
println('Invalid: ' + key)
} else if (entry['desc'] == '') {
if (accessLevel.call(jcls['access']) > accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
lines.remove(key)
println('Invalid Narrowing: ' + key)
}
} else if (!entry['desc'].contains('(')) {
if (!jcls.containsKey('fields') || !jcls['fields'].containsKey(entry['desc'])) {
lines.remove(key)
println('Invalid: ' + key)
} else {
def value = jcls['fields'][entry['desc']]
if (accessLevel.call(value['access']) > accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
lines.remove(key)
println('Invalid Narrowing: ' + key)
println(entry.comment)
}
}
} else {
def jdesc = entry['desc'].replace('(', ' (')
if (!jcls.containsKey('methods') || !jcls['methods'].containsKey(jdesc)) {
lines.remove(key)
println('Invalid: ' + key)
} else {
def value = jcls['methods'][jdesc]
if (accessLevel.call(value['access']) > accessStr.call(entry['modifier']) && (entry.comment == null || !entry.comment.startsWith('#force '))) {
lines.remove(key)
println('Invalid Narrowing: ' + key)
}
}
}
}
}
def data = []
def remapComment = { entry ->
if (!mappings || !entry || !entry.desc) return null
def comment = entry.comment?.substring(1)?.trim()
def jsonCls = json.get(entry.cls.replaceAll('\\.', '/'))
def mappingsClass = mappings?.getClass(jsonCls.name)
if (!mappingsClass) return entry.comment
def idx = entry.desc.indexOf('(')
def mappedName = idx == -1
? mappingsClass.remapField(entry.desc)
: mappingsClass.remapMethod(entry.desc.substring(0, idx), entry.desc.substring(idx))
if (!mappedName) return entry.comment
if (mappedName == '<init>')
mappedName = 'constructor'
if (comment?.startsWith(mappedName))
return '# ' + comment
if (comment && comment.indexOf(' ') != -1) {
def split = comment.split(" - ").toList()
if (split[0].indexOf(' ') != -1)
// The first string is more than one word, so append before it
return "# ${mappedName} - ${comment}"
split.remove(0)
return "# ${mappedName} - ${String.join(' - ', split)}"
}
return '# ' + mappedName
}
lines.each { key,value ->
if (!value.group) {
def comment = remapComment.call(value)
data.add(value.modifier + ' ' + key + (comment ? ' ' + comment : ''))
} else {
data.add('#group ' + value.modifier + ' ' + key + (value.comment == null ? '' : ' ' + value.comment))
value.children.each {
def line = value.modifier + ' ' + it
def (modifier, cls, desc, comment) = parse.call(line)
comment = remapComment.call([modifier: modifier, cls: cls, desc: desc, comment: comment])
data.add(line + (comment ? ' ' + comment : ''))
}
data.add('#endgroup')
}
}
f.text = data.join('\n')
}
}
}
@@ -0,0 +1,94 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
abstract class CheckExcs extends DefaultTask {
@InputFile abstract RegularFileProperty getBinary()
@InputFiles abstract ConfigurableFileCollection getExcs()
@TaskAction
protected void exec() {
Util.init()
def known = []
binary.get().asFile.withInputStream { i ->
new ZipInputStream(i).withCloseable { zin ->
def visitor = new ClassVisitor(Opcodes.ASM9) {
private String cls
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
this.cls = name
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
known.add(this.cls + '.' + name + descriptor)
super.visitMethod(access, name, descriptor, signature, exceptions)
}
}
ZipEntry zein
while ((zein = zin.nextEntry) != null) {
if (zein.name.endsWith('.class')) {
ClassReader reader = new ClassReader(zin)
reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES)
}
}
}
}
excs.each { f ->
def lines = []
f.eachLine { line ->
def idx = line.indexOf('#')
if (idx == 0 || line.isEmpty()) {
return
}
def comment = idx == -1 ? null : line.substring(idx)
if (idx != -1) line = line.substring(0, idx - 1)
if (!line.contains('=')) {
println('Invalid: ' + line)
return
}
def (key, value) = line.split('=', 2)
if (!known.contains(key)) {
println('Unknown: ' + line)
return
}
def (cls, desc) = key.split('\\.', 2)
if (!desc.contains('(')) {
println('Invalid: ' + line)
return
}
def name = desc.split('\\(', 2)[0]
desc = '(' + desc.split('\\(', 2)[1]
def (exceptions, args) = value.contains('|') ? value.split('|', 2) : [value, '']
if (args.split(',').length != Type.getArgumentTypes(desc).length) {
println('Invalid: ' + line)
return
}
lines.add(line)
}
f.text = lines.sort().join('\n')
}
}
}
@@ -0,0 +1,219 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.TaskAction
import java.nio.file.Files
import java.nio.file.Paths
import java.util.regex.Pattern
abstract class CheckPatches extends DefaultTask {
@InputDirectory abstract DirectoryProperty getPatchDir()
@Input boolean autoFix = false
@TaskAction
protected void exec() {
def hasS2SArtifact = [
Paths.get("patches/minecraft/net/minecraft/client/renderer/ViewArea.java.patch"),
Paths.get("patches/minecraft/net/minecraft/data/models/blockstates/Variant.java.patch")
]
def verified = true;
patchDir.get().asFileTree.each { patch ->
def patchPath = project.rootDir.toPath().relativize(patch.toPath())
verified &= verifyPatch(patch, autoFix, patchPath.toString(), hasS2SArtifact.contains(patchPath))
}
if (!verified)
throw new RuntimeException('One or more patches failed verification. Check the log for errors.')
}
def verifyPatch(patch, fix, patchPath, hasS2SArtifact) {
def hunk_start_pattern = Pattern.compile('^@@ -[0-9,]* \\+[0-9,_]* @@$')
def white_space_pattern = Pattern.compile('^[+\\-]\\s*$')
def import_pattern = Pattern.compile('^[+\\-]\\s*import.*')
def field_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^=;]*)(=.*)?;\\s*$')
def method_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final)?([^(]*)[(]([^)]*)?[)]\\s*[{]\\s*$')
def class_pattern = Pattern.compile('^[+\\-][\\s]*((public|protected|private)[\\s]*)?(static[\\s]*)?(final[\\s]*)?(class|interface)([^{]*)[{]\\s*$')
def accessMap = [("private"):0, (null):1, ("protected"):2, ("public"):3]
def hasProblem = false;
def lines = patch.readLines()
def hunksStart = 0
def onlyWhiteSpace = false
def didFix = false
def newLines = []
def whiteSpaceErrors = []
// First two lines are file name ++/-- and we do not care
newLines.add(lines[0] + '\n')
newLines.add(lines[1] + '\n')
int i = 2
for (; i < lines.size(); ++i) {
def line = lines[i]
newLines.add(line + '\n')
if (hunk_start_pattern.matcher(line).find()) {
if (onlyWhiteSpace) {
if (fix || hasS2SArtifact) {
logger.lifecycle("Removing white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath)
def toRemove = i - hunksStart;
while (toRemove-- > 0)
newLines.remove(newLines.size() - 1)
didFix = true
}
else {
logger.lifecycle("Patch contains only white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath)
hasProblem = true
}
}
else {
if (!whiteSpaceErrors.empty)
hasProblem = true
whiteSpaceErrors.each { error -> logger.lifecycle(error) }
whiteSpaceErrors.clear()
}
hunksStart = i
onlyWhiteSpace = true
continue
}
if (line.startsWithAny('+','-')) {
def prefixChange = false
def prevLine = lines[i - 1]
if (line.charAt(0) == (char)'+' && prevLine.charAt(0) == (char)'-') {
def prevTrim = prevLine.substring(1).replaceAll("\\s", "")
def currTrim = line.substring(1).replaceAll("\\s", "")
if (prevTrim.equals(currTrim)) {
prefixChange = true
}
def pMatcher = field_pattern.matcher(prevLine)
def cMatcher = field_pattern.matcher(line)
if (pMatcher.find() && cMatcher.find() &&
pMatcher.group(6) == cMatcher.group(6) && // = ...
pMatcher.group(5) == cMatcher.group(5) && // field name
pMatcher.group(3) == cMatcher.group(3) && // static
(accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) {
logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath)
hasProblem = true
}
pMatcher = method_pattern.matcher(prevLine)
cMatcher = method_pattern.matcher(line)
if (pMatcher.find() && cMatcher.find() &&
pMatcher.group(6) == cMatcher.group(6) && // params
pMatcher.group(5) == cMatcher.group(5) && // <T> void name
pMatcher.group(3) == cMatcher.group(3) && // static
(accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) {
logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath)
hasProblem = true
}
pMatcher = class_pattern.matcher(prevLine)
cMatcher = class_pattern.matcher(line)
if (pMatcher.find() && cMatcher.find() &&
pMatcher.group(6) == cMatcher.group(6) && // ClassName<> extends ...
pMatcher.group(5) == cMatcher.group(5) && // class | interface
pMatcher.group(3) == cMatcher.group(3) && // static
(accessMap[pMatcher.group(2)] < accessMap[cMatcher.group(2)] || pMatcher.group(4) != cMatcher.group(4))) {
logger.lifecycle("Patch contains access changes or final removal at line {}, file: {}", i + 1, patchPath)
hasProblem = true
}
}
if (line.charAt(0) == (char)'-' && i + 1 < lines.size()) {
def nextLine = lines[i + 1]
if (nextLine.charAt(0) == (char)'+') {
def nextTrim = nextLine.substring(1).replaceAll("\\s", "")
def currTrim = line.substring(1).replaceAll("\\s", "")
if (nextTrim.equals(currTrim)) {
prefixChange = true
}
}
}
def isWhiteSpaceChange = white_space_pattern.matcher(line).find()
if (!prefixChange && !isWhiteSpaceChange) {
onlyWhiteSpace = hasS2SArtifact && import_pattern.matcher(line).find()
}
else if (isWhiteSpaceChange) {
def prevLineChange = prevLine.startsWithAny('+','-')
def nextLineChange = i + 1 < lines.size() && lines[i + 1].startsWithAny('+','-')
if (!prevLineChange && !nextLineChange) {
whiteSpaceErrors.add(String.format("Patch contains white space change in valid hunk at line %d (cannot auto fix), file: %s", i + 1, patchPath))
}
}
if (line.contains("\t")) {
if (!fix) {
logger.lifecycle("Patch contains tabs on line {}, file: {}", i + 1, patchPath)
hasProblem = true
}
else {
logger.lifecycle("Fixing tabs on line {}, file: {}", i + 1, patchPath)
line = line.replaceAll('\t', ' ')
newLines.remove(newLines.size() - 1)
newLines.add(line + '\n')
didFix = true
}
}
if (import_pattern.matcher(line).find() && !hasS2SArtifact) {
logger.lifecycle("Patch contains import change on line {}, file: {}", i + 1, patchPath)
hasProblem = true
}
}
}
if (onlyWhiteSpace) {
if (fix || hasS2SArtifact) {
logger.lifecycle("Removing white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath)
def toRemove = i - hunksStart;
while (toRemove-- > 0)
newLines.remove(newLines.size() - 1)
didFix = true
}
else {
logger.lifecycle("Patch contains only white space hunk starting at line {}, file: {}", hunksStart + 1, patchPath)
hasProblem = true
}
}
else {
if (!whiteSpaceErrors.empty)
hasProblem = true
whiteSpaceErrors.each { error -> logger.lifecycle(error) }
}
if (didFix) {
if (newLines.size() <= 2) {
logger.lifecycle("Patch is now empty removing, file: {}", patchPath)
Files.delete(patch.toPath())
}
else {
if (!hasS2SArtifact)
logger.lifecycle("*** Updating patch file. Please run setup then genPatches again. ***")
patch.withWriter('UTF-8') { writer ->
newLines.each { l -> writer.write(l) }
}
}
}
return !hasProblem
}
}
@@ -0,0 +1,63 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
abstract class CheckSAS extends DefaultTask {
@InputFile abstract RegularFileProperty getInheritance()
@InputFiles abstract ConfigurableFileCollection getSass()
@TaskAction
protected void exec() {
Util.init()
def json = inheritance.get().asFile.json()
sass.each { f ->
def lines = []
f.eachLine { line ->
if (line[0] == '\t') return //Skip any tabbed lines, those are ones we add
def idx = line.indexOf('#')
if (idx == 0 || line.isEmpty()) {
lines.add(line)
return
}
def comment = idx == -1 ? null : line.substring(idx)
if (idx != -1) line = line.substring(0, idx - 1)
def (cls, desc) = (line.trim() + ' ').split(' ', -1)
cls = cls.replaceAll('\\.', '/')
desc = desc.replace('(', ' (')
if (json[cls] == null || (!desc.isEmpty() && (json[cls]['methods'] == null || json[cls]['methods'][desc] == null))) {
println('Invalid: ' + line)
return
}
//Class SAS
if (desc.isEmpty()) {
lines.add(cls + (comment == null ? '' : ' ' + comment))
if (json[cls]['methods'] != null)
(json[cls]['methods'] as TreeMap).each {
findChildMethods(json, cls, it.key).each { lines.add('\t' + it) }
}
return
}
//Method SAS
lines.add(cls + ' ' + desc.replace(' ', '') + (comment == null ? '' : ' ' + comment))
findChildMethods(json, cls, desc).each { lines.add('\t' + it) }
}
f.text = lines.join('\n')
}
}
protected static findChildMethods(json, cls, desc)
{
return json.values().findAll{ it.methods != null && it.methods[desc] != null && it.methods[desc].override == cls}
.collect { it.name + ' ' + desc.replace(' ', '') } as TreeSet
}
}
@@ -0,0 +1,31 @@
package net.minecraftforge.forge.tasks
import java.util.function.BiConsumer
public class ClosureHelper {
BiConsumer<String, Closure> callback
public ClosureHelper(Closure cl, BiConsumer<String, Closure> callback) {
this.callback = callback
apply(this, cl)
}
def methodMissing(String name, Object args) {
if (!args.class.isArray()) return
Object[] aargs = (Object[])args
if (aargs.length == 1 && aargs[0] instanceof Closure) {
this.callback.accept(name, (Closure)aargs[0])
} else {
throw new IllegalArgumentException('Unknown method: "' + name + '" with arguments ' + args + ' for ' + this)
}
}
static <T> T apply(T obj, Closure cl) {
cl.delegate = obj
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
return obj
}
}
@@ -0,0 +1,73 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
abstract class Crowdin extends DefaultTask {
@Input abstract Property<String> getId()
@Input @Optional abstract Property<String> getKey()
@Input boolean json = true
@OutputFile abstract RegularFileProperty getOutput()
@OutputFile abstract RegularFileProperty getExport()
Crowdin() {
outputs.upToDateWhen{ false }
id.convention('minecraft-forge')
output.convention(project.layout.buildDirectory.dir(name).map {it.file("output.zip") })
export.convention(project.layout.buildDirectory.dir(name).map {it.file("export.json") })
}
@TaskAction
def run() {
File outputFile = output.get().asFile
File exportFile = export.get().asFile
if (outputFile.exists())
outputFile.delete()
if (!key.isPresent())
return
String key = this.key.get()
String id = this.id.get()
// Force an export
new URL("https://api.crowdin.com/api/project/${id}/export?key=${key}").withInputStream { i ->
exportFile.withOutputStream { it << i }
}
if (!exportFile.text.contains('success')) {
throw new RuntimeException("Crowdin export failed, see ${exportFile} for more info")
}
new URL("https://api.crowdin.com/api/project/${id}/download/all.zip?key=${key}").withInputStream { i ->
new ZipInputStream(i).withCloseable { zin ->
outputFile.withOutputStream { out ->
new ZipOutputStream(out).withCloseable { zout ->
ZipEntry zein
while ((zein = zin.nextEntry) != null) {
if (zein.isDirectory()) {
zout.putNextEntry(new ZipEntry(zein.name))
} else {
// 1.13+ uses json
if (zein.name.endsWith('.json') == json) {
ZipEntry zeout = new ZipEntry(json ? zein.name.toLowerCase() : zein.name)
zeout.time = 1
zout.putNextEntry(zeout)
zout << zin
}
}
}
}
}
}
}
}
}
@@ -0,0 +1,54 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.OutputDirectory
import java.nio.file.Files
abstract class DownloadLibraries extends DefaultTask {
@InputFile abstract RegularFileProperty getInput()
@OutputDirectory abstract DirectoryProperty getOutput()
@OutputFile abstract RegularFileProperty getLibrariesOutput()
DownloadLibraries() {
output.convention(project.layout.buildDirectory.dir(name))
librariesOutput.convention(project.layout.buildDirectory.dir(name).map(d -> d.file('libraries.txt')))
}
@TaskAction
def run() {
Util.init()
File outputDir = output.get().asFile
def libraries = new ArrayList()
def json = input.get().asFile.json().libraries.each { lib ->
//TODO: Thread?
def artifacts = [lib.downloads.artifact] + lib.downloads.get('classifiers', [:]).values()
artifacts.each{ art ->
def target = new File(outputDir, art.path)
libraries.add(target.absolutePath)
if (!target.exists() || !art.sha1.equals(target.sha1())) {
project.logger.lifecycle("Downloading ${art.url}")
if (!target.parentFile.exists()) {
target.parentFile.mkdirs()
}
new URL(art.url).withInputStream { i ->
target.withOutputStream { it << i }
}
if (!art.sha1.equals(target.sha1())) {
throw new IllegalStateException("Failed to download ${art.url} to ${target.canonicalPath} SHA Mismatch")
}
}
}
}
Files.write(librariesOutput.get().asFile.toPath(), libraries)
}
}
@@ -0,0 +1,109 @@
package net.minecraftforge.forge.tasks
import groovy.transform.EqualsAndHashCode
import java.util.ArrayList
import java.util.HashMap
import java.util.TreeMap
import java.util.TreeSet
import java.util.function.BiConsumer
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.*
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.FieldNode
import org.objectweb.asm.tree.MethodNode
import static org.objectweb.asm.Opcodes.*
abstract class FieldCompareFinder extends BytecodeFinder {
@Nested
Map<String, Search> fields = [:] as HashMap
@Internal
Map<Search, String> fieldsReverse = [:] as HashMap
@Internal
Map<String, Set<ObjectTarget>> targets = [:] as TreeMap
@Override
protected pre() {
//fields.each{ k,v -> logger.lifecycle("Fields: " + k + ' ' + v) }
}
@Override
protected process(ClassNode parent, MethodNode node) {
def last = null
def parentInstance = new ObjectTarget(owner: parent.name, name: '', desc: '')
for (int x = 0; x < node.instructions.size(); x++) {
def current = node.instructions.get(x)
if (current.opcode == IF_ACMPEQ || current.opcode == IF_ACMPNE) {
if (last != null && (last.opcode == GETSTATIC || last.opcode == GETFIELD)) {
def target = new Search(cls: last.owner, name: last.name)
def wanted = fieldsReverse.get(target)
def original = fields.get(wanted)
def instance = new ObjectTarget(owner: parent.name, name: node.name, desc: node.desc)
if (wanted != null && (original.blacklist == null || (!original.blacklist.contains(instance) && !original.blacklist.contains(parentInstance)))) {
targets.computeIfAbsent(wanted, { k -> new TreeSet() }).add(instance)
}
}
}
last = current
}
}
@Internal
@Override
protected Object getData() {
def ret = [:] as HashMap
targets.forEach{ k, v ->
def e = fields.get(k)
ret[k] = [
cls: e.cls,
name: e.name,
replacement: e.replacement,
targets: v
]
}
return ret
}
@EqualsAndHashCode(excludes = ['replacement', 'blacklist'])
public static class Search {
@Input
String cls
@Input
String name
@Input
String replacement
@Nested
@Optional
Set<ObjectTarget> blacklist
@Override
String toString() {
return cls + '.' + name
}
def blacklist(def owner, def name, def desc) {
if (blacklist == null)
blacklist = new HashSet()
blacklist.add(new ObjectTarget(owner: owner, name: name, desc: desc))
}
def blacklist(def owner) {
blacklist(owner, '', '')
}
}
def fields(Closure cl) {
new ClosureHelper(cl, {name, ccl ->
def search = ClosureHelper.apply(new Search(), ccl)
this.fields.put(name, search)
this.fieldsReverse.put(search, name)
})
}
}
@@ -0,0 +1,44 @@
package net.minecraftforge.forge.tasks
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.tasks.*
import org.gradle.api.provider.SetProperty
abstract class InstallerJar extends Zip {
@Input @Optional abstract SetProperty<String> getPackedDependencies()
InstallerJar() {
archiveClassifier.set('installer')
archiveExtension.set('jar') // Needs to be Zip task to not override Manifest, so set extension
destinationDirectory.set(project.layout.buildDirectory.dir('libs'))
def installerJson = project.tasks.installerJson
def launcherJson = project.tasks.launcherJson
def downloadInstaller = project.tasks.downloadInstaller
dependsOn(installerJson, launcherJson, downloadInstaller)
from(installerJson, launcherJson)
from(project.rootProject.file('/src/main/resources/url.png'))
project.afterEvaluate {
from(project.zipTree(downloadInstaller.output)) {
duplicatesStrategy = 'exclude'
}
if (!System.env.MAVEN_USER) {
dependsOn(project.universalJar)
from(project.universalJar) {
into '/maven/' + project.group.replace('.', '/') + '/' + project.universalJar.archiveBaseName.get() + '/' + project.version + '/'
}
packedDependencies.get().forEach {
def jarTask = project.rootProject.getTasks().findByPath(it)
dependsOn(jarTask)
from(jarTask) {
into '/maven/' + jarTask.project.group.replace('.', '/') + '/' + jarTask.archiveBaseName.get() + '/' + jarTask.project.version + '/'
}
}
}
}
}
}
@@ -0,0 +1,81 @@
package net.minecraftforge.forge.tasks
import groovy.json.JsonBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
import java.nio.file.Files
abstract class InstallerJson extends DefaultTask {
@OutputFile abstract RegularFileProperty getOutput()
@InputFiles abstract ConfigurableFileCollection getInput()
@Input @Optional abstract SetProperty<String> getPackedDependencies()
@Input @Optional final Map<String, Object> libraries = new LinkedHashMap<>()
@Input Map<String, Object> json = new LinkedHashMap<>()
@InputFile abstract RegularFileProperty getIcon()
@Input abstract Property<String> getLauncherJsonName()
@Input abstract Property<String> getLogo()
@Input abstract Property<String> getMirrors()
@Input abstract Property<String> getWelcome()
InstallerJson() {
getLauncherJsonName().convention('/version.json')
getLogo().convention('/big_logo.png')
getMirrors().convention('https://files.minecraftforge.net/mirrors-2.0.json')
getWelcome().convention("Welcome to the simple ${project.name.capitalize()} installer.")
getOutput().convention(project.layout.buildDirectory.file('install_profile.json'))
['client', 'server'].each { side ->
['slim', 'extra'].each { type ->
def tsk = project.tasks.getByName("download${side.capitalize()}${type.capitalize()}")
dependsOn(tsk)
input.from(tsk.output)
}
def tsk = project.tasks.getByName("create${side.capitalize()}SRG")
dependsOn(tsk)
input.from(tsk.output)
}
project.afterEvaluate {
(packedDependencies.get().collect{ project.rootProject.tasks.findByPath(it) } + [project.universalJar]).forEach {
dependsOn(it)
input.from it.archiveFile
}
}
}
@TaskAction
protected void exec() {
def libs = libraries
for (def child : packedDependencies.get().collect{ project.rootProject.tasks.findByPath(it) } + [project.universalJar]) {
def dep = Util.getMavenDep(child)
def path = Util.getMavenPath(child)
libs.put(dep.toString(), [
name: dep,
downloads: [
artifact: [
path: path,
url: "https://maven.minecraftforge.net/${path}",
sha1: child.archiveFile.get().asFile.sha1(),
size: child.archiveFile.get().asFile.length()
]
]
])
}
json.libraries = libs.values().sort{a,b -> a.name.compareTo(b.name)}
json.icon = "data:image/png;base64," + new String(Base64.getEncoder().encode(Files.readAllBytes(icon.get().asFile.toPath())))
json.json = launcherJsonName.get()
json.logo = logo.get()
if (!mirrors.get().isEmpty())
json.mirrorList = mirrors.get()
json.welcome = welcome.get()
Files.writeString(output.get().getAsFile().toPath(), new JsonBuilder(json).toPrettyString())
}
}
@@ -0,0 +1,74 @@
package net.minecraftforge.forge.tasks
import groovy.json.JsonBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
import java.nio.file.Files
import static net.minecraftforge.forge.tasks.Util.getArtifacts
import static net.minecraftforge.forge.tasks.Util.iso8601Now
abstract class LauncherJson extends DefaultTask {
@OutputFile abstract RegularFileProperty getOutput()
@InputFiles abstract ConfigurableFileCollection getInput()
@Input Map<String, Object> json = new LinkedHashMap<>()
@Input @Optional abstract SetProperty<String> getPackedDependencies()
@Internal final vanilla = project.project(':mcp').file('build/mcp/downloadJson/version.json')
@Internal final timestamp = iso8601Now()
@Internal final comment = [
"Please do not automate the download and installation of Forge.",
"Our efforts are supported by ads from the download page.",
"If you MUST automate this, please consider supporting the project through https://www.patreon.com/LexManos/"
]
@Internal final id = "${project.rootProject.ext.MC_VERSION}-${project.name}${project.version.substring(project.rootProject.ext.MC_VERSION.length())}"
LauncherJson() {
getOutput().convention(project.layout.buildDirectory.file('version.json'))
dependsOn(':fmlloader:jar', 'universalJar')
getInput().from(project.tasks.universalJar.archiveFile,
project.project(':fmlloader').jar.archiveFile,
vanilla)
project.afterEvaluate {
packedDependencies.get().forEach {
def jarTask = project.rootProject.tasks.findByPath(it)
dependsOn(jarTask)
input.from jarTask.archiveFile
}
}
}
@TaskAction
protected void exec() {
if (!json.libraries)
json.libraries = []
def libs = [:]
getArtifacts(project, project.configurations.installer, false).each { key, lib -> libs[key] = lib }
getArtifacts(project, project.configurations.moduleonly, false).each { key, lib -> libs[key] = lib }
packedDependencies.get().collect{ project.rootProject.tasks.findByPath(it) }.forEach {
def path = Util.getMavenPath(it)
def key = Util.getMavenDep(it)
libs[key] = [
name: key,
downloads: [
artifact: [
path: path,
url: "https://maven.minecraftforge.net/${path}",
sha1: it.archiveFile.get().asFile.sha1(),
size: it.archiveFile.get().asFile.length()
]
]
]
}
libs.each { key, lib -> json.libraries.add(lib) }
Files.writeString(output.get().asFile.toPath(), new JsonBuilder(json).toPrettyString())
}
}
@@ -0,0 +1,32 @@
package net.minecraftforge.forge.tasks
import groovy.transform.EqualsAndHashCode
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.Optional
@EqualsAndHashCode
public class ObjectTarget implements Comparable<ObjectTarget> {
@Input
String owner
@Input
String name
@Input
@Optional
String desc
@Override
String toString() {
if (desc == null)
return owner + '.' + name
return owner + '.' + name + desc
}
@Override
int compareTo(ObjectTarget o) {
return toString().compareTo(o.toString())
}
}
@@ -0,0 +1,145 @@
package net.minecraftforge.forge.tasks
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import java.io.File
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.Date
public class Util {
static void init() {
File.metaClass.sha1 = { ->
MessageDigest md = MessageDigest.getInstance('SHA-1')
delegate.eachByte 4096, {bytes, size ->
md.update(bytes, 0, size)
}
return md.digest().collect {String.format "%02x", it}.join()
}
File.metaClass.getSha1 = { !delegate.exists() ? null : delegate.sha1() }
File.metaClass.json = { -> new JsonSlurper().parseText(delegate.text) }
File.metaClass.getJson = { return delegate.exists() ? new JsonSlurper().parse(delegate) : [:] }
File.metaClass.setJson = { json -> delegate.text = new JsonBuilder(json).toPrettyString() }
Date.metaClass.iso8601 = { ->
def format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
def result = format.format(delegate)
return result[0..21] + ':' + result[22..-1]
}
String.metaClass.rsplit = { String del, int limit = -1 ->
def lst = new ArrayList()
def x = 0, idx
def tmp = delegate
while ((idx = tmp.lastIndexOf(del)) != -1 && (limit == -1 || x++ < limit)) {
lst.add(0, tmp.substring(idx + del.length(), tmp.length()))
tmp = tmp.substring(0, idx)
}
lst.add(0, tmp)
return lst
}
}
public static String[] getClasspath(project, libs, artifact) {
def ret = []
artifactTree(project, artifact).each { key, lib ->
libs[lib.name] = lib
if (lib.name != artifact)
ret.add(lib.name)
}
return ret
}
public static def getArtifacts(project, config, classifiers) {
def ret = [:]
config.resolvedConfiguration.resolvedArtifacts.each {
def art = [
group: it.moduleVersion.id.group,
name: it.moduleVersion.id.name,
version: it.moduleVersion.id.version,
classifier: it.classifier,
extension: it.extension,
file: it.file
]
def key = art.group + ':' + art.name
def folder = "${art.group.replace('.', '/')}/${art.name}/${art.version}/"
def filename = "${art.name}-${art.version}"
if (art.classifier != null)
filename += "-${art.classifier}"
filename += ".${art.extension}"
def path = "${folder}${filename}"
def url = "https://libraries.minecraft.net/${path}"
if (!checkExists(url)) {
url = "https://maven.minecraftforge.net/${path}"
}
//TODO remove when Mojang launcher is updated
if (!classifiers && art.classifier != null) {
//Mojang launcher doesn't currently support classifiers, so... move it to part of the version, and force the extension to 'jar'
// However, keep the path normal so that our mirror system works.
art.version = "${art.version}-${art.classifier}"
art.classifier = null
art.extension = 'jar'
}
ret[key] = [
name: "${art.group}:${art.name}:${art.version}" + (art.classifier == null ? '' : ":${art.classifier}") + (art.extension == 'jar' ? '' : "@${art.extension}"),
downloads: [
artifact: [
path: path,
url: url,
sha1: sha1(art.file),
size: art.file.length()
]
]
]
}
return ret
}
public static def getMavenPath(task) {
def classifier = task.archiveClassifier.get()
def dep = "${task.project.group}:${task.project.name}:${task.project.version}" + (classifier == '' ? '' : ':' + classifier)
return "${task.project.group.replace('.', '/')}/${task.project.name}/${task.project.version}/${task.project.name}-${task.project.version}".toString() + (classifier == '' ? '' : '-' + classifier) + '.jar'
}
public static def getMavenDep(task) {
def classifier = task.archiveClassifier.get()
return "${task.project.group}:${task.project.name}:${task.project.version}" + (classifier == '' ? '' : ':' + classifier)
}
public static def iso8601Now() { new Date().iso8601() }
public static def sha1(file) {
MessageDigest md = MessageDigest.getInstance('SHA-1')
file.eachByte 4096, {bytes, size ->
md.update(bytes, 0, size)
}
return md.digest().collect {String.format "%02x", it}.join()
}
private static def artifactTree(project, artifact) {
if (!project.ext.has('tree_resolver'))
project.ext.tree_resolver = 1
def cfg = project.configurations.create('tree_resolver_' + project.ext.tree_resolver++)
def dep = project.dependencies.create(artifact)
cfg.dependencies.add(dep)
def files = cfg.resolve()
return getArtifacts(project, cfg, true)
}
private static boolean checkExists(url) {
try {
def code = new URL(url).openConnection().with {
requestMethod = 'HEAD'
connect()
responseCode
}
return code == 200
} catch (Exception e) {
if (e.toString().contains('unable to find valid certification path to requested target'))
throw new RuntimeException('Failed to connect to ' + url + ': Missing certificate root authority, try updating java')
throw e
}
}
}
+18
View File
@@ -0,0 +1,18 @@
Contributing to Forge
=====================
1) Keep patches to Minecraft classes minimal. If you need a lot of things done, you may either add to relevant forge classes or make a new class.
2) An example mod must be provided for all PRs adding events/hooks to Forge. Whether it's a full mod using your proposed hooks, or just a pastebin containing a simple example, an example mod is required. Please also explain in detail what your new hook does.
3) Follow Forge coding guidelines (braces on newlines, spaces instead of tabs, etc)
For more information, refer to [the wiki](https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge)
Contributor License Agreement
=============================
- You grant Forge a license to use your code contributed to the primary codebase (everything **not** under patches) in Forge, under the LGPLv2.1 license.
- You assign copyright ownership of your contributions to the patches codebase (everything under patches) to Forge, where it will be licensed under the LGPLv2.1 license.
"Forge" is Forge Development LLC, a legally incorporated entity in Oregon, USA.
+65
View File
@@ -0,0 +1,65 @@
![Forge Logo](assets/Forge_logo.svg)
MinecraftForge
=============
[![Stable Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Stable&prefix=1.18-&query=$.promos["1.18-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)](https://files.minecraftforge.net)
[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=1.18-&query=$.promos["1.18-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
)](https://files.minecraftforge.net) [![Discord](https://img.shields.io/discord/313125603924639766.svg?color=%237289da&label=Discord&logo=discord&logoColor=%237289da)](https://discord.gg/UvedJ9m) [![Support](https://img.shields.io/badge/Patreon-Support-orange.svg?logo=Patreon)](https://www.patreon.com/LexManos)
Forge is a free, open-source modding API all of your favourite mods use!
| Version | Support |
| ------------- | ------------- |
| 1.18.x | Active |
| 1.16.x | LTS |
* [Download]
* [Forum]
* [Discord]
* [Documentation]
# Installing Forge
Go to [the Forge website](https://files.minecraftforge.net)
and select the Minecraft version you wish to get Forge for from the list.
You can download the installer for the *Recommended Build* or the
*Latest build* there. Latest builds may have newer features but may be
more unstable as a result. The installer will attempt to install Forge
into your vanilla launcher environment, where you can then create a new
profile using that version and play the game!
For support and questions, visit [the Support Forum](https://www.minecraftforge.net/forum/forum/18-support-bug-reports/).
[Here is a short video from Rorax showing how to install and setup Forge.](https://www.youtube.com/watch?v=lB3ArN_-3Oc)
# Creating Mods
[See the "Getting Started" section in the Forge Documentation](https://mcforge.readthedocs.io/en/latest/gettingstarted/).
# Contribute to Forge
If you wish to actually inspect Forge, submit PRs or otherwise work
with Forge itself, you're in the right place!
[See the guide to setting up a Forge workspace](http://mcforge.readthedocs.io/en/latest/forgedev/).
### Pull requests
[See the "Making Changes and Pull Requests" section in the Forge documentation](https://mcforge.readthedocs.io/en/latest/forgedev/#making-changes-and-pull-requests).
Please read the contributing guidelines found [here](CONTRIBUTING.md) before making a pull request.
### Contributor License Agreement
We require all contributors to acknowledge the [Forge Contributor
License Agreement](https://cla-assistant.io/MinecraftForge/MinecraftForge). Please ensure you have a valid email address
associated with your GitHub account to do this. If you have previously
signed it, you should be OK.
#### Donate
*Forge is a large project with many collaborators working on it around the clock. Forge is and will always remain free to use and modify. However, it costs money to run such a large project as this, so please consider [becoming a patron](https://www.patreon.com/LexManos).*
[Download]: https://files.minecraftforge.net/
[Forum]: https://www.minecraftforge.net/forum/
[Discord]: https://discord.gg/UvedJ9m
[Documentation]: https://mcforge.readthedocs.io
View File
File renamed without changes.
+7
View File
@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="164.072 372.466 294.41 46.56">
<g fill="#DFA86A">
<path d="M266.16 417.99h10.96v-16.94h17.97v-10.27h-17.97v-7.01h19.06V373.5h-30.02zM337.33 378.7c-2.103-2.057-4.629-3.64-7.51-4.704-2.743-1.015-5.786-1.528-9.041-1.528l-.356.002c-3.362 0-6.503.556-9.338 1.651-2.857 1.106-5.357 2.707-7.434 4.761-2.073 2.052-3.714 4.559-4.877 7.45-1.158 2.876-1.748 6.104-1.748 9.59 0 3.417.59 6.582 1.753 9.403 1.163 2.829 2.807 5.297 4.88 7.329 2.073 2.03 4.572 3.621 7.425 4.724 2.834 1.096 5.975 1.651 9.339 1.651h.023c3.402-.043 6.57-.639 9.42-1.772 2.863-1.142 5.375-2.757 7.465-4.804 2.091-2.051 3.742-4.524 4.91-7.358 1.162-2.823 1.75-5.987 1.75-9.402 0-3.487-.588-6.705-1.748-9.568-1.168-2.874-2.82-5.371-4.913-7.425zm-4.644 16.762c0 1.96-.302 3.782-.896 5.413-.587 1.607-1.42 3.011-2.479 4.167-1.05 1.147-2.335 2.065-3.821 2.728-1.479.656-3.164.99-5.008.99-1.84 0-3.514-.333-4.973-.988-1.47-.662-2.747-1.578-3.799-2.729-1.062-1.156-1.895-2.559-2.479-4.167-.595-1.63-.896-3.451-.896-5.413 0-1.801.298-3.497.887-5.044.584-1.536 1.419-2.894 2.479-4.037 1.048-1.132 2.323-2.03 3.792-2.674 1.465-.642 3.145-.968 4.988-.968 1.848 0 3.539.326 5.025.971 1.481.643 2.766 1.541 3.812 2.671 1.062 1.143 1.896 2.501 2.479 4.036.589 1.548.889 3.245.889 5.044zM376.27 395.65c1.902-2.327 2.867-5.221 2.867-8.603 0-2.614-.508-4.84-1.506-6.613-.997-1.762-2.354-3.188-4.035-4.234-1.603-.995-3.445-1.705-5.482-2.114-1.938-.388-3.969-.583-6.037-.583h-16.021v44.487h10.961v-17.282h2.35l9.447 17.282h13.127l-11.199-18.646c2.262-.728 4.116-1.964 5.528-3.694zm-19.254-12.223h4.426c.844 0 1.73.054 2.636.16.784.094 1.503.283 2.132.568.496.225.888.553 1.193.998.283.415.428 1.031.428 1.836 0 .931-.16 1.643-.459 2.06-.34.472-.771.813-1.32 1.046-.686.289-1.459.477-2.301.554-.975.089-1.963.136-2.938.136h-3.795l-.002-7.358z"/>
<path d="M394.82 386.38c1.05-1.132 2.325-2.03 3.793-2.674 1.464-.642 3.144-.968 4.988-.968 1.843 0 3.611.311 5.26.921 1.609.599 2.992 1.449 4.107 2.531l1.314 1.278 8.019-8.105-1.454-1.298c-2.355-2.103-5.066-3.586-8.058-4.407-2.879-.789-5.987-1.189-9.247-1.189-3.361 0-6.503.556-9.339 1.651-2.856 1.106-5.355 2.707-7.431 4.761-2.074 2.052-3.716 4.559-4.88 7.45-1.158 2.876-1.746 6.104-1.746 9.59 0 3.417.59 6.582 1.752 9.403 1.164 2.829 2.807 5.297 4.88 7.329 2.073 2.03 4.572 3.621 7.425 4.724 2.832 1.096 5.975 1.651 9.339 1.651 6.501 0 12.475-1.432 17.751-4.25l.979-.522v-23.814h-19.313v10.27h8.354v6.639c-.871.397-1.834.709-2.881.933-1.5.314-3.127.478-4.83.478-1.841 0-3.514-.333-4.973-.988-1.472-.662-2.748-1.578-3.801-2.729-1.06-1.156-1.893-2.559-2.478-4.167-.595-1.63-.896-3.451-.896-5.413 0-1.801.299-3.497.887-5.044.586-1.54 1.421-2.897 2.479-4.041zM437.69 407.72v-7.36h18.72v-10.27h-18.72v-6.32h19.75V373.5h-30.72v44.49h31.76v-10.27z"/>
</g>
<path fill="#1E2D41" d="m243.63 379.09-37.842-1.852 46.229-.034v-3.727h-52.125l-.001 7.798v6.201c0 .115-1.52-9.144-1.87-11.734h-4.098v13.029c0 .123-1.753-10.888-1.939-12.264H164.07c1.902 1.648 12.401 10.598 19.865 14.28 3.741 1.846 8.33 1.86 12.414 1.974 2.075.06 4.25.217 5.803 1.754 2.255 2.236 2.758 5.704.814 8.33-1.922 2.594-7.335 3.156-7.335 3.156l-4.509 5.531v6.424h10.251l.319-6.348 8.863-6.285c-.946.757-3.058 2.783-6.229 7.666-.717 1.102-1.275 2.306-1.711 3.49 2.238-1.896 6.84-3.194 12.153-3.194 5.307 0 9.903 1.295 12.146 3.188-.437-1.185-.994-2.385-1.709-3.483-3.172-4.883-5.284-6.909-6.229-7.666l8.863 6.285.32 6.348h9.565v-6.424l-4.507-5.531s-6.675-.425-8.423-3.156c-5.032-7.869 2.115-20.082 18.836-23.756z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

+64
View File
@@ -0,0 +1,64 @@
plugins {
id 'com.github.ben-manes.versions'
id 'org.javamodularity.moduleplugin' version '1.8.3' apply false
}
apply plugin: 'java-library'
apply plugin: 'jacoco'
apply plugin: 'org.javamodularity.moduleplugin'
dependencyUpdates.rejectVersionIf { isNonStable(it.candidate.version) }
dependencies {
compileOnly('org.jetbrains:annotations:21.0.1')
implementation(project(':fmlloader'))
api('net.minecraftforge:eventbus:5.0.+')
implementation('commons-io:commons-io:2.5')
}
task sourcesJar(type: Jar) {
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
ext {
MANIFESTS = [
'': [
'FMLModType': 'LIBRARY',
'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'Git-Commit': GIT_INFO.abbreviatedId,
'Git-Branch': GIT_INFO.branch,
'Build-Number': "${System.getenv('BUILD_NUMBER')?:0}"
] as LinkedHashMap,
'net/minecraftforge/fml/loading/': [
'Specification-Title': 'FMLLoader',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': '1',
'Implementation-Title': 'FML Loader',
'Implementation-Version': '1.0',
'Implementation-Vendor': 'Forge'
] as LinkedHashMap
]
}
jar.doFirst {
MANIFESTS.each { pkg, values ->
if (pkg == '')
manifest.attributes(values)
else
manifest.attributes(values, pkg)
}
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:unchecked'
}
artifacts {
archives jar
archives sourcesJar
}
publishing.publications.mavenJava(MavenPublication) {
from components.java
artifact sourcesJar
}
@@ -0,0 +1,35 @@
package net.minecraftforge.fml;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.config.IConfigEvent;
import net.minecraftforge.fml.loading.FMLLoader;
import java.util.ServiceLoader;
import java.util.function.Supplier;
public class Bindings {
private static final Bindings INSTANCE = new Bindings();
private final IBindingsProvider provider;
private Bindings() {
final var providers = ServiceLoaderUtils.streamServiceLoader(()->ServiceLoader.load(FMLLoader.getGameLayer(), IBindingsProvider.class), sce->{}).toList();
if (providers.size() != 1) {
throw new IllegalStateException("Could not find bindings provider");
}
this.provider = providers.get(0);
}
public static Supplier<IEventBus> getForgeBus() {
return INSTANCE.provider.getForgeBusSupplier();
}
public static Supplier<I18NParser> getMessageParser() {
return INSTANCE.provider.getMessageParser();
}
public static Supplier<IConfigEvent.ConfigConfig> getConfigConfiguration() {
return INSTANCE.provider.getConfigConfiguration();
}
}
@@ -0,0 +1,32 @@
package net.minecraftforge.fml;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
public class CrashReportCallables {
private static final List<ISystemReportExtender> crashCallables = Collections.synchronizedList(new ArrayList<>());
public static void registerCrashCallable(ISystemReportExtender callable)
{
crashCallables.add(callable);
}
public static void registerCrashCallable(String headerName, Supplier<String> reportGenerator) {
registerCrashCallable(new ISystemReportExtender() {
@Override
public String getLabel() {
return headerName;
}
@Override
public String get() {
return reportGenerator.get();
}
});
}
public static List<ISystemReportExtender> allCrashCallables() {
return List.copyOf(crashCallables);
}
}
@@ -0,0 +1,101 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import static net.minecraftforge.fml.Logging.LOADING;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import com.google.common.base.Stopwatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Utility for running code on the main launch thread at the next available
* opportunity. There is no guaranteed order that work from various mods will be
* run, but your own work will be run sequentially.
* <p>
* <strong>Use of this class after startup is not possible.</strong> At that
* point, {@code ReentrantBlockableEventLoop} should be used instead.
* <p>
* Exceptions from tasks will be handled gracefully, causing a mod loading
* error. Tasks that take egregiously long times to run will be logged.
*/
public class DeferredWorkQueue
{
private static final Logger LOGGER = LogManager.getLogger();
private static final Map<ModLoadingStage, DeferredWorkQueue> workQueues = new HashMap<>();
private final ConcurrentLinkedDeque<TaskInfo> tasks = new ConcurrentLinkedDeque<>();
private final ModLoadingStage modLoadingStage;
public DeferredWorkQueue(ModLoadingStage modLoadingStage) {
this.modLoadingStage = modLoadingStage;
workQueues.put(modLoadingStage, this);
}
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public static Optional<DeferredWorkQueue> lookup(Optional<ModLoadingStage> parallelClass) {
return Optional.ofNullable(workQueues.get(parallelClass.orElse(null)));
}
public void runTasks() {
if (tasks.isEmpty()) return;
LOGGER.debug(LOADING, "Dispatching synchronous work for work queue {}: {} jobs", modLoadingStage, tasks.size());
Stopwatch timer = Stopwatch.createStarted();
tasks.forEach(t->makeRunnable(t, Runnable::run));
timer.stop();
LOGGER.debug(LOADING, "Synchronous work queue completed in {}", timer);
}
private static void makeRunnable(TaskInfo ti, Executor executor) {
executor.execute(() -> {
Stopwatch timer = Stopwatch.createStarted();
ModLoadingContext.get().setActiveContainer(ti.owner);
try {
ti.task.run();
} finally {
ModLoadingContext.get().setActiveContainer(null);
}
timer.stop();
if (timer.elapsed(TimeUnit.SECONDS) >= 1) {
LOGGER.warn(LOADING, "Mod '{}' took {} to run a deferred task.", ti.owner.getModId(), timer);
}
});
}
public CompletableFuture<Void> enqueueWork(final ModContainer modInfo, final Runnable work) {
return CompletableFuture.runAsync(work, r->tasks.add(new TaskInfo(modInfo, r)));
}
public <T> CompletableFuture<T> enqueueWork(final ModContainer modInfo, final Supplier<T> work) {
return CompletableFuture.supplyAsync(work, r->tasks.add(new TaskInfo(modInfo, r)));
}
record TaskInfo(ModContainer owner, Runnable task) {}
}
@@ -0,0 +1,276 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLEnvironment;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
/**
* Use to execute code conditionally based on sidedness.
* <ul>
* <li>When you want to call something on one side and return a result {@link #safeCallWhenOn(Dist, Supplier)}</li>
* <li>When you want to call one thing on one side, another thing on the other and return a result {@link #safeRunForDist(Supplier, Supplier)}</li>
* <li>When you want to run something on one side {@link #safeRunWhenOn(Dist, Supplier)}</li>
* </ul>
*/
public final class DistExecutor
{
private static final Logger LOGGER = LogManager.getLogger();
private DistExecutor() {}
/**
* Run the callable in the supplier only on the specified {@link Dist}.
* This method is NOT sided-safe and special care needs to be taken in code using this method that implicit class
* loading is not triggered by the Callable.
*
* This method can cause unexpected ClassNotFound exceptions.
*
* Use {@link #safeCallWhenOn(Dist, Supplier)} where possible.
*
* @param dist The dist to run on
* @param toRun A supplier of the callable to run (Supplier wrapper to ensure classloading only on the appropriate dist)
* @param <T> The return type from the callable
* @return The callable's result
* @deprecated use {@link #safeCallWhenOn(Dist, Supplier)} instead. This remains for advanced use cases.
*/
@Deprecated
public static <T> T callWhenOn(Dist dist, Supplier<Callable<T>> toRun) {
return unsafeCallWhenOn(dist, toRun);
}
public static <T> T unsafeCallWhenOn(Dist dist, Supplier<Callable<T>> toRun) {
if (dist == FMLEnvironment.dist) {
try
{
return toRun.get().call();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
return null;
}
/**
* Call the SafeCallable when on the correct {@link Dist}.
*
* <strong>The lambda supplied here is required to be a method reference to a method defined in
* another class, otherwise an invalid SafeReferent error will be thrown</strong>
* @param dist the dist which this will run on
* @param toRun the SafeCallable to run and return the result from
* @param <T> The type of the SafeCallable
* @return the result of the SafeCallable or null if on the wrong side
*/
public static <T> T safeCallWhenOn(Dist dist, Supplier<SafeCallable<T>> toRun) {
validateSafeReferent(toRun);
return callWhenOn(dist, toRun::get);
}
/**
* Runs the supplied Runnable on the speicified side. Same warnings apply as {@link #callWhenOn(Dist, Supplier)}.
*
* This method can cause unexpected ClassNotFound exceptions.
*
* @see #callWhenOn(Dist, Supplier)
* @param dist Dist to run this code on
* @param toRun The code to run
* @deprecated use {@link #safeRunWhenOn(Dist, Supplier)} where possible. Advanced uses only.
*/
@Deprecated
public static void runWhenOn(Dist dist, Supplier<Runnable> toRun) {
unsafeRunWhenOn(dist, toRun);
}
/**
* Runs the supplied Runnable on the speicified side. Same warnings apply as {@link #unsafeCallWhenOn(Dist, Supplier)}.
*
* This method can cause unexpected ClassNotFoundException problems in common scenarios. Understand the pitfalls of
* the way the class verifier works to load classes before using this.
*
* Use {@link #safeRunWhenOn(Dist, Supplier)} if you can.
*
* @see #unsafeCallWhenOn(Dist, Supplier)
* @param dist Dist to run this code on
* @param toRun The code to run
*/
public static void unsafeRunWhenOn(Dist dist, Supplier<Runnable> toRun) {
if (dist == FMLEnvironment.dist) {
toRun.get().run();
}
}
/**
* Call the supplied SafeRunnable when on the correct Dist.
* @param dist The dist to run on
* @param toRun The code to run
*/
public static void safeRunWhenOn(Dist dist, Supplier<SafeRunnable> toRun) {
validateSafeReferent(toRun);
if (dist == FMLEnvironment.dist) {
toRun.get().run();
}
}
/**
* Executes one of the two suppliers, based on which side is active.
*
* <p>
* Example (replacement for old SidedProxy):<br/>
* {@code Proxy p = DistExecutor.runForDist(()->ClientProxy::new, ()->ServerProxy::new);}
*
* NOTE: the double supplier is required to avoid classloading the secondary target.
*
* @param clientTarget The supplier supplier to run when on the {@link Dist#CLIENT}
* @param serverTarget The supplier supplier to run when on the {@link Dist#DEDICATED_SERVER}
* @param <T> The common type to return
* @return The returned instance
* @deprecated Use {@link #safeRunForDist(Supplier, Supplier)}
*/
@Deprecated
public static <T> T runForDist(Supplier<Supplier<T>> clientTarget, Supplier<Supplier<T>> serverTarget) {
return unsafeRunForDist(clientTarget, serverTarget);
}
/**
* Unsafe version of {@link #safeRunForDist(Supplier, Supplier)}. Use only when you know what you're doing
* and understand why the verifier can cause unexpected ClassNotFoundException crashes even when code is apparently
* not sided. Ensure you test both sides fully to be confident in using this.
*
* @param clientTarget The supplier supplier to run when on the {@link Dist#CLIENT}
* @param serverTarget The supplier supplier to run when on the {@link Dist#DEDICATED_SERVER}
* @param <T> The common type to return
* @return The returned instance
*/
public static <T> T unsafeRunForDist(Supplier<Supplier<T>> clientTarget, Supplier<Supplier<T>> serverTarget) {
switch (FMLEnvironment.dist)
{
case CLIENT:
return clientTarget.get().get();
case DEDICATED_SERVER:
return serverTarget.get().get();
default:
throw new IllegalArgumentException("UNSIDED?");
}
}
/**
* Executes one of the two suppliers, based on which side is active.
*
* <p>
* Example (replacement for old SidedProxy):<br/>
* {@code Proxy p = DistExecutor.safeRunForDist(()->ClientProxy::new, ()->ServerProxy::new);}
*
* NOTE: the double supplier is required to avoid classloading the secondary target.
*
* @param clientTarget The supplier supplier to run when on the {@link Dist#CLIENT}
* @param serverTarget The supplier supplier to run when on the {@link Dist#DEDICATED_SERVER}
* @param <T> The common type to return
* @return The returned instance
*/
public static <T> T safeRunForDist(Supplier<SafeSupplier<T>> clientTarget, Supplier<SafeSupplier<T>> serverTarget) {
validateSafeReferent(clientTarget);
validateSafeReferent(serverTarget);
switch (FMLEnvironment.dist)
{
case CLIENT:
return clientTarget.get().get();
case DEDICATED_SERVER:
return serverTarget.get().get();
default:
throw new IllegalArgumentException("UNSIDED?");
}
}
/**
* A safe referent. This will assert that it is being called via a separated class method reference. This will
* avoid the common pitfalls of {@link #callWhenOn(Dist, Supplier)} above.
*
* SafeReferents assert that they are defined as a separate method outside the scope of the calling class.
*
* <strong>Implementations need to be defined in a separate class to the referring site, with appropriate
* visibility to be accessible at the callsite (generally, avoid private methods).</strong>
*
* <p>
* Valid:<br/>
*
* {@code DistExecutor.safeCallWhenOn(Dist.CLIENT, ()->AnotherClass::clientOnlyMethod);}
*
* <p>
* Invalid:<br/>
*
* {@code DistExecutor.safeCallWhenOn(Dist.CLIENT, ()->()->Minecraft.getInstance().world);}
*/
public interface SafeReferent {}
/**
* SafeCallable version of {@link SafeReferent}.
* @see SafeReferent
* @param <T> The return type of the Callable
*/
public interface SafeCallable<T> extends SafeReferent, Callable<T>, Serializable {}
/**
* SafeSupplier version of {@link SafeReferent}
* @param <T> The return type of the Supplier
*/
public interface SafeSupplier<T> extends SafeReferent, Supplier<T>, Serializable {}
/**
* SafeRunnable version of {@link SafeReferent}
*/
public interface SafeRunnable extends SafeReferent, Runnable, Serializable {}
private static final void validateSafeReferent(Supplier<? extends SafeReferent> safeReferentSupplier) {
if (FMLEnvironment.production) return;
final SafeReferent setter;
try {
setter = safeReferentSupplier.get();
} catch (Exception e) {
// Typically a class cast exception, just return out, expected.
return;
}
for (Class<?> cl = setter.getClass(); cl != null; cl = cl.getSuperclass()) {
try {
Method m = cl.getDeclaredMethod("writeReplace");
m.setAccessible(true);
Object replacement = m.invoke(setter);
if (!(replacement instanceof SerializedLambda))
break;// custom interface implementation
SerializedLambda l = (SerializedLambda) replacement;
if (Objects.equals(l.getCapturingClass(), l.getImplClass())) {
LOGGER.fatal("Detected unsafe referent usage, please view the code at {}",Thread.currentThread().getStackTrace()[3]);
throw new RuntimeException("Unsafe Referent usage found in safe referent method");
}
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException | InvocationTargetException e) {
break;
}
}
}
}
@@ -0,0 +1,6 @@
package net.minecraftforge.fml;
public interface I18NParser {
String parseMessage(String i18nMessage, Object... args);
String stripControlCodes(String toStrip);
}
@@ -0,0 +1,12 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.config.IConfigEvent;
import java.util.function.Supplier;
public interface IBindingsProvider {
Supplier<IEventBus> getForgeBusSupplier();
Supplier<I18NParser> getMessageParser();
Supplier<IConfigEvent.ConfigConfig> getConfigConfiguration();
}
Whitespace-only changes.
@@ -0,0 +1,62 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import java.util.function.BiPredicate;
import java.util.function.Supplier;
public interface IExtensionPoint<T extends Record>
{
/**
* Compatibility display test for the mod.
* Used for displaying compatibility with remote servers with the same mod, and on disk saves.
*
* The supplier provides my "local" version for sending across the impl or writing to disk
* The predicate tests the version from a remote instance or save for acceptability (Boolean is true for impl, false for local save)
* and returns true if the version is compatible.
*
* <p>Return {@code net.minecraftforge.impl.impl.FMLNetworkConstants#IGNORESERVERONLY} in the supplier, if you wish to be ignored
* as a server side only mod.</p>
* <p>Return true in the predicate for all values of the input string (when impl boolean is true) if you are client side,
* and don't care about matching any potential server version.</p>
*
* <p>
* Examples: A server only mod
* </p>
* <pre>{@code
* registerExtensionPoint(DISPLAYTEST, ()->Pair.of(
* ()->FMLNetworkConstants.IGNORESERVERONLY, // ignore me, I'm a server only mod
* (s,b)->true // i accept anything from the server or the save, if I'm asked
* )
* }</pre>
*
* <p>
* Examples: A client only mod
* </p>
* <pre>{@code
* registerExtensionPoint(DISPLAYTEST, ()->Pair.of(
* ()->"anything. i don't care", // if i'm actually on the server, this string is sent but i'm a client only mod, so it won't be
* (remoteversionstring,networkbool)->networkbool // i accept anything from the server, by returning true if it's asking about the server
* )
* }</pre>
*
*/
record DisplayTest(Supplier<String> suppliedVersion, BiPredicate<String, Boolean> remoteVersionTest) implements IExtensionPoint<DisplayTest> {}
}
@@ -0,0 +1,25 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
public interface IModLoadingState {
String name();
String previous();
ModLoadingPhase phase();
Function<ModList, String> message();
Optional<Consumer<ModList>> inlineRunnable();
default <T extends Event & IModBusEvent> Optional<CompletableFuture<List<Throwable>>> buildTransition(final Executor syncExecutor, final Executor parallelExecutor) {
return buildTransition(syncExecutor, parallelExecutor, e->CompletableFuture.runAsync(()->{}, e), e->CompletableFuture.runAsync(()->{}, e));
}
<T extends Event & IModBusEvent> Optional<CompletableFuture<List<Throwable>>> buildTransition(Executor syncExecutor, Executor parallelExecutor, Function<Executor, CompletableFuture<Void>> preSyncTask, Function<Executor, CompletableFuture<Void>> postSyncTask);
}
@@ -0,0 +1,7 @@
package net.minecraftforge.fml;
import java.util.List;
public interface IModStateProvider {
List<IModLoadingState> getAllStates();
}
@@ -0,0 +1,87 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
@SuppressWarnings("unchecked")
public interface IModStateTransition {
static IModStateTransition buildNoopTransition() {
return new NoopTransition();
}
default <T extends Event & IModBusEvent> CompletableFuture<List<Throwable>> build(Executor syncExecutor, Executor parallelExecutor, Function<Executor, CompletableFuture<Void>> preSyncTask, Function<Executor, CompletableFuture<Void>> postSyncTask) {
List<CompletableFuture<List<Throwable>>> cfs = new ArrayList<>();
this.eventFunctionStream().get()
.map(f->(EventGenerator<T>)f)
.reduce((head, tail)-> addCompletableFutureTaskForModDispatch(syncExecutor, parallelExecutor, cfs, head, ModLoadingStage::currentState, tail))
.ifPresent(last-> addCompletableFutureTaskForModDispatch(syncExecutor, parallelExecutor, cfs, last, nextModLoadingStage(), null));
final CompletableFuture<Void> preSyncTaskCF = preSyncTask.apply(syncExecutor);
final CompletableFuture<List<Throwable>> eventDispatchCF = ModList.gather(cfs).thenCompose(ModList::completableFutureFromExceptionList);
final CompletableFuture<List<Throwable>> postEventDispatchCF = preSyncTaskCF.thenComposeAsync(n -> eventDispatchCF, parallelExecutor).thenApply(r -> {
postSyncTask.apply(syncExecutor);
return r;
});
return this.finalActivityGenerator().apply(syncExecutor, postEventDispatchCF);
}
default BiFunction<ModLoadingStage, Throwable, ModLoadingStage> nextModLoadingStage() {
return ModLoadingStage::nextState;
}
private <T extends Event & IModBusEvent> EventGenerator<T> addCompletableFutureTaskForModDispatch(final Executor syncExecutor, final Executor parallelExecutor, final List<CompletableFuture<List<Throwable>>> completeableFutures, final EventGenerator<T> eventGenerator, BiFunction<ModLoadingStage, Throwable, ModLoadingStage> nextState, final EventGenerator<T> nextGenerator) {
completeableFutures.add(((BiFunction<Executor, EventGenerator<T>, CompletableFuture<List<Throwable>>>)preDispatchHook()).apply(threadSelector().apply(syncExecutor, parallelExecutor), eventGenerator));
completeableFutures.add(ModList.get().futureVisitor(eventGenerator, nextState).apply(threadSelector().apply(syncExecutor, parallelExecutor)));
completeableFutures.add(((BiFunction<Executor, EventGenerator<T>, CompletableFuture<List<Throwable>>>)postDispatchHook()).apply(threadSelector().apply(syncExecutor, parallelExecutor), eventGenerator));
return nextGenerator;
}
Supplier<Stream<EventGenerator<?>>> eventFunctionStream();
ThreadSelector threadSelector();
BiFunction<Executor, CompletableFuture<List<Throwable>>, CompletableFuture<List<Throwable>>> finalActivityGenerator();
BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<List<Throwable>>> preDispatchHook();
BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<List<Throwable>>> postDispatchHook();
interface EventGenerator<T extends Event & IModBusEvent> extends Function<ModContainer, T> {
static <FN extends Event & IModBusEvent> EventGenerator<FN> fromFunction(Function<ModContainer, FN> fn) {
return fn::apply;
}
}
}
record NoopTransition() implements IModStateTransition {
@Override
public Supplier<Stream<EventGenerator<?>>> eventFunctionStream() {
return Stream::of;
}
@Override
public ThreadSelector threadSelector() {
return ThreadSelector.SYNC;
}
@Override
public BiFunction<Executor, CompletableFuture<List<Throwable>>, CompletableFuture<List<Throwable>>> finalActivityGenerator() {
return (e, t) -> t.thenApplyAsync(Function.identity(), e);
}
@Override
public BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<List<Throwable>>> preDispatchHook() {
return (t, f)-> CompletableFuture.completedFuture(Collections.emptyList());
}
@Override
public BiFunction<Executor, ? extends EventGenerator<?>, CompletableFuture<List<Throwable>>> postDispatchHook() {
return (t, f)-> CompletableFuture.completedFuture(Collections.emptyList());
}
}
@@ -0,0 +1,27 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import java.util.function.Supplier;
public interface ISystemReportExtender extends Supplier<String>
{
String getLabel();
}
@@ -0,0 +1,178 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class InterModComms
{
public record IMCMessage(String senderModId, String modId, String method, Supplier<?> messageSupplier) {
/**
* Deprecated: use {@link #senderModId()}
* @return The modid of the sender. This is supplied by the caller, or by the active mod container context.
* Consider it unreliable.
*/
@Deprecated
public final String getSenderModId() {
return this.senderModId;
}
/**
* Deprecated: use {@link #modId()}
* @return The modid being sent to.
*/
@Deprecated
public final String getModId() {
return this.modId;
}
/**
* Deprecated: use {@link #method()}
* @return The method being sent to.
*/
@Deprecated
public final String getMethod() {
return this.method;
}
/**
* @param <T> The type of the message.
* @return A {@link Supplier} of the message.
* Use {@link #messageSupplier()}
*/
@SuppressWarnings("unchecked")
@Deprecated
public final <T> Supplier<T> getMessageSupplier() {
return (Supplier<T>) this.messageSupplier;
}
}
private static ConcurrentMap<String, ConcurrentLinkedQueue<IMCMessage>> containerQueues = new ConcurrentHashMap<>();
/**
* Send IMC to remote. Sender will default to the active modcontainer, or minecraft if not.
*
* @param modId the mod id to send to
* @param method the method name to send
* @param thing the thing associated with the method name
* @return true if the message was enqueued for sending (the target modid is loaded)
*/
public static boolean sendTo(final String modId, final String method, final Supplier<?> thing) {
if (!ModList.get().isLoaded(modId)) return false;
containerQueues.computeIfAbsent(modId, k->new ConcurrentLinkedQueue<>()).add(new IMCMessage(ModLoadingContext.get().getActiveContainer().getModId(), modId, method, thing));
return true;
}
/**
* Send IMC to remote.
*
* @param senderModId the mod id you are sending from
* @param modId the mod id to send to
* @param method the method name to send
* @param thing the thing associated with the method name
* @return true if the message was enqueued for sending (the target modid is loaded)
*/
public static boolean sendTo(final String senderModId, final String modId, final String method, final Supplier<?> thing) {
if (!ModList.get().isLoaded(modId)) return false;
containerQueues.computeIfAbsent(modId, k->new ConcurrentLinkedQueue<>()).add(new IMCMessage(senderModId, modId, method, thing));
return true;
}
/**
* Retrieve pending messages for your modid. Use the predicate to filter the method name.
*
* @param modId the modid you are querying for
* @param methodMatcher a predicate for the method you are interested in
* @return All messages passing the supplied method predicate
*/
public static Stream<IMCMessage> getMessages(final String modId, final Predicate<String> methodMatcher) {
ConcurrentLinkedQueue<IMCMessage> queue = containerQueues.get(modId);
if (queue == null) return Stream.empty();
return StreamSupport.stream(new QueueFilteringSpliterator(queue, methodMatcher), false);
}
/**
* Retrieve all message for your modid.
*
* @param modId the modid you are querying for
* @return All messages
*/
public static Stream<IMCMessage> getMessages(final String modId) {
return getMessages(modId, s->Boolean.TRUE);
}
private static class QueueFilteringSpliterator implements Spliterator<IMCMessage>
{
private final ConcurrentLinkedQueue<IMCMessage> queue;
private final Predicate<String> methodFilter;
private final Iterator<IMCMessage> iterator;
public QueueFilteringSpliterator(final ConcurrentLinkedQueue<IMCMessage> queue, final Predicate<String> methodFilter) {
this.queue = queue;
this.iterator = queue.iterator();
this.methodFilter = methodFilter;
}
@Override
public int characteristics() {
return Spliterator.CONCURRENT | Spliterator.NONNULL | Spliterator.ORDERED;
}
@Override
public long estimateSize() {
return queue.size();
}
@Override
public boolean tryAdvance(final Consumer<? super IMCMessage> action)
{
IMCMessage next;
do
{
if (!iterator.hasNext())
{
return false;
}
next = this.iterator.next();
}
while (!methodFilter.test(next.method));
action.accept(next);
this.iterator.remove();
return true;
}
@Override
public Spliterator<IMCMessage> trySplit() {
return null;
}
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,7 @@
package net.minecraftforge.fml;
import java.util.List;
import java.util.stream.Collectors;
public class LoadingFailedException extends RuntimeException {
private final List<ModLoadingException> loadingExceptions;
@@ -31,4 +32,9 @@ public class LoadingFailedException extends RuntimeException {
public List<ModLoadingException> getErrors() {
return this.loadingExceptions;
}
@Override
public String getMessage() {
return "Loading errors encountered: " + this.loadingExceptions.stream().map(ModLoadingException::getMessage).collect(Collectors.joining(",\n\t", "[\n\t", "\n]"));
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,12 +19,8 @@
package net.minecraftforge.fml;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.config.Configurator;
public class Logging
{
@@ -35,6 +31,7 @@ public class Logging
public static final Marker SPLASH = MarkerManager.getMarker("SPLASH");
public static final Marker CAPABILITIES = MarkerManager.getMarker("CAPABILITIES");
public static final Marker MODELLOADING = MarkerManager.getMarker("MODELLOADING");
public static final Marker FORGEMOD = MarkerManager.getMarker("FORGEMOD").addParents(LOADING);
// --log CORE:+DEBUG,SCAN:-OFF
// forge log debug 5
@@ -0,0 +1,41 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
public enum LogicalSide
{
CLIENT, SERVER;
/**
* @return if the logical side is a server.
*/
public boolean isServer()
{
return !isClient();
}
/**
* @return if the logical side is a client.
*/
public boolean isClient()
{
return this == CLIENT;
}
}
@@ -0,0 +1,170 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.config.IConfigEvent;
import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.forgespi.language.IModInfo;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* The container that wraps around mods in the system.
* <p>
* The philosophy is that individual mod implementation technologies should not
* impact the actual loading and management of mod code. This class provides
* a mechanism by which we can wrap actual mod code so that the loader and other
* facilities can treat mods at arms length.
* </p>
*
* @author cpw
*
*/
public abstract class ModContainer
{
protected final String modId;
protected final String namespace;
protected final IModInfo modInfo;
protected ModLoadingStage modLoadingStage;
protected Supplier<?> contextExtension;
protected final Map<ModLoadingStage, Runnable> activityMap = new HashMap<>();
protected final Map<Class<? extends IExtensionPoint<?>>, Supplier<?>> extensionPoints = new IdentityHashMap<>();
protected final EnumMap<ModConfig.Type, ModConfig> configs = new EnumMap<>(ModConfig.Type.class);
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
protected Optional<Consumer<IConfigEvent>> configHandler = Optional.empty();
public ModContainer(IModInfo info)
{
this.modId = info.getModId();
// TODO: Currently not reading namespace from configuration..
this.namespace = this.modId;
this.modInfo = info;
this.modLoadingStage = ModLoadingStage.CONSTRUCT;
// default displaytest extension checks for version string match
registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(()->this.modInfo.getVersion().toString(),
(incoming, isNetwork)->Objects.equals(incoming, this.modInfo.getVersion().toString())));
}
/**
* Errored container state, used for filtering. Does nothing.
*/
ModContainer()
{
this.modLoadingStage = ModLoadingStage.ERROR;
modId = "BROKEN";
namespace = "BROKEN";
modInfo = null;
}
/**
* @return the modid for this mod
*/
public final String getModId()
{
return modId;
}
/**
* @return the resource prefix for the mod
*/
public final String getNamespace()
{
return namespace;
}
/**
* @return The current loading stage for this mod
*/
public ModLoadingStage getCurrentState()
{
return modLoadingStage;
}
public static <T extends Event & IModBusEvent> CompletableFuture<Void> buildTransitionHandler(
final ModContainer target,
final IModStateTransition.EventGenerator<T> eventGenerator,
final BiFunction<ModLoadingStage, Throwable, ModLoadingStage> stateChangeHandler,
final Executor executor) {
return CompletableFuture
.runAsync(() -> {
ModLoadingContext.get().setActiveContainer(target);
target.activityMap.getOrDefault(target.modLoadingStage, ()->{}).run();
target.acceptEvent(eventGenerator.apply(target));
}, executor)
.whenComplete((mc, exception) -> {
target.modLoadingStage = stateChangeHandler.apply(target.modLoadingStage, exception);
ModLoadingContext.get().setActiveContainer(null);
});
}
public IModInfo getModInfo()
{
return modInfo;
}
@SuppressWarnings("unchecked")
public <T extends Record> Optional<T> getCustomExtension(Class<? extends IExtensionPoint<T>> point) {
return Optional.ofNullable((T)extensionPoints.getOrDefault(point,()-> null).get());
}
public <T extends Record & IExtensionPoint<T>> void registerExtensionPoint(Class<? extends IExtensionPoint<T>> point, Supplier<T> extension)
{
extensionPoints.put(point, extension);
}
public void addConfig(final ModConfig modConfig) {
configs.put(modConfig.getType(), modConfig);
}
public void dispatchConfigEvent(IConfigEvent event) {
configHandler.ifPresent(configHandler->configHandler.accept(event));
}
/**
* Does this mod match the supplied mod?
*
* @param mod to compare
* @return if the mod matches
*/
public abstract boolean matches(Object mod);
/**
* @return the mod object instance
*/
public abstract Object getMod();
/**
* Accept an arbitrary event for processing by the mod. Probably posted to an event bus in the lower level container.
* @param e Event to accept
*/
protected <T extends Event & IModBusEvent> void acceptEvent(T e) {}
}
@@ -0,0 +1,245 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2022.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.ModFileScanData;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Master list of all mods - game-side version. This is classloaded in the game scope and
* can dispatch game level events as a result.
*/
public class ModList
{
private static Logger LOGGER = LogManager.getLogger();
private static ModList INSTANCE;
private final List<IModFileInfo> modFiles;
private final List<IModInfo> sortedList;
private final Map<String, ModFileInfo> fileById;
private List<ModContainer> mods;
private Map<String, ModContainer> indexedMods;
private List<ModFileScanData> modFileScanData;
private ModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
{
this.modFiles = modFiles.stream().map(ModFile::getModFileInfo).map(ModFileInfo.class::cast).collect(Collectors.toList());
this.sortedList = sortedList.stream().
map(ModInfo.class::cast).
collect(Collectors.toList());
this.fileById = this.modFiles.stream().map(IModFileInfo::getMods).flatMap(Collection::stream).
map(ModInfo.class::cast).
collect(Collectors.toMap(ModInfo::getModId, ModInfo::getOwningFile));
CrashReportCallables.registerCrashCallable("Mod List", this::crashReport);
}
private String getModContainerState(String modId) {
return getModContainerById(modId).map(ModContainer::getCurrentState).map(Object::toString).orElse("NONE");
}
private String fileToLine(IModFile mf) {
return String.format(Locale.ENGLISH, "%-50.50s|%-30.30s|%-30.30s|%-20.20s|%-10.10s|Manifest: %s", mf.getFileName(),
mf.getModInfos().get(0).getDisplayName(),
mf.getModInfos().get(0).getModId(),
mf.getModInfos().get(0).getVersion(),
getModContainerState(mf.getModInfos().get(0).getModId()),
((ModFileInfo)mf.getModFileInfo()).getCodeSigningFingerprint().orElse("NOSIGNATURE"));
}
private String crashReport() {
return "\n"+applyForEachModFile(this::fileToLine).collect(Collectors.joining("\n\t\t", "\t\t", ""));
}
public static ModList of(List<ModFile> modFiles, List<ModInfo> sortedList)
{
INSTANCE = new ModList(modFiles, sortedList);
return INSTANCE;
}
public static ModList get() {
return INSTANCE;
}
private static ForkJoinWorkerThread newForkJoinWorkerThread(ForkJoinPool pool) {
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setName("modloading-worker-" + thread.getPoolIndex());
// The default sets it to the SystemClassloader, so copy the current one.
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
return thread;
}
public List<IModFileInfo> getModFiles()
{
return modFiles;
}
public IModFileInfo getModFileById(String modid)
{
return this.fileById.get(modid);
}
<T extends Event & IModBusEvent> Function<Executor, CompletableFuture<List<Throwable>>> futureVisitor(
final IModStateTransition.EventGenerator<T> eventGenerator,
final BiFunction<ModLoadingStage, Throwable, ModLoadingStage> stateChange) {
return executor -> gather(
this.mods.stream()
.map(mod -> ModContainer.buildTransitionHandler(mod, eventGenerator, stateChange, executor))
.collect(Collectors.toList()))
.thenComposeAsync(ModList::completableFutureFromExceptionList, executor);
}
static CompletionStage<List<Throwable>> completableFutureFromExceptionList(List<? extends Map.Entry<?, Throwable>> t) {
if (t.stream().noneMatch(e->e.getValue()!=null)) {
return CompletableFuture.completedFuture(Collections.emptyList());
} else {
final List<Throwable> throwables = t.stream().filter(e -> e.getValue() != null).map(Map.Entry::getValue).collect(Collectors.toList());
CompletableFuture<List<Throwable>> cf = new CompletableFuture<>();
final RuntimeException accumulator = new RuntimeException();
cf.completeExceptionally(accumulator);
throwables.forEach(exception -> {
if (exception instanceof CompletionException) {
exception = exception.getCause();
}
if (exception.getSuppressed().length!=0) {
Arrays.stream(exception.getSuppressed()).forEach(accumulator::addSuppressed);
} else {
accumulator.addSuppressed(exception);
}
});
return cf;
}
}
static <V> CompletableFuture<List<Map.Entry<V, Throwable>>> gather(List<? extends CompletableFuture<? extends V>> futures) {
List<Map.Entry<V, Throwable>> list = new ArrayList<>(futures.size());
CompletableFuture<?>[] results = new CompletableFuture[futures.size()];
futures.forEach(future -> {
int i = list.size();
list.add(null);
results[i] = future.whenComplete((result, exception) -> list.set(i, new AbstractMap.SimpleImmutableEntry<>(result, exception)));
});
return CompletableFuture.allOf(results).handle((r, th)->null).thenApply(res -> list);
}
void setLoadedMods(final List<ModContainer> modContainers)
{
this.mods = modContainers;
this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity()));
}
@SuppressWarnings("unchecked")
public <T> Optional<T> getModObjectById(String modId)
{
return getModContainerById(modId).map(ModContainer::getMod).map(o -> (T) o);
}
public Optional<? extends ModContainer> getModContainerById(String modId)
{
return Optional.ofNullable(this.indexedMods.get(modId));
}
public Optional<? extends ModContainer> getModContainerByObject(Object obj)
{
return mods.stream().filter(mc -> mc.getMod() == obj).findFirst();
}
public List<IModInfo> getMods()
{
return this.sortedList;
}
public boolean isLoaded(String modTarget)
{
return this.indexedMods.containsKey(modTarget);
}
public int size()
{
return mods.size();
}
public List<ModFileScanData> getAllScanData()
{
if (modFileScanData == null)
{
modFileScanData = this.sortedList.stream().
map(IModInfo::getOwningFile).
filter(Objects::nonNull).
map(IModFileInfo::getFile).
distinct().
map(IModFile::getScanResult).
collect(Collectors.toList());
}
return modFileScanData;
}
public void forEachModFile(Consumer<IModFile> fileConsumer)
{
modFiles.stream().map(IModFileInfo::getFile).forEach(fileConsumer);
}
public <T> Stream<T> applyForEachModFile(Function<IModFile, T> function) {
return modFiles.stream().map(IModFileInfo::getFile).map(function);
}
public void forEachModContainer(BiConsumer<String, ModContainer> modContainerConsumer) {
indexedMods.forEach(modContainerConsumer);
}
public <T> Stream<T> applyForEachModContainer(Function<ModContainer, T> function) {
return indexedMods.values().stream().map(function);
}
private static class UncaughtModLoadingException extends ModLoadingException {
public UncaughtModLoadingException(ModLoadingStage stage, Throwable originalException) {
super(null, stage, "fml.modloading.uncaughterror", originalException);
}
}
}
@@ -0,0 +1,332 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import com.google.common.collect.ImmutableList;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.LoadingModList;
import net.minecraftforge.fml.loading.moddiscovery.InvalidModIdentifier;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.IModLanguageProvider;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.Logging.CORE;
import static net.minecraftforge.fml.Logging.LOADING;
/**
* Loads mods.
*
* Dispatch cycle is seen in {@code #loadMods()} and {@code #finishMods()}
*
* Overall sequence for loadMods is:
* <dl>
* <dt>CONSTRUCT</dt>
* <dd>Constructs the mod instance. Mods can typically setup basic environment such as Event listeners
* and Configuration specifications here.</dd>
* <dt>Automated dispatches</dt>
* <dd>Dispatches automated elements : {@code net.minecraftforge.fml.common.Mod.EventBusSubscriber},
* {@code net.minecraftforge.event.RegistryEvent}, {@code net.minecraftforge.common.capabilities.CapabilityInject}
* and others</dd>
* <dt>CONFIG_LOAD</dt>
* <dd>Dispatches ConfigLoadEvent to mods</dd>
* <dt>COMMON_SETUP</dt>
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent} to mods</dd>
* <dt>SIDED_SETUP</dt>
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent} or
* {@code net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent} to mods</dd>
* </dl>
*
* Overall sequence for finishMods is:
* <dl>
* <dt>ENQUEUE_IMC</dt>
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent} to mods,
* for enqueuing {@link InterModComms} messages for other mods to receive subsequently</dd>
* <dt>PROCESS_IMC</dt>
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.InterModProcessEvent} to mods,
* for processing {@link InterModComms} messages received from other mods prior to this event</dd>
* <dt>COMPLETE</dt>
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent} to mods,
* and completes the mod loading sequence.</dd>
* </dl>
*/
public class ModLoader
{
private static final Logger LOGGER = LogManager.getLogger();
private static ModLoader INSTANCE;
private final LoadingModList loadingModList;
private final List<ModLoadingException> loadingExceptions;
private final List<ModLoadingWarning> loadingWarnings;
private final ModStateManager stateManager;
private boolean loadingStateValid;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private final Optional<Consumer<String>> statusConsumer = StartupMessageManager.modLoaderConsumer();
private ModList modList;
private ModLoader()
{
INSTANCE = this;
this.loadingModList = FMLLoader.getLoadingModList();
this.loadingExceptions = FMLLoader.getLoadingModList().getErrors().stream()
.flatMap(ModLoadingException::fromEarlyException)
.collect(Collectors.toList());
this.loadingWarnings = FMLLoader.getLoadingModList().getBrokenFiles().stream()
.map(file -> new ModLoadingWarning(null, ModLoadingStage.VALIDATE, InvalidModIdentifier.identifyJarProblem(file.getFilePath()).orElse("fml.modloading.brokenfile"), file.getFileName()))
.collect(Collectors.toList());
FMLLoader.getLoadingModList().getModFiles().stream()
.filter(ModFileInfo::missingLicense) //Search for files with missing licenses
.filter(modFileInfo -> modFileInfo.getMods().stream().noneMatch(thisModInfo -> this.loadingExceptions.stream().map(ModLoadingException::getModInfo).anyMatch(otherInfo -> otherInfo == thisModInfo))) //Ignore files where any other mod already encountered an error
.map(modFileInfo -> new ModLoadingException(null, ModLoadingStage.VALIDATE, "fml.modloading.missinglicense", null, modFileInfo.getFile()))
.forEach(this.loadingExceptions::add);
this.stateManager = new ModStateManager();
CrashReportCallables.registerCrashCallable("ModLauncher", FMLLoader::getLauncherInfo);
CrashReportCallables.registerCrashCallable("ModLauncher launch target", FMLLoader::launcherHandlerName);
CrashReportCallables.registerCrashCallable("ModLauncher naming", FMLLoader::getNaming);
CrashReportCallables.registerCrashCallable("ModLauncher services", this::computeModLauncherServiceList);
CrashReportCallables.registerCrashCallable("FML Language Providers", this::computeLanguageList);
}
private String computeLanguageList() {
return "\n"+FMLLoader.getLanguageLoadingProvider().applyForEach(lp->lp.name() +"@"+ lp.getClass().getPackage().getImplementationVersion()).collect(Collectors.joining("\n\t\t", "\t\t", ""));
}
private String computeModLauncherServiceList() {
final List<Map<String, String>> mods = FMLLoader.modLauncherModList();
return "\n"+mods.stream().map(mod->mod.getOrDefault("file","nofile")+
" "+mod.getOrDefault("name", "missing")+
" "+mod.getOrDefault("type","NOTYPE")+
" "+mod.getOrDefault("description", "")).
collect(Collectors.joining("\n\t\t","\t\t",""));
}
public static ModLoader get()
{
return INSTANCE == null ? INSTANCE = new ModLoader() : INSTANCE;
}
/**
* Run on the primary starting thread by ClientModLoader and ServerModLoader
* @param syncExecutor An executor to run tasks on the main thread
* @param parallelExecutor An executor to run tasks on a parallel loading thread pool
* @param periodicTask Optional periodic task to perform on the main thread while other activities run
*/
public void gatherAndInitializeMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
loadingStateValid = true;
statusConsumer.ifPresent(c->c.accept("Waiting for scan to complete"));
FMLLoader.backgroundScanHandler.waitForScanToComplete(periodicTask);
statusConsumer.ifPresent(c->c.accept("Loading mods"));
final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).toList(),
loadingModList.getMods());
if (!this.loadingExceptions.isEmpty()) {
LOGGER.fatal(CORE, "Error during pre-loading phase", loadingExceptions.get(0));
modList.setLoadedMods(Collections.emptyList());
loadingStateValid = false;
throw new LoadingFailedException(loadingExceptions);
}
statusConsumer.ifPresent(c->c.accept("Building Mod List"));
final List<ModContainer> modContainers = loadingModList.getModFiles().stream()
.map(ModFileInfo::getFile)
.map(this::buildMods)
.<ModContainer>mapMulti(Iterable::forEach)
.toList();
if (!loadingExceptions.isEmpty()) {
LOGGER.fatal(CORE, "Failed to initialize mod containers", loadingExceptions.get(0));
modList.setLoadedMods(Collections.emptyList());
loadingStateValid = false;
throw new LoadingFailedException(loadingExceptions);
}
modList.setLoadedMods(modContainers);
this.modList = modList;
statusConsumer.ifPresent(c->c.accept("Dispatching gathering events"));
stateManager.getStates(ModLoadingPhase.GATHER).forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask));
statusConsumer.ifPresent(c->c.accept("Gathering phase complete"));
}
public void loadMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
statusConsumer.ifPresent(c->c.accept("Performing load phase"));
stateManager.getStates(ModLoadingPhase.LOAD).forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask));
statusConsumer.ifPresent(c->c.accept("Mod setup complete"));
}
public void finishMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
statusConsumer.ifPresent(c->c.accept("Performing completion phase"));
stateManager.getStates(ModLoadingPhase.COMPLETE).forEach(mls->dispatchAndHandleError(mls, syncExecutor, parallelExecutor, periodicTask));
statusConsumer.ifPresent(c->c.accept(String.format("Mod loading complete - %d mods loaded", this.modList.size())));
}
private void dispatchAndHandleError(IModLoadingState state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker) {
if (!isLoadingStateValid()) {
LOGGER.error("Cowardly refusing to process mod state change request from {}", state);
return;
}
statusConsumer.ifPresent(c->c.accept(state.message().apply(this.modList)));
state.inlineRunnable().ifPresent(a->a.accept(this.modList));
state.buildTransition(syncExecutor, parallelExecutor).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t));
}
private void dispatchAndHandleError(IModLoadingState state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker, Function<Executor, CompletableFuture<Void>> preSyncTask, Function<Executor, CompletableFuture<Void>> postSyncTask) {
if (!isLoadingStateValid()) {
LOGGER.error("Cowardly refusing to process mod state change request from {}", state);
return;
}
statusConsumer.ifPresent(c->c.accept(state.message().apply(this.modList)));
state.inlineRunnable().ifPresent(a->a.accept(this.modList));
state.buildTransition(syncExecutor, parallelExecutor, preSyncTask, postSyncTask).ifPresent(t->waitForTransition(state, syncExecutor, ticker, t));
}
private void waitForTransition(final IModLoadingState state, final ModWorkManager.DrivenExecutor syncExecutor, final Runnable ticker, final CompletableFuture<List<Throwable>> transition) {
while (!transition.isDone()) {
syncExecutor.drive(ticker);
}
try {
transition.join();
} catch (CompletionException e) {
loadingStateValid = false;
Throwable t = e.getCause();
final List<Throwable> notModLoading = Arrays.stream(t.getSuppressed())
.filter(obj -> !(obj instanceof ModLoadingException))
.collect(Collectors.toList());
if (!notModLoading.isEmpty()) {
LOGGER.fatal("Encountered non-modloading exceptions!", e);
throw e;
}
final List<ModLoadingException> modLoadingExceptions = Arrays.stream(t.getSuppressed())
.filter(ModLoadingException.class::isInstance)
.map(ModLoadingException.class::cast)
.collect(Collectors.toList());
LOGGER.fatal(LOADING,"Failed to complete lifecycle event {}, {} errors found", state.name(), modLoadingExceptions.size());
throw new LoadingFailedException(modLoadingExceptions);
}
}
private List<ModContainer> buildMods(final ModFile modFile)
{
final Map<String, IModInfo> modInfoMap = modFile.getModFileInfo().getMods().stream().collect(Collectors.toMap(IModInfo::getModId, Function.identity()));
LOGGER.trace(LOADING, "ModContainer is {}", ModContainer.class.getClassLoader());
final List<ModContainer> containers = modFile.getScanResult().getTargets()
.entrySet()
.stream()
.map(e -> buildModContainerFromTOML(modFile, modInfoMap, e))
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (containers.size() != modInfoMap.size()) {
LOGGER.fatal(LOADING,"File {} constructed {} mods: {}, but had {} mods specified: {}",
modFile.getFilePath(),
containers.size(), containers.stream().map(c -> c != null ? c.getModId() : "(null)").sorted().collect(Collectors.toList()),
modInfoMap.size(), modInfoMap.values().stream().map(IModInfo::getModId).sorted().collect(Collectors.toList()));
loadingExceptions.add(new ModLoadingException(null, ModLoadingStage.CONSTRUCT, "fml.modloading.missingclasses", null, modFile.getFilePath()));
}
// remove errored mod containers
return containers.stream().filter(mc -> mc.modLoadingStage != ModLoadingStage.ERROR).collect(Collectors.toList());
}
private ModContainer buildModContainerFromTOML(final ModFile modFile, final Map<String, IModInfo> modInfoMap, final Map.Entry<String, ? extends IModLanguageProvider.IModLanguageLoader> idToProviderEntry) {
try {
final String modId = idToProviderEntry.getKey();
final IModLanguageProvider.IModLanguageLoader languageLoader = idToProviderEntry.getValue();
IModInfo info = Optional.ofNullable(modInfoMap.get(modId)).
// throw a missing metadata error if there is no matching modid in the modInfoMap from the mods.toml file
orElseThrow(()->new ModLoadingException(null, ModLoadingStage.CONSTRUCT, "fml.modloading.missingmetadata", null, modId));
return languageLoader.loadMod(info, modFile.getScanResult(), FMLLoader.getGameLayer());
} catch (ModLoadingException mle) {
// exceptions are caught and added to the error list for later handling
loadingExceptions.add(mle);
// return an errored container instance here, because we tried and failed building a container.
return new ErroredModContainer();
}
}
/**
* @return If the current mod loading state is valid. Use if you interact with vanilla systems directly during loading
* and don't want to cause extraneous crashes due to trying to do things that aren't possible in a "broken load"
*/
public static boolean isLoadingStateValid() {
return get().loadingStateValid;
}
public <T extends Event & IModBusEvent> void runEventGenerator(Function<ModContainer, T> generator) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event generator to a broken mod state");
return;
}
ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(generator.apply(mc)));
}
public <T extends Event & IModBusEvent> void postEvent(T e) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
return;
}
ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(e));
}
public List<ModLoadingWarning> getWarnings()
{
return ImmutableList.copyOf(this.loadingWarnings);
}
public void addWarning(ModLoadingWarning warning)
{
this.loadingWarnings.add(warning);
}
private static boolean runningDataGen = false;
public static boolean isDataGenRunning () {
return runningDataGen;
}
private static class ErroredModContainer extends ModContainer {
public ErroredModContainer() {
super();
}
@Override
public boolean matches(final Object mod) {
return false;
}
@Override
public Object getMod() {
return null;
}
}
}
@@ -0,0 +1,75 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import net.minecraftforge.fml.config.IConfigSpec;
import net.minecraftforge.fml.config.ModConfig;
import java.util.function.Supplier;
public class ModLoadingContext
{
private static final ThreadLocal<ModLoadingContext> context = ThreadLocal.withInitial(ModLoadingContext::new);
private Object languageExtension;
private ModLoadingStage stage;
public static ModLoadingContext get() {
return context.get();
}
private ModContainer activeContainer;
public void setActiveContainer(final ModContainer container) {
this.activeContainer = container;
this.languageExtension = container == null ? null : container.contextExtension.get();
}
public ModContainer getActiveContainer() {
return activeContainer == null ? ModList.get().getModContainerById("minecraft").orElseThrow(()->new RuntimeException("Where is minecraft???!")) : activeContainer;
}
public String getActiveNamespace() {
return activeContainer == null ? "minecraft" : activeContainer.getNamespace();
}
/**
* Register an {@link IExtensionPoint} with the mod container.
* @param point The extension point to register
* @param extension An extension operator
* @param <T> The type signature of the extension operator
*/
public <T extends Record & IExtensionPoint<T>> void registerExtensionPoint(Class<? extends IExtensionPoint<T>> point, Supplier<T> extension) {
getActiveContainer().registerExtensionPoint(point, extension);
}
public void registerConfig(ModConfig.Type type, IConfigSpec<?> spec) {
getActiveContainer().addConfig(new ModConfig(type, spec, getActiveContainer()));
}
public void registerConfig(ModConfig.Type type, IConfigSpec<?> spec, String fileName) {
getActiveContainer().addConfig(new ModConfig(type, spec, getActiveContainer(), fileName));
}
@SuppressWarnings("unchecked")
public <T> T extension() {
return (T)languageExtension;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,8 @@
package net.minecraftforge.fml;
import com.google.common.collect.Streams;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.fml.loading.EarlyLoadingException;
import net.minecraftforge.forgespi.language.IModInfo;
import java.util.Arrays;
import java.util.List;
@@ -32,6 +32,7 @@ import java.util.stream.Stream;
*/
public class ModLoadingException extends RuntimeException
{
private static final long serialVersionUID = 2048947398536935507L;
/**
* Mod Info for mod with issue
*/
@@ -52,7 +53,7 @@ public class ModLoadingException extends RuntimeException
private final List<Object> context;
public ModLoadingException(final IModInfo modInfo, final ModLoadingStage errorStage, final String i18nMessage, final Throwable originalException, Object... context) {
super(ForgeI18n.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, errorStage, originalException), Stream.of(context)).toArray()), originalException);
super("Mod Loading Exception", originalException);
this.modInfo = modInfo;
this.errorStage = errorStage;
this.i18nMessage = i18nMessage;
@@ -60,7 +61,7 @@ public class ModLoadingException extends RuntimeException
}
static Stream<ModLoadingException> fromEarlyException(final EarlyLoadingException e) {
return e.getAllData().stream().map(ed->new ModLoadingException(null, ModLoadingStage.VALIDATE, ed.getI18message(), e.getCause(), ed.getArgs()));
return e.getAllData().stream().map(ed->new ModLoadingException(ed.getModInfo(), ModLoadingStage.VALIDATE, ed.getI18message(), e.getCause(), ed.getArgs()));
}
public String getI18NMessage() {
@@ -72,6 +73,18 @@ public class ModLoadingException extends RuntimeException
}
public String formatToString() {
return ForgeI18n.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, errorStage, getCause()), context.stream()).toArray());
return Bindings.getMessageParser().get().parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, errorStage, getCause()), context.stream()).toArray());
}
@Override
public String getMessage() {
return formatToString();
}
public IModInfo getModInfo() {
return modInfo;
}
public String getCleanMessage() {
return Bindings.getMessageParser().get().stripControlCodes(formatToString());
}
}
@@ -0,0 +1,9 @@
package net.minecraftforge.fml;
public enum ModLoadingPhase {
ERROR, // Special state for error handling
GATHER,
LOAD,
COMPLETE,
DONE;
}
@@ -0,0 +1,51 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
public enum ModLoadingStage
{
ERROR,
VALIDATE,
CONSTRUCT,
COMMON_SETUP,
SIDED_SETUP,
ENQUEUE_IMC,
PROCESS_IMC,
COMPLETE,
DONE;
private final DeferredWorkQueue deferredWorkQueue;
ModLoadingStage() {
deferredWorkQueue = new DeferredWorkQueue(this);
}
ModLoadingStage nextState(Throwable exception) {
return exception != null ? ERROR : values()[this.ordinal()+1];
}
public ModLoadingStage currentState(Throwable exception) {
return exception != null ? ERROR : this;
}
public DeferredWorkQueue getDeferredWorkQueue() {
return deferredWorkQueue;
}
}
@@ -0,0 +1,33 @@
package net.minecraftforge.fml;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
public record ModLoadingState(String name, String previous, Function<ModList, String> message, ModLoadingPhase phase, Optional<Consumer<ModList>> inlineRunnable, Optional<IModStateTransition> transition) implements IModLoadingState {
@Override
public <T extends Event & IModBusEvent> Optional<CompletableFuture<List<Throwable>>> buildTransition(final Executor syncExecutor, final Executor parallelExecutor, Function<Executor, CompletableFuture<Void>> preSyncTask, Function<Executor, CompletableFuture<Void>> postSyncTask) {
return transition.map(t->t.build(syncExecutor, parallelExecutor, preSyncTask, postSyncTask));
}
public static ModLoadingState empty(final String name, final String previous, final ModLoadingPhase phase) {
return new ModLoadingState(name, previous, ml->"", phase, Optional.empty(), Optional.empty());
}
public static ModLoadingState withTransition(final String name, final String previous, final ModLoadingPhase phase, IModStateTransition transition) {
return new ModLoadingState(name, previous, ml->"Processing transition "+name, phase, Optional.empty(), Optional.of(transition));
}
public static ModLoadingState withTransition(final String name, final String previous, final Function<ModList, String> message, final ModLoadingPhase phase, IModStateTransition transition) {
return new ModLoadingState(name, previous, message, phase, Optional.empty(), Optional.of(transition));
}
public static ModLoadingState withInline(final String name, final String previous, final ModLoadingPhase phase, Consumer<ModList> inline) {
return new ModLoadingState(name, previous, ml->"Processing work "+name, phase, Optional.of(inline), Optional.empty());
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -55,6 +55,6 @@ public class ModLoadingWarning
}
public String formatToString() {
return ForgeI18n.parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, warningStage), context.stream()).toArray());
return Bindings.getMessageParser().get().parseMessage(i18nMessage, Streams.concat(Stream.of(modInfo, warningStage), context.stream()).toArray());
}
}
@@ -0,0 +1,37 @@
package net.minecraftforge.fml;
import com.google.common.graph.GraphBuilder;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.toposort.TopologicalSort;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@SuppressWarnings("UnstableApiUsage")
public class ModStateManager {
static ModStateManager INSTANCE;
private final EnumMap<ModLoadingPhase, List<IModLoadingState>> stateMap;
public ModStateManager() {
INSTANCE = this;
final var sp = ServiceLoader.load(FMLLoader.getGameLayer(), IModStateProvider.class);
this.stateMap = ServiceLoaderUtils.streamWithErrorHandling(sp, sce->{})
.map(IModStateProvider::getAllStates)
.<IModLoadingState>mapMulti(Iterable::forEach)
.collect(Collectors.groupingBy(IModLoadingState::phase, ()->new EnumMap<>(ModLoadingPhase.class), Collectors.toUnmodifiableList()));
}
public List<IModLoadingState> getStates(final ModLoadingPhase phase) {
var nodes = stateMap.get(phase);
var lookup = nodes.stream().collect(Collectors.toMap(IModLoadingState::name, Function.identity()));
var graph = GraphBuilder.directed().allowsSelfLoops(false).<IModLoadingState>build();
var dummy = ModLoadingState.empty("", "", phase);
nodes.forEach(graph::addNode);
graph.addNode(dummy);
nodes.forEach(n->graph.putEdge(lookup.getOrDefault(n.previous(), dummy), n));
return TopologicalSort.topologicalSort(graph, Comparator.comparingInt(nodes::indexOf)).stream().filter(st->st!=dummy).toList();
}
}
@@ -0,0 +1,125 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import net.minecraftforge.fml.loading.FMLConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;
import static net.minecraftforge.fml.Logging.LOADING;
public class ModWorkManager {
private static final Logger LOGGER = LogManager.getLogger();
private static final long PARK_TIME = TimeUnit.MILLISECONDS.toNanos(1);
public interface DrivenExecutor extends Executor {
boolean selfDriven();
boolean driveOne();
default void drive(Runnable ticker) {
if (!selfDriven()) {
while (driveOne()) {
ticker.run();
}
} else {
// park for a bit so other threads can schedule
LockSupport.parkNanos(PARK_TIME);
}
}
}
private static class SyncExecutor implements DrivenExecutor {
private ConcurrentLinkedDeque<Runnable> tasks = new ConcurrentLinkedDeque<>();
@Override
public boolean driveOne() {
final Runnable task = tasks.pollFirst();
if (task != null) {
task.run();
}
return task != null;
}
@Override
public boolean selfDriven() {
return false;
}
@Override
public void execute(final Runnable command) {
tasks.addLast(command);
}
}
private static class WrappingExecutor implements DrivenExecutor {
private final Executor wrapped;
public WrappingExecutor(final Executor executor) {
this.wrapped = executor;
}
@Override
public boolean selfDriven() {
return true;
}
@Override
public boolean driveOne() {
return false;
}
@Override
public void execute(final Runnable command) {
wrapped.execute(command);
}
}
private static SyncExecutor syncExecutor;
public static DrivenExecutor syncExecutor() {
if (syncExecutor == null)
syncExecutor = new SyncExecutor();
return syncExecutor;
}
public static DrivenExecutor wrappedExecutor(Executor executor) {
return new WrappingExecutor(executor);
}
private static ForkJoinPool parallelThreadPool;
public static Executor parallelExecutor() {
if (parallelThreadPool == null) {
final int loadingThreadCount = FMLConfig.loadingThreadCount();
LOGGER.debug(LOADING, "Using {} threads for parallel mod-loading", loadingThreadCount);
parallelThreadPool = new ForkJoinPool(loadingThreadCount, ModWorkManager::newForkJoinWorkerThread, null, false);
}
return parallelThreadPool;
}
private static ForkJoinWorkerThread newForkJoinWorkerThread(ForkJoinPool pool) {
ForkJoinWorkerThread thread = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setName("modloading-worker-" + thread.getPoolIndex());
// The default sets it to the SystemClassloader, so copy the current one.
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
return thread;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -0,0 +1,37 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import java.util.Optional;
import java.util.function.Consumer;
public class StartupMessageManager {
public static void addModMessage(final String message) {
net.minecraftforge.fml.loading.progress.StartupMessageManager.addModMessage(message);
}
public static Optional<Consumer<String>> modLoaderConsumer() {
return net.minecraftforge.fml.loading.progress.StartupMessageManager.modLoaderConsumer();
}
public static Optional<Consumer<String>> mcLoaderConsumer() {
return net.minecraftforge.fml.loading.progress.StartupMessageManager.mcLoaderConsumer();
}
}
@@ -0,0 +1,20 @@
package net.minecraftforge.fml;
import java.util.concurrent.Executor;
import java.util.function.BinaryOperator;
public enum ThreadSelector implements BinaryOperator<Executor> {
SYNC((sync, parallel) -> sync),
PARALLEL((sync, parallel) -> parallel);
private final BinaryOperator<Executor> selector;
ThreadSelector(final BinaryOperator<Executor> selector) {
this.selector = selector;
}
@Override
public Executor apply(final Executor sync, final Executor parallel) {
return this.selector.apply(sync, parallel);
}
}
@@ -0,0 +1,290 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import com.google.gson.Gson;
import net.minecraftforge.fml.loading.FMLConfig;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.forgespi.language.IModInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.maven.artifact.versioning.ComparableVersion;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import static net.minecraftforge.fml.VersionChecker.Status.*;
public class VersionChecker
{
private static final Logger LOGGER = LogManager.getLogger();
private static final int MAX_HTTP_REDIRECTS = Integer.getInteger("http.maxRedirects", 20);
private static final int HTTP_TIMEOUT_SECS = Integer.getInteger("http.timeoutSecs", 15);
public enum Status
{
PENDING(),
FAILED(),
UP_TO_DATE(),
OUTDATED(3, true),
AHEAD(),
BETA(),
BETA_OUTDATED(6, true);
final int sheetOffset;
final boolean draw, animated;
Status()
{
this(0, false, false);
}
Status(int sheetOffset)
{
this(sheetOffset, true, false);
}
Status(int sheetOffset, boolean animated)
{
this(sheetOffset, true, animated);
}
Status(int sheetOffset, boolean draw, boolean animated)
{
this.sheetOffset = sheetOffset;
this.draw = draw;
this.animated = animated;
}
public int getSheetOffset()
{
return sheetOffset;
}
public boolean shouldDraw()
{
return draw;
}
public boolean isAnimated()
{
return animated;
}
}
public record CheckResult(VersionChecker.Status status, ComparableVersion target, Map<ComparableVersion, String> changes, String url) {}
public static void startVersionCheck()
{
new Thread("Forge Version Check")
{
private HttpClient client;
@Override
public void run()
{
if (!FMLConfig.runVersionCheck())
{
LOGGER.info("Global Forge version check system disabled, no further processing.");
return;
}
client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(HTTP_TIMEOUT_SECS)).build();
gatherMods().forEach(this::process);
}
/**
* Returns the response body as a String for the given URL while following redirects
*/
private String openUrlString(URL url) throws IOException, URISyntaxException, InterruptedException {
URL currentUrl = url;
for (int redirects = 0; redirects < MAX_HTTP_REDIRECTS; redirects++)
{
var request = HttpRequest.newBuilder()
.uri(currentUrl.toURI())
.timeout(Duration.ofSeconds(HTTP_TIMEOUT_SECS))
.setHeader("Accept-Encoding", "gzip")
.GET()
.build();
final HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
int responseCode = response.statusCode();
if (responseCode >= 300 && responseCode <= 399)
{
String newLocation = response.headers().firstValue("Location")
.orElseThrow(() -> new IOException("Got a 3xx response code but Location header was null while trying to fetch " + url));
currentUrl = new URL(currentUrl, newLocation);
continue;
}
final boolean isGzipEncoded = response.headers().firstValue("Content-Encoding").orElse("").equals("gzip");
final String bodyStr;
try (InputStream inStream = isGzipEncoded ? new GZIPInputStream(response.body()) : response.body())
{
try (var bufferedReader = new BufferedReader(new InputStreamReader(inStream)))
{
bodyStr = bufferedReader.lines().collect(Collectors.joining("\n"));
}
}
return bodyStr;
}
throw new IOException("Too many redirects while trying to fetch " + url);
}
private void process(IModInfo mod)
{
Status status = PENDING;
ComparableVersion target = null;
Map<ComparableVersion, String> changes = null;
String display_url = null;
try
{
if (mod.getUpdateURL().isEmpty()) return;
URL url = mod.getUpdateURL().get();
LOGGER.info("[{}] Starting version check at {}", mod.getModId(), url.toString());
String data = openUrlString(url);
LOGGER.debug("[{}] Received version check data:\n{}", mod.getModId(), data);
@SuppressWarnings("unchecked")
Map<String, Object> json = new Gson().fromJson(data, Map.class);
@SuppressWarnings("unchecked")
Map<String, String> promos = (Map<String, String>)json.get("promos");
display_url = (String)json.get("homepage");
var mcVersion = FMLLoader.versionInfo().mcVersion();
String rec = promos.get(mcVersion + "-recommended");
String lat = promos.get(mcVersion + "-latest");
ComparableVersion current = new ComparableVersion(mod.getVersion().toString());
if (rec != null)
{
ComparableVersion recommended = new ComparableVersion(rec);
int diff = recommended.compareTo(current);
if (diff == 0)
status = UP_TO_DATE;
else if (diff < 0)
{
status = AHEAD;
if (lat != null)
{
ComparableVersion latest = new ComparableVersion(lat);
if (current.compareTo(latest) < 0)
{
status = OUTDATED;
target = latest;
}
}
}
else
{
status = OUTDATED;
target = recommended;
}
}
else if (lat != null)
{
ComparableVersion latest = new ComparableVersion(lat);
if (current.compareTo(latest) < 0)
status = BETA_OUTDATED;
else
status = BETA;
target = latest;
}
else
status = BETA;
LOGGER.info("[{}] Found status: {} Current: {} Target: {}", mod.getModId(), status, current, target);
changes = new LinkedHashMap<>();
@SuppressWarnings("unchecked")
Map<String, String> tmp = (Map<String, String>)json.get(mcVersion);
if (tmp != null)
{
List<ComparableVersion> ordered = new ArrayList<>();
for (String key : tmp.keySet())
{
ComparableVersion ver = new ComparableVersion(key);
if (ver.compareTo(current) > 0 && (target == null || ver.compareTo(target) < 1))
{
ordered.add(ver);
}
}
Collections.sort(ordered);
for (ComparableVersion ver : ordered)
{
changes.put(ver, tmp.get(ver.toString()));
}
}
}
catch (Exception e)
{
LOGGER.warn("Failed to process update information", e);
status = FAILED;
}
results.put(mod, new CheckResult(status, target, changes, display_url));
}
}.start();
}
// Gather a list of mods that have opted in to this update system by providing a URL.
private static List<IModInfo> gatherMods()
{
List<IModInfo> ret = new LinkedList<>();
for (IModInfo info : ModList.get().getMods()) {
if (info.getUpdateURL().isPresent())
ret.add(info);
}
return ret;
}
private static Map<IModInfo, CheckResult> results = new ConcurrentHashMap<>();
private static final CheckResult PENDING_CHECK = new CheckResult(PENDING, null, null, null);
public static CheckResult getResult(IModInfo mod)
{
return results.getOrDefault(mod, PENDING_CHECK);
}
}
@@ -0,0 +1,173 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.config;
import com.electronwill.nightconfig.core.ConfigFormat;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.file.FileWatcher;
import com.electronwill.nightconfig.core.io.ParsingException;
import com.electronwill.nightconfig.core.io.WritingMode;
import net.minecraftforge.fml.loading.FMLConfig;
import net.minecraftforge.fml.loading.FMLPaths;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Function;
import static net.minecraftforge.fml.config.ConfigTracker.CONFIG;
public class ConfigFileTypeHandler {
private static final Logger LOGGER = LogManager.getLogger();
static ConfigFileTypeHandler TOML = new ConfigFileTypeHandler();
private static final Path defaultConfigPath = FMLPaths.GAMEDIR.get().resolve(FMLConfig.defaultConfigPath());
public Function<ModConfig, CommentedFileConfig> reader(Path configBasePath) {
return (c) -> {
final Path configPath = configBasePath.resolve(c.getFileName());
final CommentedFileConfig configData = CommentedFileConfig.builder(configPath).sync().
preserveInsertionOrder().
autosave().
onFileNotFound((newfile, configFormat)-> setupConfigFile(c, newfile, configFormat)).
writingMode(WritingMode.REPLACE).
build();
LOGGER.debug(CONFIG, "Built TOML config for {}", configPath.toString());
try
{
configData.load();
}
catch (ParsingException ex)
{
throw new ConfigLoadingException(c, ex);
}
LOGGER.debug(CONFIG, "Loaded TOML config file {}", configPath.toString());
try {
FileWatcher.defaultInstance().addWatch(configPath, new ConfigWatcher(c, configData, Thread.currentThread().getContextClassLoader()));
LOGGER.debug(CONFIG, "Watching TOML config file {} for changes", configPath.toString());
} catch (IOException e) {
throw new RuntimeException("Couldn't watch config file", e);
}
return configData;
};
}
public void unload(Path configBasePath, ModConfig config) {
Path configPath = configBasePath.resolve(config.getFileName());
try {
FileWatcher.defaultInstance().removeWatch(configBasePath.resolve(config.getFileName()));
} catch (RuntimeException e) {
LOGGER.error("Failed to remove config {} from tracker!", configPath.toString(), e);
}
}
private boolean setupConfigFile(final ModConfig modConfig, final Path file, final ConfigFormat<?> conf) throws IOException {
Files.createDirectories(file.getParent());
Path p = defaultConfigPath.resolve(modConfig.getFileName());
if (Files.exists(p)) {
LOGGER.info(CONFIG, "Loading default config file from path {}", p);
Files.copy(p, file);
} else {
Files.createFile(file);
conf.initEmptyFile(file);
}
return true;
}
public static void backUpConfig(final CommentedFileConfig commentedFileConfig)
{
backUpConfig(commentedFileConfig, 5); //TODO: Think of a way for mods to set their own preference (include a sanity check as well, no disk stuffing)
}
public static void backUpConfig(final CommentedFileConfig commentedFileConfig, final int maxBackups)
{
Path bakFileLocation = commentedFileConfig.getNioPath().getParent();
String bakFileName = FilenameUtils.removeExtension(commentedFileConfig.getFile().getName());
String bakFileExtension = FilenameUtils.getExtension(commentedFileConfig.getFile().getName()) + ".bak";
Path bakFile = bakFileLocation.resolve(bakFileName + "-1" + "." + bakFileExtension);
try
{
for(int i = maxBackups; i > 0; i--)
{
Path oldBak = bakFileLocation.resolve(bakFileName + "-" + i + "." + bakFileExtension);
if(Files.exists(oldBak))
{
if(i >= maxBackups)
Files.delete(oldBak);
else
Files.move(oldBak, bakFileLocation.resolve(bakFileName + "-" + (i + 1) + "." + bakFileExtension));
}
}
Files.copy(commentedFileConfig.getNioPath(), bakFile);
}
catch (IOException exception)
{
LOGGER.warn(CONFIG, "Failed to back up config file {}", commentedFileConfig.getNioPath(), exception);
}
}
private static class ConfigWatcher implements Runnable {
private final ModConfig modConfig;
private final CommentedFileConfig commentedFileConfig;
private final ClassLoader realClassLoader;
ConfigWatcher(final ModConfig modConfig, final CommentedFileConfig commentedFileConfig, final ClassLoader classLoader) {
this.modConfig = modConfig;
this.commentedFileConfig = commentedFileConfig;
this.realClassLoader = classLoader;
}
@Override
public void run() {
// Force the regular classloader onto the special thread
Thread.currentThread().setContextClassLoader(realClassLoader);
if (!this.modConfig.getSpec().isCorrecting()) {
try
{
this.commentedFileConfig.load();
if(!this.modConfig.getSpec().isCorrect(commentedFileConfig))
{
LOGGER.warn(CONFIG, "Configuration file {} is not correct. Correcting", commentedFileConfig.getFile().getAbsolutePath());
ConfigFileTypeHandler.backUpConfig(commentedFileConfig);
this.modConfig.getSpec().correct(commentedFileConfig);
commentedFileConfig.save();
}
}
catch (ParsingException ex)
{
throw new ConfigLoadingException(modConfig, ex);
}
LOGGER.debug(CONFIG, "Config file {} changed, sending notifies", this.modConfig.getFileName());
this.modConfig.getSpec().afterReload();
this.modConfig.fireEvent(IConfigEvent.reloading(this.modConfig));
}
}
}
private static class ConfigLoadingException extends RuntimeException
{
public ConfigLoadingException(ModConfig config, Exception cause)
{
super("Failed loading config file " + config.getFileName() + " of type " + config.getType() + " for modid " + config.getModId(), cause);
}
}
}
@@ -0,0 +1,110 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.config;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class ConfigTracker {
private static final Logger LOGGER = LogManager.getLogger();
static final Marker CONFIG = MarkerManager.getMarker("CONFIG");
public static final ConfigTracker INSTANCE = new ConfigTracker();
private final ConcurrentHashMap<String, ModConfig> fileMap;
private final EnumMap<ModConfig.Type, Set<ModConfig>> configSets;
private final ConcurrentHashMap<String, Map<ModConfig.Type, ModConfig>> configsByMod;
private ConfigTracker() {
this.fileMap = new ConcurrentHashMap<>();
this.configSets = new EnumMap<>(ModConfig.Type.class);
this.configsByMod = new ConcurrentHashMap<>();
this.configSets.put(ModConfig.Type.CLIENT, Collections.synchronizedSet(new LinkedHashSet<>()));
this.configSets.put(ModConfig.Type.COMMON, Collections.synchronizedSet(new LinkedHashSet<>()));
// this.configSets.put(ModConfig.Type.PLAYER, new ConcurrentSkipListSet<>());
this.configSets.put(ModConfig.Type.SERVER, Collections.synchronizedSet(new LinkedHashSet<>()));
}
void trackConfig(final ModConfig config) {
if (this.fileMap.containsKey(config.getFileName())) {
LOGGER.error(CONFIG,"Detected config file conflict {} between {} and {}", config.getFileName(), this.fileMap.get(config.getFileName()).getModId(), config.getModId());
throw new RuntimeException("Config conflict detected!");
}
this.fileMap.put(config.getFileName(), config);
this.configSets.get(config.getType()).add(config);
this.configsByMod.computeIfAbsent(config.getModId(), (k)->new EnumMap<>(ModConfig.Type.class)).put(config.getType(), config);
LOGGER.debug(CONFIG, "Config file {} for {} tracking", config.getFileName(), config.getModId());
}
public void loadConfigs(ModConfig.Type type, Path configBasePath) {
LOGGER.debug(CONFIG, "Loading configs type {}", type);
this.configSets.get(type).forEach(config -> openConfig(config, configBasePath));
}
public void unloadConfigs(ModConfig.Type type, Path configBasePath) {
LOGGER.debug(CONFIG, "Unloading configs type {}", type);
this.configSets.get(type).forEach(config -> closeConfig(config, configBasePath));
}
private void openConfig(final ModConfig config, final Path configBasePath) {
LOGGER.trace(CONFIG, "Loading config file type {} at {} for {}", config.getType(), config.getFileName(), config.getModId());
final CommentedFileConfig configData = config.getHandler().reader(configBasePath).apply(config);
config.setConfigData(configData);
config.fireEvent(IConfigEvent.loading(config));
config.save();
}
private void closeConfig(final ModConfig config, final Path configBasePath) {
if (config.getConfigData() != null) {
LOGGER.trace(CONFIG, "Closing config file type {} at {} for {}", config.getType(), config.getFileName(), config.getModId());
config.save();
config.getHandler().unload(configBasePath, config);
config.setConfigData(null);
}
}
public void loadDefaultServerConfigs() {
configSets.get(ModConfig.Type.SERVER).forEach(modConfig -> {
final CommentedConfig commentedConfig = CommentedConfig.inMemory();
modConfig.getSpec().correct(commentedConfig);
modConfig.setConfigData(commentedConfig);
modConfig.fireEvent(IConfigEvent.loading(modConfig));
});
}
public String getConfigFileName(String modId, ModConfig.Type type) {
return Optional.ofNullable(configsByMod.getOrDefault(modId, Collections.emptyMap()).getOrDefault(type, null)).
map(ModConfig::getFullPath).map(Object::toString).orElse(null);
}
public Map<ModConfig.Type, Set<ModConfig>> configSets() {
return configSets;
}
public ConcurrentHashMap<String, ModConfig> fileMap() {
return fileMap;
}
}
@@ -0,0 +1,24 @@
package net.minecraftforge.fml.config;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.Bindings;
import java.util.function.Function;
public interface IConfigEvent {
record ConfigConfig(Function<ModConfig, IConfigEvent> loading, Function<ModConfig, IConfigEvent> reloading) {}
ConfigConfig CONFIGCONFIG = Bindings.getConfigConfiguration().get();
static IConfigEvent reloading(ModConfig modConfig) {
return CONFIGCONFIG.reloading().apply(modConfig);
}
static IConfigEvent loading(ModConfig modConfig) {
return CONFIGCONFIG.loading().apply(modConfig);
}
ModConfig getConfig();
@SuppressWarnings("unchecked")
default <T extends Event & IConfigEvent> T self() {
return (T) this;
}
}
@@ -0,0 +1,21 @@
package net.minecraftforge.fml.config;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
public interface IConfigSpec<T extends IConfigSpec<T>> extends UnmodifiableConfig {
@SuppressWarnings("unchecked")
default T self() {
return (T) this;
}
void acceptConfig(CommentedConfig data);
boolean isCorrecting();
boolean isCorrect(CommentedConfig commentedFileConfig);
int correct(CommentedConfig commentedFileConfig);
void afterReload();
}
@@ -0,0 +1,142 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2022.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.config;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.toml.TomlFormat;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.loading.StringUtils;
import java.io.ByteArrayInputStream;
import java.nio.file.Path;
import java.util.Locale;
import java.util.concurrent.Callable;
public class ModConfig
{
private final Type type;
private final IConfigSpec<?> spec;
private final String fileName;
private final ModContainer container;
private final ConfigFileTypeHandler configHandler;
private CommentedConfig configData;
private Callable<Void> saveHandler;
public ModConfig(final Type type, final IConfigSpec<?> spec, final ModContainer container, final String fileName) {
this.type = type;
this.spec = spec;
this.fileName = fileName;
this.container = container;
this.configHandler = ConfigFileTypeHandler.TOML;
ConfigTracker.INSTANCE.trackConfig(this);
}
public ModConfig(final Type type, final IConfigSpec<?> spec, final ModContainer activeContainer) {
this(type, spec, activeContainer, defaultConfigName(type, activeContainer.getModId()));
}
private static String defaultConfigName(Type type, String modId) {
// config file name would be "forge-client.toml" and "forge-server.toml"
return String.format(Locale.ROOT, "%s-%s.toml", modId, type.extension());
}
public Type getType() {
return type;
}
public String getFileName() {
return fileName;
}
public ConfigFileTypeHandler getHandler() {
return configHandler;
}
@SuppressWarnings("unchecked")
public <T extends IConfigSpec<T>> IConfigSpec<T> getSpec() {
return (IConfigSpec<T>) spec;
}
public String getModId() {
return container.getModId();
}
public CommentedConfig getConfigData() {
return this.configData;
}
void setConfigData(final CommentedConfig configData) {
this.configData = configData;
this.spec.acceptConfig(this.configData);
}
void fireEvent(final IConfigEvent configEvent) {
this.container.dispatchConfigEvent(configEvent);
}
public void save() {
((CommentedFileConfig)this.configData).save();
}
public Path getFullPath() {
return ((CommentedFileConfig)this.configData).getNioPath();
}
public void acceptSyncedConfig(byte[] bytes) {
setConfigData(TomlFormat.instance().createParser().parse(new ByteArrayInputStream(bytes)));
fireEvent(IConfigEvent.reloading(this));
}
public enum Type {
/**
* Common mod config for configuration that needs to be loaded on both environments.
* Loaded on both servers and clients.
* Stored in the global config directory.
* Not synced.
* Suffix is "-common" by default.
*/
COMMON,
/**
* Client config is for configuration affecting the ONLY client state such as graphical options.
* Only loaded on the client side.
* Stored in the global config directory.
* Not synced.
* Suffix is "-client" by default.
*/
CLIENT,
// /**
// * Player type config is configuration that is associated with a player.
// * Preferences around machine states, for example.
// */
// PLAYER,
/**
* Server type config is configuration that is associated with a server instance.
* Only loaded during server startup.
* Stored in a server/save specific "serverconfig" directory.
* Synced to clients during connection.
* Suffix is "-server" by default.
*/
SERVER;
public String extension() {
return StringUtils.toLowerCase(name());
}
}
}
@@ -0,0 +1,26 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.event;
/**
* Marker interface for events dispatched on the ModLifecycle event bus instead of the primary event bus
*/
public interface IModBusEvent {
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common;
package net.minecraftforge.fml.util;
import com.google.common.collect.ImmutableList;
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common;
package net.minecraftforge.fml.util;
import java.io.PrintStream;
import java.io.PrintWriter;
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,8 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common;
import net.minecraftforge.fml.common.EnhancedRuntimeException.WrappedPrintStream;
package net.minecraftforge.fml.util;
public class LoaderException extends EnhancedRuntimeException
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common;
package net.minecraftforge.fml.util;
/**
* Prevent LoaderException from adding its own stack trace to the wrapped throwable's stack trace.
@@ -0,0 +1,276 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.StringJoiner;
import cpw.mods.modlauncher.api.INameMappingService;
import net.minecraftforge.fml.loading.FMLLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Some reflection helper code.
* This may not work properly in Java 9 with its new, more restrictive, reflection management.
* As such, if issues are encountered, please report them and we can see what we can do to expand
* the compatibility.
*
* In other cases, AccessTransformers may be used.
*
* All field and method names should be passed in as SRG names, and this will automatically resolve if MCP mappings are detected.
*
*/
@SuppressWarnings({"serial", "unchecked", "unused", "WeakerAccess"})
public class ObfuscationReflectionHelper
{
private static final Logger LOGGER = LogManager.getLogger();
private static final Marker REFLECTION = MarkerManager.getMarker("REFLECTION");
/**
* Remaps a name using the SRG naming function
* @param domain The {@link INameMappingService.Domain} to use to remap the name.
* @param name The name to try and remap.
* @return The remapped name, or the original name if it couldn't be remapped.
*/
@NotNull
public static String remapName(INameMappingService.Domain domain, String name)
{
return FMLLoader.getNameFunction("srg").map(f->f.apply(domain, name)).orElse(name);
}
/**
* Gets the value a field with the specified name in the given class.
* Note: For performance, use {@link #findField(Class, String)} if you are getting the value more than once.
* <p>
* Throws an exception if the field is not found or the value of the field cannot be gotten.
*
* @param classToAccess The class to find the field on.
* @param instance The instance of the {@code classToAccess}.
* @param fieldName The SRG (unmapped) name of the field to find (e.g. "f_46443_").
* @param <T> The type of the value.
* @param <E> The type of the {@code classToAccess}.
* @return The value of the field with the specified name in the {@code classToAccess}.
* @throws UnableToAccessFieldException If there was a problem getting the field.
* @throws UnableToAccessFieldException If there was a problem getting the value.
*/
@Nullable
public static <T, E> T getPrivateValue(Class<? super E> classToAccess, E instance, String fieldName)
{
try
{
return (T) findField(classToAccess, fieldName).get(instance);
}
catch (UnableToFindFieldException e)
{
LOGGER.error(REFLECTION,"Unable to locate field {} ({}) on type {}", fieldName, remapName(INameMappingService.Domain.FIELD, fieldName), classToAccess.getName(), e);
throw e;
}
catch (IllegalAccessException e)
{
LOGGER.error(REFLECTION,"Unable to access field {} ({}) on type {}", fieldName, remapName(INameMappingService.Domain.FIELD, fieldName), classToAccess.getName(), e);
throw new UnableToAccessFieldException(e);
}
}
/**
* Sets the value a field with the specified name in the given class.
* Note: For performance, use {@link #findField(Class, String)} if you are setting the value more than once.
* <p>
* Throws an exception if the field is not found or the value of the field cannot be set.
*
* @param classToAccess The class to find the field on.
* @param instance The instance of the {@code classToAccess}.
* @param value The new value for the field
* @param fieldName The name of the field in the {@code classToAccess}.
* @param <T> The type of the value.
* @param <E> The type of the {@code classToAccess}.
* @throws UnableToFindFieldException If there was a problem getting the field.
* @throws UnableToAccessFieldException If there was a problem setting the value of the field.
*/
public static <T, E> void setPrivateValue(@NotNull final Class<? super T> classToAccess, @NotNull final T instance, @Nullable final E value, @NotNull final String fieldName)
{
try
{
findField(classToAccess, fieldName).set(instance, value);
}
catch (UnableToFindFieldException e)
{
LOGGER.error("Unable to locate any field {} on type {}", fieldName, classToAccess.getName(), e);
throw e;
}
catch (IllegalAccessException e)
{
LOGGER.error("Unable to set any field {} on type {}", fieldName, classToAccess.getName(), e);
throw new UnableToAccessFieldException(e);
}
}
/**
* Finds a method with the specified name and parameters in the given class and makes it accessible.
* Note: For performance, store the returned value and avoid calling this repeatedly.
* <p>
* Throws an exception if the method is not found.
*
* @param clazz The class to find the method on.
* @param methodName The SRG (unmapped) name of the method to find (e.g. "m_5776_").
* @param parameterTypes The parameter types of the method to find.
* @return The method with the specified name and parameters in the given class.
* @throws NullPointerException If {@code clazz} is null.
* @throws NullPointerException If {@code methodName} is null.
* @throws IllegalArgumentException If {@code methodName} is empty.
* @throws NullPointerException If {@code parameterTypes} is null.
* @throws UnableToFindMethodException If the method could not be found.
*/
@NotNull
public static Method findMethod(@NotNull final Class<?> clazz, @NotNull final String methodName, @NotNull final Class<?>... parameterTypes)
{
Preconditions.checkNotNull(clazz, "Class to find method on cannot be null.");
Preconditions.checkNotNull(methodName, "Name of method to find cannot be null.");
Preconditions.checkArgument(!methodName.isEmpty(), "Name of method to find cannot be empty.");
Preconditions.checkNotNull(parameterTypes, "Parameter types of method to find cannot be null.");
try
{
Method m = clazz.getDeclaredMethod(remapName(INameMappingService.Domain.METHOD, methodName), parameterTypes);
m.setAccessible(true);
return m;
}
catch (Exception e)
{
throw new UnableToFindMethodException(e);
}
}
/**
* Finds a constructor with the specified parameter types in the given class and makes it accessible.
* Note: For performance, store the returned value and avoid calling this repeatedly.
* <p>
* Throws an exception if the constructor is not found.
*
* @param clazz The class to find the constructor in.
* @param parameterTypes The parameter types of the constructor.
* @param <T> The type.
* @return The constructor with the specified parameters in the given class.
* @throws NullPointerException If {@code clazz} is null.
* @throws NullPointerException If {@code parameterTypes} is null.
* @throws UnknownConstructorException If the constructor could not be found.
*/
@NotNull
public static <T> Constructor<T> findConstructor(@NotNull final Class<T> clazz, @NotNull final Class<?>... parameterTypes)
{
Preconditions.checkNotNull(clazz, "Class to find constructor on cannot be null.");
Preconditions.checkNotNull(parameterTypes, "Parameter types of constructor to find cannot be null.");
try
{
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
return constructor;
}
catch (final NoSuchMethodException e)
{
final StringBuilder desc = new StringBuilder();
desc.append(clazz.getSimpleName());
StringJoiner joiner = new StringJoiner(", ", "(", ")");
for (Class<?> type : parameterTypes)
{
joiner.add(type.getSimpleName());
}
desc.append(joiner);
throw new UnknownConstructorException("Could not find constructor '" + desc.toString() + "' in " + clazz);
}
}
/**
* Finds a field with the specified name in the given class and makes it accessible.
* Note: For performance, store the returned value and avoid calling this repeatedly.
* <p>
* Throws an exception if the field is not found.
*
* @param clazz The class to find the field on.
* @param fieldName The SRG (unmapped) name of the field to find (e.g. "f_46443_").
* @param <T> The type.
* @return The constructor with the specified parameters in the given class.
* @throws NullPointerException If {@code clazz} is null.
* @throws NullPointerException If {@code fieldName} is null.
* @throws IllegalArgumentException If {@code fieldName} is empty.
* @throws UnableToFindFieldException If the field could not be found.
*/
@NotNull
public static <T> Field findField(@NotNull final Class<? super T> clazz, @NotNull final String fieldName)
{
Preconditions.checkNotNull(clazz, "Class to find field on cannot be null.");
Preconditions.checkNotNull(fieldName, "Name of field to find cannot be null.");
Preconditions.checkArgument(!fieldName.isEmpty(), "Name of field to find cannot be empty.");
try
{
Field f = clazz.getDeclaredField(remapName(INameMappingService.Domain.FIELD, fieldName));
f.setAccessible(true);
return f;
}
catch (Exception e)
{
throw new UnableToFindFieldException(e);
}
}
public static class UnableToAccessFieldException extends RuntimeException
{
private UnableToAccessFieldException(Exception e)
{
super(e);
}
}
public static class UnableToFindFieldException extends RuntimeException
{
private UnableToFindFieldException(Exception e)
{
super(e);
}
}
public static class UnableToFindMethodException extends RuntimeException
{
public UnableToFindMethodException(Throwable failed)
{
super(failed);
}
}
public static class UnknownConstructorException extends RuntimeException
{
public UnknownConstructorException(final String message)
{
super(message);
}
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common.thread;
package net.minecraftforge.fml.util.thread;
import net.minecraftforge.fml.LogicalSide;
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,14 +17,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common.thread;
package net.minecraftforge.fml.util.thread;
import net.minecraftforge.fml.LogicalSide;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ThreadFactory;
import javax.annotation.Nonnull;
/**
* A thread group and factory combination which belongs to a {@link LogicalSide}.
*/
@@ -49,7 +48,7 @@ public final class SidedThreadGroup extends ThreadGroup implements ThreadFactory
}
@Override
public Thread newThread(@Nonnull final Runnable runnable)
public Thread newThread(@NotNull final Runnable runnable)
{
return new Thread(this, runnable);
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common.thread;
package net.minecraftforge.fml.util.thread;
import net.minecraftforge.fml.LogicalSide;
+81
View File
@@ -0,0 +1,81 @@
plugins {
id 'com.github.ben-manes.versions'
id 'org.javamodularity.moduleplugin' version '1.8.3' apply false
}
apply plugin: 'java-library'
apply plugin: 'jacoco'
apply plugin: 'org.javamodularity.moduleplugin'
dependencyUpdates.rejectVersionIf { isNonStable(it.candidate.version) }
configurations.forEach{ it.transitive = false }
dependencies {
implementation('net.sf.jopt-simple:jopt-simple:5.0.4')
compileOnly('org.jetbrains:annotations:23.0.0')
api("org.ow2.asm:asm:${ASM_VERSION}")
api("org.ow2.asm:asm-tree:${ASM_VERSION}")
api("org.ow2.asm:asm-commons:${ASM_VERSION}")
api('net.minecraftforge:forgespi:4.0.+')
api('org.apache.logging.log4j:log4j-api:2.17.0')
api('org.slf4j:slf4j-api:1.8.0-beta4')
api('com.google.guava:guava:21.0')
api('com.google.code.gson:gson:2.8.9')
api('org.apache.maven:maven-artifact:3.8.1')
api('org.apache.commons:commons-lang3:3.12.0')
api('com.electronwill.night-config:core:3.6.4')
api('com.electronwill.night-config:toml:3.6.4')
api('cpw.mods:modlauncher:9.0.+')
api('net.minecraftforge:coremods:5.0.+')
implementation("cpw.mods:securejarhandler:${SECUREJARHANDLER_VERSION}")
implementation('org.apache.logging.log4j:log4j-core:2.17.0')
annotationProcessor('org.apache.logging.log4j:log4j-core:2.17.0')
implementation('net.minecraftforge:accesstransformers:8.0.4')
implementation('net.minecrell:terminalconsoleappender:1.2.0')
// implementation('org.jline:jline:3.12.+')
testCompileOnly('org.jetbrains:annotations:21.0.0')
testRuntimeOnly("cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}")
}
task sourcesJar(type: Jar) {
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
ext {
MANIFESTS = [
'/': [
'Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'Git-Commit': GIT_INFO.abbreviatedId,
'Git-Branch': GIT_INFO.branch,
'Build-Number': "${System.getenv('BUILD_NUMBER')?:0}",
] as LinkedHashMap,
'net/minecraftforge/fml/loading/': [
'Specification-Title': 'FMLLoader',
'Specification-Vendor': 'Forge Development LLC',
'Specification-Version': '1',
'Implementation-Title': 'FML Loader',
'Implementation-Version': '1.0',
'Implementation-Vendor': 'Forge'
] as LinkedHashMap
]
}
jar.doFirst {
MANIFESTS.each { pkg, values ->
manifest.attributes(values, pkg)
}
}
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:unchecked'
}
artifacts {
archives jar
archives sourcesJar
}
publishing.publications.mavenJava(MavenPublication) {
from components.java
artifact sourcesJar
}
@@ -0,0 +1,134 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.common.asm;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.EnumSet;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
/**
* Implements getType() in CapabilityToken subclasses.
*
* Using the class's signature to determine the generic type of TypeToken, and then implements getType() using that value.
* <pre>
* Example:
*
* <code>new CapabilityToken&lt;String>(){}</code>
* Has the signature <code>"CapabilityToken&lt;Ljava/lang/String;>"</code>
*
* Implements the method:
* <code>public String getType() {
* return "java/lang/String";
* }</code>
* </pre>
*/
public class CapabilityTokenSubclass implements ILaunchPluginService {
private final String FUNC_NAME = "getType";
private final String FUNC_DESC = "()Ljava/lang/String;";
private final String CAP_INJECT = "net/minecraftforge/common/capabilities/CapabilityToken"; //Don't directly reference this to prevent class loading.
@Override
public String name() {
return "capability_token_subclass";
}
private static final EnumSet<Phase> YAY = EnumSet.of(Phase.AFTER);
private static final EnumSet<Phase> NAY = EnumSet.noneOf(Phase.class);
@Override
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty)
{
return isEmpty ? NAY : YAY;
}
@Override
public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason)
{
if (CAP_INJECT.equals(classNode.name))
{
for (MethodNode mtd : classNode.methods)
{
if (FUNC_NAME.equals(mtd.name) && FUNC_DESC.equals(mtd.desc))
{
mtd.access &= ~Opcodes.ACC_FINAL; // We have it final in code so people don't override it, cuz that'd be stupid, and make our transformer more complicated.
}
}
return ComputeFlags.SIMPLE_REWRITE;
}
else if (CAP_INJECT.equals(classNode.superName))
{
Holder cls = new Holder();
SignatureReader reader = new SignatureReader(classNode.signature); // Having a node version of this would probably be useful.
reader.accept(new SignatureVisitor(Opcodes.ASM9)
{
Deque<String> stack = new ArrayDeque<>();
@Override
public void visitClassType(final String name)
{
stack.push(name);
}
@Override
public void visitInnerClassType(final String name)
{
stack.push(stack.pop() + '$' + name);
}
@Override
public void visitEnd()
{
var val = stack.pop();
if (!stack.isEmpty() && CAP_INJECT.equals(stack.peek()))
cls.value = val;
}
});
if (cls.value == null)
throw new IllegalStateException("Could not find signature for CapabilityToken on " + classNode.name + " from " + classNode.signature);
var mtd = classNode.visitMethod(Opcodes.ACC_PUBLIC, FUNC_NAME, FUNC_DESC, null, new String[0]);
mtd.visitLdcInsn(cls.value);
mtd.visitInsn(Opcodes.ARETURN);
mtd.visitEnd();
return ComputeFlags.COMPUTE_MAXS;
}
else
{
return ComputeFlags.NO_REWRITE;
}
}
private static class Holder {
String value;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,9 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.asm;
package net.minecraftforge.fml.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -73,9 +72,9 @@ public class ObjectHolderDefinalize implements ILaunchPluginService {
}
@Override
public boolean processClass(Phase phase, ClassNode classNode, Type classType)
public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason)
{
AtomicBoolean changes = new AtomicBoolean();
final AtomicBoolean changes = new AtomicBoolean();
//Must be public static finals, and non-array objects
final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
@@ -107,7 +106,7 @@ public class ObjectHolderDefinalize implements ILaunchPluginService {
changes.compareAndSet(false, prev != f.access);
});
}
return changes.get();
return changes.get() ? ComputeFlags.SIMPLE_REWRITE : ComputeFlags.NO_REWRITE;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,9 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.asm;
package net.minecraftforge.fml.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Collectors;
@@ -69,10 +68,10 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
}
@Override
public boolean processClass(Phase phase, ClassNode classNode, Type classType)
public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason)
{
if ((classNode.access & Opcodes.ACC_ENUM) == 0)
return false;
return ComputeFlags.NO_REWRITE;
Type array = Type.getType("[" + classType.getDescriptor());
final int flags = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC;
@@ -80,7 +79,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
FieldNode values = classNode.fields.stream().filter(f -> f.desc.contentEquals(array.getDescriptor()) && ((f.access & flags) == flags)).findFirst().orElse(null);
if (!classNode.interfaces.contains(MARKER_IFACE.getInternalName())) {
return false;
return ComputeFlags.NO_REWRITE;
}
//Static methods named "create" with first argument as a string
@@ -98,8 +97,8 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
if (args.length == 0 || !args[0].equals(STRING)) {
LOGGER.fatal(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method without String as first parameter:\n");
sb.append(" Enum: " + classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(mtd.name + mtd.desc).append("\n");
sb.append(" Enum: ").append(classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(mtd.name).append(mtd.desc).append("\n");
}));
throw new IllegalStateException("Enum has create method without String as first parameter: " + mtd.name + mtd.desc);
}
@@ -108,8 +107,8 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
if (!ret.equals(classType)) {
LOGGER.fatal(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method with incorrect return type:\n");
sb.append(" Enum: " + classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(mtd.name + mtd.desc).append("\n");
sb.append(" Enum: ").append(classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(mtd.name).append(mtd.desc).append("\n");
sb.append(" Found: ").append(ret.getClassName()).append(", Expected: ").append(classType.getClassName());
}));
throw new IllegalStateException("Enum has create method with incorrect return type: " + mtd.name + mtd.desc);
@@ -215,12 +214,15 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
//EnumHelper.cleanEnumCache(ThisType.class)
ins.visitLdcInsn(classType);
ins.invokestatic(UNSAFE_HACKS.getInternalName(), "cleanEnumCache", CLEAN_DESC, false);
//init ret
ins.load(vars, classType);
ins.invokeinterface(MARKER_IFACE.getInternalName(), "init", "()V");
//return ret
ins.load(vars, classType);
ins.areturn(classType);
}
});
return true;
return ComputeFlags.COMPUTE_FRAMES;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,8 @@ import org.apache.logging.log4j.util.StringBuilderFormattable;
import java.util.function.Consumer;
public class AdvancedLogMessageAdapter implements Message, StringBuilderFormattable {
private static final long serialVersionUID = -8291754833965087436L;
private static final Object[] EMPTY = new Object[0];
private final Consumer<StringBuilder> logMessageBuilder;
@@ -0,0 +1,48 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.loading;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class BackgroundWaiter {
private static ExecutorService runner = Executors.newSingleThreadExecutor();
public static void runAndTick(Runnable r, Runnable tick) {
final Future<?> work = runner.submit(r);
do {
tick.run();
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {
}
} while (!work.isDone());
try {
runner.shutdown();
work.get();
} catch (ExecutionException ee) {
throw new RuntimeException(ee.getCause());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,6 +19,8 @@
package net.minecraftforge.fml.loading;
import net.minecraftforge.forgespi.language.IModInfo;
import java.util.List;
/**
@@ -27,12 +29,17 @@ import java.util.List;
*/
public class EarlyLoadingException extends RuntimeException {
public static class ExceptionData {
private final IModInfo modInfo;
private final String i18message;
private final Object[] args;
public ExceptionData(final String message, Object... args) {
this(message, null, args);
}
public ExceptionData(final String message, final IModInfo modInfo, Object... args) {
this.i18message = message;
this.modInfo = modInfo;
this.args = args;
}
@@ -43,6 +50,10 @@ public class EarlyLoadingException extends RuntimeException {
public Object[] getArgs() {
return args;
}
public IModInfo getModInfo() {
return modInfo;
}
}
private final List<ExceptionData> errorMessages;
@@ -0,0 +1,102 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.loading;
import com.electronwill.nightconfig.core.ConfigSpec;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.file.FileNotFoundAction;
import com.electronwill.nightconfig.core.io.ParsingException;
import com.electronwill.nightconfig.core.io.WritingMode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class FMLConfig
{
private static final Logger LOGGER = LogManager.getLogger();
private static FMLConfig INSTANCE = new FMLConfig();
private static ConfigSpec configSpec = new ConfigSpec();
static {
configSpec.define("splashscreen", Boolean.TRUE);
configSpec.define("maxThreads", -1);
configSpec.define("versionCheck", Boolean.TRUE);
configSpec.define("defaultConfigPath", "defaultconfigs");
}
private CommentedFileConfig configData;
private void loadFrom(final Path configFile)
{
configData = CommentedFileConfig.builder(configFile).sync()
.onFileNotFound(FileNotFoundAction.copyData(Objects.requireNonNull(getClass().getResourceAsStream("/META-INF/defaultfmlconfig.toml"))))
.autosave().autoreload()
.writingMode(WritingMode.REPLACE)
.build();
try
{
configData.load();
}
catch (ParsingException e)
{
throw new RuntimeException("Failed to load FML config from " + configFile.toString(), e);
}
if (!configSpec.isCorrect(configData)) {
LOGGER.warn(CORE, "Configuration file {} is not correct. Correcting", configFile);
configSpec.correct(configData, (action, path, incorrectValue, correctedValue) ->
LOGGER.warn(CORE, "Incorrect key {} was corrected from {} to {}", path, incorrectValue, correctedValue));
}
configData.save();
}
public static void load()
{
final Path configFile = FMLPaths.FMLCONFIG.get();
INSTANCE.loadFrom(configFile);
LOGGER.trace(CORE, "Loaded FML config from {}", FMLPaths.FMLCONFIG.get());
LOGGER.trace(CORE, "Splash screen is {}", FMLConfig::splashScreenEnabled);
LOGGER.trace(CORE, "Max threads for mod loading computed at {}", FMLConfig::loadingThreadCount);
LOGGER.trace(CORE, "Version check is {}", FMLConfig::runVersionCheck);
LOGGER.trace(CORE, "Default config paths at {}", FMLConfig::defaultConfigPath);
FMLPaths.getOrCreateGameRelativePath(Paths.get(FMLConfig.defaultConfigPath()), "default config directory");
}
public static boolean splashScreenEnabled() {
return INSTANCE.configData.<Boolean>getOptional("splashscreen").orElse(Boolean.FALSE);
}
public static int loadingThreadCount() {
int val = INSTANCE.configData.<Integer>getOptional("maxThreads").orElse(-1);
if (val <= 0) return Runtime.getRuntime().availableProcessors();
return val;
}
public static boolean runVersionCheck() {
return INSTANCE.configData.<Boolean>getOptional("versionCheck").orElse(Boolean.TRUE);
}
public static String defaultConfigPath() {
return INSTANCE.configData.<String>getOptional("defaultConfigPath").orElse("defaultconfigs");
}
}
@@ -0,0 +1,44 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.TypesafeMap;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.forgespi.Environment;
import java.util.function.Supplier;
public class FMLEnvironment
{
public static final Dist dist = FMLLoader.getDist();
public static final String naming = FMLLoader.getNaming();
public static final boolean production = FMLLoader.isProduction() || System.getProperties().containsKey("production");
public static final boolean secureJarsEnabled = FMLLoader.isSecureJarEnabled();
static void setupInteropEnvironment(IEnvironment environment) {
environment.computePropertyIfAbsent(IEnvironment.Keys.NAMING.get(), v->naming);
environment.computePropertyIfAbsent(Environment.Keys.DIST.get(), v->dist);
}
public static class Keys {
public static final Supplier<TypesafeMap.Key<ClassLoader>> LOCATORCLASSLOADER = IEnvironment.buildKey("LOCATORCLASSLOADER",ClassLoader.class);
}
}
@@ -0,0 +1,273 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.Launcher;
import cpw.mods.modlauncher.api.*;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModValidator;
import net.minecraftforge.accesstransformer.service.AccessTransformerService;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.progress.EarlyProgressVisualization;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.fml.loading.targets.CommonLaunchHandler;
import net.minecraftforge.forgespi.Environment;
import net.minecraftforge.forgespi.coremod.ICoreModProvider;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class FMLLoader
{
private static final Logger LOGGER = LogManager.getLogger();
private static AccessTransformerService accessTransformer;
private static ModDiscoverer modDiscoverer;
private static ICoreModProvider coreModProvider;
private static ILaunchPluginService eventBus;
private static LanguageLoadingProvider languageLoadingProvider;
private static Dist dist;
private static String naming;
private static LoadingModList loadingModList;
private static RuntimeDistCleaner runtimeDistCleaner;
private static Path gamePath;
private static VersionInfo versionInfo;
private static String launchHandlerName;
private static CommonLaunchHandler commonLaunchHandler;
public static Runnable progressWindowTick;
private static ModValidator modValidator;
public static BackgroundScanHandler backgroundScanHandler;
private static boolean production;
private static IModuleLayerManager moduleLayerManager;
static void onInitialLoad(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
{
final String version = LauncherVersion.getVersion();
LOGGER.debug(CORE,"FML {} loading", version);
final Package modLauncherPackage = ITransformationService.class.getPackage();
LOGGER.debug(CORE,"FML found ModLauncher version : {}", modLauncherPackage.getImplementationVersion());
if (!modLauncherPackage.isCompatibleWith("4.0")) {
LOGGER.fatal(CORE,"Found incompatible ModLauncher specification : {}, version {} from {}", modLauncherPackage.getSpecificationVersion(), modLauncherPackage.getImplementationVersion(), modLauncherPackage.getImplementationVendor());
throw new IncompatibleEnvironmentException("Incompatible modlauncher found "+modLauncherPackage.getSpecificationVersion());
}
accessTransformer = (AccessTransformerService) environment.findLaunchPlugin("accesstransformer").orElseThrow(()-> {
LOGGER.fatal(CORE,"Access Transformer library is missing, we need this to run");
return new IncompatibleEnvironmentException("Missing AccessTransformer, cannot run");
});
final Package atPackage = accessTransformer.getClass().getPackage();
LOGGER.debug(CORE,"FML found AccessTransformer version : {}", atPackage.getImplementationVersion());
if (!atPackage.isCompatibleWith("1.0")) {
LOGGER.fatal(CORE,"Found incompatible AccessTransformer specification : {}, version {} from {}", atPackage.getSpecificationVersion(), atPackage.getImplementationVersion(), atPackage.getImplementationVendor());
throw new IncompatibleEnvironmentException("Incompatible accesstransformer found "+atPackage.getSpecificationVersion());
}
eventBus = environment.findLaunchPlugin("eventbus").orElseThrow(()-> {
LOGGER.fatal(CORE,"Event Bus library is missing, we need this to run");
return new IncompatibleEnvironmentException("Missing EventBus, cannot run");
});
final Package eventBusPackage = eventBus.getClass().getPackage();
LOGGER.debug(CORE,"FML found EventBus version : {}", eventBusPackage.getImplementationVersion());
if (!eventBusPackage.isCompatibleWith("1.0")) {
LOGGER.fatal(CORE,"Found incompatible EventBus specification : {}, version {} from {}", eventBusPackage.getSpecificationVersion(), eventBusPackage.getImplementationVersion(), eventBusPackage.getImplementationVendor());
throw new IncompatibleEnvironmentException("Incompatible eventbus found "+eventBusPackage.getSpecificationVersion());
}
runtimeDistCleaner = (RuntimeDistCleaner)environment.findLaunchPlugin("runtimedistcleaner").orElseThrow(()-> {
LOGGER.fatal(CORE,"Dist Cleaner is missing, we need this to run");
return new IncompatibleEnvironmentException("Missing DistCleaner, cannot run!");
});
LOGGER.debug(CORE, "Found Runtime Dist Cleaner");
var coreModProviders = ServiceLoaderUtils.streamWithErrorHandling(ServiceLoader.load(FMLLoader.class.getModule().getLayer(), ICoreModProvider.class), sce -> LOGGER.fatal(CORE, "Failed to load a coremod library, expect problems", sce)).toList();
if (coreModProviders.isEmpty()) {
LOGGER.fatal(CORE, "Found no coremod provider. Cannot run");
throw new IncompatibleEnvironmentException("No coremod library found");
} else if (coreModProviders.size() > 1) {
LOGGER.fatal(CORE, "Found multiple coremod providers : {}. Cannot run", coreModProviders.stream().map(p -> p.getClass().getName()).collect(Collectors.toList()));
throw new IncompatibleEnvironmentException("Multiple coremod libraries found");
}
coreModProvider = coreModProviders.get(0);
final Package coremodPackage = coreModProvider.getClass().getPackage();
LOGGER.debug(CORE,"FML found CoreMod version : {}", coremodPackage.getImplementationVersion());
LOGGER.debug(CORE, "Found ForgeSPI package implementation version {}", Environment.class.getPackage().getImplementationVersion());
LOGGER.debug(CORE, "Found ForgeSPI package specification {}", Environment.class.getPackage().getSpecificationVersion());
if (Integer.parseInt(Environment.class.getPackage().getSpecificationVersion()) < 2) {
LOGGER.fatal(CORE, "Found an out of date ForgeSPI implementation: {}, loading cannot continue", Environment.class.getPackage().getSpecificationVersion());
throw new IncompatibleEnvironmentException("ForgeSPI is out of date, we cannot continue");
}
try {
Class.forName("com.electronwill.nightconfig.core.Config", false, environment.getClass().getClassLoader());
Class.forName("com.electronwill.nightconfig.toml.TomlFormat", false, environment.getClass().getClassLoader());
} catch (ClassNotFoundException e) {
LOGGER.fatal(CORE, "Failed to load NightConfig");
throw new IncompatibleEnvironmentException("Missing NightConfig");
}
}
static void setupLaunchHandler(final IEnvironment environment, final Map<String, Object> arguments)
{
final String launchTarget = environment.getProperty(IEnvironment.Keys.LAUNCHTARGET.get()).orElse("MISSING");
arguments.put("launchTarget", launchTarget);
final Optional<ILaunchHandlerService> launchHandler = environment.findLaunchHandler(launchTarget);
LOGGER.debug(CORE, "Using {} as launch service", launchTarget);
if (launchHandler.isEmpty()) {
LOGGER.fatal(CORE,"Missing LaunchHandler {}, cannot continue", launchTarget);
throw new RuntimeException("Missing launch handler: " + launchTarget);
}
if (!(launchHandler.get() instanceof CommonLaunchHandler)) {
LOGGER.fatal(CORE, "Incompatible Launch handler found - type {}, cannot continue", launchHandler.get().getClass().getName());
throw new RuntimeException("Incompatible launch handler found");
}
commonLaunchHandler = (CommonLaunchHandler)launchHandler.get();
launchHandlerName = launchHandler.get().name();
gamePath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".").toAbsolutePath());
naming = commonLaunchHandler.getNaming();
dist = commonLaunchHandler.getDist();
production = commonLaunchHandler.isProduction();
versionInfo = new VersionInfo(arguments);
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Early Loading!"));
accessTransformer.getExtension().accept(Pair.of(naming, "srg"));
LOGGER.debug(CORE,"Received command line version data : {}", versionInfo);
runtimeDistCleaner.getExtension().accept(dist);
}
public static List<ITransformationService.Resource> beginModScan(final Map<String,?> arguments)
{
LOGGER.debug(SCAN,"Scanning for Mod Locators");
modDiscoverer = new ModDiscoverer(arguments);
modValidator = modDiscoverer.discoverMods();
var pluginResources = modValidator.getPluginResources();
return List.of(pluginResources);
}
public static List<ITransformationService.Resource> completeScan(IModuleLayerManager layerManager) {
progressWindowTick = EarlyProgressVisualization.INSTANCE.accept(dist, commonLaunchHandler.isData(), versionInfo.mcVersion());
moduleLayerManager = layerManager;
languageLoadingProvider = new LanguageLoadingProvider();
backgroundScanHandler = modValidator.stage2Validation();
loadingModList = backgroundScanHandler.getLoadingModList();
return List.of(modValidator.getModResources());
}
public static ICoreModProvider getCoreModProvider() {
return coreModProvider;
}
public static LanguageLoadingProvider getLanguageLoadingProvider()
{
return languageLoadingProvider;
}
static ModDiscoverer getModDiscoverer() {
return modDiscoverer;
}
public static CommonLaunchHandler getLaunchHandler() {
return commonLaunchHandler;
}
public static void addAccessTransformer(Path atPath, ModFile modName)
{
LOGGER.debug(SCAN, "Adding Access Transformer in {}", modName.getFilePath());
accessTransformer.offerResource(atPath, modName.getFileName());
}
public static Dist getDist()
{
return dist;
}
public static void beforeStart(ClassLoader launchClassLoader)
{
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Launching minecraft"));
progressWindowTick.run();
}
public static LoadingModList getLoadingModList()
{
return loadingModList;
}
public static Path getGamePath()
{
return gamePath;
}
public static String getNaming() {
return naming;
}
public static Optional<BiFunction<INameMappingService.Domain, String, String>> getNameFunction(final String naming) {
return Launcher.INSTANCE.environment().findNameMapping(naming);
}
public static String getLauncherInfo() {
return Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.MLIMPL_VERSION.get()).orElse("MISSING");
}
public static List<Map<String, String>> modLauncherModList() {
return Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.MODLIST.get()).orElseGet(Collections::emptyList);
}
public static String launcherHandlerName() {
return launchHandlerName;
}
public static boolean isProduction() {
return production;
}
public static boolean isSecureJarEnabled() {
return true;
}
public static ModuleLayer getGameLayer() {
return moduleLayerManager.getLayer(IModuleLayerManager.Layer.GAME).orElseThrow();
}
public static VersionInfo versionInfo() {
return versionInfo;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -50,16 +50,16 @@ public enum FMLPaths
this.isDirectory = true;
}
private Path computePath(String... path)
{
return Paths.get(path[0], Arrays.copyOfRange(path, 1, path.length));
}
FMLPaths(boolean isDir, FMLPaths parent, String... path) {
this.relativePath = parent.relativePath.resolve(computePath(path));
this.isDirectory = isDir;
}
private Path computePath(String... path)
{
return Paths.get(path[0], Arrays.copyOfRange(path, 1, path.length));
}
public static void setup(IEnvironment env) {
final Path rootPath = env.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElseThrow(() -> new RuntimeException("No game path found"));
@@ -79,6 +79,10 @@ public enum FMLPaths
}
}
public static Path getOrCreateGameRelativePath(Path path, String name) {
return FileUtils.getOrCreateDirectory(FMLPaths.GAMEDIR.get().resolve(path), name);
}
public Path relative() {
return relativePath;
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,25 +19,27 @@
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.api.IEnvironment;
import cpw.mods.modlauncher.api.ITransformationService;
import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException;
import cpw.mods.modlauncher.api.*;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionSpecBuilder;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.forgespi.Environment;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class FMLServiceProvider implements ITransformationService
{
private static final Logger LOGGER = LogManager.getLogger();
private ArgumentAcceptingOptionSpec<String> modsOption;
private ArgumentAcceptingOptionSpec<String> modListsOption;
@@ -57,6 +59,12 @@ public class FMLServiceProvider implements ITransformationService
private String targetForgeGroup;
private Map<String, Object> arguments;
public FMLServiceProvider()
{
final String markerselection = System.getProperty("forge.logging.markers", "");
Arrays.stream(markerselection.split(",")).forEach(marker -> System.setProperty("forge.logging.marker." + marker.toLowerCase(Locale.ROOT), "ACCEPT"));
}
@Override
public String name()
{
@@ -69,6 +77,8 @@ public class FMLServiceProvider implements ITransformationService
FMLPaths.setup(environment);
LOGGER.debug(CORE, "Loading configuration");
FMLConfig.load();
LOGGER.debug(CORE, "Preparing ModFile");
environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), k->ModFile::new);
arguments = new HashMap<>();
arguments.put("modLists", modListsArgumentList);
arguments.put("mods", modsArgumentList);
@@ -85,17 +95,22 @@ public class FMLServiceProvider implements ITransformationService
}
@Override
public void beginScanning(final IEnvironment environment) {
public List<Resource> beginScanning(final IEnvironment environment) {
LOGGER.debug(CORE,"Initiating mod scan");
FMLLoader.beginModScan(arguments);
return FMLLoader.beginModScan(arguments);
}
@Override
public List<Resource> completeScan(final IModuleLayerManager layerManager) {
return FMLLoader.completeScan(layerManager);
}
@Override
public void onLoad(IEnvironment environment, Set<String> otherServices) throws IncompatibleEnvironmentException
{
LOGGER.debug("Injecting tracing printstreams for STDOUT/STDERR.");
System.setOut(new TracingPrintStream(LogManager.getLogger("STDOUT"), System.out));
System.setErr(new TracingPrintStream(LogManager.getLogger("STDERR"), System.err));
// LOGGER.debug("Injecting tracing printstreams for STDOUT/STDERR.");
// System.setOut(new TracingPrintStream(LogManager.getLogger("STDOUT"), System.out));
// System.setErr(new TracingPrintStream(LogManager.getLogger("STDERR"), System.err));
FMLLoader.onInitialLoad(environment, otherServices);
}
@@ -125,9 +140,8 @@ public class FMLServiceProvider implements ITransformationService
targetMcpMappings = option.value(mappingsOption);
}
@Nonnull
@Override
public List<ITransformer> transformers()
public @NotNull List<ITransformer> transformers()
{
LOGGER.debug(CORE, "Loading coremod transformers");
return new ArrayList<>(FMLLoader.getCoreModProvider().getCoreModTransformers());
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,10 @@
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.ServiceLoaderStreamUtils;
import cpw.mods.modlauncher.Launcher;
import cpw.mods.modlauncher.api.IModuleLayerManager;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.forgespi.language.IModLanguageProvider;
import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
@@ -29,25 +32,27 @@ import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.VersionRange;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.rethrowFunction;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class LanguageLoadingProvider
{
private static final Logger LOGGER = LogManager.getLogger();
private final LanguageClassLoader languageClassLoader;
private final List<IModLanguageProvider> languageProviders = new ArrayList<>();
private final ServiceLoader<IModLanguageProvider> serviceLoader;
private final Map<String, ModLanguageWrapper> languageProviderMap = new HashMap<>();
@@ -58,8 +63,11 @@ public class LanguageLoadingProvider
languageProviders.forEach(consumer);
}
private static class ModLanguageWrapper {
public <T> Stream<T> applyForEach(final Function<IModLanguageProvider, T> function) {
return languageProviders.stream().map(function);
}
private static class ModLanguageWrapper {
private final IModLanguageProvider modLanguageProvider;
private final ArtifactVersion version;
@@ -80,26 +88,14 @@ public class LanguageLoadingProvider
}
private static class LanguageClassLoader extends URLClassLoader
{
public LanguageClassLoader() {
super(new URL[0]);
}
@Override
public void addURL(final URL url) {
LOGGER.debug(CORE, "Adding {} to languageloader classloader", url);
super.addURL(url);
}
}
LanguageLoadingProvider() {
languageClassLoader = new LanguageClassLoader();
serviceLoader = ServiceLoader.load(IModLanguageProvider.class, languageClassLoader);
var sl = Launcher.INSTANCE.environment().findModuleLayerManager().flatMap(lm->lm.getLayer(IModuleLayerManager.Layer.PLUGIN)).orElseThrow();
serviceLoader = ServiceLoader.load(sl, IModLanguageProvider.class);
loadLanguageProviders();
}
private void loadLanguageProviders() {
LOGGER.debug(CORE, "Found {} language providers", ServiceLoaderStreamUtils.toList(serviceLoader).size());
LOGGER.debug(CORE, "Found {} language providers", ServiceLoaderUtils.streamServiceLoader(()->serviceLoader, sce->LOGGER.fatal("Problem with language loaders")).count());
serviceLoader.forEach(languageProviders::add);
languageProviders.forEach(lp -> {
@@ -110,12 +106,13 @@ public class LanguageLoadingProvider
throw new RuntimeException("Huh?", e);
}
Optional<String> implementationVersion = JarVersionLookupHandler.getImplementationVersion(lp.getClass());
String impl = implementationVersion.orElse(Files.isDirectory(lpPath) ? FMLLoader.forgeVersion.split("\\.")[0] : null);
String impl = implementationVersion.orElse(Files.isDirectory(lpPath) ? FMLLoader.versionInfo().forgeVersion().split("\\.")[0] : null);
if (impl == null) {
LOGGER.fatal(CORE, "Found unversioned language provider {}", lp.name());
throw new RuntimeException("Failed to find implementation version for language provider "+ lp.name());
}
LOGGER.debug(CORE, "Found language provider {}, version {}", lp.name(), impl);
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Loaded language provider "+lp.name()+ " " + impl));
languageProviderMap.put(lp.name(), new ModLanguageWrapper(lp, new DefaultArtifactVersion(impl)));
});
}
@@ -134,7 +131,7 @@ public class LanguageLoadingProvider
private void addLanguagePaths(final Stream<Path> langPaths) {
languageProviders.clear();
languageProviderMap.clear();
langPaths.peek(languagePaths::add).map(Path::toFile).map(File::toURI).map(rethrowFunction(URI::toURL)).forEach(languageClassLoader::addURL);
// langPaths.peek(languagePaths::add).map(Path::toFile).map(File::toURI).map(rethrowFunction(URI::toURL)).forEach(languageClassLoader::addURL);
}
public void addAdditionalLanguages(List<ModFile> modFiles)
@@ -154,11 +151,11 @@ public class LanguageLoadingProvider
final String languageFileName = mf.getLocator() instanceof ExplodedDirectoryLocator ? "in-development" : mf.getFileName();
final ModLanguageWrapper mlw = languageProviderMap.get(modLoader);
if (mlw == null) {
LOGGER.error("Missing language {} version {} wanted by {}", modLoader, modLoaderVersion, languageFileName);
LOGGER.error(LOADING,"Missing language {} version {} wanted by {}", modLoader, modLoaderVersion, languageFileName);
throw new EarlyLoadingException("Missing language "+modLoader, null, Collections.singletonList(new EarlyLoadingException.ExceptionData("fml.language.missingversion", modLoader, modLoaderVersion, languageFileName, "null")));
}
if (!modLoaderVersion.containsVersion(mlw.getVersion())) {
LOGGER.error("Missing language {} version {} wanted by {}, found {}", modLoader, modLoaderVersion, languageFileName, mlw.getVersion());
if (!VersionSupportMatrix.testVersionSupportMatrix(modLoaderVersion, modLoader, "languageloader", (llid, range) -> range.containsVersion(mlw.getVersion()))) {
LOGGER.error(LOADING,"Missing language {} version {} wanted by {}, found {}", modLoader, modLoaderVersion, languageFileName, mlw.getVersion());
throw new EarlyLoadingException("Missing language "+ modLoader + " matching range "+modLoaderVersion + " found "+mlw.getVersion(), null, Collections.singletonList(new EarlyLoadingException.ExceptionData("fml.language.missingversion", modLoader, modLoaderVersion, languageFileName, mlw.getVersion())));
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -0,0 +1,67 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.loading;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Files;
import java.nio.file.Path;
public class LibraryFinder {
private static final Logger LOGGER = LogManager.getLogger();
private static Path libsPath;
static Path findLibsPath() {
if (libsPath == null) {
libsPath = Path.of(System.getProperty("libraryDirectory","crazysnowmannonsense/cheezwhizz"));
if (!Files.isDirectory(libsPath)) {
throw new IllegalStateException("Missing libraryDirectory system property, cannot continue");
}
}
return libsPath;
}
static Path getForgeLibraryPath(final String mcVersion, final String forgeVersion, final String forgeGroup) {
Path forgePath = findLibsPath().resolve(MavenCoordinateResolver.get(forgeGroup, "forge", "", "universal", mcVersion+"-"+forgeVersion));
LOGGER.debug(LogMarkers.CORE, "Found forge path {} is {}", forgePath, pathStatus(forgePath));
return forgePath;
}
static String pathStatus(final Path path) {
return Files.exists(path) ? "present" : "missing";
}
static Path[] getMCPaths(final String mcVersion, final String mcpVersion, final String forgeVersion, final String forgeGroup, final String type) {
Path srgMcPath = findLibsPath().resolve(MavenCoordinateResolver.get("net.minecraft", type, "", "srg", mcVersion+"-"+mcpVersion));
Path mcExtrasPath = findLibsPath().resolve(MavenCoordinateResolver.get("net.minecraft", type, "", "extra", mcVersion+"-"+mcpVersion));
Path patchedBinariesPath = findLibsPath().resolve(MavenCoordinateResolver.get(forgeGroup, "forge", "", type, mcVersion+"-"+forgeVersion));
LOGGER.debug(LogMarkers.CORE,"SRG MC at {} is {}", srgMcPath.toString(), pathStatus(srgMcPath));
LOGGER.debug(LogMarkers.CORE,"MC Extras at {} is {}", mcExtrasPath.toString(), pathStatus(mcExtrasPath));
LOGGER.debug(LogMarkers.CORE,"Forge patches at {} is {}", patchedBinariesPath.toString(), pathStatus(patchedBinariesPath));
return new Path[] { patchedBinariesPath, mcExtrasPath, srgMcPath };
}
public static Path findPathForMaven(final String group, final String artifact, final String extension, final String classifier, final String version) {
return findLibsPath().resolve(MavenCoordinateResolver.get(group, artifact, extension, classifier, version));
}
public static Path findPathForMaven(final String maven) {
return findLibsPath().resolve(MavenCoordinateResolver.get(maven));
}
}
@@ -0,0 +1,178 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml.loading;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
/**
* Master list of all mods <em>in the loading context. This class cannot refer outside the
* loading package</em>
*/
public class LoadingModList
{
private static LoadingModList INSTANCE;
private final List<ModFileInfo> modFiles;
private final List<ModInfo> sortedList;
private final Map<String, ModFileInfo> fileById;
private final List<EarlyLoadingException> preLoadErrors;
private List<ModFile> brokenFiles;
private LoadingModList(final List<ModFile> modFiles, final List<ModInfo> sortedList)
{
this.modFiles = modFiles.stream()
.map(ModFile::getModFileInfo)
.map(ModFileInfo.class::cast)
.collect(Collectors.toList());
this.sortedList = sortedList.stream()
.map(ModInfo.class::cast)
.collect(Collectors.toList());
this.fileById = this.modFiles.stream()
.map(ModFileInfo::getMods)
.flatMap(Collection::stream)
.map(ModInfo.class::cast)
.collect(Collectors.toMap(ModInfo::getModId, ModInfo::getOwningFile));
this.preLoadErrors = new ArrayList<>();
}
public static LoadingModList of(List<ModFile> modFiles, List<ModInfo> sortedList, final EarlyLoadingException earlyLoadingException)
{
INSTANCE = new LoadingModList(modFiles, sortedList);
if (earlyLoadingException != null)
{
INSTANCE.preLoadErrors.add(earlyLoadingException);
}
return INSTANCE;
}
public static LoadingModList get() {
return INSTANCE;
}
public void addCoreMods()
{
modFiles.stream()
.map(ModFileInfo::getFile)
.map(ModFile::getCoreMods)
.flatMap(List::stream)
.forEach(FMLLoader.getCoreModProvider()::addCoreMod);
}
public void addAccessTransformers()
{
modFiles.stream()
.map(ModFileInfo::getFile)
.forEach(mod -> mod.getAccessTransformer().ifPresent(path -> FMLLoader.addAccessTransformer(path, mod)));
}
public void addForScanning(BackgroundScanHandler backgroundScanHandler)
{
backgroundScanHandler.setLoadingModList(this);
modFiles.stream()
.map(ModFileInfo::getFile)
.forEach(backgroundScanHandler::submitForScanning);
}
public List<ModFileInfo> getModFiles()
{
return modFiles;
}
public Path findResource(final String className)
{
for (ModFileInfo mf : modFiles) {
final Path resource = mf.getFile().findResource(className);
if (Files.exists(resource)) return resource;
}
return null;
}
public Enumeration<URL> findAllURLsForResource(final String resName) {
final String resourceName;
// strip a leading slash
if (resName.startsWith("/")) {
resourceName = resName.substring(1);
} else {
resourceName = resName;
}
return new Enumeration<URL>() {
private final Iterator<ModFileInfo> modFileIterator = modFiles.iterator();
private URL next;
@Override
public boolean hasMoreElements() {
if (next!=null) return true;
next = findNextURL();
return next != null;
}
@Override
public URL nextElement() {
if (next == null) {
next = findNextURL();
if (next == null) throw new NoSuchElementException();
}
URL result = next;
next = null;
return result;
}
private URL findNextURL() {
while (modFileIterator.hasNext()) {
final ModFileInfo next = modFileIterator.next();
final Path resource = next.getFile().findResource(resourceName);
if (Files.exists(resource)) {
return LamdbaExceptionUtils.uncheck(()->new URL("modjar://" + next.getMods().get(0).getModId() + "/" + resourceName));
}
}
return null;
}
};
}
public ModFileInfo getModFileById(String modid)
{
return this.fileById.get(modid);
}
public List<ModInfo> getMods()
{
return this.sortedList;
}
public List<EarlyLoadingException> getErrors() {
return preLoadErrors;
}
public void setBrokenFiles(final List<ModFile> brokenFiles) {
this.brokenFiles = brokenFiles;
}
public List<ModFile> getBrokenFiles() {
return this.brokenFiles;
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,5 +27,4 @@ public class LogMarkers {
public static final Marker LOADING = MarkerManager.getMarker("LOADING");
public static final Marker SCAN = MarkerManager.getMarker("SCAN");
public static final Marker SPLASH = MarkerManager.getMarker("SPLASH");
public static final Marker FORGEMOD = MarkerManager.getMarker("FORGEMOD").addParents(LOADING);
}
Loaded 100 of 3191 files, more files were not shown because too many files have changed in this diff. Show more