Split client only code into its own sourceset. ()

A common source of crashes on modded Minecraft servers comes from modders accidently calling client only code from the client, this PR is another large step towards elimitating that.

This PR has been months in the making and years in the planning, requiring major changes to Loom & Loader. In recent Minecraft versions Mojang has made it easier than ever to cleanly split the jar, going against the status-quo of merging the client and server into one jar.

From the start we have designed Fabric to have a very clear split between client and common (client & server) code. Fabric has always encoraged keeping client only code seprate from the server, this can be seen at a fundamental level with the entrypoints in Loader. Fabric API's have all been designed with this mind.

This PR provides a compile safety net around Fabric API using client only code on the server. Even though there are almost 400 changed files, minimal changes beyond moving the files were required to achieve this in Fabric API, thanks to the effort of all contributors in the past.

These changes should not affect modders or players in anyway, a single "universal" jar is still produced. Im happy to awnswer any questions.
This commit is contained in:
modmuss50 2022-05-21 16:26:46 +01:00 committed by GitHub
parent daa69e8a8b
commit 9ff28f4026
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
360 changed files with 473 additions and 235 deletions
build.gradle
deprecated
fabric-containers-v0/src
client/java/net/fabricmc/fabric
main/java/net/fabricmc/fabric/api/container
fabric-events-lifecycle-v0/src
client/java/net/fabricmc/fabric
main/java/net/fabricmc/fabric/api/event/world
fabric-keybindings-v0/src/client
java/net/fabricmc/fabric/api/client/keybinding
resources
assets/fabric-keybindings-v0
fabric.mod.json
fabric-networking-v0/src
client/java/net/fabricmc/fabric
main/java/net/fabricmc/fabric/api
fabric-renderer-registries-v1/src/client
fabric-rendering-v0/src/client
java/net/fabricmc/fabric
resources
assets/fabric-rendering-v0
fabric.mod.json
fabric-api-base
fabric-api-lookup-api-v1
fabric-biome-api-v1
fabric-blockrenderlayer-v1/src/client
java/net/fabricmc/fabric
api/blockrenderlayer/v1
impl/blockrenderlayer
mixin/blockrenderlayer
resources
fabric-command-api-v2
fabric-content-registries-v0/src
fabric-data-generation-api-v1/src
fabric-dimensions-v1
fabric-entity-events-v1
fabric-events-interaction-v0/src
fabric-game-rule-api-v1
fabric-item-api-v1/src
fabric-item-groups-v0/src
fabric-key-binding-api-v1
build.gradle
src/client
java/net/fabricmc/fabric
resources/assets/fabric-key-binding-api-v1

View file

@ -9,7 +9,7 @@ plugins {
id "eclipse"
id "idea"
id "maven-publish"
id "fabric-loom" version "0.12.27" apply false
id "fabric-loom" version "0.12.38" apply false
id "com.diffplug.spotless" version "6.5.1"
id "org.ajoberstar.grgit" version "3.1.0"
id "com.matthewprenger.cursegradle" version "1.4.0"
@ -63,10 +63,16 @@ def getBranch() {
def moduleDependencies(project, List<String> depNames) {
def deps = depNames.iterator().collect { project.dependencies.project(path: ":$it", configuration: 'namedElements') }
def clientOutputs = depNames.iterator().collect { findProject(":$it").sourceSets.client.output }
project.dependencies {
deps.each {
api it
}
clientOutputs.each {
clientImplementation it
}
}
// As we manually handle the maven artifacts, we need to also manually specify the deps.
@ -88,6 +94,21 @@ def moduleDependencies(project, List<String> depNames) {
}
}
def testDependencies(project, List<String> depNames) {
def deps = depNames.iterator().collect { project.dependencies.project(path: ":$it", configuration: 'namedElements') }
def clientOutputs = depNames.iterator().collect { findProject(":$it").sourceSets.client.output }
project.dependencies {
deps.each {
testmodImplementation it
}
clientOutputs.each {
testmodImplementation it
}
}
}
allprojects {
group = "net.fabricmc.fabric-api"
@ -126,10 +147,22 @@ allprojects {
it.options.release = 17
}
java {
// Must be added before the split source sets are setup.
withSourcesJar()
}
loom {
splitEnvironmentSourceSets()
}
sourceSets {
testmod {
compileClasspath += main.compileClasspath
runtimeClasspath += main.runtimeClasspath
compileClasspath += client.compileClasspath
runtimeClasspath += client.runtimeClasspath
}
}
@ -152,10 +185,26 @@ allprojects {
}
}
allprojects.each { p ->
if (project.name == "deprecated") return
loom.mods.register(p.name) {
sourceSet p.sourceSets.main
sourceSet p.sourceSets.client
}
loom.mods.register(p.name + "-testmod") {
sourceSet p.sourceSets.testmod
}
}
dependencies {
minecraft "com.mojang:minecraft:$rootProject.minecraft_version"
mappings "net.fabricmc:yarn:${rootProject.minecraft_version}${project.yarn_version}:v2"
modApi "net.fabricmc:fabric-loader:${project.loader_version}"
testmodImplementation sourceSets.main.output
testmodImplementation sourceSets.client.output
}
loom {
@ -176,10 +225,6 @@ allprojects {
}
}
java {
withSourcesJar()
}
checkstyle {
configFile = rootProject.file("checkstyle.xml")
toolVersion = "9.1"
@ -200,6 +245,19 @@ allprojects {
task generateResources {
group = "fabric"
}
task testmodJar(type: Jar) {
from sourceSets.testmod.output
destinationDirectory = new File(project.buildDir, "devlibs")
archiveClassifier = "testmod"
}
task remapTestmodJar(type: net.fabricmc.loom.task.RemapJarTask, dependsOn: testmodJar) {
input = testmodJar.archiveFile
archiveClassifier = "testmod"
addNestedDependencies = false
}
build.dependsOn remapTestmodJar
}
// Apply auxiliary buildscripts to submodules
@ -226,10 +284,13 @@ javadoc {
}
allprojects.each {
if (it.name == "deprecated") return
source(it.sourceSets.main.allJava.srcDirs)
source(it.sourceSets.client.allJava.srcDirs)
}
classpath = sourceSets.main.compileClasspath
classpath = files(sourceSets.main.compileClasspath, sourceSets.client.compileClasspath)
include("**/api/**")
failOnError false
}
@ -305,9 +366,12 @@ subprojects {
afterEvaluate {
// Disable the gen sources task on sub projects
genSourcesWithFernFlower.enabled = false
genSourcesWithCfr.enabled = false
unpickJar.enabled = false
genClientOnlySourcesWithFernFlower.enabled = false
genClientOnlySourcesWithCfr.enabled = false
genCommonSourcesWithCfr.enabled = false
genCommonSourcesWithFernFlower.enabled = false
unpickClientOnlyJar.enabled = false
unpickCommonJar.enabled = false
}
}
@ -395,6 +459,7 @@ dependencies {
if (it.name == "deprecated") return
api project(path: "${it.path}", configuration: "namedElements")
clientImplementation project("${it.path}:").sourceSets.client.output
testmodImplementation project("${it.path}:").sourceSets.testmod.output
}

View file

@ -24,7 +24,6 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.network.PacketByteBuf;
import net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry;
import net.fabricmc.fabric.impl.container.ContainerProviderImpl;
/**
@ -37,7 +36,7 @@ public interface ContainerProviderRegistry {
/**
* Register a "packet buffer -&gt; container" factory. This is used both on the client and server side.
*
* @param identifier a shared identifier, this identifier should also be used to register a container using {@link ScreenProviderRegistry}
* @param identifier a shared identifier, this identifier should also be used to register a container using {@link net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry}
* @param factory the ContainerFactory that should return a new {@link ScreenHandler}
*/
void registerFactory(Identifier identifier, ContainerFactory<ScreenHandler> factory);

View file

@ -18,7 +18,6 @@ package net.fabricmc.fabric.api.event.world;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
@ -27,7 +26,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
public interface WorldTickCallback {
/**
* @deprecated The new WorldTickCallback has been split into a client and server callback.
* Please use the {@link ServerTickEvents#END_WORLD_TICK server} or {@link ClientTickEvents#END_WORLD_TICK client} callbacks.
* Please use the {@link ServerTickEvents#END_WORLD_TICK server} or {@link net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents#END_WORLD_TICK client} callbacks.
*/
@Deprecated
Event<WorldTickCallback> EVENT = EventFactory.createArrayBacked(WorldTickCallback.class,

View file

@ -23,7 +23,6 @@ import net.minecraft.network.Packet;
import net.minecraft.util.Identifier;
import net.minecraft.network.PacketByteBuf;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.impl.networking.ClientSidePacketRegistryImpl;
/**
@ -34,7 +33,7 @@ import net.fabricmc.fabric.impl.networking.ClientSidePacketRegistryImpl;
* <ul><li>registering client-side packet receivers (server -&gt; client packets)
* <li>sending packets to the server (client -&gt; server packets).</ul>
*
* @deprecated Please migrate to {@link ClientPlayNetworking}.
* @deprecated Please migrate to {@link net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking}.
*/
@Deprecated
public interface ClientSidePacketRegistry extends PacketRegistry {

View file

@ -21,7 +21,6 @@ import java.util.Collection;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.fabricmc.fabric.api.networking.v1.S2CPlayChannelEvents;
@ -38,7 +37,7 @@ import net.fabricmc.fabric.api.networking.v1.S2CPlayChannelEvents;
@Deprecated
public interface C2SPacketTypeCallback {
/**
* @deprecated Please migrate to {@link C2SPlayChannelEvents#REGISTER}.
* @deprecated Please migrate to {@link net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents#REGISTER}.
*/
@Deprecated
Event<C2SPacketTypeCallback> REGISTERED = EventFactory.createArrayBacked(
@ -51,7 +50,7 @@ public interface C2SPacketTypeCallback {
);
/**
* @deprecated Please migrate to {@link C2SPlayChannelEvents#UNREGISTER}.
* @deprecated Please migrate to {@link net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents#UNREGISTER}.
*/
@Deprecated
Event<C2SPacketTypeCallback> UNREGISTERED = EventFactory.createArrayBacked(

View file

@ -20,7 +20,6 @@ import java.util.Collection;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.fabricmc.fabric.api.networking.v1.S2CPlayChannelEvents;
@ -32,7 +31,7 @@ import net.fabricmc.fabric.api.networking.v1.S2CPlayChannelEvents;
* <p>Registrations received will be for <em>client -&gt; server</em> packets
* that the sending server can understand.
*
* @deprecated Please migrate to {@link C2SPlayChannelEvents} since this was incorrectly named.
* @deprecated Please migrate to {@link net.fabricmc.fabric.api.client.networking.v1.C2SPlayChannelEvents} since this was incorrectly named.
*/
@Deprecated
public interface S2CPacketTypeCallback {

View file

@ -18,13 +18,12 @@ package net.fabricmc.fabric.api.network;
import net.minecraft.network.PacketByteBuf;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
/**
* Interface for receiving CustomPayload-based packets.
*
* @deprecated See the corresponding play packet handler in {@link ClientPlayNetworking} or {@link ServerPlayNetworking}
* @deprecated See the corresponding play packet handler in {@link net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking} or {@link ServerPlayNetworking}
*/
@Deprecated
@FunctionalInterface

View file

@ -1,7 +1,7 @@
archivesBaseName = "fabric-api-base"
version = getSubprojectVersion(project)
dependencies {
testmodImplementation project(path: ':fabric-command-api-v2', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-lifecycle-events-v1', configuration: 'namedElements')
}
testDependencies(project, [
':fabric-command-api-v2',
':fabric-lifecycle-events-v1'
])

View file

@ -6,7 +6,7 @@ moduleDependencies(project, [
'fabric-lifecycle-events-v1'
])
dependencies {
testmodImplementation project(path: ':fabric-rendering-v1', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-object-builder-api-v1', configuration: 'namedElements')
}
testDependencies(project, [
':fabric-rendering-v1',
':fabric-object-builder-api-v1'
])

View file

@ -5,7 +5,7 @@ loom {
accessWidenerPath = file("src/main/resources/fabric-biome-api-v1.accesswidener")
}
dependencies {
testmodImplementation project(path: ':fabric-api-base', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
}
testDependencies(project, [
':fabric-api-base',
':fabric-resource-loader-v0'
])

View file

@ -1,14 +1,14 @@
archivesBaseName = "fabric-command-api-v2"
version = getSubprojectVersion(project)
dependencies {
testmodImplementation project(path: ':fabric-lifecycle-events-v1', configuration: 'namedElements')
}
moduleDependencies(project, [
'fabric-api-base'
])
testDependencies(project, [
':fabric-lifecycle-events-v1',
])
loom {
accessWidenerPath = file('src/main/resources/fabric-command-api-v2.accesswidener')
}

View file

@ -0,0 +1,14 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.command.client",
"compatibilityLevel": "JAVA_16",
"client": [
"ClientCommandSourceMixin",
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin",
"MinecraftClientMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -6,12 +6,6 @@
"CommandManagerMixin",
"HelpCommandAccessor"
],
"client": [
"client.ClientCommandSourceMixin",
"client.ClientPlayerEntityMixin",
"client.ClientPlayNetworkHandlerMixin",
"client.MinecraftClientMixin"
],
"injectors": {
"defaultRequire": 1
}

View file

@ -23,7 +23,11 @@
"description": "Adds command-related hooks.",
"accessWidener": "fabric-command-api-v2.accesswidener",
"mixins": [
"fabric-command-api-v2.mixins.json"
"fabric-command-api-v2.mixins.json",
{
"config": "fabric-command-api-v2.client.mixins.json",
"environment": "client"
}
],
"custom": {
"fabric-api:module-lifecycle": "stable"

View file

@ -0,0 +1,11 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.content.registry.client",
"compatibilityLevel": "JAVA_16",
"client": [
"MixinClientPlayNetworkHandler"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -11,9 +11,6 @@
"OxidizableMixin",
"ShovelItemAccessor"
],
"client": [
"client.MixinClientPlayNetworkHandler"
],
"injectors": {
"defaultRequire": 1
}

View file

@ -23,7 +23,11 @@
},
"description": "Adds registries for vanilla mechanics that are missing them.",
"mixins": [
"fabric-content-registries-v0.mixins.json"
"fabric-content-registries-v0.mixins.json",
{
"config": "fabric-content-registries-v0.client.mixins.json",
"environment": "client"
}
],
"accessWidener" : "fabric-content-registries-v0.accesswidener",
"custom": {

View file

@ -0,0 +1,11 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.datagen.client",
"compatibilityLevel": "JAVA_16",
"client": [
"MinecraftClientMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -8,9 +8,6 @@
"DynamicRegistryManagerAccessor",
"TagBuilderMixin"
],
"client": [
"client.MinecraftClientMixin"
],
"server": [
"server.MainMixin"
],

View file

@ -20,7 +20,11 @@
},
"description": "Allows for automatic data generation.",
"mixins": [
"fabric-data-generation-api-v1.mixins.json"
"fabric-data-generation-api-v1.mixins.json",
{
"config": "fabric-data-generation-api-v1.client.mixins.json",
"environment": "client"
}
],
"accessWidener" : "fabric-data-generation-api-v1.accesswidener",
"custom": {

View file

@ -1,12 +1,12 @@
archivesBaseName = "fabric-dimensions-v1"
version = getSubprojectVersion(project)
dependencies {
testmodImplementation project(path: ':fabric-command-api-v2', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-lifecycle-events-v1', configuration: 'namedElements')
}
moduleDependencies(project, [
'fabric-api-base'
])
testDependencies(project, [
':fabric-command-api-v2',
':fabric-resource-loader-v0',
':fabric-lifecycle-events-v1'
])

View file

@ -5,9 +5,9 @@ moduleDependencies(project, [
'fabric-api-base'
])
dependencies {
testmodImplementation project(path: ':fabric-command-api-v2', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-networking-api-v1', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-registry-sync-v0', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-rendering-v1', configuration: 'namedElements')
}
testDependencies(project, [
':fabric-command-api-v2',
':fabric-networking-api-v1',
':fabric-registry-sync-v0',
':fabric-rendering-v1'
])

View file

@ -0,0 +1,12 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.entity.event",
"compatibilityLevel": "JAVA_16",
"client": [
"elytra.ClientPlayerEntityMixin"
],
"injectors": {
"defaultRequire": 1,
"maxShiftBy": 3
}
}

View file

@ -12,9 +12,6 @@
"ServerPlayerEntityMixin",
"TeleportCommandMixin"
],
"client": [
"elytra.ClientPlayerEntityMixin"
],
"injectors": {
"defaultRequire": 1,
"maxShiftBy": 3

View file

@ -20,7 +20,11 @@
},
"description": "Events to hook into entities.",
"mixins": [
"fabric-entity-events-v1.mixins.json"
"fabric-entity-events-v1.mixins.json",
{
"config": "fabric-entity-events-v1.client.mixins.json",
"environment": "client"
}
],
"custom": {
"fabric-api:module-lifecycle": "stable"

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.event.interaction;
package net.fabricmc.fabric.mixin.event.interaction.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.event.interaction;
package net.fabricmc.fabric.mixin.event.interaction.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

View file

@ -0,0 +1,12 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.event.interaction.client",
"compatibilityLevel": "JAVA_16",
"client": [
"MixinClientPlayerInteractionManager",
"MixinMinecraftClient"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -7,10 +7,6 @@
"MixinServerPlayerInteractionManager",
"MixinServerPlayNetworkHandler"
],
"client": [
"MixinClientPlayerInteractionManager",
"MixinMinecraftClient"
],
"injectors": {
"defaultRequire": 1
}

View file

@ -30,7 +30,11 @@
},
"description": "Events for player interaction with blocks and entities.",
"mixins": [
"fabric-events-interaction-v0.mixins.json"
"fabric-events-interaction-v0.mixins.json",
{
"config": "fabric-events-interaction-v0.client.mixins.json",
"environment": "client"
}
],
"custom": {
"fabric-api:module-lifecycle": "stable"

View file

@ -5,8 +5,8 @@ loom {
accessWidenerPath = file("src/main/resources/fabric-game-rule-api-v1.accesswidener")
}
dependencies {
testmodImplementation project(path: ':fabric-api-base', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-lifecycle-events-v1', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
}
testDependencies(project, [
':fabric-api-base',
':fabric-lifecycle-events-v1',
':fabric-resource-loader-v0'
])

View file

@ -0,0 +1,13 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.gamerule.client",
"compatibilityLevel": "JAVA_16",
"client": [
"EditGameRulesScreenAccessor",
"RuleListWidgetMixin",
"RuleListWidgetVisitorMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -10,11 +10,6 @@
"IntRuleAccessor",
"RuleKeyMixin"
],
"client": [
"client.EditGameRulesScreenAccessor",
"client.RuleListWidgetMixin",
"client.RuleListWidgetVisitorMixin"
],
"injectors": {
"defaultRequire": 1
}

View file

@ -20,7 +20,11 @@
},
"description": "Allows registration of custom game rules.",
"mixins": [
"fabric-game-rule-api-v1.mixins.json"
"fabric-game-rule-api-v1.mixins.json",
{
"config": "fabric-game-rule-api-v1.client.mixins.json",
"environment": "client"
}
],
"accessWidener" : "fabric-game-rule-api-v1.accesswidener",
"custom": {

View file

@ -0,0 +1,13 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.item.client",
"compatibilityLevel": "JAVA_16",
"client": [
"ClientPlayerInteractionManagerMixin",
"HeldItemRendererMixin",
"ItemStackMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -19,7 +19,6 @@ package net.fabricmc.fabric.api.item.v1;
import com.google.common.collect.Multimap;
import net.minecraft.block.BlockState;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
@ -42,7 +41,7 @@ public interface FabricItem {
* This function is called on the client side when the NBT or count of the stack has changed, but not the item,
* and returning false cancels this animation.
*
* @param player the current player; this may be safely cast to {@link ClientPlayerEntity} in client-only code
* @param player the current player; this may be safely cast to {@link net.minecraft.client.network.ClientPlayerEntity} in client-only code
* @param hand the hand; this function applies both to the main hand and the off hand
* @param oldStack the previous stack, of this item
* @param newStack the new stack, also of this item

View file

@ -7,11 +7,6 @@
"ItemMixin",
"LivingEntityMixin"
],
"client": [
"client.ClientPlayerInteractionManagerMixin",
"client.HeldItemRendererMixin",
"client.ItemStackMixin"
],
"injectors": {
"defaultRequire": 1
}

View file

@ -16,7 +16,11 @@
"FabricMC"
],
"mixins": [
"fabric-item-api-v1.mixins.json"
"fabric-item-api-v1.mixins.json",
{
"config": "fabric-item-api-v1.client.mixins.json",
"environment": "client"
}
],
"depends": {
"fabricloader": ">=0.4.0",

View file

@ -0,0 +1,12 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.item.group.client",
"compatibilityLevel": "JAVA_16",
"client": [
"MixinItemGroup",
"MixinCreativePlayerInventoryGui"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -5,10 +5,6 @@
"mixins": [
"MixinItemGroup"
],
"client": [
"client.MixinItemGroup",
"client.MixinCreativePlayerInventoryGui"
],
"injectors": {
"defaultRequire": 1
}

View file

@ -23,7 +23,11 @@
},
"description": "An API for adding custom item groups.",
"mixins": [
"fabric-item-groups-v0.mixins.json"
"fabric-item-groups-v0.mixins.json",
{
"config": "fabric-item-groups-v0.client.mixins.json",
"environment": "client"
}
],
"custom": {
"fabric-api:module-lifecycle": "stable"

View file

@ -1,8 +1,8 @@
archivesBaseName = "fabric-key-binding-api-v1"
version = getSubprojectVersion(project)
dependencies {
testmodImplementation project(path: ':fabric-api-base', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-lifecycle-events-v1', configuration: 'namedElements')
testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'namedElements')
}
testDependencies(project, [
':fabric-api-base',
':fabric-lifecycle-events-v1',
':fabric-resource-loader-v0'
])

Some files were not shown because too many files have changed in this diff Show more