Merge remote-tracking branch 'architectury/1.16' into 1.17

# Conflicts:
#	fabric/src/main/resources/architectury.mixins.json
#	gradle.properties
#	settings.gradle
This commit is contained in:
shedaniel
2021-02-11 21:35:32 +08:00
111 changed files with 2971 additions and 404 deletions

View File

@@ -1,8 +1,8 @@
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import shadow.org.apache.tools.zip.ZipEntry
import shadow.org.codehaus.plexus.util.IOUtil
import shadow.org.apache.tools.zip.ZipOutputStream
import shadow.org.codehaus.plexus.util.IOUtil
plugins {
id "com.github.johnrengelman.shadow" version "5.0.0"
@@ -10,12 +10,16 @@ plugins {
}
loom {
accessWidener(file("src/main/resources/architectury.accessWidener"))
silentMojangMappingsLicense()
accessWidener = file("src/main/resources/architectury.accessWidener")
}
configurations {
shadow
dev
}
artifacts {
dev(jar)
}
architectury {
@@ -23,25 +27,23 @@ architectury {
}
dependencies {
minecraft("com.mojang:minecraft:${rootProject.architect.minecraft}")
mappings(minecraft.officialMojangMappings())
modCompile("net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}")
modCompile("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}")
modCompileOnly("io.github.prospector:modmenu:${rootProject.mod_menu_version}")
minecraft "com.mojang:minecraft:${rootProject.architectury.minecraft}"
mappings minecraft.officialMojangMappings()
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
modCompileOnly "io.github.prospector:modmenu:${rootProject.mod_menu_version}"
implementation "net.jodah:typetools:0.6.2"
shadow "net.jodah:typetools:0.6.2"
compileOnly(project(path: ":common")) {
transitive = false
}
runtimeOnly(project(path: ":common", configuration: "transformed")) {
runtimeOnly(project(path: ":common", configuration: "transformDevelopmentFabric")) {
transitive = false
}
shadow(project(path: ":common", configuration: "transformed")) {
shadow(project(path: ":common", configuration: "transformProductionFabric")) {
transitive = false
}
testCompile project(":common").sourceSets.test.output
}
processResources {
@@ -53,9 +55,6 @@ processResources {
shadowJar {
relocate "net.jodah.typetools", "me.shedaniel.architectury.shadowed.impl.net.jodah.typetools"
transform(MergeAccessWidenersTransformer.class) {
it.resource = "architectury.accessWidener"
}
configurations = [project.configurations.shadow]
classifier "shadow"
}
@@ -75,6 +74,18 @@ publishing {
}
}
}
repositories {
if (System.getenv("MAVEN_PASS") != null) {
maven {
url = "https://deploy.shedaniel.me/"
credentials {
username = "shedaniel"
password = System.getenv("MAVEN_PASS")
}
}
}
}
}
curseforge {
@@ -87,6 +98,7 @@ curseforge {
changelog = releaseChangelog()
addGameVersion "1.16-Snapshot"
addGameVersion "1.16.4"
addGameVersion "1.16.5"
addGameVersion "Java 8"
addGameVersion "Fabric"
relations {
@@ -107,53 +119,3 @@ curseforge {
}
rootProject.tasks.getByName("curseforgePublish").dependsOn tasks.getByName("curseforge")
class MergeAccessWidenersTransformer implements Transformer {
String resource
ByteArrayOutputStream data
MergeAccessWidenersTransformer() {
data = new ByteArrayOutputStream()
data.write("accessWidener v1 named\n".bytes)
}
@Override
boolean canTransformResource(FileTreeElement element) {
def path = element.relativePath.pathString
if (resource != null && resource.equalsIgnoreCase(path)) {
return true
}
return false
}
@Override
void transform(TransformerContext context) {
def lines = context.is.readLines()
lines.removeIf { it == "accessWidener v1 named" }
IOUtil.copy(lines.join("\n"), data)
data.write('\n'.bytes)
context.is.close()
}
@Override
boolean hasTransformedResource() {
return data.size() > 0
}
void modifyOutputStream(org.apache.tools.zip.ZipOutputStream jos, boolean preserveFileTimestamps) {
throw new AbstractMethodError()
}
@Override
void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) {
ZipEntry entry = new ZipEntry(resource)
entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time)
os.putNextEntry(entry)
IOUtil.copy(new ByteArrayInputStream(data.toByteArray()), os)
data.reset()
data.write('accessWidener v1 named\n'.bytes)
}
}

View File

@@ -0,0 +1,58 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 shedaniel
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.hooks.fabric;
import com.google.common.base.Preconditions;
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import java.util.Objects;
public class BlockEntityHooksImpl {
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public static void syncData(BlockEntity entity) {
if (entity instanceof BlockEntityClientSerializable) {
((BlockEntityClientSerializable) entity).sync();
} else {
Level world = Objects.requireNonNull(entity.getLevel());
if (!(world instanceof ServerLevel)) {
throw new IllegalStateException("Cannot call sync() on the logical client! Did you check world.isClient first?");
} else {
((ServerLevel) world).getChunkSource().blockChanged(entity.getBlockPos());
}
}
}
}

View File

@@ -26,14 +26,22 @@ import me.shedaniel.architectury.utils.Fraction;
import me.shedaniel.architectury.utils.NbtType;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@@ -103,4 +111,86 @@ public class FluidStackHooksImpl {
public static Fraction bucketAmount() {
return Fraction.ofWhole(1);
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) {
if (state.getType() == Fluids.EMPTY) return null;
TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(state.getType()).getFluidSprites(level, pos, state);
if (sprites == null) return null;
return sprites[0];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(@NotNull FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return null;
TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(stack.getFluid()).getFluidSprites(null, null, stack.getFluid().defaultFluidState());
if (sprites == null) return null;
return sprites[0];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getStillTexture(@NotNull Fluid fluid) {
if (fluid == Fluids.EMPTY) return null;
TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(fluid).getFluidSprites(null, null, fluid.defaultFluidState());
if (sprites == null) return null;
return sprites[0];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) {
if (state.getType() == Fluids.EMPTY) return null;
FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
if (handler == null) return null;
TextureAtlasSprite[] sprites = handler.getFluidSprites(level, pos, state);
if (sprites == null) return null;
return sprites[1];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(@NotNull FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return null;
FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(stack.getFluid());
if (handler == null) return null;
TextureAtlasSprite[] sprites = handler.getFluidSprites(null, null, stack.getFluid().defaultFluidState());
if (sprites == null) return null;
return sprites[1];
}
@Environment(EnvType.CLIENT)
@Nullable
public static TextureAtlasSprite getFlowingTexture(@NotNull Fluid fluid) {
if (fluid == Fluids.EMPTY) return null;
TextureAtlasSprite[] sprites = FluidRenderHandlerRegistry.INSTANCE.get(fluid).getFluidSprites(null, null, fluid.defaultFluidState());
if (sprites == null) return null;
return sprites[1];
}
@Environment(EnvType.CLIENT)
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, @NotNull FluidState state) {
if (state.getType() == Fluids.EMPTY) return -1;
FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
if (handler == null) return -1;
return handler.getFluidColor(level, pos, state);
}
@Environment(EnvType.CLIENT)
public static int getColor(@NotNull FluidStack stack) {
if (stack.getFluid() == Fluids.EMPTY) return -1;
FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(stack.getFluid());
if (handler == null) return -1;
return handler.getFluidColor(null, null, stack.getFluid().defaultFluidState());
}
@Environment(EnvType.CLIENT)
public static int getColor(@NotNull Fluid fluid) {
if (fluid == Fluids.EMPTY) return -1;
FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluid);
if (handler == null) return -1;
return handler.getFluidColor(null, null, fluid.defaultFluidState());
}
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 shedaniel
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.init.fabric;
import me.shedaniel.architectury.event.events.client.ClientLifecycleEvent;
import net.minecraft.client.Minecraft;
public class ArchitecturyClient {
public static void init() {
ClientLifecycleEvent.CLIENT_SETUP.invoker().stateChanged(Minecraft.getInstance());
}
}

View File

@@ -0,0 +1,54 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 shedaniel
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.extensions.BlockEntityExtension;
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(BlockEntityExtension.class)
public interface MixinBlockEntityExtension extends BlockEntityClientSerializable {
@Shadow(remap = false)
@NotNull
CompoundTag saveClientData(@NotNull CompoundTag tag);
@Shadow(remap = false)
void loadClientData(@NotNull BlockState pos, @NotNull CompoundTag tag);
@Override
default void fromClientTag(CompoundTag tag) {
BlockEntity entity = (BlockEntity) this;
if (entity.hasLevel()) {
entity.setLevelAndPosition(entity.getLevel(), new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z")));
loadClientData(entity.getBlockState(), tag);
}
}
@Override
default CompoundTag toClientTag(CompoundTag tag) {
return saveClientData(tag);
}
}

View File

@@ -20,6 +20,7 @@
package me.shedaniel.architectury.mixin.fabric;
import me.shedaniel.architectury.event.events.PlayerEvent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.MenuProvider;
@@ -57,4 +58,9 @@ public class MixinServerPlayer {
private void doCloseContainer(CallbackInfo ci) {
PlayerEvent.CLOSE_MENU.invoker().close((ServerPlayer) (Object) this, ((ServerPlayer) (Object) this).containerMenu);
}
@Inject(method = "triggerDimensionChangeTriggers", at = @At("HEAD"))
private void changeDimension(ServerLevel serverLevel, CallbackInfo ci) {
PlayerEvent.CHANGE_DIMENSION.invoker().change((ServerPlayer) (Object) this, serverLevel.dimension(), ((ServerPlayer) (Object) this).level.dimension());
}
}

View File

@@ -0,0 +1,57 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 shedaniel
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.mixin.fabric.client;
import com.mojang.blaze3d.shaders.Program;
import net.minecraft.client.renderer.EffectInstance;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Unique
@Mixin(value = EffectInstance.class, priority = 950)
public class MixinEffectInstance {
@Redirect(
method = "<init>",
at = @At(value = "NEW",
target = "(Ljava/lang/String;)Lnet/minecraft/resources/ResourceLocation;",
ordinal = 0)
)
private ResourceLocation mojangPls(String _0, ResourceManager rm, String str) {
return mojangPls(new ResourceLocation(str), ".json");
}
@Redirect(
method = "getOrCreate",
at = @At(value = "NEW",
target = "(Ljava/lang/String;)Lnet/minecraft/resources/ResourceLocation;",
ordinal = 0)
)
private static ResourceLocation mojangPls(String _0, ResourceManager rm, Program.Type type, String str) {
return mojangPls(new ResourceLocation(str), type.getExtension());
}
private static ResourceLocation mojangPls(ResourceLocation rl, String ext) {
return new ResourceLocation(rl.getNamespace(), "shaders/program/" + rl.getPath() + ext);
}
}

View File

@@ -19,6 +19,7 @@
package me.shedaniel.architectury.mixin.fabric.client;
import me.shedaniel.architectury.event.events.client.ClientRawInputEvent;
import me.shedaniel.architectury.event.events.client.ClientScreenInputEvent;
import me.shedaniel.architectury.impl.fabric.ScreenInputDelegate;
import net.minecraft.client.KeyboardHandler;
@@ -111,4 +112,13 @@ public class MixinKeyboardHandler {
info.cancel();
}
}
@Inject(method = "keyPress", at = @At("RETURN"), cancellable = true)
public void onRawKey(long handle, int key, int scanCode, int action, int modifiers, CallbackInfo info) {
if (handle == this.minecraft.getWindow().getWindow()) {
InteractionResult result = ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(minecraft, key, scanCode, action, modifiers);
if (result != InteractionResult.PASS)
info.cancel();
}
}
}

View File

@@ -19,34 +19,49 @@
package me.shedaniel.architectury.mixin.fabric.client;
import me.shedaniel.architectury.event.events.GuiEvent;
import me.shedaniel.architectury.event.events.InteractionEvent;
import me.shedaniel.architectury.event.events.client.ClientPlayerEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ConnectScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.main.GameConfig;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.HitResult;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.io.File;
@Unique
@Mixin(Minecraft.class)
public class MixinMinecraft {
public abstract class MixinMinecraft {
// @formatter:off
@Shadow @Nullable public LocalPlayer player;
@Shadow @Nullable public HitResult hitResult;
@Shadow public abstract void setScreen(@Nullable Screen screen);
private boolean setScreenCancelled;
private String hostname;
private int port;
// @formatter:on
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/chat/NarratorChatListener;clear()V"))
private void handleLogin(Screen screen, CallbackInfo ci) {
if (player != null) {
ClientPlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(player);
}
ClientPlayerEvent.CLIENT_PLAYER_QUIT.invoker().quit(player);
}
@Inject(method = "startUseItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isEmpty()Z", ordinal = 1),
@@ -61,4 +76,78 @@ public class MixinMinecraft {
private void leftClickAir(CallbackInfo ci) {
InteractionEvent.CLIENT_LEFT_CLICK_AIR.invoker().click(player, InteractionHand.MAIN_HAND);
}
@ModifyVariable(
method = "setScreen",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/player/LocalPlayer;respawn()V",
shift = At.Shift.BY,
by = 2),
argsOnly = true
)
public Screen modifyScreen(Screen screen) {
Screen old = screen;
InteractionResultHolder<Screen> event = GuiEvent.SET_SCREEN.invoker().modifyScreen(screen);
switch (event.getResult()) {
case FAIL:
setScreenCancelled = true;
return old;
case SUCCESS:
screen = event.getObject();
if (old != null && screen != old) {
old.removed();
}
default:
setScreenCancelled = false;
return screen;
}
}
@Inject(
method = "setScreen",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/player/LocalPlayer;respawn()V",
shift = At.Shift.BY,
by = 3),
cancellable = true
)
public void cancelSetScreen(@Nullable Screen screen, CallbackInfo ci) {
if (setScreenCancelled) {
ci.cancel();
}
}
@Redirect(
method = "<init>",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;setScreen(Lnet/minecraft/client/gui/screens/Screen;)V"),
slice = @Slice(
from = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;resizeDisplay()V"),
to = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/LoadingOverlay;registerTextures(Lnet/minecraft/client/Minecraft;)V")
)
)
public void minecraftWhy(Minecraft mc, Screen screen) {
}
@Inject(
method = "<init>",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;resizeDisplay()V"),
locals = LocalCapture.CAPTURE_FAILHARD
)
public void saveLocals(GameConfig gc, CallbackInfo ci, File f, String string2, int j) {
hostname = string2;
port = j;
}
@SuppressWarnings({"UnresolvedMixinReference", "ConstantConditions"})
@Inject(
method = {"method_29338", "lambda$null$1"}, // <init>.lambda$null$1
at = @At("RETURN")
)
public void registerMainScreens(CallbackInfo ci) {
if (hostname != null) {
setScreen(new ConnectScreen(new TitleScreen(), (Minecraft) ((Object) this), hostname, port));
} else {
setScreen(new TitleScreen(true));
}
}
}

View File

@@ -19,6 +19,7 @@
package me.shedaniel.architectury.mixin.fabric.client;
import me.shedaniel.architectury.event.events.client.ClientRawInputEvent;
import me.shedaniel.architectury.event.events.client.ClientScreenInputEvent;
import me.shedaniel.architectury.impl.fabric.ScreenInputDelegate;
import net.minecraft.client.Minecraft;
@@ -52,7 +53,7 @@ public class MixinMouseHandler {
@Inject(method = "onScroll",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseScrolled(DDD)Z",
ordinal = 0), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
public void onMouseScrolled(long long_1, double double_1, double double_2, CallbackInfo info, double amount, double x, double y) {
public void onMouseScrolled(long handle, double xOffset, double yOffset, CallbackInfo info, double amount, double x, double y) {
if (!info.isCancelled()) {
InteractionResult result = ClientScreenInputEvent.MOUSE_SCROLLED_PRE.invoker().mouseScrolled(minecraft, minecraft.screen, x, y, amount);
if (result != InteractionResult.PASS)
@@ -63,29 +64,62 @@ public class MixinMouseHandler {
@Inject(method = "onScroll",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseScrolled(DDD)Z",
ordinal = 0, shift = At.Shift.AFTER), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
public void onMouseScrolledPost(long long_1, double double_1, double double_2, CallbackInfo info, double amount, double x, double y) {
public void onMouseScrolledPost(long handle, double xOffset, double yOffset, CallbackInfo info, double amount, double x, double y) {
if (!info.isCancelled()) {
InteractionResult result = ClientScreenInputEvent.MOUSE_SCROLLED_POST.invoker().mouseScrolled(minecraft, minecraft.screen, x, y, amount);
}
}
@Inject(method = "onPress", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/screens/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V",
ordinal = 0), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
public void onMouseClicked(long long_1, int button, int int_2, int int_3, CallbackInfo info, boolean bl, int i, boolean[] bls, double d, double e) {
@Inject(method = "onScroll",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z",
ordinal = 0), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
public void onRawMouseScrolled(long handle, double xOffset, double yOffset, CallbackInfo info, double amount) {
if (!info.isCancelled()) {
InteractionResult result = ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, minecraft.screen, d, e, button);
InteractionResult result = ClientRawInputEvent.MOUSE_SCROLLED.invoker().mouseScrolled(minecraft, amount);
if (result != InteractionResult.PASS)
info.cancel();
}
}
@Inject(method = "onPress", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/screens/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V",
ordinal = 0, shift = At.Shift.AFTER), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
public void onMouseClickedPost(long long_1, int button, int int_2, int int_3, CallbackInfo info, boolean bl, int i, boolean[] bls, double d, double e) {
@SuppressWarnings("UnresolvedMixinReference")
@Inject(method = {"lambda$onPress$0", "method_1611"}, at = @At("HEAD"), cancellable = true, remap = false)
public void onGuiMouseClicked(boolean[] bls, double d, double e, int button, CallbackInfo info) {
if (!info.isCancelled()) {
InteractionResult result = ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, minecraft.screen, d, e, button);
if (result != InteractionResult.PASS) {
bls[0] = true;
info.cancel();
}
}
}
@SuppressWarnings("UnresolvedMixinReference")
@Inject(method = {"lambda$onPress$0", "method_1611"}, at = @At("RETURN"), cancellable = true, remap = false)
public void onGuiMouseClickedPost(boolean[] bls, double d, double e, int button, CallbackInfo info) {
if (!info.isCancelled() && !bls[0]) {
InteractionResult result = ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(minecraft, minecraft.screen, d, e, button);
if (result != InteractionResult.PASS) {
bls[0] = true;
info.cancel();
}
}
}
@Inject(method = "onPress", at = @At(value = "FIELD",
target = "Lnet/minecraft/client/Minecraft;overlay:Lnet/minecraft/client/gui/screens/Overlay;",
ordinal = 0), cancellable = true)
public void onRawMouseClicked(long handle, int button, int action, int mods, CallbackInfo info) {
if (!info.isCancelled()) {
InteractionResult result = ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, button, action, mods);
if (result != InteractionResult.PASS)
info.cancel();
}
}
@Inject(method = "onPress", at = @At("RETURN"), cancellable = true)
public void onRawMouseClickedPost(long handle, int button, int action, int mods, CallbackInfo info) {
if (handle == this.minecraft.getWindow().getWindow()) {
InteractionResult result = ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(minecraft, button, action, mods);
if (result != InteractionResult.PASS)
info.cancel();
}

View File

@@ -0,0 +1,52 @@
package me.shedaniel.architectury.plugin.fabric;
import net.fabricmc.loader.api.FabricLoader;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public class ArchitecturyMixinPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {
// noop
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
switch (mixinClassName) {
case "me.shedaniel.architectury.mixin.fabric.client.MixinEffectInstance":
return !FabricLoader.getInstance().isModLoaded("satin");
default:
return true;
}
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
// noop
}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
// noop
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
// noop
}
}

View File

@@ -25,12 +25,35 @@ import net.minecraft.client.color.item.ItemColor;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import java.util.Objects;
import java.util.function.Supplier;
public class ColorHandlersImpl {
public static void registerItemColors(ItemColor color, ItemLike... items) {
ColorProviderRegistry.ITEM.register(color, items);
@SafeVarargs
public static void registerItemColors(ItemColor itemColor, Supplier<ItemLike>... items) {
Objects.requireNonNull(itemColor, "color is null!");
ColorProviderRegistry.ITEM.register(itemColor, unpackItems(items));
}
public static void registerBlockColors(BlockColor color, Block... blocks) {
ColorProviderRegistry.BLOCK.register(color, blocks);
@SafeVarargs
public static void registerBlockColors(BlockColor blockColor, Supplier<Block>... blocks) {
Objects.requireNonNull(blockColor, "color is null!");
ColorProviderRegistry.BLOCK.register(blockColor, unpackBlocks(blocks));
}
private static ItemLike[] unpackItems(Supplier<ItemLike>[] items) {
ItemLike[] array = new ItemLike[items.length];
for (int i = 0; i < items.length; i++) {
array[i] = Objects.requireNonNull(items[i].get());
}
return array;
}
private static Block[] unpackBlocks(Supplier<Block>[] blocks) {
Block[] array = new Block[blocks.length];
for (int i = 0; i < blocks.length; i++) {
array[i] = Objects.requireNonNull(blocks[i].get());
}
return array;
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 shedaniel
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.registry.fabric;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.GameRules;
import java.util.function.BiConsumer;
public class GameRuleFactoryImpl {
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue) {
return GameRuleFactory.createBooleanRule(defaultValue);
}
public static GameRules.Type<GameRules.BooleanValue> createBooleanRule(boolean defaultValue, BiConsumer<MinecraftServer, GameRules.BooleanValue> changedCallback) {
return GameRuleFactory.createBooleanRule(defaultValue, changedCallback);
}
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue) {
return GameRuleFactory.createIntRule(defaultValue);
}
public static GameRules.Type<GameRules.IntegerValue> createIntRule(int defaultValue, BiConsumer<MinecraftServer, GameRules.IntegerValue> changedCallback) {
return GameRuleFactory.createIntRule(defaultValue, changedCallback);
}
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 shedaniel
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.registry.fabric;
import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry;
import net.minecraft.world.level.GameRules;
public class GameRuleRegistryImpl {
public static <T extends GameRules.Value<T>> GameRules.Key<T> register(String name, GameRules.Category category, GameRules.Type<T> type) {
return GameRuleRegistry.register(name, category, type);
}
}

View File

@@ -40,7 +40,7 @@ import net.minecraft.world.inventory.MenuType;
import org.jetbrains.annotations.Nullable;
public class MenuRegistryImpl {
public static void openMenu(ServerPlayer player, ExtendedMenuProvider provider) {
public static void openExtendedMenu(ServerPlayer player, ExtendedMenuProvider provider) {
player.openMenu(new ExtendedScreenHandlerFactory() {
@Override
public void writeScreenOpeningData(ServerPlayer player, FriendlyByteBuf buf) {

View File

@@ -20,9 +20,16 @@
package me.shedaniel.architectury.registry.fabric;
import com.google.common.base.Objects;
import me.shedaniel.architectury.core.RegistryEntry;
import me.shedaniel.architectury.registry.Registries;
import me.shedaniel.architectury.registry.Registry;
import me.shedaniel.architectury.registry.RegistrySupplier;
import me.shedaniel.architectury.registry.registries.RegistryBuilder;
import me.shedaniel.architectury.registry.registries.RegistryOption;
import me.shedaniel.architectury.registry.registries.StandardRegistryOption;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
import net.minecraft.core.MappedRegistry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.LazyLoadedValue;
@@ -64,6 +71,36 @@ public class RegistriesImpl {
public <T> Registry<T> get(net.minecraft.core.Registry<T> registry) {
return new RegistryImpl<>(registry);
}
@Override
@NotNull
public <T extends RegistryEntry<T>> RegistryBuilder<T> builder(Class<T> type, ResourceLocation registryId) {
return new RegistryBuilderWrapper<>(FabricRegistryBuilder.createSimple(type, registryId));
}
}
public static class RegistryBuilderWrapper<T extends RegistryEntry<T>> implements RegistryBuilder<T> {
@NotNull
private FabricRegistryBuilder<T, MappedRegistry<T>> builder;
public RegistryBuilderWrapper(@NotNull FabricRegistryBuilder<T, MappedRegistry<T>> builder) {
this.builder = builder;
}
@Override
public @NotNull Registry<T> build() {
return RegistryProviderImpl.INSTANCE.get(builder.buildAndRegister());
}
@Override
public @NotNull RegistryBuilder<T> option(@NotNull RegistryOption option) {
if (option == StandardRegistryOption.SAVE_TO_DISC) {
this.builder.attribute(RegistryAttribute.PERSISTED);
} else if (option == StandardRegistryOption.SYNC_TO_CLIENTS) {
this.builder.attribute(RegistryAttribute.SYNCED);
}
return this;
}
}
public static class RegistryImpl<T> implements Registry<T> {
@@ -128,6 +165,11 @@ public class RegistriesImpl {
return delegate.getKey(obj);
}
@Override
public int getRawId(T obj) {
return delegate.getId(obj);
}
@Override
public Optional<ResourceKey<T>> getKey(T obj) {
return delegate.getResourceKey(obj);
@@ -138,9 +180,14 @@ public class RegistriesImpl {
return delegate.get(id);
}
@Override
public T byRawId(int rawId) {
return delegate.byId(rawId);
}
@Override
public boolean contains(ResourceLocation id) {
return delegate.containsKey(id);
return delegate.keySet().contains(id);
}
@Override

View File

@@ -39,7 +39,7 @@ public class ReloadListenersImpl {
public static void registerReloadListener(PackType type, PreparableReloadListener listener) {
byte[] bytes = new byte[8];
RANDOM.nextBytes(bytes);
ResourceLocation id = new ResourceLocation("architectury:reload_" + StringUtils.leftPad(Math.abs(Longs.fromByteArray(bytes)) + "", 19));
ResourceLocation id = new ResourceLocation("architectury:reload_" + StringUtils.leftPad(Math.abs(Longs.fromByteArray(bytes)) + "", 19, '0'));
ResourceManagerHelper.get(type).registerReloadListener(new IdentifiableResourceReloadListener() {
@Override
public ResourceLocation getFabricId() {

View File

@@ -54,4 +54,45 @@ accessible field net/minecraft/world/item/DyeColor textureDiffuseColor I
accessible method net/minecraft/world/entity/player/Player closeContainer ()V
accessible method net/minecraft/advancements/CriteriaTriggers register (Lnet/minecraft/advancements/CriterionTrigger;)Lnet/minecraft/advancements/CriterionTrigger;
accessible method net/minecraft/world/inventory/MenuType <init> (Lnet/minecraft/world/inventory/MenuType$MenuSupplier;)V
accessible class net/minecraft/world/inventory/MenuType$MenuSupplier
accessible class net/minecraft/world/inventory/MenuType$MenuSupplier
accessible method net/minecraft/world/level/block/state/BlockBehaviour$Properties <init> (Lnet/minecraft/world/level/material/Material;Ljava/util/function/Function;)V
accessible field net/minecraft/world/level/biome/Biome climateSettings Lnet/minecraft/world/level/biome/Biome$ClimateSettings;
accessible field net/minecraft/world/level/biome/Biome depth F
mutable field net/minecraft/world/level/biome/Biome depth F
accessible field net/minecraft/world/level/biome/Biome scale F
mutable field net/minecraft/world/level/biome/Biome scale F
accessible field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecraft/world/level/biome/Biome$BiomeCategory;
mutable field net/minecraft/world/level/biome/Biome biomeCategory Lnet/minecraft/world/level/biome/Biome$BiomeCategory;
accessible field net/minecraft/world/level/biome/Biome$ClimateSettings precipitation Lnet/minecraft/world/level/biome/Biome$Precipitation;
mutable field net/minecraft/world/level/biome/Biome$ClimateSettings precipitation Lnet/minecraft/world/level/biome/Biome$Precipitation;
accessible field net/minecraft/world/level/biome/Biome$ClimateSettings temperature F
mutable field net/minecraft/world/level/biome/Biome$ClimateSettings temperature F
accessible field net/minecraft/world/level/biome/Biome$ClimateSettings temperatureModifier Lnet/minecraft/world/level/biome/Biome$TemperatureModifier;
mutable field net/minecraft/world/level/biome/Biome$ClimateSettings temperatureModifier Lnet/minecraft/world/level/biome/Biome$TemperatureModifier;
accessible field net/minecraft/world/level/biome/Biome$ClimateSettings downfall F
mutable field net/minecraft/world/level/biome/Biome$ClimateSettings downfall F
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects fogColor I
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects fogColor I
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects waterColor I
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects waterColor I
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects waterFogColor I
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects waterFogColor I
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects skyColor I
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects skyColor I
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects foliageColorOverride Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects foliageColorOverride Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects grassColorOverride Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects grassColorOverride Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects grassColorModifier Lnet/minecraft/world/level/biome/BiomeSpecialEffects$GrassColorModifier;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects grassColorModifier Lnet/minecraft/world/level/biome/BiomeSpecialEffects$GrassColorModifier;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects ambientParticleSettings Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientParticleSettings Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects ambientLoopSoundEvent Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientLoopSoundEvent Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects ambientMoodSettings Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientMoodSettings Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects ambientAdditionsSettings Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientAdditionsSettings Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional;
accessible method net/minecraft/world/level/storage/LevelResource <init> (Ljava/lang/String;)V

View File

@@ -1,19 +1,45 @@
{
"required": true,
"package": "me.shedaniel.architectury.mixin.fabric",
"plugin": "me.shedaniel.architectury.plugin.fabric.ArchitecturyMixinPlugin",
"compatibilityLevel": "JAVA_8",
"minVersion": "0.7.11",
"client": [
"client.MixinClientLevel", "client.MixinClientPacketListener", "client.MixinDebugScreenOverlay", "client.MixinGameRenderer", "client.MixinIntegratedServer",
"client.MixinKeyboardHandler", "client.MixinMinecraft", "client.MixinMouseHandler", "client.MixinMultiPlayerGameMode", "client.MixinScreen",
"client.MixinClientLevel",
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinEffectInstance",
"client.MixinGameRenderer",
"client.MixinIntegratedServer",
"client.MixinKeyboardHandler",
"client.MixinMinecraft",
"client.MixinMouseHandler",
"client.MixinMultiPlayerGameMode",
"client.MixinScreen",
"client.MixinTextureAtlas"
],
"mixins": [
"ExplosionPreInvoker", "LivingDeathInvoker", "MixinBlockItem", "MixinCommands", "MixinDedicatedServer", "MixinExplosion", "MixinFurnaceResultSlot",
"MixinItemEntity", "MixinLivingEntity", "MixinPersistentEntitySectionManager", "MixinPlayer", "MixinPlayerAdvancements", "MixinPlayerList",
"MixinResultSlot", "MixinServerGamePacketListenerImpl", "MixinServerLevel", "MixinServerPlayer", "MixinServerPlayerGameMode", "PlayerAttackInvoker"
"ExplosionPreInvoker",
"LivingDeathInvoker",
"MixinBlockEntityExtension",
"MixinBlockItem",
"MixinCommands",
"MixinDedicatedServer",
"MixinExplosion",
"MixinFurnaceResultSlot",
"MixinItemEntity",
"MixinLivingEntity",
"MixinPersistentEntitySectionManager", "MixinPlayer",
"MixinPlayerAdvancements",
"MixinPlayerList",
"MixinResultSlot",
"MixinServerGamePacketListenerImpl", "MixinServerLevel",
"MixinServerPlayer",
"MixinServerPlayerGameMode",
"PlayerAttackInvoker"
],
"injectors": {
"maxShiftBy": 5,
"defaultRequire": 1
}
}

View File

@@ -16,6 +16,9 @@
"main": [
"me.shedaniel.architectury.utils.fabric.GameInstanceImpl::init"
],
"client": [
"me.shedaniel.architectury.init.fabric.ArchitecturyClient::init"
],
"modmenu": [
"me.shedaniel.architectury.compat.fabric.ModMenuCompatibility"
]