Compare commits

...
128 Commits
Author SHA1 Message Date
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
471 changed files with 9625 additions and 3545 deletions

No files matched your search

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
}
}
}
+24 -14
View File
@@ -46,15 +46,16 @@ ext {
MAPPING_VERSION = '1.17.1'
MC_VERSION = '1.17.1'
MCP_VERSION = '20210706.113038'
SPI_VERSION = '4.0.9'
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'
SECUREJARHANDLER_VERSION = '0.9.54'
BOOTSTRAPLAUNCHER_VERSION = '0.1.17'
ASM_VERSION = '9.1'
INSTALLER_VERSION = '2.1.4'
INSTALLER_VERSION = '2.1.+'
MIXIN_VERSION = '0.8.4'
GIT_INFO = gradleutils.gitInfo
VERSION = gradleutils.getFilteredMCTagOffsetBranchVersion(true, '[0-9]', MC_VERSION)
@@ -110,6 +111,15 @@ subprojects {
java.toolchain.languageVersion = JavaLanguageVersion.of(16)
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 {
mavenJava(MavenPublication) {
@@ -248,8 +258,8 @@ def sharedDeps = {
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 "org.spongepowered:mixin:${MIXIN_VERSION}"
installer 'org.openjdk.nashorn:nashorn-core:15.3'
installer 'com.google.guava:guava:21.0'
installer 'com.google.code.gson:gson:2.8.0'
@@ -391,12 +401,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 '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.8.0.jar,jna-platform-58.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'
@@ -570,8 +581,7 @@ project(':fmlonly') {
'--fml.mcVersion', MC_VERSION,
'--fml.forgeGroup', project.group,
'--fml.mcpVersion', MCP_VERSION],
jvm: ['-DlegacyClassPath=${classpath}',
"-DignoreList=${fmlonly_client.properties.ignoreList}",
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}'),
@@ -586,7 +596,7 @@ project(':fmlonly') {
}
}
task installerJson(type: InstallerJson) {
task installerJson(type: InstallerJson, dependsOn: 'signUniversalJar') {
icon = rootProject.file('icon.ico')
packedDependencies = PACKED_DEPS
@@ -930,6 +940,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,8 +1089,7 @@ project(':forge') {
'--fml.mcVersion', MC_VERSION,
'--fml.forgeGroup', project.group,
'--fml.mcpVersion', MCP_VERSION],
jvm: ['-DlegacyClassPath=${classpath}',
"-DignoreList=${forge_client.properties.ignoreList}",
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}'),
@@ -1094,7 +1104,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())
@@ -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())
}
}
-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.
+5 -5
View File
@@ -2,16 +2,16 @@
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.17.1-&query=$.promos["1.17.1-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.17.1-&query=$.promos["1.17.1-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.17.x | Active |
| 1.16.x | LTS |
* [Download]
* [Forum]
@@ -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.
*
@@ -32,30 +32,30 @@ public interface IExtensionPoint<T extends Record>
* The predicate tests the version from a remote instance or save for acceptability (Boolean is true for network, 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.fmllegacy.network.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,
* 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);
});
}
@@ -53,7 +53,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 +61,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() {
@@ -19,29 +19,34 @@
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;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import static net.minecraftforge.fml.VersionChecker.Status.*;
@@ -49,6 +54,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 +114,8 @@ public class VersionChecker
{
new Thread("Forge Version Check")
{
private HttpClient client;
@Override
public void run()
{
@@ -117,46 +125,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 +181,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 +192,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());
@@ -19,7 +19,6 @@
package net.minecraftforge.common.asm;
import java.nio.file.Path;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -33,6 +32,7 @@ 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.
*/
@Deprecated(since = "1.18", forRemoval = true)
public class CapabilityInjectDefinalize implements ILaunchPluginService {
private final String CAP = "Lnet/minecraftforge/common/capabilities/Capability;"; //Don't directly reference this to prevent class loading.
@@ -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.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;
}
}
@@ -138,9 +138,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
@@ -44,11 +44,18 @@ public class LibraryFinder {
return libsPath;
}
// Not used anywhere in Forge's codebase, scheduled for deletion unless a good need is expressed.
@Deprecated(forRemoval = true, since = "1.17.1")
public static Path findJarPathFor(final String className, final String jarName) {
final URL resource = LibraryFinder.class.getClassLoader().getResource(className);
return findJarPathFor(className, jarName, resource);
}
/*
* Only used in ClasspathLocator now, so moved too a private method and depreciated this.
* Scheduled for deletion unless a good need is expressed.
*/
@Deprecated(forRemoval = true, since = "1.17.1")
public static Path findJarPathFor(final String resourceName, final String jarName, final URL resource) {
try {
Path path;
@@ -93,7 +100,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"));
}
}
@@ -92,6 +92,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 +151,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 +162,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()
@@ -242,6 +247,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"))));
}
}
@@ -20,6 +20,10 @@
package net.minecraftforge.fml.loading.moddiscovery;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.jarhandling.JarMetadata;
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,9 +32,13 @@ 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;
@@ -38,6 +46,8 @@ import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
public abstract class AbstractJarFileLocator 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";
@Override
public void scanFile(final IModFile file, final Consumer<Path> pathConsumer) {
@@ -54,7 +64,9 @@ public abstract class AbstractJarFileLocator implements IModLocator {
@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());
}
@@ -64,4 +76,64 @@ public abstract class AbstractJarFileLocator implements IModLocator {
public boolean isValid(final IModFile modFile) {
return true;
}
private 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 = null;
var type = sj.getManifest().getMainAttributes().getValue(ModFile.TYPE);
if (sj.findFile(MODS_TOML).isPresent()) {
LOGGER.debug(SCAN, "Found {} mod of type {}: {}", MODS_TOML, type, path);
mod = ModFile.newFMLInstance(this, sj);
} else if (type != null) {
LOGGER.debug(SCAN, "Found {} mod of type {}: {}", MANIFEST, type, path);
mod = new ModFile(sj, this, this::manifestParser);
} else {
return Optional.empty();
}
mjm.setModFile(mod);
return Optional.ofNullable(mod);
}
private 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() + ")";
}
};
}
}
@@ -24,6 +24,8 @@ import net.minecraftforge.fml.loading.LoadingModList;
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.*;
@@ -32,12 +34,22 @@ 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")
@@ -51,6 +63,7 @@ public class BackgroundScanHandler
scannedFiles = new ArrayList<>();
pendingFiles = new ArrayList<>();
allFiles = new ArrayList<>();
status = ScanStatus.NOT_STARTED;
}
public List<ModFile> getModFiles() {
@@ -59,8 +72,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,6 +86,7 @@ public class BackgroundScanHandler
private void addCompletedFile(final ModFile file, final ModFileScanData modFileScanData, final Throwable throwable) {
if (throwable != null) {
status = ScanStatus.ERRORED;
LOGGER.error(SCAN,"An error occurred scanning file {}", file, throwable);
}
pendingFiles.remove(file);
@@ -88,18 +104,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 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;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN;
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(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(SCAN, "Failed to find JAR for class {} - {}", resourceName, jarName);
throw new RuntimeException("Unable to locate "+resourceName+" - "+jarName, e);
}
}
}
@@ -29,9 +29,8 @@ 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;
@@ -61,16 +60,21 @@ 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())))
var loadedFiles = new ArrayList<>();
for (IModLocator locator : locatorList) {
LOGGER.debug(SCAN,"Trying locator {}", locator);
var modFiles = locator.scanMods();
for (IModFile mf : modFiles) {
LOGGER.info(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;
}
@@ -49,6 +49,8 @@ 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.17.1")
public static final Manifest DEFAULTMANIFEST;
private static final Logger LOGGER = LogManager.getLogger();
@@ -72,6 +74,7 @@ public class ModFile implements IModFile {
private List<CoreModFile> coreMods;
private Path accessTransformer;
//TODO: Make package private in 1.18+
public static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
private SecureJar.Status securityStatus;
@@ -116,7 +119,7 @@ public class ModFile implements IModFile {
public boolean identifyMods() {
this.modFileInfo = ModFileParser.readModList(this, this.parser);
if (this.modFileInfo == null) return false;
if (this.modFileInfo == null) return this.getType() != Type.MOD;
LOGGER.debug(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()));
@@ -139,8 +142,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 +170,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");
}
@@ -214,17 +213,24 @@ public class ModFile implements IModFile {
return modFileInfo;
}
// TODO: Remove concept of factory from forgeapi.. Why expose this?
@Deprecated(forRemoval = true, since="1.17.1")
public static ModFileFactory buildFactory() {
return ModFile::new;
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.17.1")
public static ModFile newFMLInstance(final IModLocator locator, final SecureJar jar) {
return (ModFile) ModFileFactory.FACTORY.build(jar, locator, ModFileParser::modsTomlParser);
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.17.1")
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,13 @@ 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.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,7 +40,6 @@ 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;
@@ -17,18 +17,26 @@ public final class ModJarMetadata implements JarMetadata {
private IModFile modFile;
private ModuleDescriptor descriptor;
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.17.1")
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.17.1")
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);
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.17.1")
static IModFile buildFile(IModLocator locator, Path... files) {
return buildFile(locator, j->true, files).orElseThrow(()->new IllegalArgumentException("Failed to find valid JAR file"));
}
// TODO: Remove helper functions to cleanup api
@Deprecated(forRemoval = true, since="1.17.1")
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 +49,7 @@ public final class ModJarMetadata implements JarMetadata {
}
}
private ModJarMetadata() {
ModJarMetadata() {
}
public void setModFile(IModFile file) {
@@ -1,20 +1,15 @@
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.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 {
@@ -27,9 +22,14 @@ 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() {
@@ -22,16 +22,13 @@ package net.minecraftforge.fml.loading.moddiscovery;
import net.minecraftforge.fml.loading.FMLPaths;
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;
@@ -1,4 +1,5 @@
net.minecraftforge.fml.loading.RuntimeDistCleaner
net.minecraftforge.common.asm.RuntimeEnumExtender
net.minecraftforge.common.asm.ObjectHolderDefinalize
net.minecraftforge.common.asm.CapabilityInjectDefinalize
net.minecraftforge.common.asm.CapabilityInjectDefinalize
net.minecraftforge.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
+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.2-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
{
+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": 7
}
}
@@ -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,5 +1,14 @@
--- a/net/minecraft/advancements/Advancement.java
+++ b/net/minecraft/advancements/Advancement.java
@@ -127,7 +_,7 @@
return this.f_138305_;
}
- public static class Builder {
+ public static class Builder implements net.minecraftforge.common.extensions.IForgeAdvancementBuilder {
private ResourceLocation f_138332_;
private Advancement f_138333_;
private DisplayInfo f_138334_;
@@ -311,6 +_,7 @@
}
@@ -1,13 +1,14 @@
--- 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_;
@@ -257,7 +_,7 @@
import org.lwjgl.util.tinyfd.TinyFileDialogs;
@OnlyIn(Dist.CLIENT)
-public class Minecraft extends ReentrantBlockableEventLoop<Runnable> implements SnooperPopulator, WindowEventHandler {
+public class Minecraft extends ReentrantBlockableEventLoop<Runnable> implements SnooperPopulator, WindowEventHandler, net.minecraftforge.client.extensions.IForgeMinecraft {
private static Minecraft f_90981_;
private static final Logger f_90982_ = LogManager.getLogger();
public static final boolean f_91002_ = Util.m_137581_() == Util.OS.OSX;
@@ -397,14 +_,13 @@
this.f_91029_ = p_91084_.f_101908_.f_101928_;
this.f_90986_ = p_91084_.f_101905_.f_101944_;
@@ -24,6 +25,14 @@
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_;
@@ -436,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);
@@ -450,7 +_,6 @@
this.f_90990_.m_85380_(this.f_91066_.f_92113_);
@@ -58,6 +67,17 @@
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_()) {
@@ -531,6 +_,10 @@
TinyFileDialogs.tinyfd_messageBox("Minecraft", stringbuilder.toString(), "ok", "error", false);
}
+ 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_();
@@ -546,13 +_,16 @@
}
@@ -124,14 +144,6 @@
}
}
@@ -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 @@
f_90982_.error("setScreen called from non-game thread");
}
@@ -143,10 +155,11 @@
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 @@
@@ -890,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_);
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event)) return;
@@ -172,7 +185,12 @@
}
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_);
@@ -385,7 +403,7 @@
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_);
@@ -398,7 +416,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.handleClientWorldClosing(f_91073_);
this.f_91004_.m_90740_();
}
@@ -480,14 +498,6 @@
}
}
@@ -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 @@
return this.f_90993_;
}
+9 -5
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);
+ if (!aboolean[0]) {
+ aboolean[0] = this.f_91503_.f_91080_.m_6375_(d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseClickedPost(this.f_91503_.f_91080_, 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);
+ if (!aboolean[0]) {
+ aboolean[0] = this.f_91503_.f_91080_.m_6348_(d0, d1, i);
+ aboolean[0] = net.minecraftforge.client.ForgeHooksClient.onGuiMouseReleasedPost(this.f_91503_.f_91080_, d0, d1, i, aboolean[0]);
+ }
}, "mouseReleased event handler", screen.getClass().getCanonicalName());
}
}
@@ -1,11 +0,0 @@
--- a/net/minecraft/client/gui/screens/LanguageSelectScreen.java
+++ b/net/minecraft/client/gui/screens/LanguageSelectScreen.java
@@ -36,7 +_,7 @@
if (languageselectscreen$languageselectionlist$entry != null && !languageselectscreen$languageselectionlist$entry.f_96116_.getCode().equals(this.f_96080_.m_118983_().getCode())) {
this.f_96080_.m_118974_(languageselectscreen$languageselectionlist$entry.f_96116_);
this.f_96282_.f_92075_ = languageselectscreen$languageselectionlist$entry.f_96116_.getCode();
- this.f_96541_.m_91391_();
+ net.minecraftforge.client.ForgeHooksClient.refreshResources(this.f_96541_, net.minecraftforge.resource.VanillaResourceType.LANGUAGES);
this.f_96282_.m_92169_();
}
@@ -1,68 +1,142 @@
--- a/net/minecraft/client/gui/screens/Screen.java
+++ b/net/minecraft/client/gui/screens/Screen.java
@@ -163,7 +_,10 @@
@@ -125,7 +_,7 @@
}
public void m_7379_() {
- this.f_96541_.m_91152_((Screen)null);
+ this.f_96541_.popGuiLayer();
}
protected <T extends GuiEventListener & Widget & NarratableEntry> T m_142416_(T p_169406_) {
@@ -162,15 +_,29 @@
this.f_169368_.clear();
}
+ private Font tooltipFont = null;
+ private ItemStack tooltipStack = ItemStack.f_41583_;
protected void m_6057_(PoseStack p_96566_, ItemStack p_96567_, int p_96568_, int p_96569_) {
- this.m_169388_(p_96566_, this.m_96555_(p_96567_), p_96567_.m_150921_(), p_96568_, p_96569_);
+ Font font = net.minecraftforge.client.RenderProperties.get(p_96567_).getFont(p_96567_);
+ net.minecraftforge.fmlclient.gui.GuiUtils.preItemToolTip(p_96567_);
+ this.renderComponentToolTip(p_96566_, this.m_96555_(p_96567_), p_96568_, p_96569_, (font == null ? this.f_96547_ : font));
+ net.minecraftforge.fmlclient.gui.GuiUtils.postItemToolTip();
+ tooltipStack = p_96567_;
this.m_169388_(p_96566_, this.m_96555_(p_96567_), p_96567_.m_150921_(), p_96568_, p_96569_);
+ tooltipStack = ItemStack.f_41583_;
}
+ public void renderTooltip(PoseStack poseStack, List<Component> textComponents, Optional<TooltipComponent> tooltipComponent, int x, int y, ItemStack stack) {
+ this.renderTooltip(poseStack, textComponents, tooltipComponent, x, y, null, stack);
+ }
+ public void renderTooltip(PoseStack poseStack, List<Component> textComponents, Optional<TooltipComponent> tooltipComponent, int x, int y, @Nullable Font font) {
+ this.renderTooltip(poseStack, textComponents, tooltipComponent, x, y, font, ItemStack.f_41583_);
+ }
+ public void renderTooltip(PoseStack poseStack, List<Component> textComponents, Optional<TooltipComponent> tooltipComponent, int x, int y, @Nullable Font font, ItemStack stack) {
+ this.tooltipFont = font;
+ this.tooltipStack = stack;
+ this.m_169388_(poseStack, textComponents, tooltipComponent, x, y);
+ this.tooltipFont = null;
+ this.tooltipStack = ItemStack.f_41583_;
+ }
public void m_169388_(PoseStack p_169389_, List<Component> p_169390_, Optional<TooltipComponent> p_169391_, int p_169392_, int p_169393_) {
@@ -171,7 +_,7 @@
p_169391_.ifPresent((p_169399_) -> {
list.add(1, ClientTooltipComponent.m_169950_(p_169399_));
});
- this.m_169383_(p_169389_, list, p_169392_, p_169393_);
+ this.renderTooltipInternal(p_169389_, list, p_169392_, p_169393_, f_96547_);
- List<ClientTooltipComponent> list = p_169390_.stream().map(Component::m_7532_).map(ClientTooltipComponent::m_169948_).collect(Collectors.toList());
- p_169391_.ifPresent((p_169399_) -> {
- list.add(1, ClientTooltipComponent.m_169950_(p_169399_));
- });
+ List<ClientTooltipComponent> list = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_169390_, p_169391_, p_169392_, f_96543_, f_96544_, this.tooltipFont, this.f_96547_);
this.m_169383_(p_169389_, list, p_169392_, p_169393_);
}
public List<Component> m_96555_(ItemStack p_96556_) {
@@ -179,24 +_,30 @@
}
public void m_96602_(PoseStack p_96603_, Component p_96604_, int p_96605_, int p_96606_) {
- this.m_96617_(p_96603_, Arrays.asList(p_96604_.m_7532_()), p_96605_, p_96606_);
+ this.m_96597_(p_96603_, Arrays.asList(p_96604_), p_96605_, p_96606_);
@@ -183,20 +_,48 @@
}
public void m_96597_(PoseStack p_96598_, List<Component> p_96599_, int p_96600_, int p_96601_) {
- this.m_96617_(p_96598_, Lists.transform(p_96599_, Component::m_7532_), p_96600_, p_96601_);
+ this.renderComponentToolTip(p_96598_, p_96599_, p_96600_, p_96601_, f_96547_);
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, p_96599_, p_96600_, f_96543_, f_96544_, this.tooltipFont, this.f_96547_);
+ this.m_169383_(p_96598_, components, p_96600_, p_96601_);
+ }
+ public void renderComponentToolTip(PoseStack matrixStack, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, Font font) {
+ net.minecraftforge.fmlclient.gui.GuiUtils.drawHoveringText(matrixStack, tooltips, mouseX, mouseY, f_96543_, f_96544_, -1, font);
+ public void renderComponentTooltip(PoseStack poseStack, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, ItemStack stack) {
+ this.renderComponentTooltip(poseStack, tooltips, mouseX, mouseY, null, stack);
+ }
+ public void renderComponentTooltip(PoseStack poseStack, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, @Nullable Font font) {
+ this.renderComponentTooltip(poseStack, tooltips, mouseX, mouseY, font, ItemStack.f_41583_);
+ }
+ @Deprecated(forRemoval = true, since = "1.17.1") public void renderComponentToolTip(PoseStack poseStack, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, @Nullable Font font) {
+ renderComponentTooltip(poseStack, tooltips, mouseX, mouseY, font);
+ }
+ public void renderComponentTooltip(PoseStack poseStack, List<? extends net.minecraft.network.chat.FormattedText> tooltips, int mouseX, int mouseY, @Nullable Font font, ItemStack stack) {
+ this.tooltipFont = font;
+ this.tooltipStack = stack;
+ List<ClientTooltipComponent> components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(stack, tooltips, mouseX, f_96543_, f_96544_, this.tooltipFont, this.f_96547_);
+ this.m_169383_(poseStack, components, mouseX, mouseY);
+ this.tooltipFont = null;
+ this.tooltipStack = ItemStack.f_41583_;
}
public void m_96617_(PoseStack p_96618_, List<? extends FormattedCharSequence> p_96619_, int p_96620_, int p_96621_) {
- this.m_169383_(p_96618_, p_96619_.stream().map(ClientTooltipComponent::m_169948_).collect(Collectors.toList()), p_96620_, p_96621_);
+ this.renderToolTip(p_96618_, p_96619_, p_96620_, p_96621_, f_96547_);
+ }
+ public void renderToolTip(PoseStack p_96618_, List<? extends FormattedCharSequence> p_96619_, int p_96620_, int p_96621_, Font font) {
+ this.renderTooltipInternal(p_96618_, p_96619_.stream().map(ClientTooltipComponent::m_169948_).collect(Collectors.toList()), p_96620_, p_96621_, font);
this.m_169383_(p_96618_, p_96619_.stream().map(ClientTooltipComponent::m_169948_).collect(Collectors.toList()), p_96620_, p_96621_);
}
+ @Deprecated(forRemoval = true, since = "1.17.1") public void renderToolTip(PoseStack p_96618_, List<? extends FormattedCharSequence> p_96619_, int p_96620_, int p_96621_, Font font) {
+ renderTooltip(p_96618_, p_96619_, p_96620_, p_96621_, font);
+ }
+ public void renderTooltip(PoseStack poseStack, List<? extends FormattedCharSequence> lines, int x, int y, Font font) {
+ this.tooltipFont = font;
+ this.m_96617_(poseStack, lines, x, y);
+ this.tooltipFont = null;
+ }
- private void m_169383_(PoseStack p_169384_, List<ClientTooltipComponent> p_169385_, int p_169386_, int p_169387_) {
+ private void renderTooltipInternal(PoseStack p_169384_, List<ClientTooltipComponent> p_169385_, int p_169386_, int p_169387_, Font font) {
private void m_169383_(PoseStack p_169384_, List<ClientTooltipComponent> p_169385_, int p_169386_, int p_169387_) {
if (!p_169385_.isEmpty()) {
+ net.minecraftforge.client.event.RenderTooltipEvent.Pre preEvent = net.minecraftforge.client.ForgeHooksClient.preTooltipEvent(this.tooltipStack, p_169384_, p_169386_, p_169387_, f_96543_, f_96544_, p_169385_, this.tooltipFont, this.f_96547_);
+ if (preEvent.isCanceled()) return;
int i = 0;
int j = p_169385_.size() == 1 ? -2 : 0;
for(ClientTooltipComponent clienttooltipcomponent : p_169385_) {
- int k = clienttooltipcomponent.m_142069_(this.f_96547_);
+ int k = clienttooltipcomponent.m_142069_(font);
+ int k = clienttooltipcomponent.m_142069_(preEvent.getFontRenderer());
if (k > i) {
i = k;
}
@@ -204,8 +_,8 @@
j += clienttooltipcomponent.m_142103_();
}
- int j2 = p_169386_ + 12;
- int k2 = p_169387_ - 12;
+ int j2 = preEvent.getX() + 12;
+ int k2 = preEvent.getY() - 12;
if (j2 + i > this.f_96543_) {
j2 -= 28 + i;
}
@@ -226,15 +_,16 @@
RenderSystem.m_157427_(GameRenderer::m_172811_);
bufferbuilder.m_166779_(VertexFormat.Mode.QUADS, DefaultVertexFormat.f_85815_);
Matrix4f matrix4f = p_169384_.m_85850_().m_85861_();
- m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 4, j2 + i + 3, k2 - 3, 400, -267386864, -267386864);
- m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 + j + 3, j2 + i + 3, k2 + j + 4, 400, -267386864, -267386864);
- m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 3, j2 + i + 3, k2 + j + 3, 400, -267386864, -267386864);
- m_93123_(matrix4f, bufferbuilder, j2 - 4, k2 - 3, j2 - 3, k2 + j + 3, 400, -267386864, -267386864);
- m_93123_(matrix4f, bufferbuilder, j2 + i + 3, k2 - 3, j2 + i + 4, k2 + j + 3, 400, -267386864, -267386864);
- m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 3 + 1, j2 - 3 + 1, k2 + j + 3 - 1, 400, 1347420415, 1344798847);
- m_93123_(matrix4f, bufferbuilder, j2 + i + 2, k2 - 3 + 1, j2 + i + 3, k2 + j + 3 - 1, 400, 1347420415, 1344798847);
- m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 3, j2 + i + 3, k2 - 3 + 1, 400, 1347420415, 1347420415);
- m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 + j + 2, j2 + i + 3, k2 + j + 3, 400, 1344798847, 1344798847);
+ net.minecraftforge.client.event.RenderTooltipEvent.Color colorEvent = net.minecraftforge.client.ForgeHooksClient.colorTooltipEvent(this.tooltipStack, p_169384_, j2, k2, preEvent.getFontRenderer(), p_169385_);
+ m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 4, j2 + i + 3, k2 - 3, 400, colorEvent.getBackgroundStart(), colorEvent.getBackgroundStart());
+ m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 + j + 3, j2 + i + 3, k2 + j + 4, 400, colorEvent.getBackgroundEnd(), colorEvent.getBackgroundEnd());
+ m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 3, j2 + i + 3, k2 + j + 3, 400, colorEvent.getBackgroundStart(), colorEvent.getBackgroundEnd());
+ m_93123_(matrix4f, bufferbuilder, j2 - 4, k2 - 3, j2 - 3, k2 + j + 3, 400, colorEvent.getBackgroundStart(), colorEvent.getBackgroundEnd());
+ m_93123_(matrix4f, bufferbuilder, j2 + i + 3, k2 - 3, j2 + i + 4, k2 + j + 3, 400, colorEvent.getBackgroundStart(), colorEvent.getBackgroundEnd());
+ m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 3 + 1, j2 - 3 + 1, k2 + j + 3 - 1, 400, colorEvent.getBorderStart(), colorEvent.getBorderEnd());
+ m_93123_(matrix4f, bufferbuilder, j2 + i + 2, k2 - 3 + 1, j2 + i + 3, k2 + j + 3 - 1, 400, colorEvent.getBorderStart(), colorEvent.getBorderEnd());
+ m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 - 3, j2 + i + 3, k2 - 3 + 1, 400, colorEvent.getBorderStart(), colorEvent.getBorderStart());
+ m_93123_(matrix4f, bufferbuilder, j2 - 3, k2 + j + 2, j2 + i + 3, k2 + j + 3, 400, colorEvent.getBorderEnd(), colorEvent.getBorderEnd());
RenderSystem.m_69482_();
RenderSystem.m_69472_();
RenderSystem.m_69478_();
@@ -249,7 +_,7 @@
for(int i2 = 0; i2 < p_169385_.size(); ++i2) {
ClientTooltipComponent clienttooltipcomponent1 = p_169385_.get(i2);
- clienttooltipcomponent1.m_142440_(this.f_96547_, j2, l1, matrix4f, multibuffersource$buffersource);
+ clienttooltipcomponent1.m_142440_(font, j2, l1, matrix4f, multibuffersource$buffersource);
+ clienttooltipcomponent1.m_142440_(preEvent.getFontRenderer(), j2, l1, matrix4f, multibuffersource$buffersource);
l1 += clienttooltipcomponent1.m_142103_() + (i2 == 0 ? 2 : 0);
}
@@ -71,7 +145,7 @@
for(int l2 = 0; l2 < p_169385_.size(); ++l2) {
ClientTooltipComponent clienttooltipcomponent2 = p_169385_.get(l2);
- clienttooltipcomponent2.m_142162_(this.f_96547_, j2, l1, p_169384_, this.f_96542_, 400, this.f_96541_.m_91097_());
+ clienttooltipcomponent2.m_142162_(font, j2, l1, p_169384_, this.f_96542_, 400, this.f_96541_.m_91097_());
+ clienttooltipcomponent2.m_142162_(preEvent.getFontRenderer(), j2, l1, p_169384_, this.f_96542_, 400, this.f_96541_.m_91097_());
l1 += clienttooltipcomponent2.m_142103_() + (l2 == 0 ? 2 : 0);
}
@@ -88,19 +162,16 @@
this.f_96541_.f_91074_.m_108739_(p_96613_);
}
@@ -366,11 +_,24 @@
@@ -366,11 +_,21 @@
this.f_96547_ = p_96607_.f_91062_;
this.f_96543_ = p_96608_;
this.f_96544_ = p_96609_;
+ java.util.function.Consumer<GuiEventListener> add = (b) -> {
+ if (b instanceof Widget) {
+ this.f_169369_.add((Widget)b);
+ }
+
+ if (b instanceof NarratableEntry) {
+ this.f_169368_.add((NarratableEntry)b);
+ }
+ f_96540_.remove(b);
+ if (b instanceof Widget w)
+ this.f_169369_.add(w);
+ if (b instanceof NarratableEntry ne)
+ this.f_169368_.add(ne);
+ f_96540_.add(b);
+ };
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent.Pre(this, this.f_96540_, add, this::m_169411_))) {
this.m_169413_();
@@ -13,7 +13,7 @@
int l = slot.f_40220_;
int i1 = slot.f_40221_;
- m_169606_(p_97795_, l, i1, this.m_93252_());
+ renderSlotHighlight(p_97795_, l, i1, this.m_93252_(), this.getSlotColor(i1));
+ renderSlotHighlight(p_97795_, l, i1, this.m_93252_(), this.getSlotColor(k));
}
}
@@ -173,15 +173,12 @@
RenderSystem.m_157429_(1.0F, 1.0F, 1.0F, 1.0F);
this.m_7025_(p_98577_, p_98578_, p_98579_);
}
@@ -620,7 +_,10 @@
@@ -620,7 +_,7 @@
list1.add(1, creativemodetab.m_40786_().m_6881_().m_130940_(ChatFormatting.BLUE));
}
- this.m_169388_(p_98590_, list1, p_98591_.m_150921_(), p_98592_, p_98593_);
+ net.minecraft.client.gui.Font font = net.minecraftforge.client.RenderProperties.get(p_98591_).getFont(p_98591_);
+ net.minecraftforge.fmlclient.gui.GuiUtils.preItemToolTip(p_98591_);
+ this.renderComponentToolTip(p_98590_, list1, p_98592_, p_98593_, (font == null ? this.f_96547_ : font));
+ net.minecraftforge.fmlclient.gui.GuiUtils.postItemToolTip();
+ this.renderTooltip(p_98590_, list1, p_98591_.m_150921_(), p_98592_, p_98593_, p_98591_);
} else {
super.m_6057_(p_98590_, p_98591_, p_98592_, p_98593_);
}
@@ -0,0 +1,11 @@
--- a/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java
+++ b/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java
@@ -22,6 +_,8 @@
if (p_169951_ instanceof BundleTooltip) {
return new ClientBundleTooltip((BundleTooltip)p_169951_);
} else {
+ ClientTooltipComponent result = net.minecraftforge.client.MinecraftForgeClient.getClientTooltipComponent(p_169951_);
+ if (result != null) return result;
throw new IllegalArgumentException("Unknown TooltipComponent");
}
}
@@ -4,7 +4,7 @@
this.f_99855_.m_99707_(list1);
}
+ net.minecraftforge.fmlclient.ClientHooks.drawForgePingInfo(this.f_99855_, f_99857_, p_99879_, p_99882_, p_99881_, p_99883_, i1, j1);
+ net.minecraftforge.client.ForgeHooksClient.drawForgePingInfo(this.f_99855_, f_99857_, p_99879_, p_99882_, p_99881_, p_99883_, i1, j1);
+
if (this.f_99856_.f_91066_.f_92051_ || p_99887_) {
RenderSystem.m_157456_(0, ServerSelectionList.f_99759_);
@@ -9,12 +9,12 @@
this.f_100279_.add(new RecipeBookTabButton(recipebookcategories));
}
@@ -462,7 +_,7 @@
languagemanager.m_118974_(languageinfo);
this.f_100272_.f_91066_.f_92075_ = languageinfo.getCode();
- this.f_100272_.m_91391_();
+ net.minecraftforge.client.ForgeHooksClient.refreshResources(this.f_100272_, net.minecraftforge.resource.VanillaResourceType.LANGUAGES);
this.f_100272_.f_91066_.m_92169_();
@@ -319,7 +_,7 @@
}
if (itemstack != null && this.f_100272_.f_91080_ != null) {
- this.f_100272_.f_91080_.m_96597_(p_100375_, this.f_100272_.f_91080_.m_96555_(itemstack), p_100378_, p_100379_);
+ this.f_100272_.f_91080_.renderComponentTooltip(p_100375_, this.f_100272_.f_91080_.m_96555_(itemstack), p_100378_, p_100379_, itemstack);
}
}
@@ -0,0 +1,11 @@
--- a/net/minecraft/client/gui/screens/recipebook/RecipeBookPage.java
+++ b/net/minecraft/client/gui/screens/recipebook/RecipeBookPage.java
@@ -115,7 +_,7 @@
public void m_100417_(PoseStack p_100418_, int p_100419_, int p_100420_) {
if (this.f_100397_.f_91080_ != null && this.f_100395_ != null && !this.f_100396_.m_100212_()) {
- this.f_100397_.f_91080_.m_96597_(p_100418_, this.f_100395_.m_100477_(this.f_100397_.f_91080_), p_100419_, p_100420_);
+ this.f_100397_.f_91080_.renderComponentTooltip(p_100418_, this.f_100395_.m_100477_(this.f_100397_.f_91080_), p_100419_, p_100420_, this.f_100395_.m_100488_().m_8043_());
}
}
@@ -13,7 +13,7 @@
File file1 = path.toFile();
if (this.f_100832_ == null) {
this.f_100832_ = new PackRepository(PackType.SERVER_DATA, new ServerPacksSource(), new FolderRepositorySource(file1, PackSource.f_10527_));
+ net.minecraftforge.fmllegacy.packs.ResourcePackLoader.loadResourcePacks(this.f_100832_, net.minecraftforge.fmllegacy.server.ServerLifecycleHooks::buildPackFinder);
+ net.minecraftforge.fmllegacy.packs.ResourcePackLoader.loadResourcePacks(this.f_100832_, net.minecraftforge.fmllegacy.server.ServerLifecycleHooks::buildPackFinderNew);
this.f_100832_.m_10506_();
}
@@ -4,7 +4,7 @@
WoodType.m_61843_().forEach((p_171114_) -> {
builder.put(ModelLayers.m_171291_(p_171114_), layerdefinition19);
});
+ net.minecraftforge.fmlclient.registry.RenderingRegistry.loadLayerDefinitions(builder);
+ net.minecraftforge.client.ForgeHooksClient.loadLayerDefinitions(builder);
ImmutableMap<ModelLayerLocation, LayerDefinition> immutablemap = builder.build();
List<ModelLayerLocation> list = ModelLayers.m_171288_().filter((p_171117_) -> {
return !immutablemap.containsKey(p_171117_);
@@ -0,0 +1,12 @@
--- a/net/minecraft/client/model/geom/ModelLayers.java
+++ b/net/minecraft/client/model/geom/ModelLayers.java
@@ -199,7 +_,8 @@
}
public static ModelLayerLocation m_171291_(WoodType p_171292_) {
- return m_171300_("sign/" + p_171292_.m_61846_(), "main");
+ ResourceLocation location = new ResourceLocation(p_171292_.m_61846_());
+ return new ModelLayerLocation(new ResourceLocation(location.m_135827_(), "sign/" + location.m_135815_()), "main");
}
public static Stream<ModelLayerLocation> m_171288_() {
@@ -4,7 +4,7 @@
this.f_104888_.f_91064_.m_113434_();
this.f_104888_.f_91074_.m_172530_();
+ net.minecraftforge.fmlclient.ClientHooks.firePlayerLogin(this.f_104888_.f_91072_, this.f_104888_.f_91074_, this.f_104888_.m_91403_().m_6198_());
+ net.minecraftforge.client.ForgeHooksClient.firePlayerLogin(this.f_104888_.f_91072_, this.f_104888_.f_91074_, this.f_104888_.m_91403_().m_6198_());
int i = p_105030_.m_132398_();
this.f_104888_.f_91074_.m_20234_(i);
this.f_104889_.m_104630_(i, this.f_104888_.f_91074_);
@@ -43,7 +43,7 @@
+ localplayer1.updateSyncFields(localplayer); // Forge: fix MC-10657
localplayer1.m_172530_();
localplayer1.m_108748_(s);
+ net.minecraftforge.fmlclient.ClientHooks.firePlayerRespawn(this.f_104888_.f_91072_, localplayer, localplayer1, localplayer1.f_108617_.m_6198_());
+ net.minecraftforge.client.ForgeHooksClient.firePlayerRespawn(this.f_104888_.f_91072_, localplayer, localplayer1, localplayer1.f_108617_.m_6198_());
this.f_104889_.m_104630_(i, localplayer1);
localplayer1.m_146922_(-180.0F);
localplayer1.f_108618_ = new KeyboardInput(this.f_104888_.f_91066_);
@@ -77,23 +77,15 @@
if (mobeffect != null) {
MobEffectInstance mobeffectinstance = new MobEffectInstance(mobeffect, p_105130_.m_133625_(), p_105130_.m_133624_(), p_105130_.m_133627_(), p_105130_.m_133626_(), p_105130_.m_133628_());
mobeffectinstance.m_19562_(p_105130_.m_133619_());
@@ -1228,11 +_,14 @@
public void m_5859_(ClientboundUpdateTagsPacket p_105134_) {
PacketUtils.m_131363_(p_105134_, this, this.f_104888_);
TagContainer tagcontainer = TagContainer.m_144449_(this.f_104903_, p_105134_.m_179482_());
- Multimap<ResourceKey<? extends Registry<?>>, ResourceLocation> multimap = StaticTags.m_13283_(tagcontainer);
+ boolean vanillaConnection = net.minecraftforge.fmllegacy.network.NetworkHooks.isVanillaConnection(f_104885_);
+ Multimap<ResourceKey<? extends Registry<?>>, ResourceLocation> multimap = vanillaConnection ? StaticTags.m_13283_(net.minecraftforge.common.ForgeTagHandler.withNoCustom(tagcontainer)) : StaticTags.validateVanillaTags(tagcontainer);//Forge: If we are connecting to vanilla validate all tags to properly validate custom tags the client may "require", and if we are connecting to forge only validate the vanilla tag types as the custom tag types get synced in a separate packet so may still arrive
if (!multimap.isEmpty()) {
@@ -1233,6 +_,7 @@
f_104883_.warn("Incomplete server tags, disconnecting. Missing: {}", (Object)multimap);
this.f_104885_.m_129507_(new TranslatableComponent("multiplayer.disconnect.missing_tags"));
} else {
+ net.minecraftforge.common.ForgeTagHandler.resetCachedTagCollections(true, vanillaConnection);
+ tagcontainer = TagContainer.reinjectOptionalTags(tagcontainer);
+ tagcontainer = net.minecraftforge.common.ForgeTagHandler.reinjectOptionalTags(tagcontainer);
this.f_104895_ = tagcontainer;
if (!this.f_104885_.m_129531_()) {
tagcontainer.m_13431_();
@@ -1780,10 +_,12 @@
@@ -1780,7 +_,8 @@
int i5 = friendlybytebuf.m_130242_();
this.f_104888_.f_91064_.f_173815_.m_173830_(positionsource, i5);
} else {
@@ -103,7 +95,3 @@
}
} finally {
if (friendlybytebuf != null) {
+ if (false) // Forge: let packet handle releasing buffer
friendlybytebuf.release();
}
@@ -4,7 +4,7 @@
p_105461_.run();
}
+ net.minecraftforge.fmlclient.ClientHooks.processForgeListPingData(serverstatus, p_105460_);
+ net.minecraftforge.client.ForgeHooksClient.processForgeListPingData(serverstatus, p_105460_);
this.f_105477_ = Util.m_137550_();
connection.m_129512_(new ServerboundPingRequestPacket(this.f_105477_));
this.f_105475_ = true;
@@ -75,7 +75,23 @@
VoxelShape voxelshape = p_107357_.m_60808_(this.f_107287_, p_107356_);
double d0 = 0.25D;
voxelshape.m_83286_((p_172273_, p_172274_, p_172275_, p_172276_, p_172277_, p_172278_) -> {
@@ -500,6 +_,12 @@
@@ -450,7 +_,7 @@
double d7 = d4 * d1 + p_172273_;
double d8 = d5 * d2 + p_172274_;
double d9 = d6 * d3 + p_172275_;
- this.m_107344_(new TerrainParticle(this.f_107287_, (double)p_107356_.m_123341_() + d7, (double)p_107356_.m_123342_() + d8, (double)p_107356_.m_123343_() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D, p_107357_, p_107356_));
+ this.m_107344_(new TerrainParticle(this.f_107287_, (double)p_107356_.m_123341_() + d7, (double)p_107356_.m_123342_() + d8, (double)p_107356_.m_123343_() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D, p_107357_, p_107356_).updateSprite(p_107357_, p_107356_));
}
}
}
@@ -494,12 +_,18 @@
d0 = (double)i + aabb.f_82291_ + (double)0.1F;
}
- this.m_107344_((new TerrainParticle(this.f_107287_, d0, d1, d2, 0.0D, 0.0D, 0.0D, blockstate, p_107368_)).m_107268_(0.2F).m_6569_(0.6F));
+ this.m_107344_((new TerrainParticle(this.f_107287_, d0, d1, d2, 0.0D, 0.0D, 0.0D, blockstate, p_107368_).updateSprite(blockstate, p_107368_)).m_107268_(0.2F).m_6569_(0.6F));
}
}
public String m_107403_() {
return String.valueOf(this.f_107289_.values().stream().mapToInt(Collection::size).sum());
@@ -9,7 +9,7 @@
}
+ }
+
+ private Particle updateSprite(BlockState state, BlockPos pos) { //FORGE: we cannot assume that the x y z of the particles match the block pos of the block.
+ public Particle updateSprite(BlockState state, BlockPos pos) { //FORGE: we cannot assume that the x y z of the particles match the block pos of the block.
+ if (pos != null) // There are cases where we are not able to obtain the correct source pos, and need to fallback to the non-model data version
+ this.m_108337_(Minecraft.m_91087_().m_91289_().m_110907_().getTexture(state, f_107208_, pos));
+ return this;
@@ -37,6 +37,14 @@
this.f_108617_.m_104955_(new ServerboundPlayerCommandPacket(this, ServerboundPlayerCommandPacket.Action.START_FALL_FLYING));
}
}
@@ -807,6 +_,7 @@
public void m_6083_() {
super.m_6083_();
+ if (this.m_36342_() && this.m_20159_()) this.f_108618_.f_108573_ = false;
this.f_108611_ = false;
if (this.m_20202_() instanceof Boat) {
Boat boat = (Boat)this.m_20202_();
@@ -1004,6 +_,18 @@
} else {
return super.m_7398_(p_108758_);
@@ -9,6 +9,14 @@
}
}
@@ -541,6 +_,7 @@
list1.add(Pair.of(new ShaderInstance(p_172768_, "rendertype_crumbling", DefaultVertexFormat.f_85811_), (p_172733_) -> {
f_172607_ = p_172733_;
}));
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.RegisterShadersEvent(p_172768_, list1));
} catch (IOException ioexception) {
list1.forEach((p_172772_) -> {
p_172772_.getFirst().close();
@@ -703,7 +_,7 @@
d0 *= (double)Mth.m_14179_(this.f_109059_.f_91066_.f_92070_, 1.0F, 0.85714287F);
}
@@ -18,6 +26,20 @@
}
}
@@ -840,11 +_,11 @@
Window window = this.f_109059_.m_91268_();
RenderSystem.m_69421_(256, Minecraft.f_91002_);
- Matrix4f matrix4f = Matrix4f.m_162203_(0.0F, (float)((double)window.m_85441_() / window.m_85449_()), 0.0F, (float)((double)window.m_85442_() / window.m_85449_()), 1000.0F, 3000.0F);
+ Matrix4f matrix4f = Matrix4f.m_162203_(0.0F, (float)((double)window.m_85441_() / window.m_85449_()), 0.0F, (float)((double)window.m_85442_() / window.m_85449_()), 1000.0F, net.minecraftforge.client.ForgeHooksClient.getGuiFarPlane());
RenderSystem.m_157425_(matrix4f);
PoseStack posestack = RenderSystem.m_157191_();
posestack.m_166856_();
- posestack.m_85837_(0.0D, 0.0D, -2000.0D);
+ posestack.m_85837_(0.0D, 0.0D, 1000F-net.minecraftforge.client.ForgeHooksClient.getGuiFarPlane());
RenderSystem.m_157182_();
Lighting.m_84931_();
PoseStack posestack1 = new PoseStack();
@@ -879,7 +_,7 @@
}
} else if (this.f_109059_.f_91080_ != null) {
@@ -45,15 +67,3 @@
this.f_109059_.m_91307_().m_6182_("hand");
if (this.f_109070_) {
RenderSystem.m_69421_(256, Minecraft.f_91002_);
@@ -1151,6 +_,11 @@
public OverlayTexture m_109155_() {
return this.f_109075_;
+ }
+
+ @Override
+ public net.minecraftforge.resource.IResourceType getResourceType() {
+ return net.minecraftforge.resource.VanillaResourceType.SHADERS;
}
@Nullable
@@ -4,7 +4,7 @@
if (iteminhandrenderer$handrenderselection.f_172921_) {
float f4 = interactionhand == InteractionHand.MAIN_HAND ? f : 0.0F;
float f5 = 1.0F - Mth.m_14179_(p_109315_, this.f_109303_, this.f_109302_);
+ if(!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.MAIN_HAND, p_109316_, p_109317_, p_109319_, p_109315_, f1, f5, f2, this.f_109300_))
+ if(!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.MAIN_HAND, p_109316_, p_109317_, p_109319_, p_109315_, f1, f4, f5, this.f_109300_))
this.m_109371_(p_109318_, p_109315_, f1, InteractionHand.MAIN_HAND, f4, this.f_109300_, f5, p_109316_, p_109317_, p_109319_);
}
@@ -198,15 +198,3 @@
if (j < k) {
j = k;
}
@@ -2748,6 +_,11 @@
@Nullable
public RenderTarget m_109832_() {
return this.f_109417_;
+ }
+
+ @Override
+ public net.minecraftforge.resource.IResourceType getResourceType() {
+ return net.minecraftforge.resource.VanillaResourceType.MODELS;
}
@OnlyIn(Dist.CLIENT)
@@ -10,3 +10,11 @@
Resource resource = null;
try {
@@ -278,6 +_,7 @@
public void m_110038_(String p_110039_, int p_110040_, int p_110041_) {
RenderTarget rendertarget = new TextureTarget(p_110040_, p_110041_, true, Minecraft.f_91002_);
rendertarget.m_83931_(0.0F, 0.0F, 0.0F, 0.0F);
+ if (f_110006_.isStencilEnabled()) { rendertarget.enableStencil(); }
this.f_110010_.put(p_110039_, rendertarget);
if (p_110040_ == this.f_110013_ && p_110041_ == this.f_110014_) {
this.f_110011_.add(rendertarget);
@@ -0,0 +1,36 @@
--- a/net/minecraft/client/renderer/RenderType.java
+++ b/net/minecraft/client/renderer/RenderType.java
@@ -288,27 +_,27 @@
}
public static RenderType m_110497_(ResourceLocation p_110498_) {
- return f_173173_.apply(p_110498_);
+ return net.minecraftforge.client.ForgeRenderTypes.getText(p_110498_);
}
public static RenderType m_173237_(ResourceLocation p_173238_) {
- return f_173174_.apply(p_173238_);
+ return net.minecraftforge.client.ForgeRenderTypes.getTextIntensity(p_173238_);
}
public static RenderType m_181444_(ResourceLocation p_181445_) {
- return f_181442_.apply(p_181445_);
+ return net.minecraftforge.client.ForgeRenderTypes.getTextPolygonOffset(p_181445_);
}
public static RenderType m_181446_(ResourceLocation p_181447_) {
- return f_181443_.apply(p_181447_);
+ return net.minecraftforge.client.ForgeRenderTypes.getTextIntensityPolygonOffset(p_181447_);
}
public static RenderType m_110500_(ResourceLocation p_110501_) {
- return f_173175_.apply(p_110501_);
+ return net.minecraftforge.client.ForgeRenderTypes.getTextSeeThrough(p_110501_);
}
public static RenderType m_173240_(ResourceLocation p_173241_) {
- return f_173176_.apply(p_173241_);
+ return net.minecraftforge.client.ForgeRenderTypes.getTextIntensitySeeThrough(p_173241_);
}
public static RenderType m_110502_() {
@@ -0,0 +1,31 @@
--- a/net/minecraft/client/renderer/ShaderInstance.java
+++ b/net/minecraft/client/renderer/ShaderInstance.java
@@ -91,10 +_,14 @@
@Nullable
public final Uniform f_173320_;
+ @Deprecated // FORGE: Use the ResourceLocation variant below
public ShaderInstance(ResourceProvider p_173336_, String p_173337_, VertexFormat p_173338_) throws IOException {
- this.f_173300_ = p_173337_;
+ this(p_173336_, new ResourceLocation(p_173337_), p_173338_);
+ }
+ public ShaderInstance(ResourceProvider p_173336_, ResourceLocation shaderLocation, VertexFormat p_173338_) throws IOException {
+ this.f_173300_ = shaderLocation.m_135827_().equals("minecraft") ? shaderLocation.m_135815_() : shaderLocation.toString();
this.f_173307_ = p_173338_;
- ResourceLocation resourcelocation = new ResourceLocation("shaders/core/" + p_173337_ + ".json");
+ ResourceLocation resourcelocation = new ResourceLocation(shaderLocation.m_135827_(), "shaders/core/" + shaderLocation.m_135815_() + ".json");
Resource resource = null;
try {
@@ -202,8 +_,9 @@
Program program1 = p_173342_.m_85570_().get(p_173343_);
Program program;
if (program1 == null) {
- String s = "shaders/core/" + p_173343_ + p_173342_.m_85569_();
- ResourceLocation resourcelocation = new ResourceLocation(s);
+ ResourceLocation loc = new ResourceLocation(p_173343_);
+ String s = "shaders/core/" + loc.m_135815_() + p_173342_.m_85569_();
+ ResourceLocation resourcelocation = new ResourceLocation(loc.m_135827_(), s);
Resource resource = p_173341_.m_142591_(resourcelocation);
final String s1 = FileUtil.m_179922_(s);
@@ -1,6 +1,6 @@
--- a/net/minecraft/client/renderer/block/BlockModelShaper.java
+++ b/net/minecraft/client/renderer/block/BlockModelShaper.java
@@ -24,8 +_,14 @@
@@ -24,8 +_,15 @@
this.f_110878_ = p_110880_;
}
@@ -12,7 +12,8 @@
+
+ public TextureAtlasSprite getTexture(BlockState p_110883_, net.minecraft.world.level.Level level, net.minecraft.core.BlockPos pos) {
+ net.minecraftforge.client.model.data.IModelData data = net.minecraftforge.client.model.ModelDataManager.getModelData(level, pos);
+ return this.m_110893_(p_110883_).getParticleIcon(data == null ? net.minecraftforge.client.model.data.EmptyModelData.INSTANCE : data);
+ BakedModel model = this.m_110893_(p_110883_);
+ return model.getParticleIcon(model.getModelData(level, pos, p_110883_, data == null ? net.minecraftforge.client.model.data.EmptyModelData.INSTANCE : data));
}
public BakedModel m_110893_(BlockState p_110894_) {
@@ -64,14 +64,3 @@
}
}
@@ -105,5 +_,10 @@
public void m_6213_(ResourceManager p_110909_) {
this.f_110901_.m_110944_();
+ }
+
+ @Override
+ public net.minecraftforge.resource.IResourceType getResourceType() {
+ return net.minecraftforge.resource.VanillaResourceType.MODELS;
}
}
@@ -5,7 +5,7 @@
import net.minecraftforge.api.distmarker.OnlyIn;
+/**
+ * @deprecated use {@link net.minecraft.util.math.vector.TransformationMatrix} through {@link net.minecraftforge.client.extensions.IForgeBakedModel#handlePerspective}
+ * @deprecated use {@link com.mojang.math.Transformation} through {@link net.minecraftforge.client.extensions.IForgeBakedModel#handlePerspective}
+ */
@OnlyIn(Dist.CLIENT)
+@Deprecated
@@ -0,0 +1,23 @@
--- a/net/minecraft/client/renderer/entity/BoatRenderer.java
+++ b/net/minecraft/client/renderer/entity/BoatRenderer.java
@@ -52,7 +_,7 @@
p_113932_.m_85845_(new Quaternion(new Vector3f(1.0F, 0.0F, 1.0F), p_113929_.m_38352_(p_113931_), true));
}
- Pair<ResourceLocation, BoatModel> pair = this.f_173934_.get(p_113929_.m_38387_());
+ Pair<ResourceLocation, BoatModel> pair = getModelWithLocation(p_113929_);
ResourceLocation resourcelocation = pair.getFirst();
BoatModel boatmodel = pair.getSecond();
p_113932_.m_85841_(-1.0F, -1.0F, 1.0F);
@@ -69,7 +_,10 @@
super.m_7392_(p_113929_, p_113930_, p_113931_, p_113932_, p_113933_, p_113934_);
}
+ @Deprecated // forge: override getModelWithLocation to change the texture / model
public ResourceLocation m_5478_(Boat p_113927_) {
- return this.f_173934_.get(p_113927_.m_38387_()).getFirst();
+ return getModelWithLocation(p_113927_).getFirst();
}
+
+ public Pair<ResourceLocation, BoatModel> getModelWithLocation(Boat boat) { return this.f_173934_.get(boat.m_38387_()); }
}
@@ -15,14 +15,18 @@
p_114442_.m_85836_();
double d3 = d0 + Mth.m_14139_((double)p_114445_, enderdragonpart.f_19790_, enderdragonpart.m_20185_());
double d4 = d1 + Mth.m_14139_((double)p_114445_, enderdragonpart.f_19791_, enderdragonpart.m_20186_());
@@ -322,6 +_,10 @@
public Quaternion m_114470_() {
@@ -324,9 +_,14 @@
return this.f_114367_;
+ }
+
+ public Map<String, EntityRenderer<? extends Player>> getSkinMap() {
+ return java.util.Collections.unmodifiableMap(f_114363_);
}
+ public Map<String, EntityRenderer<? extends Player>> getSkinMap() {
+ return java.util.Collections.unmodifiableMap(f_114363_);
+ }
+
public void m_6213_(ResourceManager p_174004_) {
EntityRendererProvider.Context entityrendererprovider$context = new EntityRendererProvider.Context(this, this.f_173995_, p_174004_, this.f_173996_, this.f_114365_);
this.f_114362_ = EntityRenderers.m_174049_(entityrendererprovider$context);
this.f_114363_ = EntityRenderers.m_174051_(entityrendererprovider$context);
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.client.event.EntityRenderersEvent.AddLayers(f_114362_, f_114363_));
}
}
@@ -57,26 +57,7 @@
crashreportcategory.m_128165_("Item Damage", () -> {
return String.valueOf(p_174237_.m_41773_());
});
@@ -332,14 +_,15 @@
multibuffersource$buffersource.m_109911_();
}
- if (p_115176_.m_150947_()) {
+ if (p_115176_.m_41720_().showDurabilityBar(p_115176_)) {
RenderSystem.m_69465_();
RenderSystem.m_69472_();
RenderSystem.m_69461_();
Tesselator tesselator = Tesselator.m_85913_();
BufferBuilder bufferbuilder = tesselator.m_85915_();
- int i = p_115176_.m_150948_();
- int j = p_115176_.m_150949_();
+ double health = p_115176_.m_41720_().getDurabilityForDisplay(p_115176_);
+ int i = Math.round(13.0F - (float)health * 13.0F);
+ int j = p_115176_.m_41720_().getRGBDurabilityForDisplay(p_115176_);
this.m_115152_(bufferbuilder, p_115177_ + 2, p_115178_ + 13, 13, 2, 0, 0, 0, 255);
this.m_115152_(bufferbuilder, p_115177_ + 2, p_115178_ + 13, i, 1, j >> 16 & 255, j >> 8 & 255, j & 255, 255);
RenderSystem.m_69478_();
@@ -377,5 +_,14 @@
@@ -377,5 +_,9 @@
public void m_6213_(ResourceManager p_115105_) {
this.f_115095_.m_109403_();
@@ -84,10 +65,5 @@
+
+ public BlockEntityWithoutLevelRenderer getBlockEntityRenderer() {
+ return f_174223_;
+ }
+
+ @Override
+ public net.minecraftforge.resource.IResourceType getResourceType() {
+ return net.minecraftforge.resource.VanillaResourceType.MODELS;
}
}
@@ -1,12 +0,0 @@
--- a/net/minecraft/client/resources/language/LanguageManager.java
+++ b/net/minecraft/client/resources/language/LanguageManager.java
@@ -80,4 +_,9 @@
public LanguageInfo m_118976_(String p_118977_) {
return this.f_118966_.get(p_118977_);
}
+
+ @Override
+ public net.minecraftforge.resource.IResourceType getResourceType() {
+ return net.minecraftforge.resource.VanillaResourceType.LANGUAGES;
+ }
}
@@ -1,14 +0,0 @@
--- a/net/minecraft/client/searchtree/SearchRegistry.java
+++ b/net/minecraft/client/searchtree/SearchRegistry.java
@@ -31,6 +_,11 @@
return (MutableSearchTree<T>)this.f_119944_.get(p_119950_);
}
+ @Override
+ public net.minecraftforge.resource.IResourceType getResourceType() {
+ return net.minecraftforge.resource.VanillaResourceType.LANGUAGES;
+ }
+
@OnlyIn(Dist.CLIENT)
public static class Key<T> {
}
@@ -0,0 +1,38 @@
--- a/net/minecraft/data/advancements/AdvancementProvider.java
+++ b/net/minecraft/data/advancements/AdvancementProvider.java
@@ -22,11 +_,18 @@
private static final Gson f_123961_ = (new GsonBuilder()).setPrettyPrinting().create();
private final DataGenerator f_123962_;
private final List<Consumer<Consumer<Advancement>>> f_123963_ = ImmutableList.of(new TheEndAdvancements(), new HusbandryAdvancements(), new AdventureAdvancements(), new NetherAdvancements(), new StoryAdvancements());
+ protected net.minecraftforge.common.data.ExistingFileHelper fileHelper;
+ @Deprecated
public AdvancementProvider(DataGenerator p_123966_) {
this.f_123962_ = p_123966_;
}
+ public AdvancementProvider(DataGenerator generatorIn, net.minecraftforge.common.data.ExistingFileHelper fileHelperIn) {
+ this.f_123962_ = generatorIn;
+ this.fileHelper = fileHelperIn;
+ }
+
public void m_6865_(HashCache p_123969_) {
Path path = this.f_123962_.m_123916_();
Set<ResourceLocation> set = Sets.newHashSet();
@@ -45,6 +_,16 @@
}
};
+ registerAdvancements(consumer, fileHelper);
+ }
+
+ /**
+ * Override this method for registering and generating custom {@link Advancement}s. <br>
+ * Just use {@link Advancement.Builder} to build your Advancements, you don't need an extra consumer like the vanilla classes.
+ * @param consumer used for the register function from {@link Advancement.Builder}
+ * @param fileHelper used for the register function from {@link Advancement.Builder}
+ */
+ protected void registerAdvancements(Consumer<Advancement> consumer, net.minecraftforge.common.data.ExistingFileHelper fileHelper) {
for(Consumer<Consumer<Advancement>> consumer1 : this.f_123963_) {
consumer1.accept(consumer);
}
@@ -0,0 +1,15 @@
--- a/net/minecraft/data/tags/GameEventTagsProvider.java
+++ b/net/minecraft/data/tags/GameEventTagsProvider.java
@@ -8,8 +_,12 @@
import net.minecraft.world.level.gameevent.GameEvent;
public class GameEventTagsProvider extends TagsProvider<GameEvent> {
+ @Deprecated
public GameEventTagsProvider(DataGenerator p_176826_) {
super(p_176826_, Registry.f_175412_);
+ }
+ public GameEventTagsProvider(DataGenerator p_126517_, String modId, @javax.annotation.Nullable net.minecraftforge.common.data.ExistingFileHelper existingFileHelper) {
+ super(p_126517_, Registry.f_175412_, modId, existingFileHelper);
}
protected void m_6577_() {
@@ -77,7 +77,7 @@
- protected static class TagAppender<T> {
+ public static class TagAppender<T> implements net.minecraftforge.common.extensions.IForgeTagAppender<T> {
private final Tag.Builder f_126568_;
private final Registry<T> f_126569_;
public final Registry<T> f_126569_;
private final String f_126570_;
@@ -114,7 +_,7 @@
return this;
@@ -9,3 +9,11 @@
private static final int f_178834_ = 1048576;
public static final ResourceLocation f_132012_ = new ResourceLocation("brand");
public static final ResourceLocation f_132013_ = new ResourceLocation("debug/path");
@@ -52,6 +_,7 @@
public void m_5797_(ClientGamePacketListener p_132041_) {
p_132041_.m_7413_(this);
+ this.f_132030_.release(); // FORGE: Fix network buffer leaks (MC-121884)
}
public ResourceLocation m_132042_() {
@@ -9,14 +9,22 @@
atomicreference.get().m_130011_();
}, "Server thread");
thread.setUncaughtExceptionHandler((p_177909_, p_177910_) -> {
@@ -402,6 +_,7 @@
@@ -365,6 +_,7 @@
this.f_129732_ = new CommandStorage(dimensiondatastorage);
WorldBorder worldborder = serverlevel.m_6857_();
worldborder.m_61931_(serverleveldata.m_5813_());
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(f_129762_.get(Level.f_46428_)));
if (!serverleveldata.m_6535_()) {
try {
m_177896_(serverlevel, serverleveldata, worldgensettings.m_64660_(), flag);
@@ -401,6 +_,7 @@
ServerLevel serverlevel1 = new ServerLevel(this, this.f_129738_, this.f_129744_, derivedleveldata, resourcekey1, dimensiontype1, p_129816_, chunkgenerator1, flag, j, ImmutableList.of(), false);
worldborder.m_61929_(new BorderChangeListener.DelegateBorderChangeListener(serverlevel1.m_6857_()));
this.f_129762_.put(resourcekey1, serverlevel1);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(f_129762_.get(resourcekey)));
}
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(f_129762_.get(resourcekey)));
}
}
@@ -411,6 +_,7 @@
p_177898_.m_7250_(BlockPos.f_121853_.m_6630_(80), 0.0F);
} else {
@@ -167,7 +175,7 @@
}
public static DataPackConfig m_129819_(PackRepository p_129820_, DataPackConfig p_129821_, boolean p_129822_) {
+ net.minecraftforge.fmllegacy.packs.ResourcePackLoader.loadResourcePacks(p_129820_, net.minecraftforge.fmllegacy.server.ServerLifecycleHooks::buildPackFinder);
+ net.minecraftforge.fmllegacy.packs.ResourcePackLoader.loadResourcePacks(p_129820_, net.minecraftforge.fmllegacy.server.ServerLifecycleHooks::buildPackFinderNew);
p_129820_.m_10506_();
+ DataPackConfig.f_45842_.addModPacks(net.minecraftforge.common.ForgeHooks.getModPacks());
+ p_129821_.addModPacks(net.minecraftforge.common.ForgeHooks.getModPacks());
@@ -8,11 +8,3 @@
}
public ServerFunctionLibrary m_136157_() {
@@ -94,6 +_,7 @@
public void m_136179_() {
this.f_136148_.m_13480_().m_13431_();
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.TagsUpdatedEvent.CustomTagTypes(f_136148_.m_13480_()));
}
public void close() {
@@ -1,7 +1,11 @@
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -173,6 +_,7 @@
final Int2ObjectMap<EnderDragonPart> f_143247_ = new Int2ObjectOpenHashMap<>();
@@ -170,9 +_,10 @@
private final List<CustomSpawner> f_8558_;
@Nullable
private final EndDragonFight f_8559_;
- final Int2ObjectMap<EnderDragonPart> f_143247_ = new Int2ObjectOpenHashMap<>();
+ final Int2ObjectMap<net.minecraftforge.entity.PartEntity<?>> f_143247_ = new Int2ObjectOpenHashMap<>();
private final StructureFeatureManager f_8560_;
private final boolean f_8561_;
+ private net.minecraftforge.common.util.WorldCapabilityData capabilityData;
@@ -102,14 +106,14 @@
}
+ public void removePlayer(ServerPlayer p_8850_, boolean keepData) {
+ p_8850_.remove(keepData);
+ p_8850_.m_146870_();
+ this.removeEntity(p_8850_, keepData);
+ }
+
+ public void removeEntityComplete(Entity p_8865_, boolean keepData) {
+ if(p_8865_.isMultipartEntity()) {
+ for(net.minecraftforge.entity.PartEntity<?> parts : p_8865_.getParts()) {
+ parts.remove(keepData);
+ parts.m_146870_();
+ }
+ }
+
@@ -125,7 +129,7 @@
+ }
+
+ p_8865_.onRemovedFromWorld();
+ p_8865_.remove(keepData);
+ p_8865_.m_146870_();
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityLeaveWorldEvent(p_8865_, this));
+ }
+
@@ -146,30 +150,30 @@
Entity entity = this.m_142646_().m_142694_(p_8854_.m_142081_());
if (entity != null) {
f_8566_.warn("Force-added player with duplicate UUID {}", (Object)p_8854_.m_142081_().toString());
@@ -747,6 +_,7 @@
@@ -746,7 +_,8 @@
this.m_143261_((ServerPlayer)entity, Entity.RemovalReason.DISCARDED);
}
this.f_143244_.m_157533_(p_8854_);
- this.f_143244_.m_157533_(p_8854_);
+ this.f_143244_.addNewEntityWithoutEvent(p_8854_);
+ p_8854_.onAddedToWorld();
}
private boolean m_8872_(Entity p_8873_) {
@@ -754,6 +_,7 @@
@@ -754,7 +_,12 @@
f_8566_.warn("Tried to add entity {} but it was marked as removed already", (Object)EntityType.m_20613_(p_8873_.m_6095_()));
return false;
} else {
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(p_8873_, this))) return false;
return this.f_143244_.m_157533_(p_8873_);
- return this.f_143244_.m_157533_(p_8873_);
+ if (this.f_143244_.m_157533_(p_8873_)) {
+ p_8873_.onAddedToWorld();
+ return true;
+ } else {
+ return false;
+ }
}
}
@@ -762,6 +_,7 @@
if (p_8861_.m_142428_().map(Entity::m_142081_).anyMatch(this.f_143244_::m_157550_)) {
return false;
} else {
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(p_8861_, this))) return false;
this.m_47205_(p_8861_);
return true;
}
@@ -790,10 +_,20 @@
}
@@ -199,16 +203,38 @@
explosion.m_46061_();
explosion.m_46075_(false);
if (p_8661_ == Explosion.BlockInteraction.NONE) {
@@ -1355,6 +_,12 @@
BlockPos.m_121976_(i - 2, j, k - 2, i + 2, j, k + 2).forEach((p_143260_) -> {
p_8618_.m_46597_(p_143260_, Blocks.f_50080_.m_49966_());
@@ -1357,6 +_,12 @@
});
+ }
+
}
+ protected void initCapabilities() {
+ this.gatherCapabilities();
+ capabilityData = this.m_8895_().m_164861_(e -> net.minecraftforge.common.util.WorldCapabilityData.load(e, getCapabilities()), () -> new net.minecraftforge.common.util.WorldCapabilityData(getCapabilities()), net.minecraftforge.common.util.WorldCapabilityData.ID);
+ capabilityData.setCapabilities(getCapabilities());
}
+ }
+
public LevelEntityGetter<Entity> m_142646_() {
return this.f_143244_.m_157567_();
}
@@ -1422,8 +_,8 @@
ServerLevel.this.f_143246_.add((Mob)p_143371_);
}
- if (p_143371_ instanceof EnderDragon) {
- for(EnderDragonPart enderdragonpart : ((EnderDragon)p_143371_).m_31156_()) {
+ if (p_143371_.isMultipartEntity()) {
+ for(net.minecraftforge.entity.PartEntity<?> enderdragonpart : p_143371_.getParts()) {
ServerLevel.this.f_143247_.put(enderdragonpart.m_142049_(), enderdragonpart);
}
}
@@ -1442,8 +_,8 @@
ServerLevel.this.f_143246_.remove(p_143375_);
}
- if (p_143375_ instanceof EnderDragon) {
- for(EnderDragonPart enderdragonpart : ((EnderDragon)p_143375_).m_31156_()) {
+ if (p_143375_.isMultipartEntity()) {
+ for(net.minecraftforge.entity.PartEntity<?> enderdragonpart : p_143375_.getParts()) {
ServerLevel.this.f_143247_.remove(enderdragonpart.m_142049_());
}
}
@@ -150,6 +150,14 @@
}
public boolean m_143432_() {
@@ -1265,6 +_,7 @@
public void m_9213_(Entity p_9214_) {
Entity entity = this.m_8954_();
this.f_8926_ = (Entity)(p_9214_ == null ? this : p_9214_);
+ while (this.f_8926_ instanceof net.minecraftforge.entity.PartEntity<?> partEntity) this.f_8926_ = partEntity.getParent(); // FORGE: fix MC-46486
if (entity != this.f_8926_) {
this.f_8906_.m_141995_(new ClientboundSetCameraPacket(this.f_8926_));
this.m_6021_(this.f_8926_.m_20185_(), this.f_8926_.m_20186_(), this.f_8926_.m_20189_());
@@ -1294,7 +_,11 @@
@Nullable
@@ -57,7 +57,7 @@
private void m_143678_(InteractionHand p_143679_, ServerGamePacketListenerImpl.EntityInteraction p_143680_) {
ItemStack itemstack = ServerGamePacketListenerImpl.this.f_9743_.m_21120_(p_143679_).m_41777_();
InteractionResult interactionresult = p_143680_.m_143694_(ServerGamePacketListenerImpl.this.f_9743_, entity, p_143679_);
+ // TODO: if (net.minecraftforge.common.ForgeHooks.onInteractEntityAt(player, entity, entity.position(), p_143679_) != null) return;
+ if (net.minecraftforge.common.ForgeHooks.onInteractEntityAt(f_9743_, entity, entity.m_20182_(), p_143679_) != null) return;
if (interactionresult.m_19077_()) {
CriteriaTriggers.f_10565_.m_61494_(ServerGamePacketListenerImpl.this.f_9743_, itemstack, entity);
if (interactionresult.m_19080_()) {
@@ -0,0 +1,13 @@
--- a/net/minecraft/server/packs/AbstractPackResources.java
+++ b/net/minecraft/server/packs/AbstractPackResources.java
@@ -120,4 +_,10 @@
public String m_8017_() {
return this.f_10203_.getName();
}
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s: %s", getClass().getName(), f_10203_.getPath());
+ }
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/server/packs/repository/PackRepository.java
+++ b/net/minecraft/server/packs/repository/PackRepository.java
@@ -24,12 +_,12 @@
@@ -24,13 +_,14 @@
public PackRepository(Pack.PackConstructor p_10502_, RepositorySource... p_10503_) {
this.f_10500_ = p_10502_;
@@ -14,8 +14,10 @@
+ this((p_143894_, p_143895_, p_143896_, p_143897_, p_143898_, p_143899_, p_143900_, hidden) -> {
+ return new Pack(p_143894_, p_143895_, p_143896_, p_143897_, p_143898_, p_143890_, p_143899_, p_143900_, hidden);
}, p_143891_);
+ net.minecraftforge.fml.ModLoader.get().postEvent(new net.minecraftforge.event.AddPackFindersEvent(p_143890_, f_10497_::add));
}
public void m_10506_() {
@@ -91,6 +_,10 @@
@Nullable
public Pack m_10507_(String p_10508_) {
@@ -1,22 +1,12 @@
--- a/net/minecraft/server/packs/resources/ResourceManagerReloadListener.java
+++ b/net/minecraft/server/packs/resources/ResourceManagerReloadListener.java
@@ -5,6 +_,11 @@
import net.minecraft.util.Unit;
import net.minecraft.util.profiling.ProfilerFiller;
+/**
+ * @deprecated Forge: {@link net.minecraftforge.resource.ISelectiveResourceReloadListener}, which selectively allows
+ * individual resource types being reloaded should rather be used where possible.
+ */
+@Deprecated
public interface ResourceManagerReloadListener extends PreparableReloadListener {
default CompletableFuture<Void> m_5540_(PreparableReloadListener.PreparationBarrier p_10752_, ResourceManager p_10753_, ProfilerFiller p_10754_, ProfilerFiller p_10755_, Executor p_10756_, Executor p_10757_) {
return p_10752_.m_6769_(Unit.INSTANCE).thenRunAsync(() -> {
@@ -17,4 +_,9 @@
@@ -17,4 +_,11 @@
}
void m_6213_(ResourceManager p_10758_);
+
+ /** @deprecated Selective reloading is no longer supported due to vanilla now reloading resources in parallel, so this is no longer needed */
+ @Deprecated(since="1.17.1", forRemoval = true)
+ @javax.annotation.Nullable
+ default net.minecraftforge.resource.IResourceType getResourceType() {
+ return null;
@@ -16,14 +16,14 @@
GameRules gamerules = serverlevel1.m_46469_();
boolean flag = gamerules.m_46207_(GameRules.f_46156_);
boolean flag1 = gamerules.m_46207_(GameRules.f_46145_);
@@ -160,6 +_,7 @@
@@ -158,6 +_,7 @@
servergamepacketlistenerimpl.m_141995_(new ClientboundChangeDifficultyPacket(leveldata.m_5472_(), leveldata.m_5474_()));
servergamepacketlistenerimpl.m_141995_(new ClientboundPlayerAbilitiesPacket(p_11263_.m_150110_()));
servergamepacketlistenerimpl.m_141995_(new ClientboundSetCarriedItemPacket(p_11263_.m_150109_().f_35977_));
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.OnDatapackSyncEvent(this, p_11263_));
servergamepacketlistenerimpl.m_141995_(new ClientboundUpdateRecipesPacket(this.f_11195_.m_129894_().m_44051_()));
servergamepacketlistenerimpl.m_141995_(new ClientboundUpdateTagsPacket(this.f_11195_.m_129895_().m_144442_(this.f_11206_)));
+ net.minecraftforge.fmllegacy.network.NetworkHooks.syncCustomTagTypes(p_11263_, this.f_11195_.m_129895_());
this.m_11289_(p_11263_);
p_11263_.m_8951_().m_12850_();
p_11263_.m_8952_().m_12789_(p_11263_);
@@ -174,7 +_,7 @@
this.m_11264_(mutablecomponent.m_130940_(ChatFormatting.YELLOW), ChatType.SYSTEM, Util.f_137441_);
@@ -65,34 +65,6 @@
ServerLevel serverlevel = p_11287_.m_9236_();
p_11287_.m_36220_(Stats.f_12989_);
this.m_6765_(p_11287_);
@@ -328,7 +_,7 @@
p_11287_.m_19877_();
serverlevel.m_143261_(p_11287_, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
p_11287_.m_8960_().m_135978_();
- this.f_11196_.remove(p_11287_);
+ this.removePlayer(p_11287_);
this.f_11195_.m_129901_().m_136305_(p_11287_);
UUID uuid = p_11287_.m_142081_();
ServerPlayer serverplayer = this.f_11197_.get(uuid);
@@ -390,8 +_,8 @@
}
public ServerPlayer m_11236_(ServerPlayer p_11237_, boolean p_11238_) {
- this.f_11196_.remove(p_11237_);
- p_11237_.m_9236_().m_143261_(p_11237_, Entity.RemovalReason.DISCARDED);
+ this.removePlayer(p_11237_);
+ p_11237_.m_9236_().removePlayer(p_11237_, true); // Forge: keep data until copyFrom called
BlockPos blockpos = p_11237_.m_8961_();
float f = p_11237_.m_8962_();
boolean flag = p_11237_.m_8964_();
@@ -407,6 +_,7 @@
ServerPlayer serverplayer = new ServerPlayer(this.f_11195_, serverlevel1, p_11237_.m_36316_());
serverplayer.f_8906_ = p_11237_.f_8906_;
serverplayer.m_9015_(p_11237_, p_11238_);
+ p_11237_.remove(false); // Forge: clone event had a chance to see old data, now discard it
serverplayer.m_20234_(p_11237_.m_142049_());
serverplayer.m_36163_(p_11237_.m_5737_());
@@ -447,10 +_,11 @@
this.m_11229_(serverplayer, serverlevel1);
this.m_11289_(serverplayer);
@@ -106,6 +78,22 @@
if (flag2) {
serverplayer.f_8906_.m_141995_(new ClientboundSoundPacket(SoundEvents.f_12377_, SoundSource.BLOCKS, (double)blockpos.m_123341_(), (double)blockpos.m_123342_(), (double)blockpos.m_123343_(), 1.0F, 1.0F));
}
@@ -535,6 +_,7 @@
}
public void m_5749_(GameProfile p_11254_) {
+ if (net.minecraftforge.event.ForgeEventFactory.onPermissionChanged(p_11254_, this.f_11195_.m_7022_(), this)) return;
this.f_11200_.m_11381_(new ServerOpListEntry(p_11254_, this.f_11195_.m_7022_(), this.f_11200_.m_11351_(p_11254_)));
ServerPlayer serverplayer = this.m_11259_(p_11254_.getId());
if (serverplayer != null) {
@@ -544,6 +_,7 @@
}
public void m_5750_(GameProfile p_11281_) {
+ if (net.minecraftforge.event.ForgeEventFactory.onPermissionChanged(p_11281_, 0, this)) return;
this.f_11200_.m_11393_(p_11281_);
ServerPlayer serverplayer = this.m_11259_(p_11281_.getId());
if (serverplayer != null) {
@@ -726,13 +_,6 @@
if (serverstatscounter == null) {
File file1 = this.f_11195_.m_129843_(LevelResource.f_78175_).toFile();
@@ -138,14 +126,14 @@
}
@Nullable
@@ -786,6 +_,7 @@
@@ -785,6 +_,7 @@
playeradvancements.m_135981_(this.f_11195_.m_129889_());
}
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.OnDatapackSyncEvent(this, null));
this.m_11268_(new ClientboundUpdateTagsPacket(this.f_11195_.m_129895_().m_144442_(this.f_11206_)));
+ net.minecraftforge.fmllegacy.network.NetworkHooks.syncCustomTagTypes(this.f_11195_.m_129895_());
ClientboundUpdateRecipesPacket clientboundupdaterecipespacket = new ClientboundUpdateRecipesPacket(this.f_11195_.m_129894_().m_44051_());
for(ServerPlayer serverplayer : this.f_11196_) {
@@ -797,5 +_,13 @@
public boolean m_11316_() {
@@ -0,0 +1,17 @@
--- a/net/minecraft/tags/GameEventTags.java
+++ b/net/minecraft/tags/GameEventTags.java
@@ -12,6 +_,14 @@
return f_144301_.m_13244_(p_144308_);
}
+ public static net.minecraftforge.common.Tags.IOptionalNamedTag<GameEvent> createOptional(net.minecraft.resources.ResourceLocation name) {
+ return createOptional(name, null);
+ }
+
+ public static net.minecraftforge.common.Tags.IOptionalNamedTag<GameEvent> createOptional(net.minecraft.resources.ResourceLocation name, @javax.annotation.Nullable java.util.Set<java.util.function.Supplier<GameEvent>> defaults) {
+ return f_144301_.createOptional(name, defaults);
+ }
+
public static TagCollection<GameEvent> m_144306_() {
return f_144301_.m_13246_();
}
@@ -4,11 +4,11 @@
private final String f_144327_;
private TagCollection<T> f_13227_ = TagCollection.m_13410_();
private final List<StaticTagHelper.Wrapper<T>> f_13228_ = Lists.newArrayList();
+ private static java.util.Map<ResourceLocation, List<StaticTagHelper.Wrapper<?>>> toAdd = com.google.common.collect.Maps.newHashMap();
+ @Nullable private static java.util.Map<ResourceLocation, List<StaticTagHelper.Wrapper<?>>> toAdd = com.google.common.collect.Maps.newHashMap();
public StaticTagHelper(ResourceKey<? extends Registry<T>> p_144329_, String p_144330_) {
this.f_144326_ = p_144329_;
@@ -24,9 +_,46 @@
@@ -24,9 +_,60 @@
}
public Tag.Named<T> m_13244_(String p_13245_) {
@@ -55,13 +55,8 @@
+ namedtag.m_13260_(f_13227_::m_13404_);
+ this.f_13228_.add(namedtag);
+ return namedtag;
}
public void m_13232_() {
@@ -47,13 +_,31 @@
});
}
+ }
+
+ public TagCollection<T> reinjectOptionalTags(TagCollection<T> tagCollection) {
+ java.util.Map<ResourceLocation, Tag<T>> currentTags = tagCollection.m_5643_();
+ java.util.Map<ResourceLocation, Tag<T>> missingOptionals = this.f_13228_.stream().filter(e -> e instanceof OptionalNamedTag && !currentTags.containsKey(e.m_6979_())).collect(Collectors.toMap(Wrapper::m_6979_, namedTag -> {
@@ -74,16 +69,11 @@
+ return TagCollection.m_13396_(missingOptionals);
+ }
+ return tagCollection;
+ }
+
public TagCollection<T> m_13246_() {
return this.f_13227_;
}
+ public List<? extends Tag.Named<T>> getWrappers() {
+ return this.f_13228_;
+ }
+
public void m_13232_() {
@@ -53,7 +_,7 @@
public Set<ResourceLocation> m_13247_(TagContainer p_13248_) {
TagCollection<T> tagcollection = p_13248_.m_144452_(this.f_144326_);
- Set<ResourceLocation> set = this.f_13228_.stream().map(StaticTagHelper.Wrapper::m_6979_).collect(Collectors.toSet());
@@ -108,7 +98,7 @@
+
+ @Override
+ public String toString() {
+ return "NamedTag[" + m_6979_().toString() + ']';
+ return "NamedTag[" + m_6979_() + ']';
+ }
+ @Override public boolean equals(Object o) { return (o == this) || (o instanceof Tag.Named && java.util.Objects.equals(this.m_6979_(), ((Tag.Named<T>)o).m_6979_())); }
+ @Override public int hashCode() { return m_6979_().hashCode(); }
@@ -138,7 +128,7 @@
+
+ @Override
+ public String toString() {
+ return "OptionalNamedTag[" + m_6979_().toString() + ']';
+ return "OptionalNamedTag[" + m_6979_() + ']';
}
}
}
@@ -21,42 +21,20 @@
return statictaghelper;
}
}
@@ -55,11 +_,29 @@
private static void m_144356_() {
Set<ResourceKey<?>> set = m_144355_().stream().map(StaticTagHelper::m_144338_).collect(Collectors.toSet());
- if (!Sets.difference(f_144340_, set).isEmpty()) {
+ if (!Sets.difference(set, f_144340_).isEmpty()) { // Forge: Fix bug with extra tag collections crashing
throw new IllegalStateException("Missing helper registrations");
}
@@ -54,10 +_,16 @@
}
private static void m_144356_() {
+ if (true) { m_144355_(); return; } //FORGE this check is unnecessary as the 2 collections are patched back into a map above. Still need to 'clinit' them though.
Set<ResourceKey<?>> set = m_144355_().stream().map(StaticTagHelper::m_144338_).collect(Collectors.toSet());
if (!Sets.difference(f_144340_, set).isEmpty()) {
throw new IllegalStateException("Missing helper registrations");
}
+ }
+
+ @javax.annotation.Nullable
+ public static StaticTagHelper<?> get(ResourceLocation rl) {
+ return HELPER_MAP.get(ResourceKey.m_135788_(rl));
+ }
+
+ public static Multimap<ResourceKey<? extends Registry<?>>, ResourceLocation> validateVanillaTags(TagContainer tagCollectionSupplier) {
+ Multimap<ResourceKey<? extends Registry<?>>, ResourceLocation> multimap = HashMultimap.create();
+ f_13264_.forEach((tagHelper) -> {
+ if (!net.minecraftforge.common.ForgeTagHandler.getCustomTagTypeNames().contains(tagHelper.m_144338_().m_135782_()))
+ multimap.putAll(tagHelper.m_144338_(), tagHelper.m_13247_(tagCollectionSupplier));
+ });
+ return multimap;
+ }
+
+ public static void fetchCustomTagTypes(TagContainer tagCollectionSupplier) {
+ net.minecraftforge.common.ForgeTagHandler.getCustomTagTypeNames().forEach(tagRegistry -> HELPER_MAP.get(ResourceKey.m_135788_(tagRegistry)).m_13242_(tagCollectionSupplier));
+ }
+
}
public static void m_144349_(Consumer<StaticTagHelper<?>> p_144350_) {
f_13264_.forEach(p_144350_);
}
@@ -70,6 +_,7 @@
f_13264_.forEach((p_144344_) -> {
p_144344_.m_144336_(tagcontainer$builder);
});
+ net.minecraftforge.common.ForgeTagHandler.populateTagCollectionManager();
return tagcontainer$builder.m_144485_();
}
}
@@ -1,8 +1,18 @@
--- a/net/minecraft/tags/Tag.java
+++ b/net/minecraft/tags/Tag.java
@@ -49,6 +_,7 @@
@@ -47,8 +_,16 @@
return SetTag.m_13222_(p_13301_);
}
public static class Builder {
- public static class Builder {
+ public static class Builder implements net.minecraftforge.common.extensions.IForgeRawTagBuilder {
+ private final List<Tag.BuilderEntry> removeEntries = Lists.newArrayList(); // FORGE: internal field for tracking "remove" entries
+ /** FORGE: Gets a view of this builder's "remove" entries (only used during datagen) **/
+ public Stream<Tag.BuilderEntry> getRemoveEntries() { return this.removeEntries.stream(); }
+ public Tag.Builder remove(final Tag.BuilderEntry proxy) { // internal forge method for adding remove entries
+ this.removeEntries.add(proxy);
+ return this;
+ }
private final List<Tag.BuilderEntry> f_13302_ = Lists.newArrayList();
+ private boolean replace = false;
@@ -32,15 +42,17 @@
list.forEach((p_13319_) -> {
this.f_13302_.add(new Tag.BuilderEntry(p_13319_, p_13314_));
});
@@ -155,7 +_,7 @@
@@ -155,8 +_,9 @@
tag$builderentry.m_13347_().m_6383_(jsonarray);
}
- jsonobject.addProperty("replace", false);
+ jsonobject.addProperty("replace", replace);
jsonobject.add("values", jsonarray);
+ this.serializeTagAdditions(jsonobject);
return jsonobject;
}
}
@@ -211,6 +_,7 @@
public String toString() {
return this.f_13349_.toString();
@@ -1,33 +1,18 @@
--- a/net/minecraft/tags/TagContainer.java
+++ b/net/minecraft/tags/TagContainer.java
@@ -15,7 +_,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-public class TagContainer {
+public class TagContainer implements net.minecraftforge.common.extensions.IForgeTagContainer {
static final Logger f_144432_ = LogManager.getLogger();
public static final TagContainer f_13420_ = new TagContainer(ImmutableMap.of());
public final Map<ResourceKey<? extends Registry<?>>, TagCollection<?>> f_144433_;
@@ -74,6 +_,7 @@
public void m_13431_() {
StaticTags.m_13269_(this);
Blocks.m_50758_();
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.TagsUpdatedEvent.VanillaTagTypes(this));
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.TagsUpdatedEvent(this));
}
public Map<ResourceKey<? extends Registry<?>>, TagCollection.NetworkPayload> m_144442_(final RegistryAccess p_144443_) {
@@ -108,6 +_,13 @@
f_144432_.error("Unknown registry {}", (Object)p_144447_);
}
+ }
+
+ public static TagContainer reinjectOptionalTags(TagContainer tagCollectionSupplier) {
+ TagContainer.Builder builder = new TagContainer.Builder();
+ //noinspection unchecked,rawtypes
+ StaticTags.m_144349_(h -> builder.m_144486_(h.m_144338_(), h.reinjectOptionalTags(tagCollectionSupplier.m_144452_((ResourceKey) h.m_144338_()))));
+ return builder.m_144485_();
}
public static class Builder {
@@ -81,6 +_,7 @@
this.m_144436_(new TagContainer.CollectionConsumer() {
public <T> void m_142574_(ResourceKey<? extends Registry<T>> p_144481_, TagCollection<T> p_144482_) {
Optional<? extends Registry<T>> optional = p_144443_.m_6632_(p_144481_);
+ optional = net.minecraftforge.common.ForgeTagHandler.getWrapperRegistry(p_144481_, optional);
if (optional.isPresent()) {
map.put(p_144481_, p_144482_.m_144411_(optional.get()));
} else {
@@ -8,34 +8,20 @@
private TagContainer f_13478_ = TagContainer.f_13420_;
public TagManager(RegistryAccess p_144572_) {
@@ -40,15 +_,16 @@
}
});
- return CompletableFuture.allOf(list.stream().map((p_144591_) -> {
- return p_144591_.f_144598_;
- }).toArray((p_144574_) -> {
- return new CompletableFuture[p_144574_];
- })).thenCompose(p_13482_::m_6769_).thenAcceptAsync((p_144594_) -> {
+ CompletableFuture<java.util.List<net.minecraftforge.common.ForgeTagHandler.TagCollectionReaderInfo>> customTagTypeResults = net.minecraftforge.common.ForgeTagHandler.getCustomTagTypeReloadResults(p_13483_, p_13486_, customTagTypeReaders);
+ List<CompletableFuture<?>> futures = Lists.newArrayList();
+ list.stream().map(li -> li.f_144598_).forEach(futures::add);
+ futures.add(customTagTypeResults);
+ return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).thenCompose(p_13482_::m_6769_).thenAcceptAsync((p_144594_) -> {
TagContainer.Builder tagcontainer$builder = new TagContainer.Builder();
list.forEach((p_144586_) -> {
p_144586_.m_144602_(tagcontainer$builder);
});
+ net.minecraftforge.common.ForgeTagHandler.updateCustomTagTypes(customTagTypeResults.join());
TagContainer tagcontainer = tagcontainer$builder.m_144485_();
Multimap<ResourceKey<? extends Registry<?>>, ResourceLocation> multimap = StaticTags.m_13283_(tagcontainer);
if (!multimap.isEmpty()) {
@@ -56,6 +_,8 @@
@@ -56,6 +_,7 @@
return p_144596_.getKey() + ":" + p_144596_.getValue();
}).sorted().collect(Collectors.joining(",")));
} else {
+ tagcontainer = TagContainer.reinjectOptionalTags(tagcontainer);
+ net.minecraftforge.common.ForgeTagHandler.reinjectOptionalTagsCustomTypes();
+ tagcontainer = net.minecraftforge.common.ForgeTagHandler.reinjectOptionalTags(tagcontainer);
SerializationTags.m_13202_(tagcontainer);
this.f_13478_ = tagcontainer;
}
@@ -73,6 +_,8 @@
}, p_144577_);
return new TagManager.LoaderInfo<>(p_144578_, completablefuture);
} else {
+ if (net.minecraftforge.common.ForgeTagHandler.getCustomTagTypeNames().contains(p_144578_.m_144338_().m_135782_()))
+ return new TagManager.LoaderInfo<>(p_144578_, CompletableFuture.supplyAsync(() -> ((TagLoader<T>) customTagTypeReaders.get(p_144578_.m_144338_().m_135782_())).m_144544_(p_144576_), p_144577_));
f_144568_.warn("Can't find registry for {}", (Object)p_144578_.m_144338_());
return null;
}
@@ -17,7 +17,7 @@
}
public void m_6742_(LivingEntity p_19467_, int p_19468_) {
@@ -179,4 +_,28 @@
@@ -179,4 +_,29 @@
public boolean m_19486_() {
return this.f_19447_ == MobEffectCategory.BENEFICIAL;
}
@@ -34,7 +34,8 @@
+ }
+
+ private void initClient() {
+ if (net.minecraftforge.fml.loading.FMLEnvironment.dist == net.minecraftforge.api.distmarker.Dist.CLIENT) {
+ // Minecraft instance isn't available in datagen, so don't call initializeClient if in datagen
+ if (net.minecraftforge.fml.loading.FMLEnvironment.dist == net.minecraftforge.api.distmarker.Dist.CLIENT && !net.minecraftforge.fml.loading.FMLLoader.getLaunchHandler().isData()) {
+ initializeClient(properties -> {
+ this.effectRenderer = properties;
+ });
@@ -72,9 +72,9 @@
+ this.curativeItems = curativeItems;
+ }
+ private static MobEffectInstance readCurativeItems(MobEffectInstance effect, CompoundTag nbt) {
+ if (nbt.m_128425_("CurativeItems", net.minecraftforge.common.util.Constants.NBT.TAG_LIST)) {
+ if (nbt.m_128425_("CurativeItems", net.minecraft.nbt.Tag.f_178202_)) {
+ java.util.List<net.minecraft.world.item.ItemStack> items = new java.util.ArrayList<net.minecraft.world.item.ItemStack>();
+ net.minecraft.nbt.ListTag list = nbt.m_128437_("CurativeItems", net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND);
+ net.minecraft.nbt.ListTag list = nbt.m_128437_("CurativeItems", net.minecraft.nbt.Tag.f_178203_);
+ for (int i = 0; i < list.size(); i++) {
+ items.add(net.minecraft.world.item.ItemStack.m_41712_(list.m_128728_(i)));
+ }
@@ -38,20 +38,14 @@
}
public boolean m_20039_(BlockPos p_20040_, BlockState p_20041_) {
@@ -339,6 +_,13 @@
@@ -335,6 +_,7 @@
if (p_146834_ == Entity.RemovalReason.KILLED) {
this.m_146850_(GameEvent.f_157809_);
}
+ this.invalidateCaps();
}
public void m_142036_() {
+ this.remove(false);
+ }
+
+ public void remove(boolean keepData) {
+ this.m_146870_();
+ if (!keepData)
+ this.invalidateCaps();
}
public void m_20124_(Pose p_20125_) {
@@ -599,13 +_,13 @@
double d0 = vec3.f_82479_;
double d1 = vec3.f_82480_;
@@ -157,7 +151,7 @@
+ CompoundTag caps = serializeCaps();
+ if (caps != null) p_20241_.m_128365_("ForgeCaps", caps);
+ if (persistentData != null) p_20241_.m_128365_("ForgeData", persistentData);
+ if (persistentData != null) p_20241_.m_128365_("ForgeData", persistentData.m_6426_());
+
this.m_7380_(p_20241_);
if (this.m_20160_()) {
@@ -84,7 +84,7 @@
return false;
} else {
MobEffectInstance mobeffectinstance = this.f_20945_.get(p_147208_.m_19544_());
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionAddedEvent(this, mobeffectinstance, p_147208_));
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.living.PotionEvent.PotionAddedEvent(this, mobeffectinstance, p_147208_, p_147209_));
if (mobeffectinstance == null) {
this.f_20945_.put(p_147208_.m_19544_(), p_147208_);
this.m_142540_(p_147208_, p_147209_);
@@ -505,12 +505,10 @@
}
public boolean m_5830_() {
@@ -3198,6 +_,58 @@
public void m_21190_(InteractionHand p_21191_) {
@@ -3200,6 +_,64 @@
this.m_21166_(p_21191_ == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND);
+ }
+
}
+ /* ==== FORGE START ==== */
+ /***
+ * Removes all potion effects that have curativeItem as a curative item for its effect
@@ -544,7 +542,7 @@
+ return this instanceof net.minecraft.world.entity.animal.Pig;
+ }
+
+ private final net.minecraftforge.common.util.LazyOptional<?>[] handlers = net.minecraftforge.items.wrapper.EntityEquipmentInvWrapper.create(this);
+ private net.minecraftforge.common.util.LazyOptional<?>[] handlers = net.minecraftforge.items.wrapper.EntityEquipmentInvWrapper.create(this);
+
+ @Override
+ public <T> net.minecraftforge.common.util.LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
@@ -557,10 +555,36 @@
+ }
+
+ @Override
+ protected void invalidateCaps() {
+ public void invalidateCaps() {
+ super.invalidateCaps();
+ for (int x = 0; x < handlers.length; x++)
+ handlers[x].invalidate();
+ }
+
+ @Override
+ public void reviveCaps() {
+ super.reviveCaps();
+ handlers = net.minecraftforge.items.wrapper.EntityEquipmentInvWrapper.create(this);
+ }
+
public AABB m_6921_() {
if (this.m_6844_(EquipmentSlot.HEAD).m_150930_(Items.f_42683_)) {
float f = 0.5F;
@@ -3210,6 +_,8 @@
}
public AABB m_6921_() {
public static EquipmentSlot m_147233_(ItemStack p_147234_) {
+ final EquipmentSlot slot = p_147234_.getEquipmentSlot();
+ if (slot != null) return slot; // FORGE: Allow modders to set a non-default equipment slot for a stack; e.g. a non-armor chestplate-slot item
Item item = p_147234_.m_41720_();
if (!p_147234_.m_150930_(Items.f_42047_) && (!(item instanceof BlockItem) || !(((BlockItem)item).m_40614_() instanceof AbstractSkullBlock))) {
if (item instanceof ArmorItem) {
@@ -3217,7 +_,7 @@
} else if (p_147234_.m_150930_(Items.f_42741_)) {
return EquipmentSlot.CHEST;
} else {
- return p_147234_.m_150930_(Items.f_42740_) ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND;
+ return p_147234_.canPerformAction(net.minecraftforge.common.ToolActions.SHIELD_BLOCK) ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND;
}
} else {
return EquipmentSlot.HEAD;
@@ -26,7 +26,7 @@
+ f_20891_ = 0;
+ entity = null;
+ } else if (result == net.minecraftforge.eventbus.api.Event.Result.ALLOW) {
+ this.remove(false);
+ this.m_146870_();
+ entity = null;
+ }
if (entity != null) {
@@ -0,0 +1,20 @@
--- a/net/minecraft/world/entity/TamableAnimal.java
+++ b/net/minecraft/world/entity/TamableAnimal.java
@@ -197,11 +_,15 @@
}
public void m_6667_(DamageSource p_21809_) {
+ // FORGE: Super moved to top so that death message would be cancelled properly
+ net.minecraft.network.chat.Component deathMessage = this.m_21231_().m_19293_();
+ super.m_6667_(p_21809_);
+
+ if (this.f_20890_)
if (!this.f_19853_.f_46443_ && this.f_19853_.m_46469_().m_46207_(GameRules.f_46142_) && this.m_142480_() instanceof ServerPlayer) {
- this.m_142480_().m_6352_(this.m_21231_().m_19293_(), Util.f_137441_);
+ this.m_142480_().m_6352_(deathMessage, Util.f_137441_);
}
- super.m_6667_(p_21809_);
}
public boolean m_21827_() {
@@ -0,0 +1,17 @@
--- a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
+++ b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
@@ -77,11 +_,12 @@
private static final Map<EntityType<? extends LivingEntity>, AttributeSupplier> f_22294_ = ImmutableMap.<EntityType<? extends LivingEntity>, AttributeSupplier>builder().put(EntityType.f_20529_, LivingEntity.m_21183_().m_22265_()).put(EntityType.f_147039_, Axolotl.m_149176_().m_22265_()).put(EntityType.f_20549_, Bat.m_27455_().m_22265_()).put(EntityType.f_20550_, Bee.m_27858_().m_22265_()).put(EntityType.f_20551_, Blaze.m_32238_().m_22265_()).put(EntityType.f_20553_, Cat.m_28168_().m_22265_()).put(EntityType.f_20554_, CaveSpider.m_32267_().m_22265_()).put(EntityType.f_20555_, Chicken.m_28263_().m_22265_()).put(EntityType.f_20556_, AbstractFish.m_27495_().m_22265_()).put(EntityType.f_20557_, Cow.m_28307_().m_22265_()).put(EntityType.f_20558_, Creeper.m_32318_().m_22265_()).put(EntityType.f_20559_, Dolphin.m_28379_().m_22265_()).put(EntityType.f_20560_, AbstractChestedHorse.m_30501_().m_22265_()).put(EntityType.f_20562_, Zombie.m_34328_().m_22265_()).put(EntityType.f_20563_, ElderGuardian.m_32471_().m_22265_()).put(EntityType.f_20566_, EnderMan.m_32541_().m_22265_()).put(EntityType.f_20567_, Endermite.m_32619_().m_22265_()).put(EntityType.f_20565_, EnderDragon.m_31167_().m_22265_()).put(EntityType.f_20568_, Evoker.m_32657_().m_22265_()).put(EntityType.f_20452_, Fox.m_28553_().m_22265_()).put(EntityType.f_20453_, Ghast.m_32752_().m_22265_()).put(EntityType.f_20454_, Giant.m_32796_().m_22265_()).put(EntityType.f_147034_, GlowSquid.m_29988_().m_22265_()).put(EntityType.f_147035_, Goat.m_149401_().m_22265_()).put(EntityType.f_20455_, Guardian.m_32853_().m_22265_()).put(EntityType.f_20456_, Hoglin.m_34551_().m_22265_()).put(EntityType.f_20457_, AbstractHorse.m_30627_().m_22265_()).put(EntityType.f_20458_, Zombie.m_34328_().m_22265_()).put(EntityType.f_20459_, Illusioner.m_32931_().m_22265_()).put(EntityType.f_20460_, IronGolem.m_28883_().m_22265_()).put(EntityType.f_20466_, Llama.m_30824_().m_22265_()).put(EntityType.f_20468_, MagmaCube.m_33000_().m_22265_()).put(EntityType.f_20504_, Cow.m_28307_().m_22265_()).put(EntityType.f_20503_, AbstractChestedHorse.m_30501_().m_22265_()).put(EntityType.f_20505_, Ocelot.m_29036_().m_22265_()).put(EntityType.f_20507_, Panda.m_29157_().m_22265_()).put(EntityType.f_20508_, Parrot.m_29438_().m_22265_()).put(EntityType.f_20509_, Monster.m_33035_().m_22265_()).put(EntityType.f_20510_, Pig.m_29503_().m_22265_()).put(EntityType.f_20511_, Piglin.m_34770_().m_22265_()).put(EntityType.f_20512_, PiglinBrute.m_35075_().m_22265_()).put(EntityType.f_20513_, Pillager.m_33307_().m_22265_()).put(EntityType.f_20532_, Player.m_36340_().m_22265_()).put(EntityType.f_20514_, PolarBear.m_29560_().m_22265_()).put(EntityType.f_20516_, AbstractFish.m_27495_().m_22265_()).put(EntityType.f_20517_, Rabbit.m_29717_().m_22265_()).put(EntityType.f_20518_, Ravager.m_33371_().m_22265_()).put(EntityType.f_20519_, AbstractFish.m_27495_().m_22265_()).put(EntityType.f_20520_, Sheep.m_29873_().m_22265_()).put(EntityType.f_20521_, Shulker.m_33477_().m_22265_()).put(EntityType.f_20523_, Silverfish.m_33551_().m_22265_()).put(EntityType.f_20524_, AbstractSkeleton.m_32166_().m_22265_()).put(EntityType.f_20525_, SkeletonHorse.m_30918_().m_22265_()).put(EntityType.f_20526_, Monster.m_33035_().m_22265_()).put(EntityType.f_20528_, SnowGolem.m_29934_().m_22265_()).put(EntityType.f_20479_, Spider.m_33815_().m_22265_()).put(EntityType.f_20480_, Squid.m_29988_().m_22265_()).put(EntityType.f_20481_, AbstractSkeleton.m_32166_().m_22265_()).put(EntityType.f_20482_, Strider.m_33937_().m_22265_()).put(EntityType.f_20488_, Llama.m_30824_().m_22265_()).put(EntityType.f_20489_, AbstractFish.m_27495_().m_22265_()).put(EntityType.f_20490_, Turtle.m_30207_().m_22265_()).put(EntityType.f_20491_, Vex.m_34040_().m_22265_()).put(EntityType.f_20492_, Villager.m_35503_().m_22265_()).put(EntityType.f_20493_, Vindicator.m_34104_().m_22265_()).put(EntityType.f_20494_, Mob.m_21552_().m_22265_()).put(EntityType.f_20495_, Witch.m_34155_().m_22265_()).put(EntityType.f_20496_, WitherBoss.m_31501_().m_22265_()).put(EntityType.f_20497_, AbstractSkeleton.m_32166_().m_22265_()).put(EntityType.f_20499_, Wolf.m_30425_().m_22265_()).put(EntityType.f_20500_, Zoglin.m_34257_().m_22265_()).put(EntityType.f_20501_, Zombie.m_34328_().m_22265_()).put(EntityType.f_20502_, ZombieHorse.m_31008_().m_22265_()).put(EntityType.f_20530_, Zombie.m_34328_().m_22265_()).put(EntityType.f_20531_, ZombifiedPiglin.m_34470_().m_22265_()).build();
public static AttributeSupplier m_22297_(EntityType<? extends LivingEntity> p_22298_) {
- return f_22294_.get(p_22298_);
+ AttributeSupplier supplier = net.minecraftforge.common.ForgeHooks.getAttributesView().get(p_22298_);
+ return supplier != null ? supplier : f_22294_.get(p_22298_);
}
public static boolean m_22301_(EntityType<?> p_22302_) {
- return f_22294_.containsKey(p_22302_);
+ return f_22294_.containsKey(p_22302_) || net.minecraftforge.common.ForgeHooks.getAttributesView().containsKey(p_22302_);
}
public static void m_22296_() {
@@ -1,5 +1,25 @@
--- a/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java
+++ b/net/minecraft/world/entity/ai/goal/RangedBowAttackGoal.java
@@ -8,7 +_,7 @@
import net.minecraft.world.item.BowItem;
import net.minecraft.world.item.Items;
-public class RangedBowAttackGoal<T extends Monster & RangedAttackMob> extends Goal {
+public class RangedBowAttackGoal<T extends net.minecraft.world.entity.Mob & RangedAttackMob> extends Goal {
private final T f_25782_;
private final double f_25783_;
private int f_25784_;
@@ -19,6 +_,10 @@
private boolean f_25789_;
private int f_25790_ = -1;
+ public <M extends Monster & RangedAttackMob> RangedBowAttackGoal(M p_25792_, double p_25793_, int p_25794_, float p_25795_){
+ this((T) p_25792_, p_25793_, p_25794_, p_25795_);
+ }
+
public RangedBowAttackGoal(T p_25792_, double p_25793_, int p_25794_, float p_25795_) {
this.f_25782_ = p_25792_;
this.f_25783_ = p_25793_;
@@ -36,7 +_,7 @@
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -223,9 +_,9 @@
@@ -223,10 +_,10 @@
Vec3 vec3 = this.m_7475_();
this.f_26505_ = this.f_26494_.m_20205_() > 0.75F ? this.f_26494_.m_20205_() / 2.0F : 0.75F - this.f_26494_.m_20205_() / 2.0F;
Vec3i vec3i = this.f_26496_.m_77400_();
@@ -8,7 +8,9 @@
+ double d0 = Math.abs(this.f_26494_.m_20185_() - ((double)vec3i.m_123341_() + (this.f_26494_.m_20205_() + 1) / 2D)); //Forge: Fix MC-94054
double d1 = Math.abs(this.f_26494_.m_20186_() - (double)vec3i.m_123342_());
- double d2 = Math.abs(this.f_26494_.m_20189_() - ((double)vec3i.m_123343_() + 0.5D));
- boolean flag = d0 < (double)this.f_26505_ && d2 < (double)this.f_26505_ && d1 < 1.0D;
+ double d2 = Math.abs(this.f_26494_.m_20189_() - ((double)vec3i.m_123343_() + (this.f_26494_.m_20205_() + 1) / 2D)); //Forge: Fix MC-94054
boolean flag = d0 < (double)this.f_26505_ && d2 < (double)this.f_26505_ && d1 < 1.0D;
+ boolean flag = d0 <= (double)this.f_26505_ && d2 <= (double)this.f_26505_ && d1 < 1.0D; //Forge: Fix MC-94054
if (flag || this.f_26494_.m_21481_(this.f_26496_.m_77401_().f_77282_) && this.m_26559_(vec3)) {
this.f_26496_.m_77374_();
}
@@ -1,13 +1,5 @@
--- a/net/minecraft/world/entity/animal/Bee.java
+++ b/net/minecraft/world/entity/animal/Bee.java
@@ -212,6 +_,7 @@
this.f_27710_ = p_27793_.m_128451_("TicksSincePollination");
this.f_27711_ = p_27793_.m_128451_("CannotEnterHiveTicks");
this.f_27712_ = p_27793_.m_128451_("CropsGrownSincePollination");
+ if(!f_19853_.f_46443_) //FORGE: allow this entity to be read from nbt on client. (Fixes MC-189565)
this.m_147285_(this.f_19853_, p_27793_);
}
@@ -469,7 +_,7 @@
return false;
} else {
@@ -13,11 +13,3 @@
}
}
@@ -148,6 +_,7 @@
public void m_7378_(CompoundTag p_28857_) {
super.m_7378_(p_28857_);
this.m_28887_(p_28857_.m_128471_("PlayerCreated"));
+ if(!f_19853_.f_46443_) //FORGE: allow this entity to be read from nbt on client. (Fixes MC-189565)
this.m_147285_(this.f_19853_, p_28857_);
}
@@ -18,49 +18,47 @@
this.m_5851_(SoundSource.PLAYERS);
this.m_146852_(GameEvent.f_157781_, p_28941_);
if (!this.f_19853_.f_46443_) {
@@ -235,6 +_,45 @@
@@ -141,7 +_,16 @@
}
}
+ @Override
+ public java.util.List<ItemStack> onSheared(@javax.annotation.Nullable Player player, @javax.annotation.Nonnull ItemStack item, Level world, BlockPos pos, int fortune) {
+ return shearInternal(player == null ? SoundSource.BLOCKS : SoundSource.PLAYERS);
+ }
+
public void m_5851_(SoundSource p_28924_) {
+ shearInternal(p_28924_).forEach(s -> this.f_19853_.m_7967_(new ItemEntity(this.f_19853_, this.m_20185_(), this.m_20227_(1.0D), this.m_20189_(), s)));
+ }
+
+ private java.util.List<ItemStack> shearInternal(SoundSource p_28924_) {
this.f_19853_.m_6269_((Player)null, this, SoundEvents.f_12075_, p_28924_, 1.0F, 1.0F);
if (!this.f_19853_.m_5776_()) {
((ServerLevel)this.f_19853_).m_8767_(ParticleTypes.f_123813_, this.m_20185_(), this.m_20227_(0.5D), this.m_20189_(), 1, 0.0D, 0.0D, 0.0D, 0.0D);
@@ -162,10 +_,13 @@
cow.m_20331_(this.m_20147_());
this.f_19853_.m_7967_(cow);
+ java.util.List<ItemStack> items = new java.util.ArrayList<>();
for(int i = 0; i < 5; ++i) {
- this.f_19853_.m_7967_(new ItemEntity(this.f_19853_, this.m_20185_(), this.m_20227_(1.0D), this.m_20189_(), new ItemStack(this.m_28955_().f_28961_.m_60734_())));
+ items.add(new ItemStack(this.m_28955_().f_28961_.m_60734_()));
}
+ return items;
}
+ return java.util.Collections.emptyList();
}
@@ -234,6 +_,11 @@
}
return mushroomcow$mushroomtype2;
}
+ }
+
+ @Override
+ public boolean isShearable(@javax.annotation.Nonnull ItemStack item, Level world, BlockPos pos) {
+ return m_6220_();
+ }
+
+ @javax.annotation.Nonnull
+ @Override
+ public java.util.List<ItemStack> onSheared(@javax.annotation.Nullable Player player, @javax.annotation.Nonnull ItemStack item, Level world, BlockPos pos, int fortune) {
+ world.m_6269_(null, this, SoundEvents.f_12075_, player == null ? SoundSource.BLOCKS : SoundSource.PLAYERS, 1.0F, 1.0F);
+ if (!world.m_5776_()) {
+ ((ServerLevel)this.f_19853_).m_8767_(ParticleTypes.f_123813_, this.m_20185_(), this.m_20227_(0.5D), this.m_20189_(), 1, 0.0D, 0.0D, 0.0D, 0.0D);
+ this.remove(false);
+ Cow cow = EntityType.f_20557_.m_20615_(this.f_19853_);
+ cow.m_7678_(this.m_20185_(), this.m_20186_(), this.m_20189_(), this.m_146909_(), this.m_146908_());
+ cow.m_21153_(this.m_21223_());
+ cow.f_20883_ = this.f_20883_;
+ if (this.m_8077_()) {
+ cow.m_6593_(this.m_7770_());
+ cow.m_20340_(this.m_20151_());
+ }
+
+ if (this.m_21532_()) {
+ cow.m_21530_();
+ }
+
+ cow.m_20331_(this.m_20147_());
+ this.f_19853_.m_7967_(cow);
+
+ java.util.List<ItemStack> items = new java.util.ArrayList<>();
+ for (int i = 0; i < 5; ++i) {
+ items.add(new ItemStack(this.m_28955_().f_28961_.m_60734_()));
+ }
+
+ return items;
+ }
+ return java.util.Collections.emptyList();
+ }
+
}
public static enum MushroomType {
RED("red", Blocks.f_50073_.m_49966_()),
@@ -1,10 +0,0 @@
--- a/net/minecraft/world/entity/animal/PolarBear.java
+++ b/net/minecraft/world/entity/animal/PolarBear.java
@@ -105,6 +_,7 @@
public void m_7378_(CompoundTag p_29541_) {
super.m_7378_(p_29541_);
+ if(!f_19853_.f_46443_) //FORGE: allow this entity to be read from nbt on client. (Fixes MC-189565)
this.m_147285_(this.f_19853_, p_29541_);
}
Loaded 100 of 471 files, more files were not shown because too many files have changed in this diff. Show more