Compare commits

..
242 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
1379 changed files with 23820 additions and 27816 deletions

No files matched your search

+3 -2
View File
@@ -24,7 +24,7 @@
/projects/clean/
/projects/forge/
/projects/fmlonly/
#/patches/
#/patches/*
#occupational hazards
/projects/**/build/
@@ -36,7 +36,7 @@ src/generated/resources/.cache/
#Patch rejects
/patches-/
#*.patch.rej
*.patch.rej
/projects/*/rejects/
# FML changelog
@@ -44,3 +44,4 @@ changelog.txt
*.py
*.7z
/logs/
+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()
}
})
Vendored
+12 -1
View File
@@ -7,7 +7,7 @@ pipeline {
agent {
docker {
image 'gradle:7-jdk16'
args '-v forgegc:/home/gradle/.gradle/'
//args '-v forgegc:/home/gradle/.gradle_cache/'
}
}
environment {
@@ -34,6 +34,15 @@ 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 {
withGradle {
@@ -41,6 +50,7 @@ pipeline {
}
script {
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()
}
}
}
@@ -76,6 +86,7 @@ pipeline {
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
}
}
}
+2 -16
View File
@@ -1,16 +1,2 @@
Minecraft Forge
Copyright (c) 2016-${year}.
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
+253 -104
View File
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+'
classpath 'net.minecraftforge.gradle:ForgeGradle:[5.1.26,)'
}
}
@@ -27,8 +27,9 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
plugins {
id 'org.cadixdev.licenser' version '0.6.1'
id 'com.github.ben-manes.versions' version '0.36.0'
id 'net.minecraftforge.gradleutils' version '1.+'
id 'net.minecraftforge.gradleutils' version '2.+'
id 'eclipse'
id 'de.undercouch.download' version '4.1.2'
}
Util.init() //Init all our extension methods!
@@ -43,18 +44,19 @@ ext {
]
}
MAPPING_CHANNEL = 'official'
MAPPING_VERSION = '1.17.1'
MC_VERSION = '1.17.1'
MCP_VERSION = '20210706.113038'
SPI_VERSION = '4.0.9'
MAPPING_VERSION = '1.18.2'
MC_VERSION = '1.18.2'
MCP_VERSION = '20220228.144236'
SPI_VERSION = '4.0.10'
ACCESSTRANSFORMERS_VERSION = '8.0.4'
COREMODS_VERSION = '5.0.1'
EVENTBUS_VERSION = '5.0.3'
MODLAUNCHER_VERSION = '9.0.7'
SECUREJARHANDLER_VERSION = '0.9.44'
BOOTSTRAPLAUNCHER_VERSION = '0.1.15'
ASM_VERSION = '9.1'
INSTALLER_VERSION = '2.1.4'
MODLAUNCHER_VERSION = '9.1.3'
SECUREJARHANDLER_VERSION = '1.0.3'
BOOTSTRAPLAUNCHER_VERSION = '1.0.0'
ASM_VERSION = '9.2'
INSTALLER_VERSION = '2.1.+'
MIXIN_VERSION = '0.8.5'
GIT_INFO = gradleutils.gitInfo
VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, '[0-9]', MC_VERSION)
@@ -62,10 +64,11 @@ ext {
FORGE_VERSION = VERSION.substring(MC_VERSION.length() + 1)
SPECIAL_SOURCE = 'net.md-5:SpecialSource:1.10.0'
VIGNETTE = 'net.minecraftforge.lex:vignette:0.2.0.16'
BINPATCH_TOOL = 'net.minecraftforge:binarypatcher:1.0.12:fatjar'
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.2.7'
INSTALLER_TOOLS = 'net.minecraftforge:installertools:1.2.10'
JAR_SPLITTER = 'net.minecraftforge:jarsplitter:1.1.4'
FART = 'net.minecraftforge:ForgeAutoRenamingTool:0.1.17:all'
MIN_TAG_FOR_CHANGELOG = "39.0"
}
println('Version: ' + VERSION +
@@ -73,14 +76,41 @@ println('Version: ' + VERSION +
' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ')' +
' Arch: ' + System.getProperty('os.arch'))
changelog {
fromTag MIN_TAG_FOR_CHANGELOG
}
def extraTxts = [
rootProject.file('CREDITS.txt'),
rootProject.file('LICENSE.txt')
rootProject.file('LICENSE.txt'),
rootProject.tasks.createChangelog.outputFile
]
def changelog = rootProject.file('build/changelog.txt')
if (changelog.exists())
extraTxts += changelog
task downloadVersionManifest(type: Download) {
src 'https://launchermeta.mojang.com/mc/game/version_manifest_v2.json'
dest file('build/versions/version_manifest.json')
useETag 'all'
onlyIfModified true
quiet true
}
task downloadJson(type: Download, dependsOn: downloadVersionManifest) {
inputs.file downloadVersionManifest.dest
src { downloadVersionManifest.dest.json.versions.find{ it.id == MC_VERSION }.url }
dest file("build/versions/${MC_VERSION}/version.json")
useETag 'all'
onlyIfModified true
quiet true
}
['client', 'server'].each { id ->
task "download${id.capitalize()}Raw"(type: Download, dependsOn: downloadJson) {
inputs.file downloadJson.dest
src { downloadJson.dest.json.downloads.get(id).url }
dest file("build/versions/${MC_VERSION}/${id}.jar")
useETag 'all'
onlyIfModified true
quiet true
}
}
subprojects {
apply plugin: 'maven-publish'
@@ -108,7 +138,16 @@ subprojects {
}
}
java.toolchain.languageVersion = JavaLanguageVersion.of(16)
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
tasks.withType(Javadoc).configureEach {
options.tags = [
'apiNote:a:<em>API Note:</em>',
'implSpec:a:<em>Implementation Requirements:</em>',
'implNote:a:<em>Implementation Note:</em>'
]
options.addStringOption('Xdoclint:all,-missing', '-public')
}
publishing {
publications {
@@ -144,20 +183,7 @@ subprojects {
}
}
repositories {
maven {
if (System.env.MAVEN_USER) {
url 'https://maven.minecraftforge.net/releases/'
authentication {
basic(BasicAuthentication)
}
credentials {
username = System.env.MAVEN_USER ?: 'not'
password = System.env.MAVEN_PASSWORD ?: 'set'
}
} else {
url 'file://' + rootProject.file('repo').getAbsolutePath()
}
}
maven gradleutils.getPublishingForgeMaven()
}
}
}
@@ -237,21 +263,15 @@ def sharedDeps = {
installer "net.minecraftforge:coremods:${COREMODS_VERSION}"
installer "cpw.mods:modlauncher:${MODLAUNCHER_VERSION}"
installer 'net.minecraftforge:unsafe:0.2.+'
installer 'com.electronwill.night-config:core:3.6.3'
installer 'com.electronwill.night-config:toml:3.6.3'
installer 'com.electronwill.night-config:core:3.6.4'
installer 'com.electronwill.night-config:toml:3.6.4'
installer 'org.apache.maven:maven-artifact:3.6.3'
installer 'org.apache.commons:commons-lang3:3.8.1'
installer 'net.jodah:typetools:0.8.3'
installer 'org.apache.logging.log4j:log4j-api:2.14.1'
installer 'org.apache.logging.log4j:log4j-core:2.14.1'
installer 'net.minecrell:terminalconsoleappender:1.2.0'
installer 'org.jline:jline-reader:3.12.+' //Dep of TerminaalConsoleeAppender
installer 'org.jline:jline-terminal:3.12.+' //Dep of TerminaalConsoleeAppender
installer 'net.sf.jopt-simple:jopt-simple:5.0.4'
// installer 'org.spongepowered:mixin:0.8.3'
installer 'org.openjdk.nashorn:nashorn-core:15.1.1'
installer 'com.google.guava:guava:21.0'
installer 'com.google.code.gson:gson:2.8.0'
installer "org.spongepowered:mixin:${MIXIN_VERSION}"
installer 'org.openjdk.nashorn:nashorn-core:15.3'
/*
installer 'org.lwjgl:lwjgl:3.2.2'
@@ -275,18 +295,16 @@ def sharedFmlonlyForge = { Project prj ->
}
} else {
prj.task([type: RenameJar, dependsOn: prj.tasks.createMcp2Srg], "create${side}SRG") {
tool = VIGNETTE
tool = FART
args = [
'--jar-in', '{input}',
'--jar-out', '{output}',
'--mapping-format', 'tsrg2',
'--mappings', '{mappings}',
// '--stable',
'--create-inits', '--fix-param-annotations', '--fernflower-meta'
'--input', '{input}',
'--output', '{output}',
'--names', '{mappings}',
'--ann-fix', '--ids-fix', '--src-fix', '--record-fix'
]
mappings = prj.tasks.createMcp2Srg.srg
input = prj.tasks.getByName("download${side}Slim").output
output = file("build/create${side}SRG/output.jar")
output = prj.file("build/create${side}SRG/output.jar")
}
}
@@ -347,6 +365,9 @@ def sharedFmlonlyForge = { Project prj ->
environment 'MCP_MAPPINGS', '{mcp_mappings}'
property 'nativesDirectory', '{natives}'
if (prj.name == 'forge') {
property 'forge.enableGameTest', 'true'
}
args '--launchTarget', "${launchPrefix}clientuserdev"
args '--version', 'MOD_DEV'
@@ -358,9 +379,22 @@ def sharedFmlonlyForge = { Project prj ->
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
if (prj.name == 'forge') {
property 'forge.enableGameTest', 'true'
}
args '--launchTarget', "${launchPrefix}serveruserdev"
}
if (prj.name == 'forge') {
gameTestServer {
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
args '--launchTarget', "${launchPrefix}gametestserveruserdev"
}
}
data {
environment 'MOD_CLASSES', '{source_roots}'
environment 'MCP_MAPPINGS', '{mcp_mappings}'
@@ -391,12 +425,13 @@ def sharedFmlonlyForge = { Project prj ->
}
// SecureJarHandler bootstrap values.
run.property 'legacyClassPath', '{runtime_classpath}'
run.property 'ignoreList', prj.configurations.moduleonly.files.collect {it.name}.join(',') + ",client-extra,fmlcore,javafmllanguage,mclanguage,${prj.name}-${prj.version},${prj.rootProject.ext.MC_VERSION}-${prj.name}${prj.version.substring(prj.rootProject.ext.MC_VERSION.length())}"
run.property 'mergeModules', 'jna-5.8.0.jar,jna-platform-58.0.jar,java-objc-bridge-1.0.0.jar'
run.property 'ignoreList', prj.configurations.moduleonly.files.collect {it.name.replaceAll(/([-_]([.\d]*\d+)|\.jar$)/, '') }.join(',') + ",client-extra,fmlcore,javafmllanguage,mclanguage,${prj.name}-"
//run.property 'mergeModules', 'jna-5.10.0.jar,jna-platform-5.10.0.jar,java-objc-bridge-1.0.0.jar'
if (userdevRuns.contains(run)) {
run.property 'legacyClassPath.file', '{minecraft_classpath_file}'
run.jvmArgs '-p', '{modules}'
} else {
run.property 'legacyClassPath.file', '{runtime_classpath_file}'
run.jvmArgs '-p', prj.configurations.moduleonly.files.collect { it.path }.join(File.pathSeparator)
}
run.jvmArgs '--add-modules', 'ALL-MODULE-PATH'
@@ -439,11 +474,6 @@ def sharedFmlonlyForge = { Project prj ->
}
def MODULE_PATH = Util.getArtifacts(prj, prj.configurations.moduleonly, false).values().collect{"libraries/${it.downloads.artifact.path}"}
def CLASS_PATH = Util.getArtifacts(prj, prj.configurations.installer, false).values().collect{"libraries/${it.downloads.artifact.path}"} +
[
'libraries/' + Util.getMavenPath(rootProject.tasks.findByPath(':fmlloader:jar')),
"libraries/net/minecraft/server/${MC_VERSION}-${MCP_VERSION}/server-${MC_VERSION}-${MCP_VERSION}-extra.jar"
]
def tokens = [
TASK: prj.name.equals('forge') ? 'forgeserver' : 'fmlserver',
MAVEN_PATH: prj.ext.MAVEN_PATH.toString(),
@@ -454,9 +484,37 @@ def sharedFmlonlyForge = { Project prj ->
IGNORE_LIST: Util.getArtifacts(prj, prj.configurations.moduleonly, false).values().collect{it.downloads.artifact.path.rsplit('/', 1)[1]}.join(','),
MODULES: 'ALL-MODULE-PATH'
]
prj.task([dependsOn: rootProject.downloadServerRaw], 'makeClasspathFiles') {
doLast {
def CLASS_PATH = Util.getArtifacts(prj, prj.configurations.installer, false).values().collect{"libraries/${it.downloads.artifact.path}"} +
[
'libraries/' + Util.getMavenPath(rootProject.tasks.findByPath(':fmlloader:jar')),
"libraries/net/minecraft/server/${MC_VERSION}-${MCP_VERSION}/server-${MC_VERSION}-${MCP_VERSION}-extra.jar"
]
def claimed = CLASS_PATH.collect{ it.rsplit('/', 2)[0] }.toSet() // Allow us to override versions
try (def zip = new java.util.zip.ZipFile(rootProject.downloadServerRaw.dest)) {
CLASS_PATH += zip.getInputStream(zip.getEntry('META-INF/classpath-joined')).text.split(';')
.findAll{ it.startsWith('libraries/') && !claimed.contains(it.rsplit('/', 2)[0]) }
}
configure(prj.installerJar) {
from(rootProject.file('server_files/args.txt')) {
filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(';'), CLASS_PATH: CLASS_PATH.join(';')])
rename { 'data/win_args.txt' }
}
from(rootProject.file('server_files/args.txt')) {
filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(':'), CLASS_PATH: CLASS_PATH.join(':')])
rename { 'data/unix_args.txt' }
}
}
}
}
prj.afterEvaluate {
prj.installerJar {
dependsOn('makeClasspathFiles')
from(rootProject.file('server_files/')) {
exclude 'args.txt'
filter(ReplaceTokens, tokens: tokens)
@@ -464,16 +522,6 @@ def sharedFmlonlyForge = { Project prj ->
//rename 'run.sh', "run_forge_${VERSION.replace('-', '_').sh"
//rename 'run.bat', "run_forge_${VERSION.replace('-', '_').bat"
}
from(rootProject.file('server_files/args.txt')) {
filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(';'), CLASS_PATH: CLASS_PATH.join(';')])
rename { 'data/win_args.txt' }
}
from(rootProject.file('server_files/args.txt')) {
filter(ReplaceTokens, tokens: tokens + [MODULE_PATH: MODULE_PATH.join(':'), CLASS_PATH: CLASS_PATH.join(':')])
rename { 'data/unix_args.txt' }
}
}
}
}
@@ -570,9 +618,8 @@ project(':fmlonly') {
'--fml.mcVersion', MC_VERSION,
'--fml.forgeGroup', project.group,
'--fml.mcpVersion', MCP_VERSION],
jvm: ['-DlegacyClassPath=${classpath}',
"-DignoreList=${fmlonly_client.properties.ignoreList}",
"-DmergeModules=${fmlonly_client.properties.mergeModules}",
jvm: ["-DignoreList=${fmlonly_client.properties.ignoreList},\${version_name}.jar",
//"-DmergeModules=${fmlonly_client.properties.mergeModules}",
'-DlibraryDirectory=${library_directory}',
'-p', Util.getArtifacts(project, configurations.moduleonly, false).values().collect{"\${library_directory}/${it.downloads.artifact.path}"}.join('${classpath_separator}'),
'--add-modules', 'ALL-MODULE-PATH',
@@ -586,7 +633,7 @@ project(':fmlonly') {
}
}
task installerJson(type: InstallerJson) {
task installerJson(type: InstallerJson, dependsOn: 'signUniversalJar') {
icon = rootProject.file('icon.ico')
packedDependencies = PACKED_DEPS
@@ -614,6 +661,10 @@ project(':fmlonly') {
client: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]",
server: "[${MCP_ARTIFACT.group}:${MCP_ARTIFACT.name}:${MCP_ARTIFACT.version}:mappings-merged@txt]"
],
MC_UNPACKED: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:unpacked]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:unpacked]"
],
MC_SLIM: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:slim]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]"
@@ -674,6 +725,26 @@ project(':fmlonly') {
'--from', 'data/unix_args.txt',
'--to', "{ROOT}/libraries/${MAVEN_PATH}/unix_args.txt"
]
], [
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'BUNDLER_EXTRACT',
'--input', '{MINECRAFT_JAR}',
'--output', '{ROOT}/libraries/',
'--libraries'
]
], [
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'BUNDLER_EXTRACT',
'--input', '{MINECRAFT_JAR}',
'--output', '{MC_UNPACKED}',
'--jar-only'
]
], [
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
@@ -703,11 +774,12 @@ project(':fmlonly') {
'--classes', '--reverse-right'
]
], [
sides: ['client'],
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
args: [
'--input', '{MINECRAFT_JAR}',
'--slim', '{MC_SLIM}',
'--slim', '{MC_SLIM}',
'--extra', '{MC_EXTRA}',
'--srg', '{MERGED_MAPPINGS}'
],
@@ -716,15 +788,27 @@ project(':fmlonly') {
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
jar: VIGNETTE,
classpath: getClasspath(project, libs, VIGNETTE),
sides: ['server'],
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
args: [
'--jar-in', '{MC_SLIM}',
'--jar-out', '{MC_SRG}',
'--mapping-format', 'tsrg2',
'--mappings', '{MERGED_MAPPINGS}',
// '--stable',
'--create-inits', '--fix-param-annotations', '--fernflower-meta'
'--input', '{MC_UNPACKED}',
'--slim', '{MC_SLIM}',
'--extra', '{MC_EXTRA}',
'--srg', '{MERGED_MAPPINGS}'
],
outputs: [
'{MC_SLIM}': '{MC_SLIM_SHA}',
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
jar: FART,
classpath: getClasspath(project, libs, FART),
args: [
'--input', '{MC_SLIM}',
'--output', '{MC_SRG}',
'--names', '{MERGED_MAPPINGS}',
'--ann-fix', '--ids-fix', '--src-fix', '--record-fix'
]/*,
outputs: [
'{MC_SRG}': '{MC_SRG_SHA}'
@@ -829,6 +913,7 @@ project(':forge') {
implementation project(':fmlloader')
implementation project(':javafmllanguage')
implementation project(':mclanguage')
runtimeOnly "cpw.mods:bootstraplauncher:${BOOTSTRAPLAUNCHER_VERSION}"
}
dependencies sharedDeps
@@ -855,6 +940,7 @@ project(':forge') {
parent runs.forge_client
taskName 'forge_test_client'
property 'forge.enableGameTest', 'true'
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
ideaModule "${rootProject.name}.${project.name}.test"
@@ -877,6 +963,7 @@ project(':forge') {
parent runs.forge_server
taskName 'forge_test_server'
property 'forge.enableGameTest', 'true'
environment 'MOD_CLASSES', 'dummy' // Needed to work around FG limitation, FG will replace this!
ideaModule "${rootProject.name}.${project.name}.test"
@@ -886,6 +973,27 @@ project(':forge') {
}
}
forge_gameTestServer {
taskName 'forge_gameTestServer'
args '--launchTarget', 'forgegametestserverdev'
ideaModule "${rootProject.name}.${project.name}.main"
mods {
minecraft { source sourceSets.main }
}
}
forge_test_gameTestServer {
parent runs.forge_gameTestServer
taskName 'forge_test_gameTestServer'
ideaModule "${rootProject.name}.${project.name}.test"
mods {
tests { sources sourceSets.test }
}
}
def forgeDataArgs = [
'--mod', 'forge',
'--all',
@@ -930,6 +1038,7 @@ project(':forge') {
'--mod', 'scaffolding_test',
'--mod', 'custom_tag_types_test',
'--mod', 'new_model_loader_test',
'--mod', 'remove_tag_datagen_test',
'--output', rootProject.file('src/generated_test/resources/'),
'--existing', sourceSets.main.resources.srcDirs[0],
'--existing', sourceSets.test.resources.srcDirs[0]
@@ -1078,9 +1187,8 @@ project(':forge') {
'--fml.mcVersion', MC_VERSION,
'--fml.forgeGroup', project.group,
'--fml.mcpVersion', MCP_VERSION],
jvm: ['-DlegacyClassPath=${classpath}',
"-DignoreList=${forge_client.properties.ignoreList}",
"-DmergeModules=${forge_client.properties.mergeModules}",
jvm: ["-DignoreList=${forge_client.properties.ignoreList},\${version_name}.jar",
//"-DmergeModules=${forge_client.properties.mergeModules}",
'-DlibraryDirectory=${library_directory}',
'-p', Util.getArtifacts(project, configurations.moduleonly, false).values().collect{'${library_directory}/' + it.downloads.artifact.path}.join('${classpath_separator}'),
'--add-modules', 'ALL-MODULE-PATH',
@@ -1094,7 +1202,7 @@ project(':forge') {
}
}
task installerJson(type: InstallerJson, dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches]) {
task installerJson(type: InstallerJson, dependsOn: [launcherJson, genClientBinPatches, applyClientBinPatches, applyServerBinPatches, 'signUniversalJar']) {
ext {
// remove :fatjar
BIN_PATCHER = BINPATCH_TOOL.substring(0, BINPATCH_TOOL.length() - 1 - BINPATCH_TOOL.split(':')[3].length())
@@ -1130,6 +1238,10 @@ project(':forge') {
client: '/data/client.lzma',
server: '/data/server.lzma'
],
MC_UNPACKED: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:unpacked]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:unpacked]"
],
MC_SLIM: [
client: "[net.minecraft:client:${MC_VERSION}-${MCP_VERSION}:slim]",
server: "[net.minecraft:server:${MC_VERSION}-${MCP_VERSION}:slim]"
@@ -1198,6 +1310,26 @@ project(':forge') {
'--from', 'data/unix_args.txt',
'--to', "{ROOT}/libraries/${MAVEN_PATH}/unix_args.txt"
]
], [
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'BUNDLER_EXTRACT',
'--input', '{MINECRAFT_JAR}',
'--output', '{ROOT}/libraries/',
'--libraries'
]
], [
sides: ['server'],
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
args: [
'--task', 'BUNDLER_EXTRACT',
'--input', '{MINECRAFT_JAR}',
'--output', '{MC_UNPACKED}',
'--jar-only'
]
], [
jar: INSTALLER_TOOLS,
classpath: getClasspath(project, libs, INSTALLER_TOOLS),
@@ -1227,6 +1359,7 @@ project(':forge') {
'--classes', '--reverse-right'
]
], [
sides: ['client'],
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
args: [
@@ -1240,15 +1373,27 @@ project(':forge') {
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
jar: VIGNETTE,
classpath: getClasspath(project, libs, VIGNETTE),
sides: ['server'],
jar: JAR_SPLITTER,
classpath: getClasspath(project, libs, JAR_SPLITTER),
args: [
'--jar-in', '{MC_SLIM}',
'--jar-out', '{MC_SRG}',
'--mapping-format', 'tsrg2',
'--mappings', '{MERGED_MAPPINGS}',
// '--stable',
'--create-inits', '--fix-param-annotations', '--fernflower-meta'
'--input', '{MC_UNPACKED}',
'--slim', '{MC_SLIM}',
'--extra', '{MC_EXTRA}',
'--srg', '{MERGED_MAPPINGS}'
],
outputs: [
'{MC_SLIM}': '{MC_SLIM_SHA}',
'{MC_EXTRA}': '{MC_EXTRA_SHA}'
]
], [
jar: FART,
classpath: getClasspath(project, libs, FART),
args: [
'--input', '{MC_SLIM}',
'--output', '{MC_SRG}',
'--names', '{MERGED_MAPPINGS}',
'--ann-fix', '--ids-fix', '--src-fix', '--record-fix'
]/*,
outputs: [
'{MC_SRG}': '{MC_SRG_SHA}'
@@ -1331,7 +1476,7 @@ project(':forge') {
MAPPING_CHANNEL: MAPPING_CHANNEL,
MAPPING_VERSION: MAPPING_VERSION,
FORGE_SPEC_VERSION: SPEC_VERSION.split("\\.")[0],
MC_NEXT_VERSION: "1."+((MC_VERSION.split("\\.")[1] as int)+1)
MC_NEXT_VERSION: "1."+((MC_VERSION.split("[\\.-]")[1] as int)+1)
])
rename 'gitignore\\.txt', '.gitignore'
rename 'gitattributes\\.txt', '.gitattributes'
@@ -1341,10 +1486,6 @@ project(':forge') {
license {
header = file("$rootDir/LICENSE-header.txt")
ext {
year = new Date().format("yyyy")
}
include 'net/minecraftforge/'
exclude 'net/minecraftforge/server/terminalconsole/'
exclude 'net/minecraftforge/api/' // exclude API here because it's validated in the SPI build
@@ -1365,7 +1506,8 @@ project(':forge') {
}
reobfJar {
tool = SPECIAL_SOURCE + ':shaded'
tool = FART
args = ['--input', '{input}', '--output', '{output}', '--map', '{srg}']
}
tasks.eclipse.dependsOn('genEclipseRuns')
@@ -1385,11 +1527,6 @@ project(':forge') {
publications {
mavenJava(MavenPublication) {
artifact universalJar
if (changelog.exists()) {
artifact(changelog) {
classifier = 'changelog'
}
}
artifact installerJar
//TODO: installer-win
artifact makeMdk
@@ -1409,3 +1546,15 @@ task setup() { //These must be strings so that we can do lazy resolution. Else
dependsOn ':fmlonly:extractMapped'
dependsOn ':forge:extractMapped'
}
//Also output FMLOnly when building a version.
if (System.env.TEAMCITY_VERSION) {
//Only setup the CI environment if and only if the environment variables are set.
tasks.configureTeamCity {
doLast {
println "##teamcity[buildNumber '${project(':forge').version}']"
println "##teamcity[setParameter name='env.PUBLISHED_JAVA_ARTIFACT_VERSION' value='${project(':forge').version}']"
println "##teamcity[setParameter name='env.PUBLISHED_JAVA_FML_ARTIFACT_VERSION' value='${project(':fmlonly').version}']"
}
}
}
@@ -48,14 +48,16 @@ abstract class LauncherJson extends DefaultTask {
protected void exec() {
if (!json.libraries)
json.libraries = []
getArtifacts(project, project.configurations.installer, false).each { key, lib -> json.libraries.add(lib) }
getArtifacts(project, project.configurations.moduleonly, false).each { key, lib -> json.libraries.add(lib) }
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)
json.libraries.add([
name: Util.getMavenDep(it),
libs[key] = [
name: key,
downloads: [
artifact: [
path: path,
@@ -64,8 +66,9 @@ abstract class LauncherJson extends DefaultTask {
size: it.archiveFile.get().asFile.length()
]
]
])
]
}
libs.each { key, lib -> json.libraries.add(lib) }
Files.writeString(output.get().asFile.toPath(), new JsonBuilder(json).toPrettyString())
}
}
@@ -1,5 +1,6 @@
package net.minecraftforge.forge.tasks
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import java.io.File
@@ -16,8 +17,11 @@ public class Util {
}
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")
-4
View File
@@ -15,8 +15,4 @@ 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.
-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
+5 -8
View File
@@ -2,25 +2,22 @@
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.16.5-&query=$.promos["1.16.5-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.16.5-&query=$.promos["1.16.5-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=
[![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 |
| Version | Support |
| ------------- | ------------- |
| 1.16.x | Active |
| 1.15.x | LTS |
| 1.18.x | Active |
| 1.16.x | LTS |
* [Download]
* [Forum]
* [Discord]
* [Documentation]
#### Notes:
- Introduced in 1.13 was a new FML, information found [here](NewFML.md).
# Installing Forge
Go to [the Forge website](https://files.minecraftforge.net)
+6 -11
View File
@@ -1,12 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg enable-background="new 164.072 372.466 294.41 46.56" version="1.1" viewBox="164.072 372.466 294.41 46.56" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<g fill="#DFA86A">
<polygon points="266.16 417.99 277.12 417.99 277.12 401.05 295.09 401.05 295.09 390.78 277.12 390.78 277.12 383.77 296.18 383.77 296.18 373.5 266.16 373.5"/>
<path d="m337.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-0.356 2e-3c-3.362 0-6.503 0.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 0.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.651h0.023c3.402-0.043 6.57-0.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-0.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-0.302 3.782-0.896 5.413-0.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 0.656-3.164 0.99-5.008 0.99-1.84 0-3.514-0.333-4.973-0.988-1.47-0.662-2.747-1.578-3.799-2.729-1.062-1.156-1.895-2.559-2.479-4.167-0.595-1.63-0.896-3.451-0.896-5.413 0-1.801 0.298-3.497 0.887-5.044 0.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-0.642 3.145-0.968 4.988-0.968 1.848 0 3.539 0.326 5.025 0.971 1.481 0.643 2.766 1.541 3.812 2.671 1.062 1.143 1.896 2.501 2.479 4.036 0.589 1.548 0.889 3.245 0.889 5.044z"/>
<path d="m376.27 395.65c1.902-2.327 2.867-5.221 2.867-8.603 0-2.614-0.508-4.84-1.506-6.613-0.997-1.762-2.354-3.188-4.035-4.234-1.603-0.995-3.445-1.705-5.482-2.114-1.938-0.388-3.969-0.583-6.037-0.583h-16.021v44.487h10.961v-17.282h2.35l9.447 17.282h13.127l-11.199-18.646c2.262-0.728 4.116-1.964 5.528-3.694zm-19.254-12.223h4.426c0.844 0 1.73 0.054 2.636 0.16 0.784 0.094 1.503 0.283 2.132 0.568 0.496 0.225 0.888 0.553 1.193 0.998 0.283 0.415 0.428 1.031 0.428 1.836 0 0.931-0.16 1.643-0.459 2.06-0.34 0.472-0.771 0.813-1.32 1.046-0.686 0.289-1.459 0.477-2.301 0.554-0.975 0.089-1.963 0.136-2.938 0.136h-3.795l-2e-3 -7.358z"/>
<path d="m394.82 386.38c1.05-1.132 2.325-2.03 3.793-2.674 1.464-0.642 3.144-0.968 4.988-0.968 1.843 0 3.611 0.311 5.26 0.921 1.609 0.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-0.789-5.987-1.189-9.247-1.189-3.361 0-6.503 0.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 0.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.25l0.979-0.522v-23.814h-19.313v10.27h8.354v6.639c-0.871 0.397-1.834 0.709-2.881 0.933-1.5 0.314-3.127 0.478-4.83 0.478-1.841 0-3.514-0.333-4.973-0.988-1.472-0.662-2.748-1.578-3.801-2.729-1.06-1.156-1.893-2.559-2.478-4.167-0.595-1.63-0.896-3.451-0.896-5.413 0-1.801 0.299-3.497 0.887-5.044 0.586-1.54 1.421-2.897 2.479-4.041z"/>
<polygon points="437.69 407.72 437.69 400.36 456.41 400.36 456.41 390.09 437.69 390.09 437.69 383.77 457.44 383.77 457.44 373.5 426.72 373.5 426.72 417.99 458.48 417.99 458.48 407.72"/>
</g>
<path d="m243.63 379.09l-37.842-1.852 46.229-0.034v-3.727h-52.125l-1e-3 7.798v6.201c0 0.115-1.52-9.144-1.87-11.734h-4.098v13.029c0 0.123-1.753-10.888-1.939-12.264h-27.914c1.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 0.06 4.25 0.217 5.803 1.754 2.255 2.236 2.758 5.704 0.814 8.33-1.922 2.594-7.335 3.156-7.335 3.156l-4.509 5.531v6.424h10.251l0.319-6.348 8.863-6.285c-0.946 0.757-3.058 2.783-6.229 7.666-0.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-0.437-1.185-0.994-2.385-1.709-3.483-3.172-4.883-5.284-6.909-6.229-7.666l8.863 6.285 0.32 6.348h9.565v-6.424l-4.507-5.531s-6.675-0.425-8.423-3.156c-5.032-7.869 2.115-20.082 18.836-23.756z" fill="#1E2D41"/>
<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>

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -1,7 +1,6 @@
package net.minecraftforge.fml;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.eventbus.api.BusBuilder;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.config.IConfigEvent;
import net.minecraftforge.fml.loading.FMLLoader;
@@ -34,15 +34,13 @@ import com.google.common.base.Stopwatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.minecraftforge.forgespi.language.IModInfo;
/**
* 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, {@link IThreadListener} should be used instead.
* 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.
@@ -78,7 +76,12 @@ public class DeferredWorkQueue
private static void makeRunnable(TaskInfo ti, Executor executor) {
executor.execute(() -> {
Stopwatch timer = Stopwatch.createStarted();
ti.task.run();
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);
@@ -86,13 +89,13 @@ public class DeferredWorkQueue
});
}
public CompletableFuture<Void> enqueueWork(final IModInfo modInfo, final Runnable work) {
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 IModInfo modInfo, final Supplier<T> work) {
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(IModInfo owner, Runnable task) {}
record TaskInfo(ModContainer owner, Runnable task) {}
}
@@ -46,7 +46,7 @@ public final class DistExecutor
private DistExecutor() {}
/**
* Run the callable in the supplier only on the specified {@link Side}.
* 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.
*
@@ -28,34 +28,34 @@ 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 network or writing to disk
* The predicate tests the version from a remote instance or save for acceptability (Boolean is true for network, false for local save)
* 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 {@link net.minecraftforge.fml.network.FMLNetworkConstants#IGNORESERVERONLY} in the supplier, if you wish to be ignored
* <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 network boolean is true) if you are client side,
* <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
*
* <code><pre>
* </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></code>
* </p>
* }</pre>
*
* <p>
* Examples: A client only mod
* <code><pre>
* </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></code>
* </p>
* }</pre>
*
*/
record DisplayTest(Supplier<String> suppliedVersion, BiPredicate<String, Boolean> remoteVersionTest) implements IExtensionPoint<DisplayTest> {}
@@ -116,13 +116,13 @@ public abstract class ModContainer
final Executor executor) {
return CompletableFuture
.runAsync(() -> {
ModLoadingContext.get().setActiveContainer(target, target.contextExtension.get());
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, null);
ModLoadingContext.get().setActiveContainer(null);
});
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
* 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
@@ -37,6 +37,7 @@ 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;
@@ -85,7 +86,7 @@ public class ModList
}
private String fileToLine(IModFile mf) {
return String.format("%-50.50s|%-30.30s|%-30.30s|%-20.20s|%-10.10s|Manifest: %s", mf.getFileName(),
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(),
@@ -34,7 +34,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -53,7 +52,7 @@ import static net.minecraftforge.fml.Logging.LOADING;
/**
* Loads mods.
*
* Dispatch cycle is seen in {@link #loadMods()} and {@link #finishMods()}
* Dispatch cycle is seen in {@code #loadMods()} and {@code #finishMods()}
*
* Overall sequence for loadMods is:
* <dl>
@@ -61,28 +60,28 @@ import static net.minecraftforge.fml.Logging.LOADING;
* <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 : {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber},
* {@link net.minecraftforge.event.RegistryEvent}, {@link net.minecraftforge.common.capabilities.CapabilityInject}
* <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 {@link net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent} to mods</dd>
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent} to mods</dd>
* <dt>SIDED_SETUP</dt>
* <dd>Dispatches {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent} or
* {@link net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent} to mods</dd>
* <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 {@link net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent} to mods,
* <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 {@link net.minecraftforge.fml.event.lifecycle.InterModProcessEvent} to mods,
* <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 {@link net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent} to mods,
* <dd>Dispatches {@code net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent} to mods,
* and completes the mod loading sequence.</dd>
* </dl>
*/
@@ -36,9 +36,9 @@ public class ModLoadingContext
private ModContainer activeContainer;
public void setActiveContainer(final ModContainer container, final Object languageExtension) {
public void setActiveContainer(final ModContainer container) {
this.activeContainer = container;
this.languageExtension = languageExtension;
this.languageExtension = container == null ? null : container.contextExtension.get();
}
public ModContainer getActiveContainer() {
@@ -1,7 +1,6 @@
package net.minecraftforge.fml;
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.MutableGraph;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.toposort.TopologicalSort;
@@ -19,22 +19,24 @@
package net.minecraftforge.fml;
import com.google.common.io.ByteStreams;
import com.google.gson.Gson;
import net.minecraftforge.fml.loading.FMLConfig;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
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.net.HttpURLConnection;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.http.HttpClient;
import java.nio.charset.StandardCharsets;
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;
@@ -42,6 +44,8 @@ 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.*;
@@ -49,6 +53,7 @@ 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
{
@@ -108,6 +113,8 @@ public class VersionChecker
{
new Thread("Forge Version Check")
{
private HttpClient client;
@Override
public void run()
{
@@ -117,46 +124,52 @@ public class VersionChecker
return;
}
client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(HTTP_TIMEOUT_SECS)).build();
gatherMods().forEach(this::process);
}
/**
* Opens stream for given URL while following redirects
* Returns the response body as a String for the given URL while following redirects
*/
private InputStream openUrlStream(URL url) throws IOException
{
private String openUrlString(URL url) throws IOException, URISyntaxException, InterruptedException {
URL currentUrl = url;
for (int redirects = 0; redirects < MAX_HTTP_REDIRECTS; redirects++)
{
URLConnection c = currentUrl.openConnection();
if (c instanceof HttpURLConnection)
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)
{
HttpURLConnection huc = (HttpURLConnection) c;
huc.setInstanceFollowRedirects(false);
int responseCode = huc.getResponseCode();
if (responseCode >= 300 && responseCode <= 399)
{
try
{
String loc = huc.getHeaderField("Location");
currentUrl = new URL(currentUrl, loc);
continue;
}
finally
{
huc.disconnect();
}
}
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;
}
return c.getInputStream();
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)
{
// HttpClient.newBuilder().build();
Status status = PENDING;
ComparableVersion target = null;
Map<ComparableVersion, String> changes = null;
@@ -167,9 +180,7 @@ public class VersionChecker
URL url = mod.getUpdateURL().get();
LOGGER.info("[{}] Starting version check at {}", mod.getModId(), url.toString());
InputStream con = openUrlStream(url);
String data = new String(ByteStreams.toByteArray(con), StandardCharsets.UTF_8);
con.close();
String data = openUrlString(url);
LOGGER.debug("[{}] Received version check data:\n{}", mod.getModId(), data);
@@ -180,8 +191,7 @@ public class VersionChecker
Map<String, String> promos = (Map<String, String>)json.get("promos");
display_url = (String)json.get("homepage");
// String mcVersion = MCPVersion.getMCVersion();
var mcVersion = "1.17";
var mcVersion = FMLLoader.versionInfo().mcVersion();
String rec = promos.get(mcVersion + "-recommended");
String lat = promos.get(mcVersion + "-latest");
ComparableVersion current = new ComparableVersion(mod.getVersion().toString());
@@ -81,6 +81,7 @@ public class ConfigFileTypeHandler {
}
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);
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
* 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
@@ -27,6 +27,7 @@ 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
@@ -54,7 +55,7 @@ public class ModConfig
private static String defaultConfigName(Type type, String modId) {
// config file name would be "forge-client.toml" and "forge-server.toml"
return String.format("%s-%s.toml", modId, type.extension());
return String.format(Locale.ROOT, "%s-%s.toml", modId, type.extension());
}
public Type getType() {
return type;
+9 -8
View File
@@ -11,23 +11,24 @@ configurations.forEach{ it.transitive = false }
dependencies {
implementation('net.sf.jopt-simple:jopt-simple:5.0.4')
compileOnly('org.jetbrains:annotations:21.0.0')
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.14.1')
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.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.8.1')
api('com.electronwill.night-config:core:3.6.3')
api('com.electronwill.night-config:toml:3.6.3')
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.14.1')
annotationProcessor('org.apache.logging.log4j:log4j-core:2.14.1')
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.+')
@@ -1,76 +0,0 @@
/*
* 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.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
/**
* Removes the final modifier from fields with the @CapabilityInject annotation, prevents the JITer from in lining them so our runtime replacements can work.
*/
public class CapabilityInjectDefinalize implements ILaunchPluginService {
private final String CAP = "Lnet/minecraftforge/common/capabilities/Capability;"; //Don't directly reference this to prevent class loading.
private final String CAP_INJECT = "Lnet/minecraftforge/common/capabilities/CapabilityInject;"; //Don't directly reference this to prevent class loading.
@Override
public String name() {
return "capability_inject_definalize";
}
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;
}
private boolean hasHolder(List<AnnotationNode> lst)
{
return lst != null && lst.stream().anyMatch(n -> n.desc.equals(CAP_INJECT));
}
@Override
public int processClassWithFlags(final Phase phase, final ClassNode classNode, final Type classType, final String reason)
{
final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
final AtomicBoolean changed = new AtomicBoolean();
classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.equals(CAP) && hasHolder(f.visibleAnnotations)).forEach(f ->
{
int prev = f.access;
f.access &= ~Opcodes.ACC_FINAL; //Strip final
f.access |= Opcodes.ACC_SYNTHETIC; //Add Synthetic so we can check in runtime.
changed.compareAndSet(false, prev != f.access);
});
return changed.get() ? ComputeFlags.SIMPLE_REWRITE : ComputeFlags.NO_REWRITE;
}
}
@@ -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;
}
}
@@ -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;
@@ -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;
@@ -24,15 +24,12 @@ 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 net.minecraftforge.api.distmarker.Dist;
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.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
@@ -23,9 +23,12 @@ 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.moddiscovery.*;
import net.minecraftforge.fml.loading.progress.EarlyProgressVisualization;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.fml.loading.targets.CommonLaunchHandler;
@@ -138,9 +141,10 @@ public class FMLLoader
}
}
static void setupLaunchHandler(final IEnvironment environment, final Map<String, ?> arguments)
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()) {
@@ -19,30 +19,23 @@
package net.minecraftforge.fml.loading;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.modlauncher.api.*;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionSpecBuilder;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.forgespi.Environment;
import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
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 java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class FMLServiceProvider implements ITransformationService
@@ -85,7 +78,7 @@ public class FMLServiceProvider implements ITransformationService
LOGGER.debug(CORE, "Loading configuration");
FMLConfig.load();
LOGGER.debug(CORE, "Preparing ModFile");
environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), k->ModFile.buildFactory());
environment.computePropertyIfAbsent(Environment.Keys.MODFILEFACTORY.get(), k->ModFile::new);
arguments = new HashMap<>();
arguments.put("modLists", modListsArgumentList);
arguments.put("mods", modsArgumentList);
@@ -32,11 +32,7 @@ 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;
@@ -22,14 +22,8 @@ package net.minecraftforge.fml.loading;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class LibraryFinder {
private static final Logger LOGGER = LogManager.getLogger();
@@ -44,32 +38,9 @@ public class LibraryFinder {
return libsPath;
}
public static Path findJarPathFor(final String className, final String jarName) {
final URL resource = LibraryFinder.class.getClassLoader().getResource(className);
return findJarPathFor(className, jarName, resource);
}
public static Path findJarPathFor(final String resourceName, final String jarName, final URL resource) {
try {
Path path;
final URI uri = resource.toURI();
if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) {
int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/");
path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl)));
} else {
path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length())));
}
LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString());
return path;
} catch (NullPointerException | URISyntaxException e) {
LOGGER.fatal(CORE, "Failed to find JAR for class {} - {}", resourceName, jarName);
throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e);
}
}
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(CORE, "Found forge path {} is {}", forgePath, pathStatus(forgePath));
LOGGER.debug(LogMarkers.CORE, "Found forge path {} is {}", forgePath, pathStatus(forgePath));
return forgePath;
}
@@ -81,9 +52,9 @@ public class LibraryFinder {
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(CORE,"SRG MC at {} is {}", srgMcPath.toString(), pathStatus(srgMcPath));
LOGGER.debug(CORE,"MC Extras at {} is {}", mcExtrasPath.toString(), pathStatus(mcExtrasPath));
LOGGER.debug(CORE,"Forge patches at {} is {}", patchedBinariesPath.toString(), pathStatus(patchedBinariesPath));
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 };
}
@@ -93,7 +64,4 @@ public class LibraryFinder {
public static Path findPathForMaven(final String maven) {
return findLibsPath().resolve(MavenCoordinateResolver.get(maven));
}
public static Path getFMLCorePath() {
return findLibsPath().resolve(MavenCoordinateResolver.get("net.minecraftforge:fmlcore:1.0"));
}
}
@@ -14,8 +14,6 @@ import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class MCPNamingService implements INameMappingService {
private static final Logger LOGGER = LogManager.getLogger();
private HashMap<String, String> methods;
@@ -58,7 +56,7 @@ public class MCPNamingService implements INameMappingService {
HashMap<String,String> tmpmethods = new HashMap<>(1000);
loadMappings("methods.csv", tmpmethods::put);
methods = tmpmethods;
LOGGER.debug(CORE, "Loaded {} method mappings from methods.csv", methods.size());
LOGGER.debug(LogMarkers.CORE, "Loaded {} method mappings from methods.csv", methods.size());
}
return methods.getOrDefault(origin, origin);
}
@@ -68,7 +66,7 @@ public class MCPNamingService implements INameMappingService {
HashMap<String,String> tmpfields = new HashMap<>(1000);
loadMappings("fields.csv", tmpfields::put);
fields = tmpfields;
LOGGER.debug(CORE, "Loaded {} field mappings from fields.csv", fields.size());
LOGGER.debug(LogMarkers.CORE, "Loaded {} field mappings from fields.csv", fields.size());
}
return fields.getOrDefault(origin, origin);
}
@@ -81,7 +79,7 @@ public class MCPNamingService implements INameMappingService {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(path.openStream()))) {
reader.lines().skip(1).map(e -> e.split(",")).forEach(e -> mapStore.accept(e[0], e[1]));
} catch (IOException e1) {
LOGGER.error(CORE, "Error reading mappings", e1);
LOGGER.error(LogMarkers.CORE, "Error reading mappings", e1);
}
}
}
@@ -30,7 +30,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
public class ModDirTransformerDiscoverer implements ITransformerDiscoveryService {
@@ -32,7 +32,6 @@ import net.minecraftforge.fml.loading.toposort.TopologicalSort;
import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.StringBuilderFormattable;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
@@ -92,6 +91,7 @@ public class ModSorter
AtomicInteger counter = new AtomicInteger();
Map<IModFileInfo, Integer> infos = modFiles.stream()
.map(ModFile::getModFileInfo)
.filter(ModFileInfo.class::isInstance)
.collect(toMap(Function.identity(), e -> counter.incrementAndGet()));
infos.keySet().forEach(i -> graph.addNode((ModFileInfo) i));
modFiles.stream()
@@ -150,9 +150,9 @@ public class ModSorter
private void buildUniqueList()
{
// Collect mod files by first modid in the file. This will be used for deduping purposes
// Collect mod files by module name. This will be used for deduping purposes
final Map<String, List<IModFile>> modFilesByFirstId = modFiles.stream()
.collect(groupingBy(mf -> mf.getModInfos().get(0).getModId()));
.collect(groupingBy(mf -> mf.getModFileInfo().moduleName()));
// Capture forge and MC here, so we can keep them for later
forgeAndMC = new ArrayList<>();
@@ -161,6 +161,10 @@ public class ModSorter
forgeAndMC.add((ModFile) mc.get(0));
else
throw new IllegalStateException("Failed to find minecraft somehow?");
// TODO: remove this hardcoding and make it more flexible
var forge = modFilesByFirstId.get("forge");
if (forge != null && !forge.isEmpty())
forgeAndMC.add((ModFile) forge.get(0)); // Silently ignore if Forge isn't present
// Select the newest by artifact version sorting of non-unique files thus identified
this.modFiles = modFilesByFirstId.entrySet().stream()
@@ -230,6 +234,13 @@ public class ModSorter
LOGGER.debug(LOADING, "Found {} mod requirements missing ({} mandatory, {} optional)", missingVersions.size(), mandatoryMissing, missingVersions.size() - mandatoryMissing);
if (!missingVersions.isEmpty()) {
if (mandatoryMissing > 0) {
LOGGER.error(LOADING, "Missing mandatory dependencies: {}", missingVersions.stream().filter(IModInfo.ModVersion::isMandatory).map(IModInfo.ModVersion::getModId).collect(Collectors.joining(", ")));
}
if (missingVersions.size() - mandatoryMissing > 0) {
LOGGER.error(LOADING, "Unsupported installed optional dependencies: {}", missingVersions.stream().filter(ver -> !ver.isMandatory()).map(IModInfo.ModVersion::getModId).collect(Collectors.joining(", ")));
}
return missingVersions.stream()
.map(mv -> new ExceptionData(mv.isMandatory() ? "fml.modloading.missingdependency" : "fml.modloading.missingdependency.optional",
mv.getOwner(), mv.getModId(), mv.getOwner().getModId(), mv.getVersionRange(),
@@ -242,6 +253,6 @@ public class ModSorter
private boolean modVersionNotContained(final IModInfo.ModVersion mv, final Map<String, ArtifactVersion> modVersions)
{
return !(VersionSupportMatrix.testVersionSupportMatrix(mv.getVersionRange(), mv.getModId(), "mod", (modId, range) -> modVersions.containsKey(modId) &&
(range.containsVersion(modVersions.get(modId)) || modVersions.get(modId).toString().equals("NONE"))));
(range.containsVersion(modVersions.get(modId)) || modVersions.get(modId).toString().equals("0.0NONE"))));
}
}
@@ -19,7 +19,6 @@
package net.minecraftforge.fml.loading;
import net.minecraftforge.forgespi.language.MavenVersionAdapter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.VersionRange;
@@ -0,0 +1,37 @@
package net.minecraftforge.fml.loading.log4j;
import cpw.mods.modlauncher.api.NamedPath;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
import org.objectweb.asm.Type;
import org.slf4j.LoggerFactory;
import java.util.EnumSet;
public class SLF4JFixerLaunchPluginService implements ILaunchPluginService {
private static final EnumSet<Phase> NO_PHASES = EnumSet.noneOf(Phase.class);
@Override
public String name() {
return "slf4jfixer";
}
@Override
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
return NO_PHASES;
}
@Override
public void initializeLaunch(ITransformerLoader transformerLoader, NamedPath[] specialPaths) {
Thread curThread = Thread.currentThread();
ClassLoader contextClassLoader = curThread.getContextClassLoader();
// Set the CCL of the current thread to MC-BOOTSTRAP ModuleClassLoader
curThread.setContextClassLoader(this.getClass().getClassLoader());
// Force SLF4J to bind the service providers while we manually set the context classloader to be correct
LoggerFactory.getILoggerFactory();
// Set CCL back to TransformingClassLoader
curThread.setContextClassLoader(contextClassLoader);
}
}
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
* 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
@@ -20,6 +20,11 @@
package net.minecraftforge.fml.loading.moddiscovery;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.jarhandling.JarMetadata;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.language.IConfigurable;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.IModLocator;
import org.apache.logging.log4j.LogManager;
@@ -28,40 +33,39 @@ import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public abstract class AbstractJarFileLocator implements IModLocator {
public abstract class AbstractJarFileLocator extends AbstractModLocator {
private static final Logger LOGGER = LogManager.getLogger();
@Override
public void scanFile(final IModFile file, final Consumer<Path> pathConsumer) {
LOGGER.debug(SCAN,"Scan started: {}", file);
LOGGER.debug(LogMarkers.SCAN,"Scan started: {}", file);
final Function<Path, SecureJar.Status> status = p->file.getSecureJar().verifyPath(p);
try (Stream<Path> files = Files.find(file.getSecureJar().getRootPath(), Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
file.setSecurityStatus(files.peek(pathConsumer).map(status).reduce((s1, s2)-> SecureJar.Status.values()[Math.min(s1.ordinal(), s2.ordinal())]).orElse(SecureJar.Status.INVALID));
} catch (IOException e) {
e.printStackTrace();
}
LOGGER.debug(SCAN,"Scan finished: {}", file);
LOGGER.debug(LogMarkers.SCAN,"Scan finished: {}", file);
}
@Override
public List<IModFile> scanMods() {
return scanCandidates()
.map(mc -> ModFile.newFMLInstance(this, mc))
.map(this::createMod)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}
public abstract Stream<Path> scanCandidates();
@Override
public boolean isValid(final IModFile modFile) {
return true;
}
}
@@ -0,0 +1,110 @@
/*
* 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.loading.moddiscovery;
import cpw.mods.jarhandling.JarMetadata;
import cpw.mods.jarhandling.SecureJar;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.language.IConfigurable;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.IModLocator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.jar.Manifest;
public abstract class AbstractModLocator implements IModLocator {
private static final Logger LOGGER = LogManager.getLogger();
protected static final String MODS_TOML = "META-INF/mods.toml";
protected static final String MANIFEST = "META-INF/MANIFEST.MF";
protected Optional<IModFile> createMod(Path... path) {
var mjm = new ModJarMetadata();
var sj = SecureJar.from(
Manifest::new,
jar -> jar.findFile(MODS_TOML).isPresent() ? mjm : JarMetadata.from(jar, path),
(root, p) -> true,
path
);
IModFile mod;
var type = sj.getManifest().getMainAttributes().getValue(ModFile.TYPE);
if (sj.findFile(MODS_TOML).isPresent()) {
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MODS_TOML, type, path);
mod = new ModFile(sj, this, ModFileParser::modsTomlParser);
} else if (type != null) {
LOGGER.debug(LogMarkers.SCAN, "Found {} mod of type {}: {}", MANIFEST, type, path);
mod = new ModFile(sj, this, this::manifestParser);
} else {
return Optional.empty();
}
mjm.setModFile(mod);
return Optional.of(mod);
}
protected IModFileInfo manifestParser(final IModFile mod) {
Function<String, Optional<String>> cfg = name -> Optional.ofNullable(mod.getSecureJar().getManifest().getMainAttributes().getValue(name));
var license = cfg.apply("LICENSE").orElse("");
var dummy = new IConfigurable() {
@Override
public <T> Optional<T> getConfigElement(String... key) {
return Optional.empty();
}
@Override
public List<? extends IConfigurable> getConfigList(String... key) {
return Collections.emptyList();
}
};
return new IModFileInfo() {
@Override public List<IModInfo> getMods() { return Collections.emptyList(); }
@Override public List<LanguageSpec> requiredLanguageLoaders() { return Collections.emptyList(); }
@Override public boolean showAsResourcePack() { return false; }
@Override public Map<String, Object> getFileProperties() { return Collections.emptyMap(); }
@Override public String getLicense() { return license; }
@Override public IModFile getFile() { return mod; }
@Override public IConfigurable getConfig() { return dummy; }
// These Should never be called as it's only called from ModJarMetadata.version and we bypass that
@Override public String moduleName() { return mod.getSecureJar().name(); }
@Override public String versionString() { return null; }
@Override public List<String> usesServices() { return null; }
@Override
public String toString() {
return "IModFileInfo(" + mod.getFilePath() + ")";
}
};
}
@Override
public boolean isValid(final IModFile modFile) {
return true;
}
}
@@ -19,28 +19,38 @@
package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.forgespi.language.ModFileScanData;
import net.minecraftforge.fml.loading.LoadingModList;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.language.ModFileScanData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class BackgroundScanHandler
{
private enum ScanStatus {
NOT_STARTED,
RUNNING,
COMPLETE,
TIMED_OUT,
INTERRUPTED,
ERRORED
}
private static final Logger LOGGER = LogManager.getLogger();
private final ExecutorService modContentScanner;
private final List<ModFile> pendingFiles;
private final List<ModFile> scannedFiles;
private final List<ModFile> allFiles;
private final List<ModFile> modFiles;
private ScanStatus status;
private LoadingModList loadingModList;
@SuppressWarnings("UnstableApiUsage")
public BackgroundScanHandler(final List<ModFile> modFiles) {
this.modFiles = modFiles;
modContentScanner = Executors.newSingleThreadExecutor(r -> {
@@ -51,6 +61,7 @@ public class BackgroundScanHandler
scannedFiles = new ArrayList<>();
pendingFiles = new ArrayList<>();
allFiles = new ArrayList<>();
status = ScanStatus.NOT_STARTED;
}
public List<ModFile> getModFiles() {
@@ -59,8 +70,10 @@ public class BackgroundScanHandler
public void submitForScanning(final ModFile file) {
if (modContentScanner.isShutdown()) {
status = ScanStatus.ERRORED;
throw new IllegalStateException("Scanner has shutdown");
}
status = ScanStatus.RUNNING;
allFiles.add(file);
pendingFiles.add(file);
final CompletableFuture<ModFileScanData> future = CompletableFuture.supplyAsync(file::compileContent, modContentScanner)
@@ -71,7 +84,8 @@ public class BackgroundScanHandler
private void addCompletedFile(final ModFile file, final ModFileScanData modFileScanData, final Throwable throwable) {
if (throwable != null) {
LOGGER.error(SCAN,"An error occurred scanning file {}", file, throwable);
status = ScanStatus.ERRORED;
LOGGER.error(LogMarkers.SCAN,"An error occurred scanning file {}", file, throwable);
}
pendingFiles.remove(file);
scannedFiles.add(file);
@@ -88,18 +102,19 @@ public class BackgroundScanHandler
}
public void waitForScanToComplete(final Runnable ticker) {
boolean interrupted = false;
boolean succeeded = false;
boolean timeoutActive = System.getProperty("fml.disableScanTimeout") == null;
Instant deadline = Instant.now().plus(Duration.ofMinutes(10));
modContentScanner.shutdown();
do {
ticker.run();
try {
succeeded = modContentScanner.awaitTermination(50, TimeUnit.MILLISECONDS);
status = modContentScanner.awaitTermination(50, TimeUnit.MILLISECONDS) ? ScanStatus.COMPLETE : ScanStatus.RUNNING;
} catch (InterruptedException e) {
interrupted = true;
status = ScanStatus.INTERRUPTED;
}
} while (!modContentScanner.isShutdown());
if (interrupted) Thread.currentThread().interrupt();
if (!succeeded) throw new IllegalStateException("Failed to complete mod scan");
if (timeoutActive && Instant.now().isAfter(deadline)) status = ScanStatus.TIMED_OUT;
} while (status == ScanStatus.RUNNING);
if (status == ScanStatus.INTERRUPTED) Thread.currentThread().interrupt();
if (status != ScanStatus.COMPLETE) throw new IllegalStateException("Failed to complete mod scan");
}
}
@@ -0,0 +1,106 @@
/*
* 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.moddiscovery;
import net.minecraftforge.fml.loading.LogMarkers;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public class ClasspathLocator extends AbstractJarFileLocator {
private static final Logger LOGGER = LogManager.getLogger();
private final List<Path> legacyClasspath = Arrays.stream(System.getProperty("legacyClassPath", "").split(File.pathSeparator)).map(Path::of).toList();
private boolean enabled = false;
@Override
public String name() {
return "userdev classpath";
}
@Override
public Stream<Path> scanCandidates() {
if (!enabled)
return Stream.of();
try {
var claimed = new ArrayList<>(legacyClasspath);
var paths = Stream.<Path>builder();
findPaths(claimed, MODS_TOML).forEach(paths::add);
findPaths(claimed, MANIFEST).forEach(paths::add);
return paths.build();
} catch (IOException e) {
LOGGER.fatal(LogMarkers.SCAN, "Error trying to find resources", e);
throw new RuntimeException(e);
}
}
private List<Path> findPaths(List<Path> claimed, String resource) throws IOException {
var ret = new ArrayList<Path>();
final Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources(resource);
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
Path path = findJarPathFor(resource, resource, url);
if (claimed.stream().anyMatch(path::equals) || !Files.exists(path) || Files.isDirectory(path))
continue;
ret.add(path);
}
return ret;
}
@Override
public void initArguments(Map<String, ?> arguments) {
var launchTarget = (String) arguments.get("launchTarget");
enabled = launchTarget != null && launchTarget.contains("dev");
}
private Path findJarPathFor(final String resourceName, final String jarName, final URL resource) {
try {
Path path;
final URI uri = resource.toURI();
if (uri.getScheme().equals("jar") && uri.getRawSchemeSpecificPart().contains("!/")) {
int lastExcl = uri.getRawSchemeSpecificPart().lastIndexOf("!/");
path = Paths.get(new URI(uri.getRawSchemeSpecificPart().substring(0, lastExcl)));
} else {
path = Paths.get(new URI("file://"+uri.getRawSchemeSpecificPart().substring(0, uri.getRawSchemeSpecificPart().length()-resourceName.length())));
}
//LOGGER.debug(CORE, "Found JAR {} at path {}", jarName, path.toString());
return path;
} catch (NullPointerException | URISyntaxException e) {
LOGGER.fatal(LogMarkers.SCAN, "Failed to find JAR for class {} - {}", resourceName, jarName);
throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e);
}
}
}
@@ -19,6 +19,7 @@
package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.IModLocator;
import org.apache.logging.log4j.LogManager;
@@ -34,9 +35,6 @@ import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class ExplodedDirectoryLocator implements IModLocator {
private static final Logger LOGGER = LogManager.getLogger();
@@ -47,8 +45,12 @@ public class ExplodedDirectoryLocator implements IModLocator {
@Override
public List<IModFile> scanMods() {
explodedMods.forEach(explodedMod -> ModJarMetadata.buildFile(this, jar ->jar.findFile("/META-INF/mods.toml").isPresent(), explodedMod.paths().toArray(Path[]::new))
.ifPresentOrElse(f->mods.put(explodedMod, f), () -> LOGGER.warn(LOADING, "Failed to find exploded resource mods.toml in directory {}", explodedMod.paths().get(0).toString())));
explodedMods.forEach(explodedMod ->
ModJarMetadata.buildFile(this,
jar->jar.findFile("/META-INF/mods.toml").isPresent(),
(a,b) -> true,
explodedMod.paths().toArray(Path[]::new))
.ifPresentOrElse(f->mods.put(explodedMod, f), () -> LOGGER.warn(LogMarkers.LOADING, "Failed to find exploded resource mods.toml in directory {}", explodedMod.paths().get(0).toString())));
return List.copyOf(mods.values());
}
@@ -59,13 +61,13 @@ public class ExplodedDirectoryLocator implements IModLocator {
@Override
public void scanFile(final IModFile file, final Consumer<Path> pathConsumer) {
LOGGER.debug(SCAN,"Scanning exploded directory {}", file.getFilePath().toString());
LOGGER.debug(LogMarkers.SCAN,"Scanning exploded directory {}", file.getFilePath().toString());
try (Stream<Path> files = Files.find(file.getSecureJar().getRootPath(), Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
files.forEach(pathConsumer);
} catch (IOException e) {
e.printStackTrace();
}
LOGGER.debug(SCAN,"Exploded directory scan complete {}", file.getFilePath().toString());
LOGGER.debug(LogMarkers.SCAN,"Exploded directory scan complete {}", file.getFilePath().toString());
}
@Override
@@ -1,6 +1,6 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
* 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
@@ -21,13 +21,15 @@ package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.forgespi.language.IModFileInfo;
import java.util.Locale;
public class InvalidModFileException extends RuntimeException
{
private final IModFileInfo modFileInfo;
public InvalidModFileException(String message, IModFileInfo modFileInfo)
{
super(String.format("%s (%s)", message, ((ModFileInfo)modFileInfo).getFile().getFileName()));
super(String.format(Locale.ENGLISH, "%s (%s)", message, ((ModFileInfo)modFileInfo).getFile().getFileName()));
this.modFileInfo = modFileInfo;
}
}
@@ -1,11 +1,29 @@
/*
* 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.loading.moddiscovery;
import com.electronwill.nightconfig.core.Config;
import com.electronwill.nightconfig.core.file.FileConfig;
import cpw.mods.jarhandling.SecureJar;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.MavenVersionAdapter;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.IModLocator;
import net.minecraftforge.forgespi.locating.ModFileFactory;
@@ -18,10 +36,8 @@ import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class MinecraftLocator implements IModLocator {
public class MinecraftLocator extends AbstractModLocator {
private static final Logger LOGGER = LogManager.getLogger();
@Override
@@ -29,8 +45,14 @@ public class MinecraftLocator implements IModLocator {
final var launchHandler = FMLLoader.getLaunchHandler();
var baseMC = launchHandler.getMinecraftPaths();
var mcjar = ModJarMetadata.buildFile(j->ModFileFactory.FACTORY.build(j, this, this::buildMinecraftTOML), j->true, baseMC.minecraftFilter(), baseMC.minecraftPaths().toArray(Path[]::new)).orElseThrow();
var artifacts = baseMC.otherArtifacts().stream().map(SecureJar::from).map(sj->ModFile.newFMLInstance(this, sj)).collect(Collectors.<IModFile>toList());
var othermods = baseMC.otherModPaths().stream().map(p->ModJarMetadata.buildFile(this, p.toArray(Path[]::new))).toList();
var artifacts = baseMC.otherArtifacts().stream()
.map(SecureJar::from)
.map(sj -> new ModFile(sj, this, ModFileParser::modsTomlParser))
.collect(Collectors.<IModFile>toList());
var othermods = baseMC.otherModPaths().stream()
.map(p -> createMod(p.toArray(Path[]::new)).orElse(null))
.filter(Objects::nonNull)
.toList();
artifacts.add(mcjar);
artifacts.addAll(othermods);
return artifacts;
@@ -97,22 +119,17 @@ public class MinecraftLocator implements IModLocator {
@Override
public void scanFile(final IModFile modFile, final Consumer<Path> pathConsumer) {
LOGGER.debug(SCAN, "Scan started: {}", modFile);
LOGGER.debug(LogMarkers.SCAN, "Scan started: {}", modFile);
try (Stream<Path> files = Files.find(modFile.getSecureJar().getRootPath(), Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
files.forEach(pathConsumer);
} catch (IOException e) {
e.printStackTrace();
}
LOGGER.debug(SCAN, "Scan finished: {}", modFile);
LOGGER.debug(LogMarkers.SCAN, "Scan finished: {}", modFile);
}
@Override
public void initArguments(final Map<String, ?> arguments) {
// no op
}
@Override
public boolean isValid(final IModFile modFile) {
return true;
}
}
@@ -22,6 +22,7 @@ package net.minecraftforge.fml.loading.moddiscovery;
import cpw.mods.modlauncher.Launcher;
import cpw.mods.modlauncher.api.IModuleLayerManager;
import cpw.mods.modlauncher.util.ServiceLoaderUtils;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.forgespi.Environment;
import net.minecraftforge.forgespi.locating.IModFile;
@@ -29,16 +30,12 @@ import net.minecraftforge.forgespi.locating.IModLocator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class ModDiscoverer {
private static final Logger LOGGER = LogManager.getLogger();
private final ServiceLoader<IModLocator> locators;
@@ -46,12 +43,12 @@ public class ModDiscoverer {
public ModDiscoverer(Map<String, ?> arguments) {
Launcher.INSTANCE.environment().computePropertyIfAbsent(Environment.Keys.MODDIRECTORYFACTORY.get(), v->ModsFolderLocator::new);
Launcher.INSTANCE.environment().computePropertyIfAbsent(Environment.Keys.PROGRESSMESSAGE.get(), v->StartupMessageManager.locatorConsumer().orElseGet(()->s->{}));
Launcher.INSTANCE.environment().computePropertyIfAbsent(Environment.Keys.PROGRESSMESSAGE.get(), v-> StartupMessageManager.locatorConsumer().orElseGet(()-> s->{}));
final var moduleLayerManager = Launcher.INSTANCE.environment().findModuleLayerManager().orElseThrow();
locators = ServiceLoader.load(moduleLayerManager.getLayer(IModuleLayerManager.Layer.SERVICE).orElseThrow(), IModLocator.class);
locatorList = ServiceLoaderUtils.streamServiceLoader(()->locators, sce->LOGGER.error("Failed to load locator list", sce)).collect(Collectors.toList());
locatorList.forEach(l->l.initArguments(arguments));
LOGGER.debug(CORE,"Found Mod Locators : {}", ()->locatorList.stream().map(iModLocator -> "("+iModLocator.name() + ":" + iModLocator.getClass().getPackage().getImplementationVersion()+")").collect(Collectors.joining(",")));
LOGGER.debug(LogMarkers.CORE,"Found Mod Locators : {}", ()->locatorList.stream().map(iModLocator -> "("+iModLocator.name() + ":" + iModLocator.getClass().getPackage().getImplementationVersion()+")").collect(Collectors.joining(",")));
}
ModDiscoverer(List<IModLocator> locatorList) {
@@ -60,17 +57,22 @@ public class ModDiscoverer {
}
public ModValidator discoverMods() {
LOGGER.debug(SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size());
final var modFiles = locatorList.stream()
.peek(loc -> LOGGER.debug(SCAN,"Trying locator {}", loc))
.map(IModLocator::scanMods)
.<IModFile>mapMulti(Iterable::forEach)
.peek(mf -> LOGGER.info(SCAN,"Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator()))
.peek(mf -> StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Found mod file "+mf.getFileName()+" of type "+mf.getType())))
LOGGER.debug(LogMarkers.SCAN,"Scanning for mods and other resources to load. We know {} ways to find mods", locatorList.size());
var loadedFiles = new ArrayList<>();
for (IModLocator locator : locatorList) {
LOGGER.debug(LogMarkers.SCAN,"Trying locator {}", locator);
var modFiles = locator.scanMods();
for (IModFile mf : modFiles) {
LOGGER.info(LogMarkers.SCAN, "Found mod file {} of type {} with locator {}", mf.getFileName(), mf.getType(), mf.getLocator());
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Found mod file "+mf.getFileName()+" of type "+mf.getType()));
}
loadedFiles.addAll(modFiles);
}
final var modFilesMap = loadedFiles.stream()
.map(ModFile.class::cast)
.collect(Collectors.groupingBy(IModFile::getType));
var validator = new ModValidator(modFiles);
var validator = new ModValidator(modFilesMap);
validator.stage1Validation();
return validator;
}
@@ -21,8 +21,9 @@ package net.minecraftforge.fml.loading.moddiscovery;
import com.google.common.collect.ImmutableMap;
import cpw.mods.jarhandling.SecureJar;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.IModLanguageProvider;
@@ -46,9 +47,9 @@ import java.util.function.Supplier;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class ModFile implements IModFile {
// Mods either must have a mods.toml or a manifest. We can no longer just put any jar on the classpath.
@Deprecated(forRemoval = true, since = "1.18")
public static final Manifest DEFAULTMANIFEST;
private static final Logger LOGGER = LogManager.getLogger();
@@ -72,7 +73,7 @@ public class ModFile implements IModFile {
private List<CoreModFile> coreMods;
private Path accessTransformer;
public static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
private SecureJar.Status securityStatus;
public ModFile(final SecureJar jar, final IModLocator locator, final ModFileFactory.ModFileInfoParser parser) {
@@ -116,10 +117,10 @@ public class ModFile implements IModFile {
public boolean identifyMods() {
this.modFileInfo = ModFileParser.readModList(this, this.parser);
if (this.modFileInfo == null) return false;
LOGGER.debug(LOADING,"Loading mod file {} with languages {}", this.getFilePath(), this.modFileInfo.requiredLanguageLoaders());
if (this.modFileInfo == null) return this.getType() != Type.MOD;
LOGGER.debug(LogMarkers.LOADING,"Loading mod file {} with languages {}", this.getFilePath(), this.modFileInfo.requiredLanguageLoaders());
this.coreMods = ModFileParser.getCoreMods(this);
this.coreMods.forEach(mi-> LOGGER.debug(LOADING,"Found coremod {}", mi.getPath()));
this.coreMods.forEach(mi-> LOGGER.debug(LogMarkers.LOADING,"Found coremod {}", mi.getPath()));
this.accessTransformer = findResource("META-INF", "accesstransformer.cfg");
return true;
}
@@ -139,8 +140,7 @@ public class ModFile implements IModFile {
locator.scanFile(this, pathConsumer);
}
public void setFutureScanResult(CompletableFuture<ModFileScanData> future)
{
public void setFutureScanResult(CompletableFuture<ModFileScanData> future) {
this.futureScanResult = future;
}
@@ -168,20 +168,17 @@ public class ModFile implements IModFile {
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Completed deep scan of "+this.getFileName()));
}
public void setFileProperties(Map<String, Object> fileProperties)
{
public void setFileProperties(Map<String, Object> fileProperties) {
this.fileProperties = fileProperties;
}
@Override
public List<IModLanguageProvider> getLoaders()
{
public List<IModLanguageProvider> getLoaders() {
return loaders;
}
@Override
public Path findResource(String... path)
{
public Path findResource(String... path) {
if (path.length < 1) {
throw new IllegalArgumentException("Missing path");
}
@@ -190,7 +187,7 @@ public class ModFile implements IModFile {
public void identifyLanguage() {
this.loaders = this.modFileInfo.requiredLanguageLoaders().stream()
.map(spec->FMLLoader.getLanguageLoadingProvider().findLanguage(this, spec.languageName(), spec.acceptedVersions()))
.map(spec-> FMLLoader.getLanguageLoadingProvider().findLanguage(this, spec.languageName(), spec.acceptedVersions()))
.toList();
}
@@ -214,17 +211,6 @@ public class ModFile implements IModFile {
return modFileInfo;
}
public static ModFileFactory buildFactory() {
return ModFile::new;
}
public static ModFile newFMLInstance(final IModLocator locator, final SecureJar jar) {
return (ModFile) ModFileFactory.FACTORY.build(jar, locator, ModFileParser::modsTomlParser);
}
public static ModFile newFMLInstance(final IModLocator locator, final Path... paths) {
return (ModFile) ModJarMetadata.buildFile(locator, paths);
}
@Override
public void setSecurityStatus(final SecureJar.Status status) {
this.securityStatus = status;
@@ -21,17 +21,14 @@ package net.minecraftforge.fml.loading.moddiscovery;
import com.google.common.base.Strings;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import cpw.mods.util.LambdaExceptionUtils;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.loading.StringUtils;
import net.minecraftforge.forgespi.language.IConfigurable;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import net.minecraftforge.forgespi.language.MavenVersionAdapter;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.maven.artifact.versioning.VersionRange;
import javax.security.auth.x500.X500Principal;
import java.net.URL;
import java.security.CodeSigner;
@@ -44,12 +41,9 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class ModFileInfo implements IModFileInfo, IConfigurable
{
private static final Logger LOGGER = LogManager.getLogger();
@@ -88,7 +82,7 @@ public class ModFileInfo implements IModFileInfo, IConfigurable
this.mods = modConfigs.stream()
.map(mi-> new ModInfo(this, mi))
.collect(Collectors.toList());
LOGGER.debug(LOADING, "Found valid mod file {} with {} mods - versions {}",
LOGGER.debug(LogMarkers.LOADING, "Found valid mod file {} with {} mods - versions {}",
this.modFile::getFileName,
() -> this.mods.stream().map(IModInfo::getModId).collect(Collectors.joining(",", "{", "}")),
() -> this.mods.stream().map(IModInfo::getVersion).map(Objects::toString).collect(Collectors.joining(",", "{", "}")));
@@ -22,6 +22,7 @@ package net.minecraftforge.fml.loading.moddiscovery;
import com.electronwill.nightconfig.core.file.FileConfig;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.language.IModFileInfo;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.ModFileFactory;
@@ -37,8 +38,6 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
public class ModFileParser {
private static final Logger LOGGER = LogManager.getLogger();
@@ -48,10 +47,10 @@ public class ModFileParser {
public static IModFileInfo modsTomlParser(final IModFile imodFile) {
ModFile modFile = (ModFile) imodFile;
LOGGER.debug(LOADING,"Considering mod file candidate {}", modFile.getFilePath());
LOGGER.debug(LogMarkers.LOADING,"Considering mod file candidate {}", modFile.getFilePath());
final Path modsjson = modFile.findResource("META-INF", "mods.toml");
if (!Files.exists(modsjson)) {
LOGGER.warn(LOADING, "Mod file {} is missing mods.toml file", modFile.getFilePath());
LOGGER.warn(LogMarkers.LOADING, "Mod file {} is missing mods.toml file", modFile.getFilePath());
return null;
}
@@ -75,12 +74,12 @@ public class ModFileParser {
final Gson gson = new Gson();
coreModPaths = gson.fromJson(Files.newBufferedReader(coremodsjson), type);
} catch (IOException e) {
LOGGER.debug(LOADING,"Failed to read coremod list coremods.json", e);
LOGGER.debug(LogMarkers.LOADING,"Failed to read coremod list coremods.json", e);
return Collections.emptyList();
}
return coreModPaths.entrySet().stream()
.peek(e-> LOGGER.debug(LOADING,"Found coremod {} with Javascript path {}", e.getKey(), e.getValue()))
.peek(e-> LOGGER.debug(LogMarkers.LOADING,"Found coremod {} with Javascript path {}", e.getKey(), e.getValue()))
.map(e -> new CoreModFile(e.getKey(), modFile.findResource(e.getValue()),modFile))
.collect(Collectors.toList());
}
@@ -42,7 +42,8 @@ public class ModInfo implements IModInfo, IConfigurable
{
private static final Logger LOGGER = LogManager.getLogger();
private static final DefaultArtifactVersion DEFAULT_VERSION = new DefaultArtifactVersion("1");
private static final Pattern VALID_LABEL = Pattern.compile("^[a-z][a-z0-9_-]{1,63}$");
private static final Pattern VALID_MODID = Pattern.compile("^[a-z][a-z0-9_]{1,63}$");
private static final Pattern VALID_NAMESPACE = Pattern.compile("^[a-z][a-z0-9_.-]{1,63}$");
private final ModFileInfo owningFile;
private final String modId;
@@ -64,13 +65,13 @@ public class ModInfo implements IModInfo, IConfigurable
this.config = config;
this.modId = config.<String>getConfigElement("modId")
.orElseThrow(() -> new InvalidModFileException("Missing modId", owningFile));
if (!VALID_LABEL.matcher(this.modId).matches()) {
LOGGER.fatal("Invalid modId found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.modId, VALID_LABEL.pattern());
if (!VALID_MODID.matcher(this.modId).matches()) {
LOGGER.fatal("Invalid modId found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.modId, VALID_MODID.pattern());
throw new InvalidModFileException("Invalid modId found : " + this.modId, owningFile);
}
this.namespace = config.<String>getConfigElement("namespace").orElse(this.modId);
if (!VALID_LABEL.matcher(this.namespace).matches()) {
LOGGER.fatal("Invalid override namespace found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.namespace, VALID_LABEL.pattern());
if (!VALID_NAMESPACE.matcher(this.namespace).matches()) {
LOGGER.fatal("Invalid override namespace found in file {} - {} does not match the standard: {}", this.owningFile.getFile().getFilePath(), this.namespace, VALID_NAMESPACE.pattern());
throw new InvalidModFileException("Invalid override namespace found : " + this.namespace, owningFile);
}
this.version = config.<String>getConfigElement("version")
@@ -17,18 +17,20 @@ public final class ModJarMetadata implements JarMetadata {
private IModFile modFile;
private ModuleDescriptor descriptor;
static Optional<IModFile> buildFile(IModLocator locator, Predicate<SecureJar> jarTest, Path... files) {
return buildFile(locator, jarTest, (a,b) -> true, files);
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.18")
static Optional<IModFile> buildFile(IModLocator locator, Predicate<SecureJar> jarTest, BiPredicate<String, String> filter, Path... files) {
return buildFile(j->ModFile.newFMLInstance(locator, j), jarTest, filter, files);
return buildFile(j->new ModFile(j, locator, ModFileParser::modsTomlParser), jarTest, filter, files);
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.18")
static IModFile buildFile(IModLocator locator, Path... files) {
return buildFile(locator, j->true, files).orElseThrow(()->new IllegalArgumentException("Failed to find valid JAR file"));
return buildFile(locator, j->true, (a,b) -> true, files).orElseThrow(()->new IllegalArgumentException("Failed to find valid JAR file"));
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.18")
static Optional<IModFile> buildFile(Function<SecureJar, IModFile> mfConstructor, Predicate<SecureJar> jarTest, BiPredicate<String, String> filter, Path... files) {
var mjm = new ModJarMetadata();
var sj = SecureJar.from(()->ModFile.DEFAULTMANIFEST, j->mjm, filter, files);
@@ -41,7 +43,7 @@ public final class ModJarMetadata implements JarMetadata {
}
}
private ModJarMetadata() {
ModJarMetadata() {
}
public void setModFile(IModFile file) {
@@ -21,6 +21,7 @@ package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.fml.loading.FileUtils;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.loading.MavenCoordinateResolver;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
@@ -35,8 +36,6 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public class ModListHandler {
private static final Logger LOGGER = LogManager.getLogger();
/**
@@ -59,22 +58,22 @@ public class ModListHandler {
filter(path -> Files.exists(path.getLeft())).
findFirst().
orElseGet(()->{
LOGGER.warn(CORE, "Failed to find coordinate {}", mc);
LOGGER.warn(LogMarkers.CORE, "Failed to find coordinate {}", mc);
return null;
})).
filter(Objects::nonNull).
collect(Collectors.toList());
final List<String> found = foundCoordinates.stream().map(Pair::getRight).collect(Collectors.toList());
LOGGER.debug(CORE, "Found mod coordinates from lists: {}", found);
LOGGER.debug(LogMarkers.CORE, "Found mod coordinates from lists: {}", found);
return found;
}
private static List<String> transformPathToList(final String path) {
LOGGER.debug(CORE, "Reading mod list {}", path);
LOGGER.debug(LogMarkers.CORE, "Reading mod list {}", path);
Path filePath = FMLPaths.GAMEDIR.get().resolve(path);
if (!Files.exists(filePath)) {
LOGGER.warn(CORE, "Failed to find modlist file at {}", filePath);
LOGGER.warn(LogMarkers.CORE, "Failed to find modlist file at {}", filePath);
return Collections.emptyList();
}
@@ -82,7 +81,7 @@ public class ModListHandler {
if (Objects.equals("list",extension)) {
return readListFile(filePath).stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
} else {
LOGGER.warn(CORE, "Failed to read unknown file list type {} for file {}", extension, filePath);
LOGGER.warn(LogMarkers.CORE, "Failed to read unknown file list type {} for file {}", extension, filePath);
}
return Collections.emptyList();
}
@@ -96,7 +95,7 @@ public class ModListHandler {
try {
return Files.readAllLines(filePath);
} catch (IOException e) {
LOGGER.warn(CORE, "Failed to read file list {}", filePath, e);
LOGGER.warn(LogMarkers.CORE, "Failed to read file list {}", filePath, e);
return Collections.emptyList();
}
}
@@ -1,21 +1,18 @@
package net.minecraftforge.fml.loading.moddiscovery;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.modlauncher.api.IModuleLayerManager;
import cpw.mods.modlauncher.api.ITransformationService;
import net.minecraftforge.fml.loading.*;
import net.minecraftforge.fml.loading.EarlyLoadingException;
import net.minecraftforge.fml.loading.LoadingModList;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.loading.ModSorter;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.ModFileFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class ModValidator {
private static final Logger LOGGER = LogManager.getLogger();
@@ -27,14 +24,19 @@ public class ModValidator {
public ModValidator(final Map<IModFile.Type, List<ModFile>> modFiles) {
this.modFiles = modFiles;
this.candidateMods = new ArrayList<>(modFiles.getOrDefault(IModFile.Type.MOD, List.of()));
this.candidatePlugins = new ArrayList<>(modFiles.getOrDefault(IModFile.Type.LANGPROVIDER, List.of()));
this.candidatePlugins.addAll(modFiles.getOrDefault(IModFile.Type.LIBRARY, List.of()));
this.candidateMods = lst(modFiles.get(IModFile.Type.MOD));
this.candidateMods.addAll(lst(modFiles.get(IModFile.Type.GAMELIBRARY)));
this.candidatePlugins = lst(modFiles.get(IModFile.Type.LANGPROVIDER));
this.candidatePlugins.addAll(lst(modFiles.get(IModFile.Type.LIBRARY)));
}
private static List<ModFile> lst(List<ModFile> files) {
return files == null ? new ArrayList<>() : new ArrayList<>(files);
}
public void stage1Validation() {
brokenFiles = validateFiles(candidateMods);
LOGGER.debug(SCAN,"Found {} mod files with {} mods", candidateMods::size, ()-> candidateMods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
LOGGER.debug(LogMarkers.SCAN,"Found {} mod files with {} mods", candidateMods::size, ()-> candidateMods.stream().mapToInt(mf -> mf.getModInfos().size()).sum());
StartupMessageManager.modLoaderConsumer().ifPresent(c->c.accept("Found "+ candidateMods.size()+" modfiles to load"));
}
@@ -45,7 +47,7 @@ public class ModValidator {
{
ModFile mod = iterator.next();
if (!mod.getLocator().isValid(mod) || !mod.identifyMods()) {
LOGGER.warn(SCAN, "File {} has been ignored - it is invalid", mod.getFilePath());
LOGGER.warn(LogMarkers.SCAN, "File {} has been ignored - it is invalid", mod.getFilePath());
iterator.remove();
brokenFiles.add(mod);
}
@@ -20,22 +20,19 @@
package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.fml.loading.ModDirTransformerDiscoverer;
import net.minecraftforge.fml.loading.StringUtils;
import net.minecraftforge.forgespi.locating.IModFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
/**
* Support loading mods located in JAR files in the mods folder
@@ -61,7 +58,7 @@ public class ModsFolderLocator extends AbstractJarFileLocator {
@Override
public Stream<Path> scanCandidates() {
LOGGER.debug(SCAN,"Scanning mods dir {} for mods", this.modFolder);
LOGGER.debug(LogMarkers.SCAN,"Scanning mods dir {} for mods", this.modFolder);
var excluded = ModDirTransformerDiscoverer.allExcluded();
return uncheck(()-> Files.list(this.modFolder))
@@ -19,6 +19,7 @@
package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.forgespi.language.IModLanguageProvider;
import net.minecraftforge.forgespi.language.ModFileScanData;
import org.apache.logging.log4j.LogManager;
@@ -31,8 +32,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public class Scanner {
private static final Logger LOGGER = LogManager.getLogger();
private final ModFile fileToScan;
@@ -48,7 +47,7 @@ public class Scanner {
final List<IModLanguageProvider> loaders = fileToScan.getLoaders();
if (loaders != null) {
loaders.forEach(loader -> {
LOGGER.debug(SCAN, "Scanning {} with language loader {}", fileToScan.getFilePath(), loader.name());
LOGGER.debug(LogMarkers.SCAN, "Scanning {} with language loader {}", fileToScan.getFilePath(), loader.name());
loader.getFileVisitor().accept(result);
});
}
@@ -56,7 +55,7 @@ public class Scanner {
}
private void fileVisitor(final Path path, final ModFileScanData result) {
LOGGER.debug(SCAN,"Scanning {} path {}", fileToScan, path);
LOGGER.debug(LogMarkers.SCAN,"Scanning {} path {}", fileToScan, path);
try (InputStream in = Files.newInputStream(path)){
ModClassVisitor mcv = new ModClassVisitor();
ClassReader cr = new ClassReader(in);
@@ -20,8 +20,8 @@
package net.minecraftforge.fml.loading.progress;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.api.distmarker.Dist;
import org.jetbrains.annotations.Nullable;
import java.util.function.IntConsumer;
@@ -58,7 +58,7 @@ public enum EarlyProgressVisualization {
default long handOffWindow(final IntSupplier width, final IntSupplier height, final Supplier<String> title, LongSupplier monitorSupplier) {
return FMLLoader.getGameLayer().findModule("forge")
.map(l->Class.forName(l, "net.minecraftforge.fmllegacy.NoVizFallback"))
.map(l->Class.forName(l, "net.minecraftforge.client.loading.NoVizFallback"))
.map(LamdbaExceptionUtils.rethrowFunction(c->c.getMethod("fallback", IntSupplier.class, IntSupplier.class, Supplier.class, LongSupplier.class)))
.map(LamdbaExceptionUtils.rethrowFunction(m->(LongSupplier)m.invoke(null, width, height, title, monitorSupplier)))
.map(LongSupplier::getAsLong)
@@ -19,10 +19,10 @@
package net.minecraftforge.fml.loading.targets;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.LibraryFinder;
import net.minecraftforge.fml.loading.VersionInfo;
import net.minecraftforge.api.distmarker.Dist;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -21,6 +21,7 @@ package net.minecraftforge.fml.loading.targets;
import cpw.mods.modlauncher.api.ILaunchHandlerService;
import cpw.mods.modlauncher.api.ITransformingClassLoaderBuilder;
import net.minecraftforge.fml.loading.LogMarkers;
import net.minecraftforge.api.distmarker.Dist;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -35,8 +36,6 @@ import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
import static net.minecraftforge.fml.loading.LogMarkers.CORE;
public abstract class CommonLaunchHandler implements ILaunchHandlerService {
public record LocatedPaths(List<Path> minecraftPaths, BiPredicate<String, String> minecraftFilter, List<List<Path>> otherModPaths, List<Path> otherArtifacts) {}
@@ -63,7 +62,7 @@ public abstract class CommonLaunchHandler implements ILaunchHandlerService {
protected final Map<String, List<Path>> getModClasses() {
final String modClasses = Optional.ofNullable(System.getenv("MOD_CLASSES")).orElse("");
LOGGER.debug(CORE, "Got mod coordinates {} from env", modClasses);
LOGGER.debug(LogMarkers.CORE, "Got mod coordinates {} from env", modClasses);
record ExplodedModPath(String modid, Path path) {}
// "a/b/;c/d/;" -> "modid%%c:\fish\pepper;modid%%c:\fish2\pepper2\;modid2%%c:\fishy\bums;modid2%%c:\hmm"
@@ -72,7 +71,7 @@ public abstract class CommonLaunchHandler implements ILaunchHandlerService {
.map(splitString -> new ExplodedModPath(splitString.length == 1 ? "defaultmodid" : splitString[0], Paths.get(splitString[splitString.length - 1])))
.collect(Collectors.groupingBy(ExplodedModPath::modid, Collectors.mapping(ExplodedModPath::path, Collectors.toList())));
LOGGER.debug(CORE, "Found supplied mod coordinates [{}]", modClassPaths);
LOGGER.debug(LogMarkers.CORE, "Found supplied mod coordinates [{}]", modClassPaths);
//final var explodedTargets = ((Map<String, List<ExplodedDirectoryLocator.ExplodedMod>>)arguments).computeIfAbsent("explodedTargets", a -> new ArrayList<>());
//modClassPaths.forEach((modlabel,paths) -> explodedTargets.add(new ExplodedDirectoryLocator.ExplodedMod(modlabel, paths)));
@@ -20,10 +20,10 @@
package net.minecraftforge.fml.loading.targets;
import cpw.mods.jarhandling.SecureJar;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.LibraryFinder;
import net.minecraftforge.fml.loading.VersionInfo;
import net.minecraftforge.api.distmarker.Dist;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -17,33 +17,23 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.server.permission.context;
package net.minecraftforge.fml.loading.targets;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
public class TargetContext extends PlayerContext
{
private final Entity target;
public TargetContext(Player ep, @Nullable Entity entity)
{
super(ep);
target = entity;
}
public class ForgeGametestDevLaunchHandler extends CommonDevLaunchHandler {
@Override public String name() { return "forgegametestserverdev"; }
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
@Override
@Nullable
public <T> T get(ContextKey<T> key)
{
return key.equals(ContextKeys.TARGET) ? (T) target : super.get(key);
}
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
return () -> {
var args = preLaunch(arguments, layer);
@Override
protected boolean covers(ContextKey<?> key)
{
return target != null && key.equals(ContextKeys.TARGET);
Class.forName(layer.findModule("forge").orElseThrow(), "net.minecraftforge.gametest.GameTestMain").getMethod("main", String[].class).invoke(null, (Object)args);
return null;
};
}
}
}
@@ -17,30 +17,23 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.server.permission.context;
package net.minecraftforge.fml.loading.targets;
import com.google.common.base.Preconditions;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
public class PlayerContext extends Context
{
private final Player player;
import java.util.concurrent.Callable;
public PlayerContext(Player ep)
{
player = Preconditions.checkNotNull(ep, "Player can't be null in PlayerContext!");
}
public class ForgeGametestUserdevLaunchHandler extends ForgeUserdevLaunchHandler {
@Override public String name() { return "forgegametestserveruserdev"; }
@Override public Dist getDist() { return Dist.DEDICATED_SERVER; }
@Override
public Level getWorld()
{
return player.getCommandSenderWorld();
}
public Callable<Void> launchService(String[] arguments, ModuleLayer layer) {
return () -> {
var args = preLaunch(arguments, layer);
@Override
public Player getPlayer()
{
return player;
Class.forName(layer.findModule("forge").orElseThrow(), "net.minecraftforge.gametest.GameTestMain").getMethod("main", String[].class).invoke(null, (Object)args);
return null;
};
}
}
}
@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.server;
package net.minecraftforge.fml.server;
import cpw.mods.modlauncher.InvalidLauncherSetupException;
import cpw.mods.modlauncher.Launcher;
@@ -14,3 +14,5 @@ net.minecraftforge.fml.loading.targets.ForgeServerDevLaunchHandler
net.minecraftforge.fml.loading.targets.ForgeServerUserdevLaunchHandler
net.minecraftforge.fml.loading.targets.ForgeDataDevLaunchHandler
net.minecraftforge.fml.loading.targets.ForgeDataUserdevLaunchHandler
net.minecraftforge.fml.loading.targets.ForgeGametestDevLaunchHandler
net.minecraftforge.fml.loading.targets.ForgeGametestUserdevLaunchHandler
@@ -1,4 +1,5 @@
net.minecraftforge.fml.loading.log4j.SLF4JFixerLaunchPluginService
net.minecraftforge.fml.loading.RuntimeDistCleaner
net.minecraftforge.common.asm.RuntimeEnumExtender
net.minecraftforge.common.asm.ObjectHolderDefinalize
net.minecraftforge.common.asm.CapabilityInjectDefinalize
net.minecraftforge.fml.common.asm.RuntimeEnumExtender
net.minecraftforge.fml.common.asm.ObjectHolderDefinalize
net.minecraftforge.fml.common.asm.CapabilityTokenSubclass
@@ -2,3 +2,4 @@ net.minecraftforge.fml.loading.moddiscovery.ModsFolderLocator
net.minecraftforge.fml.loading.moddiscovery.MavenDirectoryLocator
net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator
net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator
net.minecraftforge.fml.loading.moddiscovery.ClasspathLocator
+8 -8
View File
@@ -20,24 +20,24 @@
<Appenders>
<TerminalConsole name="Console">
<PatternLayout>
<LoggerNamePatternSelector defaultPattern="%highlightForge{[%d{HH:mm:ss}] [%t/%level] [%c{2.}/%markerSimpleName]: %minecraftFormatting{%msg}%n%tEx}">
<LoggerNamePatternSelector defaultPattern="%highlightForge{[%d{HH:mm:ss}] [%t/%level] [%c{2.}/%markerSimpleName]: %minecraftFormatting{%msg{nolookup}}%n%tEx}">
<!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
<PatternMatch key="net.minecraft." pattern="%highlightForge{[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg}%n%tEx}"/>
<PatternMatch key="com.mojang." pattern="%highlightForge{[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg}%n%tEx}"/>
<PatternMatch key="net.minecraft." pattern="%highlightForge{[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg{nolookup}}%n%tEx}"/>
<PatternMatch key="com.mojang." pattern="%highlightForge{[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg{nolookup}}%n%tEx}"/>
</LoggerNamePatternSelector>
</PatternLayout>
</TerminalConsole>
<Queue name="ServerGuiConsole" ignoreExceptions="true">
<PatternLayout>
<LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%c{2.}/%markerSimpleName]: %minecraftFormatting{%msg}{strip}%n">
<LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%c{2.}/%markerSimpleName]: %minecraftFormatting{%msg{nolookup}}{strip}%n">
<!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
<PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg}{strip}%n"/>
<PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg}{strip}%n"/>
<PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg{nolookup}}{strip}%n"/>
<PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg{nolookup}}{strip}%n"/>
</LoggerNamePatternSelector>
</PatternLayout>
</Queue>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="[%d{ddMMMyyyy HH:mm:ss.SSS}] [%t/%level] [%logger/%markerSimpleName]: %minecraftFormatting{%msg}{strip}%n%xEx"/>
<PatternLayout pattern="[%d{ddMMMyyyy HH:mm:ss.SSS}] [%t/%level] [%logger/%markerSimpleName]: %minecraftFormatting{%msg{nolookup}}{strip}%n%xEx"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<OnStartupTriggeringPolicy/>
@@ -45,7 +45,7 @@
<DefaultRolloverStrategy max="99" fileIndex="min"/>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
<PatternLayout pattern="[%d{ddMMMyyyy HH:mm:ss.SSS}] [%t/%level] [%logger/%markerSimpleName]: %minecraftFormatting{%msg}{strip}%n%xEx"/>
<PatternLayout pattern="[%d{ddMMMyyyy HH:mm:ss.SSS}] [%t/%level] [%logger/%markerSimpleName]: %minecraftFormatting{%msg{nolookup}}{strip}%n%xEx"/>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="200MB"/>
@@ -31,7 +31,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.LoadingFailedException;
import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.ModWorkManager;
import net.minecraftforge.fml.VersionChecker;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -39,8 +38,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
@OnlyIn(Dist.CLIENT)
public class ClientModLoader
{
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-7.2-20210702220150+0000-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+159 -110
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
@@ -33,7 +33,7 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
/**
* This defines a Mod to FML.
* Any class found with this annotation applied will be loaded as a Mod. The instance that is loaded will
* represent the mod to other Mods in the system. It will be sent various subclasses of {@link ModLifecycleEvent}
* represent the mod to other Mods in the system. It will be sent various subclasses of {@code ModLifecycleEvent}
* at pre-defined times during the loading of the game.
*/
@Retention(RetentionPolicy.RUNTIME)
@@ -51,7 +51,7 @@ public @interface Mod
/**
* Annotate a class which will be subscribed to an Event Bus at mod construction time.
* Defaults to subscribing the current modid to the {@link MinecraftForge#EVENT_BUS}
* Defaults to subscribing the current modid to the {@code MinecraftForge#EVENT_BUS}
* on both sides.
*
* @see Bus
@@ -84,7 +84,8 @@ public @interface Mod
enum Bus {
/**
* The main Forge Event Bus.
* @see MinecraftForge#EVENT_BUS
*
* <p>See {@code MinecraftForge#EVENT_BUS}</p>
*/
FORGE(Bindings.getForgeBus()),
/**
@@ -41,7 +41,7 @@ import static net.minecraftforge.fml.Logging.LOADING;
/**
* Automatic eventbus subscriber - reads {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber}
* annotations and passes the class instances to the {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus}
* defined by the annotation. Defaults to {@link MinecraftForge#EVENT_BUS}
* defined by the annotation. Defaults to {@code MinecraftForge#EVENT_BUS}
*/
public class AutomaticEventSubscriber
{
+41 -18
View File
@@ -8,29 +8,34 @@ buildscript {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
}
}
apply plugin: 'net.minecraftforge.gradle'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
plugins {
id 'eclipse'
id 'maven-publish'
}
apply plugin: 'net.minecraftforge.gradle'
version = '1.0'
group = 'com.yourname.modid' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'modid'
// Mojang ships Java 16 to end users in 1.17+ instead of Java 8 in 1.16 or lower, so your mod should target Java 16.
java.toolchain.languageVersion = JavaLanguageVersion.of(16)
// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17.
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}"
minecraft {
// The mappings can be changed at any time and must be in the following format.
// Channel: Version:
// snapshot YYYYMMDD Snapshot are built nightly.
// stable # Stables are built at the discretion of the MCP team.
// official MCVersion Official field/method names from Mojang mapping files
// official MCVersion Official field/method names from Mojang mapping files
// parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official
//
// You must be aware of the Mojang license when using the 'official' mappings.
// You must be aware of the Mojang license when using the 'official' or 'parchment' mappings.
// See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
//
// Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge
// Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started
//
// Use non-default mappings at your own risk. They may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: '@MAPPING_CHANNEL@', version: '@MAPPING_VERSION@'
@@ -55,6 +60,9 @@ minecraft {
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
property 'forge.enabledGameTestNamespaces', 'examplemod'
mods {
examplemod {
source sourceSets.main
@@ -65,6 +73,26 @@ minecraft {
server {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
property 'forge.enabledGameTestNamespaces', 'examplemod'
mods {
examplemod {
source sourceSets.main
}
}
}
// This run config launches GameTestServer and runs all registered gametests, then exits.
// By default, the server will crash when no gametests are provided.
// The gametest system is also enabled by default for other run configs under the /test command.
gameTestServer {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be added/remove as needed separated by commas.
// "SCAN": For mods scan.
@@ -77,6 +105,9 @@ minecraft {
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
property 'forge.enabledGameTestNamespaces', 'examplemod'
mods {
examplemod {
source sourceSets.main
@@ -87,16 +118,8 @@ minecraft {
data {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
// The markers can be added/remove as needed separated by commas.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
property 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
property 'forge.logging.console.level', 'debug'
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
@@ -1,5 +1,6 @@
package com.example.examplemod;
import com.mojang.logging.LogUtils;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.common.MinecraftForge;
@@ -10,10 +11,9 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartingEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.slf4j.Logger;
import java.util.stream.Collectors;
@@ -21,10 +21,11 @@ import java.util.stream.Collectors;
@Mod("examplemod")
public class ExampleMod
{
// Directly reference a log4j logger.
private static final Logger LOGGER = LogManager.getLogger();
// Directly reference a slf4j logger
private static final Logger LOGGER = LogUtils.getLogger();
public ExampleMod() {
public ExampleMod()
{
// Register the setup method for modloading
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
// Register the enqueueIMC method for modloading
@@ -45,31 +46,35 @@ public class ExampleMod
private void enqueueIMC(final InterModEnqueueEvent event)
{
// some example code to dispatch IMC to another mod
// Some example code to dispatch IMC to another mod
InterModComms.sendTo("examplemod", "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
}
private void processIMC(final InterModProcessEvent event)
{
// some example code to receive and process InterModComms from other mods
// Some example code to receive and process InterModComms from other mods
LOGGER.info("Got IMC {}", event.getIMCStream().
map(m->m.messageSupplier().get()).
collect(Collectors.toList()));
}
// You can use SubscribeEvent and let the Event Bus discover methods to call
@SubscribeEvent
public void onServerStarting(FMLServerStartingEvent event) {
// do something when the server starts
public void onServerStarting(ServerStartingEvent event)
{
// Do something when the server starts
LOGGER.info("HELLO from server starting");
}
// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
// Event bus for receiving Registry Events)
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents {
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class RegistryEvents
{
@SubscribeEvent
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent) {
// register a new block here
public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent)
{
// Register a new block here
LOGGER.info("HELLO from Register Block");
}
}
+1 -2
View File
@@ -1,7 +1,6 @@
{
"pack": {
"description": "examplemod resources",
"pack_format": 6,
"_comment": "A pack_format of 6 requires json lang files and some texture changes from 1.16.2. Note: we require v6 pack meta for all mods."
"pack_format": 9
}
}
@@ -1,6 +1,6 @@
--- a/com/mojang/blaze3d/platform/GlStateManager.java
+++ b/com/mojang/blaze3d/platform/GlStateManager.java
@@ -530,9 +_,16 @@
@@ -539,9 +_,16 @@
f_84077_[f_84076_].f_84800_ = false;
}
@@ -8,7 +8,7 @@
+ public static float lastBrightnessX = 0.0f;
+ public static float lastBrightnessY = 0.0f;
public static void m_84160_(int p_84161_, int p_84162_, float p_84163_) {
RenderSystem.m_69393_(RenderSystem::m_69587_);
RenderSystem.m_187555_();
GL11.glTexParameterf(p_84161_, p_84162_, p_84163_);
+ if (p_84161_ == GL13.GL_TEXTURE1) {
+ lastBrightnessX = p_84162_;
@@ -1,15 +1,15 @@
--- a/com/mojang/blaze3d/vertex/VertexConsumer.java
+++ b/com/mojang/blaze3d/vertex/VertexConsumer.java
@@ -15,7 +_,7 @@
@@ -14,7 +_,7 @@
import org.lwjgl.system.MemoryStack;
@OnlyIn(Dist.CLIENT)
-public interface VertexConsumer {
+public interface VertexConsumer extends net.minecraftforge.client.extensions.IForgeVertexConsumer {
Logger f_85943_ = LogManager.getLogger();
VertexConsumer m_5483_(double p_85945_, double p_85946_, double p_85947_);
@@ -100,11 +_,12 @@
VertexConsumer m_6122_(int p_85973_, int p_85974_, int p_85975_, int p_85976_);
@@ -101,11 +_,12 @@
f5 = afloat[k] * p_86001_;
}
@@ -1,5 +1,14 @@
--- a/com/mojang/math/Vector3f.java
+++ b/com/mojang/math/Vector3f.java
@@ -138,7 +_,7 @@
public boolean m_122278_() {
float f = this.f_122228_ * this.f_122228_ + this.f_122229_ * this.f_122229_ + this.f_122230_ * this.f_122230_;
- if ((double)f < 1.0E-5D) {
+ if (f < Float.MIN_NORMAL) { //Forge: Fix MC-239212
return false;
} else {
float f1 = Mth.m_14195_(f);
@@ -207,4 +_,16 @@
public String toString() {
return "[" + this.f_122228_ + ", " + this.f_122229_ + ", " + this.f_122230_ + "]";
@@ -1,7 +1,7 @@
--- a/com/mojang/realmsclient/gui/screens/RealmsGenericErrorScreen.java
+++ b/com/mojang/realmsclient/gui/screens/RealmsGenericErrorScreen.java
@@ -69,6 +_,15 @@
return (new TextComponent("")).m_7220_(this.f_88666_).m_130946_(": ").m_7220_(this.f_88667_);
@@ -67,6 +_,15 @@
return (new TextComponent("")).m_7220_(this.f_200947_.getFirst()).m_130946_(": ").m_7220_(this.f_200947_.getSecond());
}
+ @Override
@@ -15,4 +15,4 @@
+
public void m_6305_(PoseStack p_88679_, int p_88680_, int p_88681_, float p_88682_) {
this.m_7333_(p_88679_);
m_93215_(p_88679_, this.f_96547_, this.f_88666_, this.f_96543_ / 2, 80, 16777215);
m_93215_(p_88679_, this.f_96547_, this.f_200947_.getFirst(), this.f_96543_ / 2, 80, 16777215);
@@ -13,7 +13,7 @@
-
- p_127520_.append("\n");
+ p_127520_.append("Stacktrace:");
+ p_127520_.append(net.minecraftforge.fmllegacy.CrashReportExtender.generateEnhancedStackTrace(this.f_127506_));
+ p_127520_.append(net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(this.f_127506_));
}
for(CrashReportCategory crashreportcategory : this.f_127503_) {
@@ -21,7 +21,7 @@
p_127520_.append("\n\n");
}
+ net.minecraftforge.fmllegacy.CrashReportExtender.extendSystemReport(f_178624_);
+ net.minecraftforge.logging.CrashReportExtender.extendSystemReport(f_178624_);
this.f_178624_.m_143525_(p_127520_);
}
@@ -41,13 +41,13 @@
- }
-
- return s;
+ return net.minecraftforge.fmllegacy.CrashReportExtender.generateEnhancedStackTrace(throwable);
+ return net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(throwable);
}
public String m_127526_() {
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("---- Minecraft Crash Report ----\n");
+ net.minecraftforge.fmllegacy.CrashReportExtender.addCrashReportHeader(stringbuilder, this);
+ net.minecraftforge.logging.CrashReportExtender.addCrashReportHeader(stringbuilder, this);
stringbuilder.append("// ");
stringbuilder.append(m_127531_());
stringbuilder.append("\n\n");
@@ -22,7 +22,7 @@
- p_128169_.append("\n\tat ");
- p_128169_.append((Object)stacktraceelement);
- }
+ p_128169_.append(net.minecraftforge.fmllegacy.CrashReportExtender.generateEnhancedStackTrace(this.f_128139_));
+ p_128169_.append(net.minecraftforge.logging.CrashReportExtender.generateEnhancedStackTrace(this.f_128139_));
}
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/SharedConstants.java
+++ b/net/minecraft/SharedConstants.java
@@ -160,6 +_,7 @@
@@ -183,6 +_,7 @@
}
static {
@@ -1,18 +1,18 @@
--- a/net/minecraft/Util.java
+++ b/net/minecraft/Util.java
@@ -127,6 +_,9 @@
return executorservice;
@@ -155,6 +_,9 @@
return 255;
}
+ // We add this inner class to compensate for Mojang's missing inner class and allow us to obf subsequent anon inner classes correctly.
+ @SuppressWarnings("unused") private static LongSupplier INNER_CLASS_SHIFT = new LongSupplier() { public long getAsLong() { return 0; } };
+
public static Executor m_137577_() {
public static ExecutorService m_183988_() {
return f_137443_;
}
@@ -205,7 +_,7 @@
@@ -233,7 +_,7 @@
try {
type = DataFixers.m_14512_().getSchema(DataFixUtils.makeKey(SharedConstants.m_136187_().getWorldVersion())).getChoiceType(p_137552_, p_137553_);
type = DataFixers.m_14512_().getSchema(DataFixUtils.makeKey(SharedConstants.m_183709_().getWorldVersion())).getChoiceType(p_137552_, p_137553_);
} catch (IllegalArgumentException illegalargumentexception) {
- f_137446_.error("No data fixer registered for {}", (Object)p_137553_);
+ f_137446_.debug("No data fixer registered for {}", (Object)p_137553_);
@@ -1,6 +1,16 @@
--- a/net/minecraft/advancements/Advancement.java
+++ b/net/minecraft/advancements/Advancement.java
@@ -311,6 +_,7 @@
@@ -129,8 +_,8 @@
return this.f_138305_;
}
- public static class Builder {
@Nullable
+ public static class Builder implements net.minecraftforge.common.extensions.IForgeAdvancementBuilder {
private ResourceLocation f_138332_;
@Nullable
private Advancement f_138333_;
@@ -321,6 +_,7 @@
}
public static Advancement.Builder m_138380_(JsonObject p_138381_, DeserializationContext p_138382_) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/advancements/AdvancementList.java
+++ b/net/minecraft/advancements/AdvancementList.java
@@ -90,6 +_,7 @@
@@ -91,6 +_,7 @@
}
}
@@ -4,8 +4,8 @@
public void m_9989_(ServerPlayer p_9990_) {
p_9990_.m_6756_(this.f_9979_);
- LootContext lootcontext = (new LootContext.Builder(p_9990_.m_9236_())).m_78972_(LootContextParams.f_81455_, p_9990_).m_78972_(LootContextParams.f_81460_, p_9990_.m_20182_()).m_78977_(p_9990_.m_21187_()).m_78975_(LootContextParamSets.f_81418_);
+ LootContext lootcontext = (new LootContext.Builder(p_9990_.m_9236_())).m_78972_(LootContextParams.f_81455_, p_9990_).m_78972_(LootContextParams.f_81460_, p_9990_.m_20182_()).m_78977_(p_9990_.m_21187_()).m_78963_(p_9990_.m_36336_()).m_78975_(LootContextParamSets.f_81418_); // FORGE: luck to LootContext
- LootContext lootcontext = (new LootContext.Builder(p_9990_.m_183503_())).m_78972_(LootContextParams.f_81455_, p_9990_).m_78972_(LootContextParams.f_81460_, p_9990_.m_20182_()).m_78977_(p_9990_.m_21187_()).m_78975_(LootContextParamSets.f_81418_);
+ LootContext lootcontext = (new LootContext.Builder(p_9990_.m_183503_())).m_78972_(LootContextParams.f_81455_, p_9990_).m_78972_(LootContextParams.f_81460_, p_9990_.m_20182_()).m_78977_(p_9990_.m_21187_()).m_78963_(p_9990_.m_36336_()).m_78975_(LootContextParamSets.f_81418_); // FORGE: luck to LootContext
boolean flag = false;
for(ResourceLocation resourcelocation : this.f_9980_) {
@@ -1,6 +1,6 @@
--- a/net/minecraft/advancements/critereon/ItemPredicate.java
+++ b/net/minecraft/advancements/critereon/ItemPredicate.java
@@ -29,6 +_,8 @@
@@ -28,6 +_,8 @@
import net.minecraft.world.level.ItemLike;
public class ItemPredicate {
@@ -8,8 +8,8 @@
+ private static final Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> unmod_predicates = java.util.Collections.unmodifiableMap(custom_predicates);
public static final ItemPredicate f_45028_ = new ItemPredicate();
@Nullable
private final Tag<Item> f_45029_;
@@ -108,6 +_,11 @@
private final TagKey<Item> f_45029_;
@@ -107,6 +_,11 @@
public static ItemPredicate m_45051_(@Nullable JsonElement p_45052_) {
if (p_45052_ != null && !p_45052_.isJsonNull()) {
JsonObject jsonobject = GsonHelper.m_13918_(p_45052_, "item");
@@ -21,7 +21,7 @@
MinMaxBounds.Ints minmaxbounds$ints = MinMaxBounds.Ints.m_55373_(jsonobject.get("count"));
MinMaxBounds.Ints minmaxbounds$ints1 = MinMaxBounds.Ints.m_55373_(jsonobject.get("durability"));
if (jsonobject.has("data")) {
@@ -219,6 +_,14 @@
@@ -214,6 +_,14 @@
} else {
return new ItemPredicate[0];
}
@@ -5,6 +5,6 @@
@DontObfuscate
public static String m_129629_() {
- return "vanilla";
+ return net.minecraftforge.fmllegacy.BrandingControl.getClientBranding();
+ return net.minecraftforge.internal.BrandingControl.getClientBranding();
}
}
@@ -105,7 +105,7 @@
public boolean m_90864_() {
- return this.f_90816_.equals(this.f_90814_);
+ return this.f_90816_.equals(this.f_90814_) && getKeyModifier() == getKeyModifierDefault();
+ return this.f_90816_.equals(this.f_90814_) && getKeyModifier() == getDefaultKeyModifier();
}
public String m_90865_() {
@@ -174,7 +174,7 @@
+ }
+
+ @Override
+ public net.minecraftforge.client.settings.KeyModifier getKeyModifierDefault() {
+ public net.minecraftforge.client.settings.KeyModifier getDefaultKeyModifier() {
+ return keyModifierDefault;
+ }
+
@@ -1,44 +1,44 @@
--- a/net/minecraft/client/KeyboardHandler.java
+++ b/net/minecraft/client/KeyboardHandler.java
@@ -312,7 +_,9 @@
@@ -307,7 +_,9 @@
}
Screen screen = this.f_90867_.f_91080_;
- if (p_90897_ == 1 && (!(this.f_90867_.f_91080_ instanceof ControlsScreen) || ((ControlsScreen)screen).f_97515_ <= Util.m_137550_() - 20L)) {
- if (p_90897_ == 1 && (!(this.f_90867_.f_91080_ instanceof KeyBindsScreen) || ((KeyBindsScreen)screen).f_193976_ <= Util.m_137550_() - 20L)) {
+
+ if ((!(this.f_90867_.f_91080_ instanceof ControlsScreen) || ((ControlsScreen)screen).f_97515_ <= Util.m_137550_() - 20L)) {
+ if ((!(this.f_90867_.f_91080_ instanceof KeyBindsScreen) || ((KeyBindsScreen)screen).f_193976_ <= Util.m_137550_() - 20L)) {
+ if (p_90897_ == 1) {
if (this.f_90867_.f_91066_.f_92105_.m_90832_(p_90895_, p_90896_)) {
this.f_90867_.m_91268_().m_85438_();
this.f_90867_.f_91066_.f_92052_ = this.f_90867_.m_91268_().m_85440_();
@@ -331,6 +_,8 @@
@@ -326,6 +_,8 @@
});
return;
}
+ } else if (p_90897_ == 0 /*GLFW_RELEASE*/ && this.f_90867_.f_91080_ instanceof ControlsScreen)
+ ((ControlsScreen)this.f_90867_.f_91080_).f_97514_ = null; //Forge: Unset pure modifiers.
+ } else if (p_90897_ == 0 /*GLFW_RELEASE*/ && this.f_90867_.f_91080_ instanceof KeyBindsScreen)
+ ((KeyBindsScreen)this.f_90867_.f_91080_).f_193975_ = null; //Forge: Unset pure modifiers.
}
if (NarratorChatListener.f_93311_.m_93316_()) {
@@ -354,11 +_,15 @@
@@ -349,11 +_,15 @@
Screen.m_96579_(() -> {
if (p_90897_ != 1 && (p_90897_ != 2 || !this.f_90868_)) {
if (p_90897_ == 0) {
- aboolean[0] = screen.m_7920_(p_90895_, p_90896_, p_90898_);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyReleasedPre(this.f_90867_.f_91080_, p_90895_, p_90896_, p_90898_);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleasedPre(screen, p_90895_, p_90896_, p_90898_);
+ if (!aboolean[0]) aboolean[0] = screen.m_7920_(p_90895_, p_90896_, p_90898_);
+ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyReleasedPost(this.f_90867_.f_91080_, p_90895_, p_90896_, p_90898_);
+ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleasedPost(screen, p_90895_, p_90896_, p_90898_);
}
} else {
screen.m_169416_();
- aboolean[0] = screen.m_7933_(p_90895_, p_90896_, p_90898_);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyPressedPre(this.f_90867_.f_91080_, p_90895_, p_90896_, p_90898_);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressedPre(screen, p_90895_, p_90896_, p_90898_);
+ if (!aboolean[0]) aboolean[0] = screen.m_7933_(p_90895_, p_90896_, p_90898_);
+ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiKeyPressedPost(this.f_90867_.f_91080_, p_90895_, p_90896_, p_90898_);
+ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenKeyPressedPost(screen, p_90895_, p_90896_, p_90898_);
}
}, "keyPressed event handler", screen.getClass().getCanonicalName());
@@ -411,7 +_,7 @@
@@ -406,22 +_,26 @@
}
}
}
@@ -47,22 +47,25 @@
}
}
@@ -421,12 +_,16 @@
private void m_90889_(long p_90890_, int p_90891_, int p_90892_) {
if (p_90890_ == this.f_90867_.m_91268_().m_85439_()) {
- GuiEventListener guieventlistener = this.f_90867_.f_91080_;
+ Screen guieventlistener = this.f_90867_.f_91080_;
if (guieventlistener != null && this.f_90867_.m_91265_() == null) {
if (Character.charCount(p_90891_) == 1) {
Screen.m_96579_(() -> {
- guieventlistener.m_5534_((char)p_90891_, p_90892_);
+ if (net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPre(this.f_90867_.f_91080_, (char)p_90891_, p_90892_)) return;
+ if (net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPre(guieventlistener, (char)p_90891_, p_90892_)) return;
+ if (guieventlistener.m_5534_((char)p_90891_, p_90892_)) return;
+ net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPost(this.f_90867_.f_91080_, (char)p_90891_, p_90892_);
+ net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPost(guieventlistener, (char)p_90891_, p_90892_);
}, "charTyped event handler", guieventlistener.getClass().getCanonicalName());
} else {
for(char c0 : Character.toChars(p_90891_)) {
Screen.m_96579_(() -> {
- guieventlistener.m_5534_(c0, p_90892_);
+ if (net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPre(this.f_90867_.f_91080_, c0, p_90892_)) return;
+ if (net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPre(guieventlistener, c0, p_90892_)) return;
+ if (guieventlistener.m_5534_(c0, p_90892_)) return;
+ net.minecraftforge.client.ForgeHooksClient.onGuiCharTypedPost(this.f_90867_.f_91080_, c0, p_90892_);
+ net.minecraftforge.client.ForgeHooksClient.onScreenCharTypedPost(guieventlistener, c0, p_90892_);
}, "charTyped event handler", guieventlistener.getClass().getCanonicalName());
}
}
@@ -1,14 +1,15 @@
--- a/net/minecraft/client/Minecraft.java
+++ b/net/minecraft/client/Minecraft.java
@@ -390,6 +_,7 @@
public Minecraft(GameConfig p_91084_) {
super("Client");
f_90981_ = this;
+ net.minecraftforge.client.ForgeHooksClient.invalidateLog4jThreadCache();
this.f_91069_ = p_91084_.f_101907_.f_101916_;
File file1 = p_91084_.f_101907_.f_101918_;
this.f_90985_ = p_91084_.f_101907_.f_101917_;
@@ -397,14 +_,13 @@
@@ -252,7 +_,7 @@
import org.slf4j.Logger;
@OnlyIn(Dist.CLIENT)
-public class Minecraft extends ReentrantBlockableEventLoop<Runnable> implements WindowEventHandler {
+public class Minecraft extends ReentrantBlockableEventLoop<Runnable> implements WindowEventHandler, net.minecraftforge.client.extensions.IForgeMinecraft {
private static Minecraft f_90981_;
private static final Logger f_90982_ = LogUtils.getLogger();
public static final boolean f_91002_ = Util.m_137581_() == Util.OS.OSX;
@@ -394,14 +_,13 @@
this.f_91029_ = p_91084_.f_101908_.f_101928_;
this.f_90986_ = p_91084_.f_101905_.f_101944_;
this.f_91037_ = new ClientPackSource(new File(this.f_91069_, "server-resource-packs"), p_91084_.f_101907_.m_101925_());
@@ -17,14 +18,22 @@
this.f_91030_ = p_91084_.f_101905_.f_101945_;
YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(this.f_91030_);
this.f_91048_ = yggdrasilauthenticationservice.createMinecraftSessionService();
this.f_91049_ = this.m_91130_(yggdrasilauthenticationservice, p_91084_);
this.f_193584_ = this.m_193585_(yggdrasilauthenticationservice, p_91084_);
this.f_90998_ = p_91084_.f_101905_.f_101942_;
f_90982_.info("Setting user: {}", (Object)this.f_90998_.m_92546_());
- f_90982_.debug("(Session ID is {})", (Object)this.f_90998_.m_92544_());
this.f_91033_ = p_91084_.f_101908_.f_101926_;
this.f_91034_ = !p_91084_.f_101908_.f_101929_;
this.f_91035_ = !p_91084_.f_101908_.f_101930_;
@@ -450,7 +_,6 @@
@@ -433,6 +_,7 @@
}
Util.f_137440_ = RenderSystem.m_69576_();
+ if (net.minecraftforge.common.ForgeConfig.CLIENT.forceSystemNanoTime.get()) Util.f_137440_ = System::nanoTime;
this.f_90989_ = new VirtualScreen(this);
this.f_90990_ = this.f_90989_.m_110872_(displaydata, this.f_91066_.f_92123_, this.m_91270_());
this.m_7440_(true);
@@ -448,7 +_,6 @@
this.f_90990_.m_85380_(this.f_91066_.f_92113_);
this.f_91067_ = new MouseHandler(this);
@@ -32,15 +41,15 @@
this.f_91068_ = new KeyboardHandler(this);
this.f_91068_.m_90887_(this.f_90990_.m_85439_());
RenderSystem.m_69580_(this.f_91066_.f_92035_, false);
@@ -458,6 +_,7 @@
@@ -456,6 +_,7 @@
this.f_91042_.m_83931_(0.0F, 0.0F, 0.0F, 0.0F);
this.f_91042_.m_83954_(f_91002_);
this.f_91036_ = new SimpleReloadableResourceManager(PackType.CLIENT_RESOURCES);
+ net.minecraftforge.fmlclient.ClientModLoader.begin(this, this.f_91038_, this.f_91036_, this.f_91037_);
this.f_91036_ = new ReloadableResourceManager(PackType.CLIENT_RESOURCES);
+ net.minecraftforge.client.loading.ClientModLoader.begin(this, this.f_91038_, this.f_91036_, this.f_91037_);
this.f_91038_.m_10506_();
this.f_91066_.m_92145_(this.f_91038_);
this.f_91039_ = new LanguageManager(this.f_91066_.f_92075_);
@@ -506,6 +_,7 @@
@@ -504,6 +_,7 @@
this.m_91271_();
this.f_91036_.m_7217_(this.f_90997_);
this.f_91061_ = new ParticleEngine(this.f_91073_, this.f_90987_);
@@ -48,21 +57,33 @@
this.f_91036_.m_7217_(this.f_91061_);
this.f_91053_ = new PaintingTextureManager(this.f_90987_);
this.f_91036_.m_7217_(this.f_91053_);
@@ -513,7 +_,8 @@
this.f_91036_.m_7217_(this.f_91054_);
@@ -512,7 +_,8 @@
this.f_91047_ = new GpuWarnlistManager();
this.f_91036_.m_7217_(this.f_91047_);
this.f_91036_.m_7217_(this.f_205120_);
- this.f_91065_ = new Gui(this);
+ this.f_91065_ = new net.minecraftforge.client.gui.ForgeIngameGui(this);
+ this.f_91067_.m_91524_(this.f_90990_.m_85439_()); //Forge: Moved below ingameGUI setting to prevent NPEs in handeler.
this.f_91064_ = new DebugRenderer(this);
RenderSystem.m_69900_(this::m_91113_);
if (this.f_91042_.f_83915_ == this.f_90990_.m_85441_() && this.f_91042_.f_83916_ == this.f_90990_.m_85442_()) {
@@ -546,13 +_,16 @@
@@ -530,6 +_,11 @@
TinyFileDialogs.tinyfd_messageBox("Minecraft", stringbuilder.toString(), "ok", "error", false);
}
+ net.minecraftforge.gametest.ForgeGameTestHooks.registerGametests();
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.RegisterClientReloadListenersEvent(this.f_91036_));
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.EntityRenderersEvent.RegisterLayerDefinitions());
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.EntityRenderersEvent.RegisterRenderers());
+
this.f_90990_.m_85409_(this.f_91066_.f_92041_);
this.f_90990_.m_85424_(this.f_91066_.f_92034_);
this.f_90990_.m_85426_();
@@ -545,13 +_,16 @@
}
this.f_167847_.m_168556_();
+ if (net.minecraftforge.fmlclient.ClientModLoader.completeModLoading()) return; // Do not overwrite the error screen
+ if (net.minecraftforge.client.loading.ClientModLoader.completeModLoading()) return; // Do not overwrite the error screen
+ // FORGE: Move opening initial screen to after startup and events are enabled.
+ // Also Fixes MC-145102
+ if (s != null) {
@@ -80,59 +101,42 @@
}
@@ -587,6 +_,8 @@
@@ -594,6 +_,8 @@
private SocialInteractionsService m_91130_(YggdrasilAuthenticationService p_91131_, GameConfig p_91132_) {
private UserApiService m_193585_(YggdrasilAuthenticationService p_193586_, GameConfig p_193587_) {
try {
+ if ("0".equals(p_91132_.f_101905_.f_101942_.m_92547_())) // Forge: We use "0" in dev. Short circuit to stop exception spam.
+ return new OfflineSocialInteractions();
return p_91131_.createSocialInteractionsService(p_91132_.f_101905_.f_101942_.m_92547_());
+ if ("0".equals(p_193587_.f_101905_.f_101942_.m_92547_())) // Forge: We use "0" in dev. Short circuit to stop exception spam.
+ return UserApiService.OFFLINE;
return p_193586_.createUserApiService(p_193587_.f_101905_.f_101942_.m_92547_());
} catch (AuthenticationException authenticationexception) {
f_90982_.error("Failed to verify authentication", (Throwable)authenticationexception);
@@ -599,7 +_,7 @@
@@ -606,7 +_,7 @@
}
private void m_91239_(Throwable p_91240_) {
- if (this.f_91038_.m_10523_().size() > 1) {
+ if (this.f_91038_.m_10524_().stream().anyMatch(e -> !e.m_10449_())) { //Forge: This caused infinite loop if any resource packs are forced. Such as mod resources. So check if we can disable any.
Component component;
if (p_91240_ instanceof SimpleReloadableResourceManager.ResourcePackLoadingFailure) {
component = new TextComponent(((SimpleReloadableResourceManager.ResourcePackLoadingFailure)p_91240_).m_10921_().m_8017_());
@@ -690,7 +_,7 @@
return Stream.of(Registry.f_122827_.m_7981_(p_91317_.m_41720_()));
});
ReloadableIdSearchTree<ItemStack> reloadableidsearchtree = new ReloadableIdSearchTree<>((p_91121_) -> {
- return ItemTags.m_13193_().m_13394_(p_91121_.m_41720_()).stream();
+ return p_91121_.m_41720_().getTags().stream();
});
NonNullList<ItemStack> nonnulllist = NonNullList.m_122779_();
@@ -760,13 +_,13 @@
this.m_91241_(p_91240_, (Component)null);
} else {
Util.m_137559_(p_91240_);
@@ -763,13 +_,13 @@
Bootstrap.m_135875_(p_91333_.m_127526_());
if (p_91333_.m_127527_() != null) {
Bootstrap.m_135875_("#@!@# Game crashed! Crash report saved to: #@!@# " + p_91333_.m_127527_());
- System.exit(-1);
+ net.minecraftforge.fmllegacy.server.ServerLifecycleHooks.handleExit(-1);
+ net.minecraftforge.server.ServerLifecycleHooks.handleExit(-1);
} else if (p_91333_.m_127512_(file2)) {
Bootstrap.m_135875_("#@!@# Game crashed! Crash report saved to: #@!@# " + file2.getAbsolutePath());
- System.exit(-1);
+ net.minecraftforge.fmllegacy.server.ServerLifecycleHooks.handleExit(-1);
+ net.minecraftforge.server.ServerLifecycleHooks.handleExit(-1);
} else {
Bootstrap.m_135875_("#@?@# Game crashed! Crash report could not be saved. #@?@#");
- System.exit(-2);
+ net.minecraftforge.fmllegacy.server.ServerLifecycleHooks.handleExit(-2);
+ net.minecraftforge.server.ServerLifecycleHooks.handleExit(-2);
}
}
@@ -779,6 +_,7 @@
return this.m_168019_(false);
}
+ @Deprecated // Forge: Use selective refreshResources method in FMLClientHandler
private CompletableFuture<Void> m_168019_(boolean p_168020_) {
if (this.f_91024_ != null) {
return this.f_91024_;
@@ -876,10 +_,6 @@
@@ -879,10 +_,6 @@
f_90982_.error("setScreen called from non-game thread");
}
@@ -143,36 +147,42 @@
if (p_91153_ == null && this.f_91073_ == null) {
p_91153_ = new TitleScreen();
} else if (p_91153_ == null && this.f_91074_.m_21224_()) {
@@ -890,6 +_,14 @@
@@ -893,6 +_,15 @@
}
}
+ net.minecraftforge.client.ForgeHooksClient.clearGuiLayers(this);
+ Screen old = this.f_91080_;
+ net.minecraftforge.client.event.GuiOpenEvent event = new net.minecraftforge.client.event.GuiOpenEvent(p_91153_);
+ net.minecraftforge.client.event.ScreenOpenEvent event = new net.minecraftforge.client.event.ScreenOpenEvent(p_91153_);
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return;
+
+ p_91153_ = event.getGui();
+ p_91153_ = event.getScreen();
+ if (old != null && p_91153_ != old)
+ old.m_7861_();
+
this.f_91080_ = p_91153_;
BufferUploader.m_166835_();
if (p_91153_ != null) {
@@ -1018,11 +_,13 @@
@@ -1022,11 +_,13 @@
RenderSystem.m_69481_();
this.f_91026_.m_7238_();
if (!this.f_91079_) {
+ net.minecraftforge.fmllegacy.hooks.BasicEventHooks.onRenderTickStart(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_);
+ net.minecraftforge.event.ForgeEventFactory.onRenderTickStart(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_);
this.f_91026_.m_6182_("gameRenderer");
this.f_91063_.m_109093_(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_, i, p_91384_);
this.f_91026_.m_6182_("toasts");
this.f_91003_.m_94920_(new PoseStack());
this.f_91026_.m_7238_();
+ net.minecraftforge.fmllegacy.hooks.BasicEventHooks.onRenderTickEnd(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_);
+ net.minecraftforge.event.ForgeEventFactory.onRenderTickEnd(this.f_91012_ ? this.f_91013_ : this.f_90991_.f_92518_);
}
if (this.f_91056_ != null) {
@@ -1136,6 +_,7 @@
@@ -1132,10 +_,12 @@
this.f_90990_.m_85378_((double)i);
if (this.f_91080_ != null) {
this.f_91080_.m_6574_(this, this.f_90990_.m_85445_(), this.f_90990_.m_85446_());
+ net.minecraftforge.client.ForgeHooksClient.resizeGuiLayers(this, this.f_90990_.m_85445_(), this.f_90990_.m_85446_());
}
RenderTarget rendertarget = this.m_91385_();
rendertarget.m_83941_(this.f_90990_.m_85441_(), this.f_90990_.m_85442_(), f_91002_);
@@ -204,36 +214,36 @@
}
}
@@ -1455,6 +_,8 @@
@@ -1460,6 +_,8 @@
return false;
} else {
boolean flag = false;
+ net.minecraftforge.client.event.InputEvent.ClickInputEvent inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(0, this.f_91066_.f_92096_, InteractionHand.MAIN_HAND);
+ if (!inputEvent.isCanceled())
switch(this.f_91077_.m_6662_()) {
case ENTITY:
this.f_91072_.m_105223_(this.f_91074_, ((EntityHitResult)this.f_91077_).m_82443_());
@@ -1467,7 +_,7 @@
case BLOCK:
BlockHitResult blockhitresult = (BlockHitResult)this.f_91077_;
BlockPos blockpos = blockhitresult.m_82425_();
- if (!this.f_91073_.m_8055_(blockpos).m_60795_()) {
+ if (!this.f_91073_.m_46859_(blockpos)) {
this.f_91072_.m_105269_(blockpos, blockhitresult.m_82434_());
if (this.f_91073_.m_8055_(blockpos).m_60795_()) {
flag = true;
@@ -1480,8 +_,10 @@
}
} else if (!this.f_91074_.m_108637_()) {
+ net.minecraftforge.client.event.InputEvent.ClickInputEvent inputEvent = net.minecraftforge.client.ForgeHooksClient.onClickInput(0, this.f_91066_.f_92096_, InteractionHand.MAIN_HAND);
+ if (!inputEvent.isCanceled())
switch(this.f_91077_.m_6662_()) {
case ENTITY:
this.f_91072_.m_105223_(this.f_91074_, ((EntityHitResult)this.f_91077_).m_82443_());
@@ -1462,7 +_,7 @@
case BLOCK:
BlockHitResult blockhitresult = (BlockHitResult)this.f_91077_;
BlockPos blockpos = blockhitresult.m_82425_();
- if (!this.f_91073_.m_8055_(blockpos).m_60795_()) {
+ if (!this.f_91073_.m_46859_(blockpos)) {
this.f_91072_.m_105269_(blockpos, blockhitresult.m_82434_());
break;
}
@@ -1472,8 +_,10 @@
}
this.f_91074_.m_36334_();
+ net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(this.f_91074_);
}
+ if (inputEvent.shouldSwingHand())
this.f_91074_.m_6674_(InteractionHand.MAIN_HAND);
this.f_91074_.m_36334_();
+ net.minecraftforge.common.ForgeHooks.onEmptyLeftClick(this.f_91074_);
}
+ if (inputEvent.shouldSwingHand())
this.f_91074_.m_6674_(InteractionHand.MAIN_HAND);
return flag;
}
@@ -1488,6 +_,11 @@
@@ -1496,6 +_,11 @@
}
for(InteractionHand interactionhand : InteractionHand.values()) {
@@ -245,7 +255,7 @@
ItemStack itemstack = this.f_91074_.m_21120_(interactionhand);
if (this.f_91077_ != null) {
switch(this.f_91077_.m_6662_()) {
@@ -1501,6 +_,7 @@
@@ -1513,6 +_,7 @@
if (interactionresult.m_19077_()) {
if (interactionresult.m_19080_()) {
@@ -253,7 +263,7 @@
this.f_91074_.m_6674_(interactionhand);
}
@@ -1513,6 +_,7 @@
@@ -1525,6 +_,7 @@
InteractionResult interactionresult1 = this.f_91072_.m_105262_(this.f_91074_, this.f_91073_, interactionhand, blockhitresult);
if (interactionresult1.m_19077_()) {
if (interactionresult1.m_19080_()) {
@@ -261,7 +271,7 @@
this.f_91074_.m_6674_(interactionhand);
if (!itemstack.m_41619_() && (itemstack.m_41613_() != i || this.f_91072_.m_105290_())) {
this.f_91063_.f_109055_.m_109320_(interactionhand);
@@ -1528,6 +_,9 @@
@@ -1540,6 +_,9 @@
}
}
@@ -271,21 +281,21 @@
if (!itemstack.m_41619_()) {
InteractionResult interactionresult2 = this.f_91072_.m_105235_(this.f_91074_, this.f_91073_, interactionhand);
if (interactionresult2.m_19077_()) {
@@ -1554,6 +_,8 @@
@@ -1566,6 +_,8 @@
--this.f_91011_;
}
+ net.minecraftforge.fmllegacy.hooks.BasicEventHooks.onPreClientTick();
+ net.minecraftforge.event.ForgeEventFactory.onPreClientTick();
+
this.f_91026_.m_6180_("gui");
if (!this.f_91012_) {
this.f_91065_.m_93066_();
@@ -1679,6 +_,8 @@
this.f_91065_.m_193832_(this.f_91012_);
this.f_91026_.m_7238_();
@@ -1694,6 +_,8 @@
this.f_91026_.m_6182_("keyboard");
this.f_91068_.m_90931_();
this.f_91026_.m_7238_();
+
+ net.minecraftforge.fmllegacy.hooks.BasicEventHooks.onPostClientTick();
+ net.minecraftforge.event.ForgeEventFactory.onPostClientTick();
}
private boolean m_91278_() {
@@ -293,69 +303,69 @@
}
public void m_91200_(String p_91201_) {
- this.m_91219_(p_91201_, RegistryAccess.m_123086_(), Minecraft::m_91133_, Minecraft::m_91135_, false, Minecraft.ExperimentalDialogType.BACKUP);
+ this.doLoadLevel(p_91201_, RegistryAccess.m_123086_(), Minecraft::m_91133_, Minecraft::m_91135_, false, Minecraft.ExperimentalDialogType.BACKUP, false);
- this.m_205205_(p_91201_, WorldStem.DataPackConfigSupplier::m_206928_, WorldStem.WorldDataSupplier::m_206954_, false, Minecraft.ExperimentalDialogType.BACKUP);
+ this.doLoadLevel(p_91201_, WorldStem.DataPackConfigSupplier::m_206928_, WorldStem.WorldDataSupplier::m_206954_, false, Minecraft.ExperimentalDialogType.BACKUP, false);
}
public void m_91202_(String p_91203_, LevelSettings p_91204_, RegistryAccess.RegistryHolder p_91205_, WorldGenSettings p_91206_) {
- this.m_91219_(p_91203_, p_91205_, (p_167869_) -> {
+ this.doLoadLevel(p_91203_, p_91205_, (p_91129_) -> {
return p_91204_.m_46934_();
}, (p_167886_, p_167887_, p_167888_, p_167889_) -> {
RegistryWriteOps<JsonElement> registrywriteops = RegistryWriteOps.m_135767_(JsonOps.INSTANCE, p_91205_);
@@ -1828,10 +_,10 @@
});
WorldGenSettings worldgensettings = dataresult.resultOrPartial(Util.m_137489_("Error reading worldgen settings after loading data packs: ", f_90982_::error)).orElse(p_91206_);
return new PrimaryLevelData(p_91204_, worldgensettings, dataresult.lifecycle());
public void m_205185_(String p_205186_, LevelSettings p_205187_, RegistryAccess p_205188_, WorldGenSettings p_205189_) {
- this.m_205205_(p_205186_, (p_210684_) -> {
+ this.doLoadLevel(p_205186_, (p_210684_) -> {
return p_205187_::m_46934_;
}, (p_210718_) -> {
return (p_210712_, p_210713_) -> {
@@ -1831,10 +_,10 @@
WorldGenSettings worldgensettings = dataresult.getOrThrow(false, Util.m_137489_("Error reading worldgen settings after loading data packs: ", f_90982_::error));
return Pair.of(new PrimaryLevelData(p_205187_, worldgensettings, dataresult.lifecycle()), registryaccess$writable.m_203557_());
};
- }, false, Minecraft.ExperimentalDialogType.CREATE);
+ }, false, Minecraft.ExperimentalDialogType.CREATE, true);
}
- private void m_91219_(String p_91220_, RegistryAccess.RegistryHolder p_91221_, Function<LevelStorageSource.LevelStorageAccess, DataPackConfig> p_91222_, Function4<LevelStorageSource.LevelStorageAccess, RegistryAccess.RegistryHolder, ResourceManager, DataPackConfig, WorldData> p_91223_, boolean p_91224_, Minecraft.ExperimentalDialogType p_91225_) {
+ private void doLoadLevel(String p_91220_, RegistryAccess.RegistryHolder p_91221_, Function<LevelStorageSource.LevelStorageAccess, DataPackConfig> p_91222_, Function4<LevelStorageSource.LevelStorageAccess, RegistryAccess.RegistryHolder, ResourceManager, DataPackConfig, WorldData> p_91223_, boolean p_91224_, Minecraft.ExperimentalDialogType p_91225_, boolean creating) {
- private void m_205205_(String p_205206_, Function<LevelStorageSource.LevelStorageAccess, WorldStem.DataPackConfigSupplier> p_205207_, Function<LevelStorageSource.LevelStorageAccess, WorldStem.WorldDataSupplier> p_205208_, boolean p_205209_, Minecraft.ExperimentalDialogType p_205210_) {
+ private void doLoadLevel(String p_205206_, Function<LevelStorageSource.LevelStorageAccess, WorldStem.DataPackConfigSupplier> p_205207_, Function<LevelStorageSource.LevelStorageAccess, WorldStem.WorldDataSupplier> p_205208_, boolean p_205209_, Minecraft.ExperimentalDialogType p_205210_, boolean creating) {
LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess;
try {
levelstoragesource$levelstorageaccess = this.f_91031_.m_78260_(p_91220_);
@@ -1843,12 +_,17 @@
}
levelstoragesource$levelstorageaccess = this.f_91031_.m_78260_(p_205206_);
@@ -1849,11 +_,18 @@
Minecraft.ServerStem minecraft$serverstem;
+ final RegistryAccess.RegistryHolder dyn_f;
WorldStem worldstem;
try {
- minecraft$serverstem = this.m_91190_(p_91221_, p_91222_, p_91223_, p_91224_, levelstoragesource$levelstorageaccess);
+ Minecraft.ServerStem mgr = this.m_91190_(p_91221_, p_91222_, p_91223_, p_91224_, levelstoragesource$levelstorageaccess);
+ // We need to rebuild this if we're loading world, so that it gets all the information from AFTER we inject our mappings from the save.
+ dyn_f = creating ? p_91221_ : RegistryAccess.m_123086_();
+ minecraft$serverstem = creating ? mgr : this.m_91190_(dyn_f, p_91222_, p_91223_, p_91224_, levelstoragesource$levelstorageaccess); //Note this runs the injection again... which isn't good.. but hey.. we need a better spot to hook in.
+
+ //TODO-PATCHING: World loading has changed massively. Figure out what calls need to be delayed.
+ /*if (!creating) levelstoragesource$levelstorageaccess.readAdditionalLevelSaveData();
+ registryHolder = creating ? p_91221_ : RegistryAccess.m_123086_();
+ minecraft$serverstem = this.m_91190_(registryHolder, p_91222_, p_91223_, p_91224_, levelstoragesource$levelstorageaccess);
+*/
+
worldstem = this.m_205125_(packrepository, p_205209_, p_205207_.apply(levelstoragesource$levelstorageaccess), p_205208_.apply(levelstoragesource$levelstorageaccess));
} catch (Exception exception) {
f_90982_.warn("Failed to load datapacks, can't proceed with server load", (Throwable)exception);
this.m_91152_(new DatapackLoadFailureScreen(() -> {
- this.m_91219_(p_91220_, p_91221_, p_91222_, p_91223_, true, p_91225_);
+ this.doLoadLevel(p_91220_, p_91221_, p_91222_, p_91223_, true, p_91225_, creating);
- this.m_205205_(p_205206_, p_205207_, p_205208_, true, p_205210_);
+ this.doLoadLevel(p_205206_, p_205207_, p_205208_, true, p_205210_, creating);
}));
try {
@@ -1868,7 +_,7 @@
this.f_90999_.set((StoringChunkProgressListener)null);
@@ -1875,7 +_,7 @@
try {
- levelstoragesource$levelstorageaccess.m_78287_(p_91221_, worlddata);
+ levelstoragesource$levelstorageaccess.m_78287_(dyn_f, worlddata);
minecraft$serverstem.m_91433_().m_136179_();
RegistryAccess.Frozen registryaccess$frozen = worldstem.f_206894_();
- levelstoragesource$levelstorageaccess.m_78287_(registryaccess$frozen, worlddata);
+ levelstoragesource$levelstorageaccess.m_78287_(registryaccess$frozen, worlddata); //TODO-PATCHING: Figure out what registry access needs to be passed in here.
worldstem.m_206901_();
YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(this.f_91030_);
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
@@ -1880,7 +_,7 @@
SkullBlockEntity.m_182462_(this);
@@ -1885,7 +_,7 @@
SkullBlockEntity.m_196700_(gameprofilecache, minecraftsessionservice, this);
GameProfileCache.m_11004_(false);
this.f_91007_ = MinecraftServer.m_129872_((p_167898_) -> {
- return new IntegratedServer(p_167898_, this, p_91221_, levelstoragesource$levelstorageaccess, minecraft$serverstem.m_91432_(), minecraft$serverstem.m_91433_(), worlddata, minecraftsessionservice, gameprofilerepository, gameprofilecache, (p_168000_) -> {
+ return new IntegratedServer(p_167898_, this, dyn_f, levelstoragesource$levelstorageaccess, minecraft$serverstem.m_91432_(), minecraft$serverstem.m_91433_(), worlddata, minecraftsessionservice, gameprofilerepository, gameprofilecache, (p_168000_) -> {
StoringChunkProgressListener storingchunkprogresslistener = new StoringChunkProgressListener(p_168000_ + 0);
this.f_91007_ = MinecraftServer.m_129872_((p_210695_) -> {
- return new IntegratedServer(p_210695_, this, levelstoragesource$levelstorageaccess, packrepository, worldstem, minecraftsessionservice, gameprofilerepository, gameprofilecache, (p_210795_) -> {
+ return new IntegratedServer(p_210695_, this, levelstoragesource$levelstorageaccess, packrepository, worldstem, minecraftsessionservice, gameprofilerepository, gameprofilecache, (p_210795_) -> { //TODO-PATCHING: Handle the registry freeze delay again.
StoringChunkProgressListener storingchunkprogresslistener = new StoringChunkProgressListener(p_210795_ + 0);
this.f_90999_.set(storingchunkprogresslistener);
return ProcessorChunkProgressListener.m_143583_(storingchunkprogresslistener, this.f_91023_::add);
@@ -1924,11 +_,16 @@
connection.m_129505_(new ClientHandshakePacketListenerImpl(connection, this, (Screen)null, (p_167998_) -> {
@@ -1929,11 +_,16 @@
connection.m_129505_(new ClientHandshakePacketListenerImpl(connection, this, (Screen)null, (p_210793_) -> {
}));
connection.m_129512_(new ClientIntentionPacket(socketaddress.toString(), 0, ConnectionProtocol.LOGIN));
- connection.m_129512_(new ServerboundHelloPacket(this.m_91094_().m_92548_()));
@@ -367,13 +377,13 @@
+ connection.m_129512_(new ServerboundHelloPacket(gameProfile));
this.f_91009_ = connection;
} else {
this.m_91143_(p_91225_, p_91220_, flag, () -> {
- this.m_91219_(p_91220_, p_91221_, p_91222_, p_91223_, p_91224_, Minecraft.ExperimentalDialogType.NONE);
+ this.doLoadLevel(p_91220_, dyn_f, p_91222_, p_91223_, p_91224_, Minecraft.ExperimentalDialogType.NONE, creating);
this.m_91143_(p_205210_, p_205206_, flag, () -> {
- this.m_205205_(p_205206_, p_205207_, p_205208_, p_205209_, Minecraft.ExperimentalDialogType.NONE);
+ this.doLoadLevel(p_205206_, p_205207_, p_205208_, p_205209_, Minecraft.ExperimentalDialogType.NONE, creating);
});
minecraft$serverstem.close();
worldstem.close();
@@ -2016,6 +_,7 @@
@@ -2026,6 +_,7 @@
}
public void m_91156_(ClientLevel p_91157_) {
@@ -381,11 +391,11 @@
ProgressScreen progressscreen = new ProgressScreen(true);
progressscreen.m_6309_(new TranslatableComponent("connect.joining"));
this.m_91362_(progressscreen);
@@ -2049,10 +_,12 @@
@@ -2058,10 +_,12 @@
IntegratedServer integratedserver = this.f_91007_;
this.f_91007_ = null;
this.f_91063_.m_109150_();
+ net.minecraftforge.fmlclient.ClientHooks.firePlayerLogout(this.f_91072_, this.f_91074_);
+ net.minecraftforge.client.ForgeHooksClient.firePlayerLogout(this.f_91072_, this.f_91074_);
this.f_91072_ = null;
NarratorChatListener.f_93311_.m_93328_();
this.m_91362_(p_91321_);
@@ -394,23 +404,15 @@
if (integratedserver != null) {
this.f_91026_.m_6180_("waitForServer");
@@ -2067,6 +_,7 @@
@@ -2076,6 +_,7 @@
this.f_91065_.m_93089_();
this.f_91008_ = null;
this.f_91010_ = false;
+ net.minecraftforge.fmlclient.ClientHooks.handleClientWorldClosing(f_91073_);
+ net.minecraftforge.client.ForgeHooksClient.handleClientLevelClosing(f_91073_);
this.f_91004_.m_90740_();
}
@@ -2097,6 +_,7 @@
this.f_91061_.m_107342_(p_91325_);
this.f_167845_.m_112257_(p_91325_);
this.m_91341_();
+ net.minecraftforge.client.MinecraftForgeClient.clearRenderCache();
}
public boolean m_91400_() {
@@ -2152,66 +_,9 @@
@@ -2162,66 +_,9 @@
private void m_91280_() {
if (this.f_91077_ != null && this.f_91077_.m_6662_() != HitResult.Type.MISS) {
@@ -480,15 +482,7 @@
}
}
@@ -2318,6 +_,7 @@
return f_90981_;
}
+ @Deprecated // Forge: Use selective scheduleResourceRefresh method in FMLClientHandler
public CompletableFuture<Void> m_91088_() {
return this.m_18691_(() -> this.m_91391_()).thenCompose((p_167945_) -> {
return p_167945_;
@@ -2768,7 +_,7 @@
@@ -2713,7 +_,7 @@
return this.f_90993_;
}
@@ -497,7 +491,7 @@
int i = p_167938_.m_10374_();
Supplier<PackResources> supplier = p_167937_;
if (i <= 3) {
@@ -2779,7 +_,7 @@
@@ -2724,7 +_,7 @@
supplier = m_91352_(supplier);
}
@@ -506,7 +500,7 @@
}
private static Supplier<PackResources> m_91330_(Supplier<PackResources> p_91331_) {
@@ -2796,6 +_,14 @@
@@ -2741,6 +_,14 @@
public void m_91312_(int p_91313_) {
this.f_91051_.m_119410_(p_91313_);
+17 -13
View File
@@ -8,21 +8,25 @@
boolean[] aboolean = new boolean[]{false};
if (this.f_91503_.m_91265_() == null) {
if (this.f_91503_.f_91080_ == null) {
@@ -82,11 +_,15 @@
@@ -82,11 +_,19 @@
if (flag) {
screen.m_169415_();
Screen.m_96579_(() -> {
- aboolean[0] = screen.m_6375_(d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseClickedPre(this.f_91503_.f_91080_, d0, d1, i);
+ if (!aboolean[0]) aboolean[0] = this.f_91503_.f_91080_.m_6375_(d0, d1, i);
+ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseClickedPost(this.f_91503_.f_91080_, d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseClickedPre(screen, d0, d1, i);
+ if (!aboolean[0]) {
+ aboolean[0] = this.f_91503_.f_91080_.m_6375_(d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseClickedPost(screen, d0, d1, i, aboolean[0]);
+ }
}, "mouseClicked event handler", screen.getClass().getCanonicalName());
} else {
Screen.m_96579_(() -> {
- aboolean[0] = screen.m_6348_(d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseReleasedPre(this.f_91503_.f_91080_, d0, d1, i);
+ if (!aboolean[0]) aboolean[0] = this.f_91503_.f_91080_.m_6348_(d0, d1, i);
+ if (!aboolean[0]) aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseReleasedPost(this.f_91503_.f_91080_, d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseReleasedPre(screen, d0, d1, i);
+ if (!aboolean[0]) {
+ aboolean[0] = this.f_91503_.f_91080_.m_6348_(d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onScreenMouseReleasedPost(screen, d0, d1, i, aboolean[0]);
+ }
}, "mouseReleased event handler", screen.getClass().getCanonicalName());
}
}
@@ -50,28 +54,28 @@
double d2 = this.f_91508_ * (double)this.f_91503_.m_91268_().m_85446_() / (double)this.f_91503_.m_91268_().m_85444_();
- this.f_91503_.f_91080_.m_6050_(d1, d2, d0);
this.f_91503_.f_91080_.m_169415_();
+ if (net.minecraftforge.client.ForgeHooksClient.onGuiMouseScrollPre(this, this.f_91503_.f_91080_, d0)) return;
+ if (net.minecraftforge.client.ForgeHooksClient.onScreenMouseScrollPre(this, this.f_91503_.f_91080_, d0)) return;
+ if (this.f_91503_.f_91080_.m_6050_(d1, d2, d0)) return;
+ net.minecraftforge.client.ForgeHooksClient.onGuiMouseScrollPost(this, this.f_91503_.f_91080_, d0);
+ net.minecraftforge.client.ForgeHooksClient.onScreenMouseScrollPost(this, this.f_91503_.f_91080_, d0);
} else if (this.f_91503_.f_91074_ != null) {
if (this.f_91518_ != 0.0D && Math.signum(d0) != Math.signum(this.f_91518_)) {
this.f_91518_ = 0.0D;
@@ -135,6 +_,7 @@
}
this.f_91518_ -= (double)f1;
this.f_91518_ -= (double)i;
+ if (net.minecraftforge.client.ForgeHooksClient.onMouseScroll(this, d0)) return;
if (this.f_91503_.f_91074_.m_5833_()) {
if (this.f_91503_.f_91065_.m_93085_().m_94768_()) {
this.f_91503_.f_91065_.m_93085_().m_94769_((double)(-f1));
this.f_91503_.f_91065_.m_93085_().m_205380_(-i);
@@ -203,7 +_,9 @@
double d2 = (p_91563_ - this.f_91507_) * (double)this.f_91503_.m_91268_().m_85445_() / (double)this.f_91503_.m_91268_().m_85443_();
double d3 = (p_91564_ - this.f_91508_) * (double)this.f_91503_.m_91268_().m_85446_() / (double)this.f_91503_.m_91268_().m_85444_();
Screen.m_96579_(() -> {
- screen.m_7979_(d0, d1, this.f_91510_, d2, d3);
+ if (net.minecraftforge.client.ForgeHooksClient.onGuiMouseDragPre(this.f_91503_.f_91080_, d0, d1, this.f_91510_, d2, d3)) return;
+ if (net.minecraftforge.client.ForgeHooksClient.onScreenMouseDragPre(screen, d0, d1, this.f_91510_, d2, d3)) return;
+ if (screen.m_7979_(d0, d1, this.f_91510_, d2, d3)) return;
+ net.minecraftforge.client.ForgeHooksClient.onGuiMouseDragPost(this.f_91503_.f_91080_, d0, d1, this.f_91510_, d2, d3);
+ net.minecraftforge.client.ForgeHooksClient.onScreenMouseDragPost(screen, d0, d1, this.f_91510_, d2, d3);
}, "mouseDragged event handler", screen.getClass().getCanonicalName());
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/Options.java
+++ b/net/minecraft/client/Options.java
@@ -179,6 +_,7 @@
@@ -188,6 +_,7 @@
public boolean f_92076_;
public Options(Minecraft p_92138_, File p_92139_) {
@@ -8,8 +8,8 @@
this.f_92060_ = p_92138_;
this.f_92110_ = new File(p_92139_, "options.txt");
if (p_92138_.m_91103_() && Runtime.getRuntime().maxMemory() >= 1000000000L) {
@@ -283,10 +_,14 @@
this.f_92076_ = p_168428_.m_142682_("syncChunkWrites", this.f_92076_);
@@ -302,10 +_,14 @@
this.f_193762_ = p_168428_.m_142682_("allowServerListing", this.f_193762_);
for(KeyMapping keymapping : this.f_92059_) {
- String s = keymapping.m_90865_();
@@ -25,15 +25,15 @@
}
}
@@ -474,6 +_,7 @@
@@ -493,6 +_,7 @@
}
public void m_92169_() {
+ if (net.minecraftforge.fmlclient.ClientModLoader.isLoading()) return; //Don't save settings before mods add keybindigns and the like to prevent them from being deleted.
+ if (net.minecraftforge.client.loading.ClientModLoader.isLoading()) return; //Don't save settings before mods add keybindigns and the like to prevent them from being deleted.
try {
final PrintWriter printwriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(this.f_92110_), StandardCharsets.UTF_8));
@@ -622,6 +_,23 @@
@@ -641,6 +_,23 @@
}
p_92146_.m_10509_(set);
@@ -11,7 +11,7 @@
+ }
+ final File target = event.getScreenshotFile();
+
Util.m_137579_().execute(() -> {
Util.m_183992_().execute(() -> {
try {
- nativeimage.m_85056_(file2);
+ nativeimage.m_85056_(target);
@@ -1,16 +1,16 @@
--- a/net/minecraft/client/User.java
+++ b/net/minecraft/client/User.java
@@ -18,8 +_,22 @@
private final String f_92536_;
private final String f_92537_;
@@ -21,8 +_,22 @@
private final Optional<String> f_193796_;
private final Optional<String> f_193797_;
private final User.Type f_92538_;
+ /** Forge: Cache of the local session's GameProfile properties. */
+ private com.mojang.authlib.properties.PropertyMap properties;
public User(String p_92540_, String p_92541_, String p_92542_, String p_92543_) {
+ if (p_92540_ == null || p_92540_.isEmpty()) {
+ p_92540_ = "MissingName";
+ p_92541_ = p_92542_ = "NotValid";
public User(String p_193799_, String p_193800_, String p_193801_, Optional<String> p_193802_, Optional<String> p_193803_, User.Type p_193804_) {
+ if (p_193799_ == null || p_193799_.isEmpty()) {
+ p_193799_ = "MissingName";
+ p_193800_ = p_193801_ = "NotValid";
+ org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger(getClass().getName());
+ logger.warn("=========================================================");
+ logger.warn("WARNING!! the username was not set for this session, typically");
@@ -20,10 +20,10 @@
+ logger.warn("when asking for help!");
+ logger.warn("=========================================================");
+ }
this.f_92535_ = p_92540_;
this.f_92536_ = p_92541_;
this.f_92537_ = p_92542_;
@@ -45,10 +_,22 @@
this.f_92535_ = p_193799_;
this.f_92536_ = p_193800_;
this.f_92537_ = p_193801_;
@@ -58,10 +_,22 @@
public GameProfile m_92548_() {
try {
UUID uuid = UUIDTypeAdapter.fromString(this.m_92545_());
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/Gui.java
+++ b/net/minecraft/client/gui/Gui.java
@@ -446,6 +_,10 @@
@@ -463,6 +_,10 @@
for(MobEffectInstance mobeffectinstance : Ordering.natural().reverse().sortedCopy(collection)) {
MobEffect mobeffect = mobeffectinstance.m_19544_();
@@ -9,17 +9,17 @@
+ // Rebind in case previous renderHUDEffect changed texture
+ RenderSystem.m_157456_(0, AbstractContainerScreen.f_97725_);
if (mobeffectinstance.m_19575_()) {
int k = this.f_92977_;
int l = 1;
@@ -483,6 +_,7 @@
int i = this.f_92977_;
int j = 1;
@@ -500,6 +_,7 @@
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, f1);
m_93200_(p_93029_, j1 + 3, k1 + 3, this.m_93252_(), 18, 18, textureatlassprite);
m_93200_(p_93029_, l + 3, i1 + 3, this.m_93252_(), 18, 18, textureatlassprite);
});
+ renderer.renderHUDEffect(mobeffectinstance,this, p_93029_, k, l, this.m_93252_(), f);
+ renderer.renderHUDEffect(mobeffectinstance,this, p_93029_, i, j, this.m_93252_(), f);
}
}
@@ -608,7 +_,8 @@
@@ -625,7 +_,8 @@
mutablecomponent.m_130940_(ChatFormatting.ITALIC);
}
@@ -29,7 +29,7 @@
int j = (this.f_92977_ - i) / 2;
int k = this.f_92978_ - 59;
if (!this.f_92986_.f_91072_.m_105205_()) {
@@ -624,7 +_,13 @@
@@ -641,7 +_,13 @@
RenderSystem.m_69478_();
RenderSystem.m_69453_();
m_93172_(p_93070_, j - 2, k - 2, j + i + 2, k + 9 + 2, this.f_92986_.f_91066_.m_92143_(0));
@@ -44,7 +44,7 @@
RenderSystem.m_69461_();
}
}
@@ -1128,7 +_,7 @@
@@ -1153,7 +_,7 @@
ItemStack itemstack = this.f_92986_.f_91074_.m_150109_().m_36056_();
if (itemstack.m_41619_()) {
this.f_92993_ = 0;
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/gui/MapRenderer.java
+++ b/net/minecraft/client/gui/MapRenderer.java
@@ -123,6 +_,7 @@
@@ -118,6 +_,7 @@
for(MapDecoration mapdecoration : this.f_93280_.m_164811_()) {
if (!p_93294_ || mapdecoration.m_77809_()) {
@@ -13,4 +13,4 @@
+
@OnlyIn(Dist.CLIENT)
public abstract static class Entry<E extends AbstractSelectionList.Entry<E>> implements GuiEventListener {
@Deprecated
/** @deprecated */
@@ -5,7 +5,7 @@
for(LerpingBossEvent lerpingbossevent : this.f_93699_.values()) {
int k = i / 2 - 91;
+ net.minecraftforge.client.event.RenderGameOverlayEvent.BossInfo event =
+ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPre(p_93705_, this.f_93698_.m_91268_(), lerpingbossevent, k, j, 10 + this.f_93698_.f_91062_.f_92710_);
+ net.minecraftforge.client.ForgeHooksClient.renderBossEventPre(p_93705_, this.f_93698_.m_91268_(), lerpingbossevent, k, j, 10 + this.f_93698_.f_91062_.f_92710_);
+ if (!event.isCanceled()) {
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.m_157456_(0, f_93697_);
@@ -17,7 +17,7 @@
- j += 10 + 9;
+ }
+ j += event.getIncrement();
+ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPost(p_93705_, this.f_93698_.m_91268_());
+ net.minecraftforge.client.ForgeHooksClient.renderBossEventPost(p_93705_, this.f_93698_.m_91268_());
if (j >= this.f_93698_.m_91268_().m_85446_() / 3) {
break;
}
Loaded 100 of 1379 files, more files were not shown because too many files have changed in this diff. Show more