Port for 1.21.9

This commit is contained in:
shedaniel
2025-10-02 18:09:01 +08:00
parent 97ceb68560
commit bc6c57c33a
102 changed files with 1408 additions and 1856 deletions

View File

@@ -19,12 +19,7 @@
package dev.architectury.test;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.architectury.event.events.client.ClientCommandRegistrationEvent;
import dev.architectury.event.events.client.ClientLifecycleEvent;
import dev.architectury.registry.CreativeTabRegistry;
import dev.architectury.registry.client.gui.ClientTooltipComponentRegistry;
import dev.architectury.registry.client.level.entity.EntityRendererRegistry;
import dev.architectury.test.debug.ConsoleMessageSink;
import dev.architectury.test.debug.MessageSink;
import dev.architectury.test.debug.client.ClientOverlayMessageSink;
@@ -35,16 +30,11 @@ import dev.architectury.test.loot.TestLoot;
import dev.architectury.test.networking.TestModNet;
import dev.architectury.test.particle.TestParticles;
import dev.architectury.test.registry.TestRegistries;
import dev.architectury.test.registry.client.TestKeybinds;
import dev.architectury.test.registry.objects.ItemWithTooltip;
import dev.architectury.test.tags.TestTags;
import dev.architectury.test.trade.TestTrades;
import dev.architectury.test.worldgen.TestWorldGeneration;
import dev.architectury.utils.Env;
import dev.architectury.utils.EnvExecutor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.renderer.entity.CowRenderer;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.ItemStack;
@@ -66,34 +56,11 @@ public class TestMod {
TestBlockInteractions.init();
TestLoot.init();
TestWorldGeneration.initialize();
EnvExecutor.runInEnv(Env.CLIENT, () -> TestMod.Client::initializeClient);
EnvExecutor.runInEnv(Env.CLIENT, () -> TestModClient::initializeClient);
CreativeTabRegistry.modifyBuiltin(BuiltInRegistries.CREATIVE_MODE_TAB.getValue(CreativeModeTabs.BUILDING_BLOCKS), (flags, output, canUseGameMasterBlocks) -> {
ItemStack sword = Items.DIAMOND_SWORD.getDefaultInstance();
output.acceptBefore(new ItemStack(Items.OAK_WOOD), sword);
output.acceptAfter(Blocks.STRIPPED_OAK_LOG, Items.BEDROCK);
});
}
@Environment(EnvType.CLIENT)
public static class Client {
@Environment(EnvType.CLIENT)
public static void initializeClient() {
ClientLifecycleEvent.CLIENT_STARTED.register((client) -> SINK.accept("Client started!"));
ClientLifecycleEvent.CLIENT_STOPPING.register((client) -> SINK.accept("Client stopping!"));
TestKeybinds.initialize();
TestModNet.initializeClient();
EntityRendererRegistry.register(TestRegistries.TEST_ENTITY, CowRenderer::new);
EntityRendererRegistry.register(TestRegistries.TEST_ENTITY_2, CowRenderer::new);
ClientTooltipComponentRegistry.register(ItemWithTooltip.MyTooltipComponent.class, ItemWithTooltip.MyClientTooltipComponent::new);
ClientCommandRegistrationEvent.EVENT.register((dispatcher, access) -> {
dispatcher.register(ClientCommandRegistrationEvent.literal("cool_client")
.then(ClientCommandRegistrationEvent.argument("string", StringArgumentType.string())
.executes(context -> {
String string = StringArgumentType.getString(context, "string");
SINK.accept("Cool client command for " + string);
return 0;
})));
});
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 dev.architectury.test;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.architectury.event.events.client.ClientCommandRegistrationEvent;
import dev.architectury.event.events.client.ClientLifecycleEvent;
import dev.architectury.registry.client.gui.ClientTooltipComponentRegistry;
import dev.architectury.registry.client.level.entity.EntityRendererRegistry;
import dev.architectury.test.networking.TestModNet;
import dev.architectury.test.registry.TestRegistries;
import dev.architectury.test.registry.client.TestKeybinds;
import dev.architectury.test.registry.objects.ItemWithTooltip;
import dev.architectury.test.registry.objects.MyClientTooltipComponent;
import net.minecraft.client.renderer.entity.CowRenderer;
import static dev.architectury.test.TestMod.SINK;
public class TestModClient {
public static void initializeClient() {
ClientLifecycleEvent.CLIENT_STARTED.register((client) -> SINK.accept("Client started!"));
ClientLifecycleEvent.CLIENT_STOPPING.register((client) -> SINK.accept("Client stopping!"));
TestKeybinds.initialize();
TestModNet.initializeClient();
EntityRendererRegistry.register(TestRegistries.TEST_ENTITY, CowRenderer::new);
EntityRendererRegistry.register(TestRegistries.TEST_ENTITY_2, CowRenderer::new);
ClientTooltipComponentRegistry.register(ItemWithTooltip.MyTooltipComponent.class, MyClientTooltipComponent::new);
ClientCommandRegistrationEvent.EVENT.register((dispatcher, access) -> {
dispatcher.register(ClientCommandRegistrationEvent.literal("cool_client")
.then(ClientCommandRegistrationEvent.argument("string", StringArgumentType.string())
.executes(context -> {
String string = StringArgumentType.getString(context, "string");
SINK.accept("Cool client command for " + string);
return 0;
})));
});
}
}

View File

@@ -22,8 +22,6 @@ package dev.architectury.test.debug.client;
import com.google.common.collect.Lists;
import dev.architectury.event.events.client.ClientGuiEvent;
import dev.architectury.test.debug.ConsoleMessageSink;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.Util;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
@@ -34,7 +32,6 @@ import net.minecraft.util.Mth;
import java.util.Collections;
import java.util.List;
@Environment(EnvType.CLIENT)
public class ClientOverlayMessageSink extends ConsoleMessageSink {
private final List<Message> messages = Collections.synchronizedList(Lists.newArrayList());
@@ -42,7 +39,7 @@ public class ClientOverlayMessageSink extends ConsoleMessageSink {
ClientGuiEvent.RENDER_POST.register((screen, graphics, mouseX, mouseY, delta) -> render(graphics, delta));
ClientGuiEvent.RENDER_HUD.register((graphics, delta) -> {
if (Minecraft.getInstance().screen == null && !Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) {
render(graphics, delta);
render(graphics, delta.getRealtimeDeltaTicks());
}
});
}
@@ -53,7 +50,7 @@ public class ClientOverlayMessageSink extends ConsoleMessageSink {
messages.add(0, new Message(Component.literal(message), Util.getMillis()));
}
public void render(GuiGraphics graphics, DeltaTracker delta) {
public void render(GuiGraphics graphics, float delta) {
graphics.pose().pushMatrix();
graphics.pose().scale(0.5f, 0.5f);
var minecraft = Minecraft.getInstance();

View File

@@ -0,0 +1,143 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 dev.architectury.test.events;
import com.mojang.blaze3d.platform.InputConstants;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.client.*;
import dev.architectury.event.events.common.InteractionEvent;
import dev.architectury.test.TestMod;
import net.minecraft.client.gui.screens.inventory.AnvilScreen;
import net.minecraft.network.chat.Component;
import static dev.architectury.test.events.DebugEvents.logSide;
import static dev.architectury.test.events.DebugEvents.toSimpleName;
public class ClientDebugEvents {
public static void debugEventsClient() {
ClientTickEvent.CLIENT_LEVEL_PRE.register(instance -> {
try {
// Uncomment the following line to see the profiler spike for root.tick.level.architecturyClientLevelPreTick
//Thread.sleep(10);
} catch (Throwable e) {
e.printStackTrace();
}
});
ClientChatEvent.SEND.register((message, component) -> {
TestMod.SINK.accept("Client chat sent: " + message);
if (message.contains("error")) {
return EventResult.interruptFalse();
}
return EventResult.pass();
});
ClientChatEvent.RECEIVED.register((type, message) -> {
TestMod.SINK.accept("Client chat received: " + message.getString());
if (message.getString().contains("terraria")) {
return CompoundEventResult.interruptTrue(message.copy().append(" + terraria is a great game!"));
}
if (message.getString().contains("potato")) {
return CompoundEventResult.interruptFalse(Component.empty());
}
return CompoundEventResult.pass();
});
ClientLifecycleEvent.CLIENT_LEVEL_LOAD.register(world -> {
TestMod.SINK.accept("Client world loaded: " + world.dimension().location().toString());
});
ClientPlayerEvent.CLIENT_PLAYER_JOIN.register(player -> {
TestMod.SINK.accept(player.getScoreboardName() + " joined (client)");
});
ClientPlayerEvent.CLIENT_PLAYER_QUIT.register(player -> {
if (player != null) {
TestMod.SINK.accept(player.getScoreboardName() + " quit (client)");
}
});
ClientPlayerEvent.CLIENT_PLAYER_RESPAWN.register((oldPlayer, newPlayer) -> {
TestMod.SINK.accept(newPlayer.getScoreboardName() + " respawned (client)");
});
ClientGuiEvent.INIT_PRE.register((screen, access) -> {
TestMod.SINK.accept(toSimpleName(screen) + " initializes");
return EventResult.pass();
});
ClientGuiEvent.INIT_POST.register(((screen, access) -> {
TestMod.SINK.accept(toSimpleName(screen) + " initialized");
}));
InteractionEvent.CLIENT_LEFT_CLICK_AIR.register((player, hand) -> {
TestMod.SINK.accept(player.getScoreboardName() + " left clicks air" + logSide(player.level()));
});
InteractionEvent.CLIENT_RIGHT_CLICK_AIR.register((player, hand) -> {
TestMod.SINK.accept(player.getScoreboardName() + " right clicks air" + logSide(player.level()));
});
ClientRecipeUpdateEvent.EVENT.register(recipeManager -> {
TestMod.SINK.accept("Client recipes received");
});
// ClientTextureStitchEvent.POST.register(atlas -> {
// TestMod.SINK.accept("Client texture stitched: " + atlas.location());
// });
ClientScreenInputEvent.MOUSE_SCROLLED_PRE.register((client, screen, mouseX, mouseY, amountX, amountY) -> {
TestMod.SINK.accept("Screen Mouse scrolled: %.2f x-distance %.2f y-distance", amountX, amountY);
return EventResult.pass();
});
ClientScreenInputEvent.MOUSE_CLICKED_PRE.register((client, screen, event, doubleClick) -> {
TestMod.SINK.accept("Screen Mouse clicked: " + event.button());
return EventResult.pass();
});
ClientScreenInputEvent.MOUSE_RELEASED_PRE.register((client, screen, event) -> {
TestMod.SINK.accept("Screen Mouse released: " + event.button());
return EventResult.pass();
});
ClientScreenInputEvent.MOUSE_DRAGGED_PRE.register((client, screen, event, mouseX2, mouseY2) -> {
TestMod.SINK.accept("Screen Mouse dragged: %d (%d,%d) by (%d,%d)", event.button(), (int) event.x(), (int) event.y(), (int) mouseX2, (int) mouseY2);
return EventResult.pass();
});
ClientScreenInputEvent.CHAR_TYPED_PRE.register((client, screen, characterEvent) -> {
TestMod.SINK.accept("Screen Char typed: " + characterEvent.codepointAsString());
return EventResult.pass();
});
ClientScreenInputEvent.KEY_PRESSED_PRE.register((client, screen, keyEvent) -> {
TestMod.SINK.accept("Screen Key pressed: " + InputConstants.getKey(keyEvent).getDisplayName().getString());
return EventResult.pass();
});
ClientScreenInputEvent.KEY_RELEASED_PRE.register((client, screen, keyEvent) -> {
TestMod.SINK.accept("Screen Key released: " + InputConstants.getKey(keyEvent).getDisplayName().getString());
return EventResult.pass();
});
ClientRawInputEvent.MOUSE_SCROLLED.register((client, amountX, amountY) -> {
TestMod.SINK.accept("Raw Mouse scrolled: %.2f x-distance %.2f y-distance", amountX, amountY);
return EventResult.pass();
});
ClientRawInputEvent.MOUSE_CLICKED_PRE.register((client, event, action) -> {
TestMod.SINK.accept("Raw Mouse clicked: " + event.button());
return EventResult.pass();
});
ClientRawInputEvent.KEY_PRESSED.register((client, keyCode, keyEvent) -> {
TestMod.SINK.accept("Raw Key pressed: " + InputConstants.getKey(keyEvent).getDisplayName().getString());
return EventResult.pass();
});
ClientGuiEvent.SET_SCREEN.register(screen -> {
if (screen instanceof AnvilScreen) {
return CompoundEventResult.interruptFalse(screen);
}
TestMod.SINK.accept("Screen has been changed to " + toSimpleName(screen));
return CompoundEventResult.pass();
});
}
}

View File

@@ -19,19 +19,13 @@
package dev.architectury.test.events;
import com.mojang.blaze3d.platform.InputConstants;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.client.*;
import dev.architectury.event.events.common.*;
import dev.architectury.platform.Platform;
import dev.architectury.test.TestMod;
import dev.architectury.utils.Env;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.ChatFormatting;
import net.minecraft.advancements.Advancement;
import net.minecraft.client.gui.screens.inventory.AnvilScreen;
import net.minecraft.core.Position;
import net.minecraft.core.Vec3i;
import net.minecraft.network.chat.Component;
@@ -50,7 +44,7 @@ public class DebugEvents {
public static void initialize() {
debugEvents();
if (Platform.getEnvironment() == Env.CLIENT)
debugEventsClient();
ClientDebugEvents.debugEventsClient();
}
public static void debugEvents() {
@@ -251,116 +245,6 @@ public class DebugEvents {
return " (server)";
}
@Environment(EnvType.CLIENT)
public static void debugEventsClient() {
ClientTickEvent.CLIENT_LEVEL_PRE.register(instance -> {
try {
// Uncomment the following line to see the profiler spike for root.tick.level.architecturyClientLevelPreTick
//Thread.sleep(10);
} catch (Throwable e) {
e.printStackTrace();
}
});
ClientChatEvent.SEND.register((message, component) -> {
TestMod.SINK.accept("Client chat sent: " + message);
if (message.contains("error")) {
return EventResult.interruptFalse();
}
return EventResult.pass();
});
ClientChatEvent.RECEIVED.register((type, message) -> {
TestMod.SINK.accept("Client chat received: " + message.getString());
if (message.getString().contains("terraria")) {
return CompoundEventResult.interruptTrue(message.copy().append(" + terraria is a great game!"));
}
if (message.getString().contains("potato")) {
return CompoundEventResult.interruptFalse(Component.empty());
}
return CompoundEventResult.pass();
});
ClientLifecycleEvent.CLIENT_LEVEL_LOAD.register(world -> {
TestMod.SINK.accept("Client world loaded: " + world.dimension().location().toString());
});
ClientPlayerEvent.CLIENT_PLAYER_JOIN.register(player -> {
TestMod.SINK.accept(player.getScoreboardName() + " joined (client)");
});
ClientPlayerEvent.CLIENT_PLAYER_QUIT.register(player -> {
if (player != null) {
TestMod.SINK.accept(player.getScoreboardName() + " quit (client)");
}
});
ClientPlayerEvent.CLIENT_PLAYER_RESPAWN.register((oldPlayer, newPlayer) -> {
TestMod.SINK.accept(newPlayer.getScoreboardName() + " respawned (client)");
});
ClientGuiEvent.INIT_PRE.register((screen, access) -> {
TestMod.SINK.accept(toSimpleName(screen) + " initializes");
return EventResult.pass();
});
ClientGuiEvent.INIT_POST.register(((screen, access) -> {
TestMod.SINK.accept(toSimpleName(screen) + " initialized");
}));
InteractionEvent.CLIENT_LEFT_CLICK_AIR.register((player, hand) -> {
TestMod.SINK.accept(player.getScoreboardName() + " left clicks air" + logSide(player.level()));
});
InteractionEvent.CLIENT_RIGHT_CLICK_AIR.register((player, hand) -> {
TestMod.SINK.accept(player.getScoreboardName() + " right clicks air" + logSide(player.level()));
});
ClientRecipeUpdateEvent.EVENT.register(recipeManager -> {
TestMod.SINK.accept("Client recipes received");
});
// ClientTextureStitchEvent.POST.register(atlas -> {
// TestMod.SINK.accept("Client texture stitched: " + atlas.location());
// });
ClientScreenInputEvent.MOUSE_SCROLLED_PRE.register((client, screen, mouseX, mouseY, amountX, amountY) -> {
TestMod.SINK.accept("Screen Mouse scrolled: %.2f x-distance %.2f y-distance", amountX, amountY);
return EventResult.pass();
});
ClientScreenInputEvent.MOUSE_CLICKED_PRE.register((client, screen, mouseX, mouseY, button) -> {
TestMod.SINK.accept("Screen Mouse clicked: " + button);
return EventResult.pass();
});
ClientScreenInputEvent.MOUSE_RELEASED_PRE.register((client, screen, mouseX, mouseY, button) -> {
TestMod.SINK.accept("Screen Mouse released: " + button);
return EventResult.pass();
});
ClientScreenInputEvent.MOUSE_DRAGGED_PRE.register((client, screen, mouseX1, mouseY1, button, mouseX2, mouseY2) -> {
TestMod.SINK.accept("Screen Mouse dragged: %d (%d,%d) by (%d,%d)", button, (int) mouseX1, (int) mouseY1, (int) mouseX2, (int) mouseY2);
return EventResult.pass();
});
ClientScreenInputEvent.CHAR_TYPED_PRE.register((client, screen, character, keyCode) -> {
TestMod.SINK.accept("Screen Char typed: " + character);
return EventResult.pass();
});
ClientScreenInputEvent.KEY_PRESSED_PRE.register((client, screen, keyCode, scanCode, modifiers) -> {
TestMod.SINK.accept("Screen Key pressed: " + InputConstants.getKey(keyCode, scanCode).getDisplayName().getString());
return EventResult.pass();
});
ClientScreenInputEvent.KEY_RELEASED_PRE.register((client, screen, keyCode, scanCode, modifiers) -> {
TestMod.SINK.accept("Screen Key released: " + InputConstants.getKey(keyCode, scanCode).getDisplayName().getString());
return EventResult.pass();
});
ClientRawInputEvent.MOUSE_SCROLLED.register((client, amountX, amountY) -> {
TestMod.SINK.accept("Raw Mouse scrolled: %.2f x-distance %.2f y-distance", amountX, amountY);
return EventResult.pass();
});
ClientRawInputEvent.MOUSE_CLICKED_PRE.register((client, button, action, mods) -> {
TestMod.SINK.accept("Raw Mouse clicked: " + button);
return EventResult.pass();
});
ClientRawInputEvent.KEY_PRESSED.register((client, keyCode, scanCode, action, modifiers) -> {
TestMod.SINK.accept("Raw Key pressed: " + InputConstants.getKey(keyCode, scanCode).getDisplayName().getString());
return EventResult.pass();
});
ClientGuiEvent.SET_SCREEN.register(screen -> {
if (screen instanceof AnvilScreen) {
return CompoundEventResult.interruptFalse(screen);
}
TestMod.SINK.accept("Screen has been changed to " + toSimpleName(screen));
return CompoundEventResult.pass();
});
}
private static String chunkPos(int x, int z) {
return "[" + x + ", " + z + "]";
}
@@ -369,7 +253,7 @@ public class DebugEvents {
return "[" + x + ", " + y + ", " + z + "]";
}
private static String toSimpleName(Object o) {
static String toSimpleName(Object o) {
return o == null ? "null" : o.getClass().getSimpleName() + "@" + Integer.toHexString(o.hashCode());
}
}

View File

@@ -38,7 +38,7 @@ public final class TestBlockInteractions {
return ctx.getLevel().isDarkOutside();
}, ctx -> {
BlockPos pos = ctx.getClickedPos();
if (!ctx.getLevel().isClientSide) {
if (!ctx.getLevel().isClientSide()) {
Player player = ctx.getPlayer();
if (player != null)
player.displayClientMessage(Component.literal("Thou has successfully committed the dark arts of alchemy!!"), false);

View File

@@ -20,36 +20,26 @@
package dev.architectury.test.networking;
import dev.architectury.networking.NetworkManager;
import dev.architectury.networking.simple.BaseC2SMessage;
import dev.architectury.networking.simple.MessageType;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public class ButtonClickedMessage extends BaseC2SMessage {
private final int buttonId;
/**
* To send this message from client to server, call new ButtonClickedMessage(id).sendToServer()
*/
public ButtonClickedMessage(int id) {
buttonId = id;
}
public ButtonClickedMessage(RegistryFriendlyByteBuf buf) {
buttonId = buf.readVarInt();
}
public record ButtonClickedMessage(int buttonId) implements CustomPacketPayload {
public static final Type<ButtonClickedMessage> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("architectury", "button_clicked"));
public static final StreamCodec<RegistryFriendlyByteBuf, ButtonClickedMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.VAR_INT,
ButtonClickedMessage::buttonId,
ButtonClickedMessage::new
);
@Override
public MessageType getType() {
return TestModNet.BUTTON_CLICKED;
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
@Override
public void write(RegistryFriendlyByteBuf buf) {
buf.writeVarInt(buttonId);
}
@Override
public void handle(NetworkManager.PacketContext context) {
context.getPlayer().displayClientMessage(Component.literal("You clicked button #" + buttonId), false);
}

View File

@@ -20,39 +20,27 @@
package dev.architectury.test.networking;
import dev.architectury.networking.NetworkManager;
import dev.architectury.networking.simple.BaseS2CMessage;
import dev.architectury.networking.simple.MessageType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
public class SyncDataMessage extends BaseS2CMessage {
private final CompoundTag serverData;
/**
* To send this message, call new SyncDataMessage(tag).sendToPlayer(player) / sendToAll(server) / etc.
*
* @see BaseS2CMessage
*/
public SyncDataMessage(CompoundTag tag) {
serverData = tag;
}
public SyncDataMessage(RegistryFriendlyByteBuf buf) {
serverData = buf.readNbt();
}
public record SyncDataMessage(CompoundTag serverData) implements CustomPacketPayload {
public static final Type<SyncDataMessage> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath("architectury", "sync_data"));
public static final StreamCodec<RegistryFriendlyByteBuf, SyncDataMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.COMPOUND_TAG,
SyncDataMessage::serverData,
SyncDataMessage::new
);
@Override
public MessageType getType() {
return TestModNet.SYNC_DATA;
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
@Override
public void write(RegistryFriendlyByteBuf buf) {
buf.writeNbt(serverData);
}
@Override
public void handle(NetworkManager.PacketContext context) {
context.getPlayer().displayClientMessage(Component.literal("Received data from server: " + serverData), false);
}

View File

@@ -22,8 +22,6 @@ package dev.architectury.test.networking;
import dev.architectury.event.events.client.ClientPlayerEvent;
import dev.architectury.event.events.common.PlayerEvent;
import dev.architectury.networking.NetworkManager;
import dev.architectury.networking.simple.MessageType;
import dev.architectury.networking.simple.SimpleNetworkManager;
import dev.architectury.networking.transformers.SplitPacketTransformer;
import dev.architectury.test.TestMod;
import io.netty.buffer.Unpooled;
@@ -37,13 +35,6 @@ import java.util.Collections;
import java.util.List;
public interface TestModNet {
SimpleNetworkManager NET = SimpleNetworkManager.create(TestMod.MOD_ID);
// An example Client to Server message
MessageType BUTTON_CLICKED = NET.registerC2S("button_clicked", ButtonClickedMessage::new);
// An example Server to Client message
MessageType SYNC_DATA = NET.registerS2C("sync_data", SyncDataMessage::new);
ResourceLocation BIG_DATA = ResourceLocation.fromNamespaceAndPath(TestMod.MOD_ID, "big_data");
ResourceLocation SERVER_TO_CLIENT_TEST = ResourceLocation.fromNamespaceAndPath(TestMod.MOD_ID, "s2c_test");
CustomPacketPayload.Type<ServerToClientTestPayload> SERVER_TO_CLIENT_TEST_PAYLOAD = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(TestMod.MOD_ID, "s2c_test_payload"));
@@ -51,6 +42,8 @@ public interface TestModNet {
String BIG_STRING = StringUtils.repeat('a', 100000);
static void initialize() {
NetworkManager.registerReceiver(NetworkManager.Side.C2S, ButtonClickedMessage.TYPE, ButtonClickedMessage.STREAM_CODEC, ButtonClickedMessage::handle);
NetworkManager.registerReceiver(NetworkManager.Side.C2S, SyncDataMessage.TYPE, SyncDataMessage.STREAM_CODEC, SyncDataMessage::handle);
NetworkManager.registerReceiver(NetworkManager.Side.C2S, BIG_DATA, Collections.singletonList(new SplitPacketTransformer()), (buf, context) -> {
String utf = buf.readUtf(Integer.MAX_VALUE / 4);
if (utf.equals(BIG_STRING)) {

View File

@@ -21,7 +21,6 @@ package dev.architectury.test.registry;
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
import dev.architectury.core.fluid.SimpleArchitecturyFluidAttributes;
import dev.architectury.core.item.ArchitecturySpawnEggItem;
import dev.architectury.hooks.level.entity.EntityHooks;
import dev.architectury.platform.Platform;
import dev.architectury.registry.CreativeTabRegistry;
@@ -45,10 +44,7 @@ import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.*;
import net.minecraft.world.item.component.Consumables;
import net.minecraft.world.item.consume_effects.ApplyStatusEffectsConsumeEffect;
import net.minecraft.world.item.crafting.CustomRecipe;
@@ -58,10 +54,12 @@ import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
@@ -124,11 +122,9 @@ public class TestRegistries {
.setId(id(Registries.ITEM, "test_edible")));
});
public static final RegistrySupplier<Item> TEST_SPAWN_EGG = ITEMS.register("test_spawn_egg", () ->
new ArchitecturySpawnEggItem(TestRegistries.TEST_ENTITY,
new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_spawn_egg"))));
new SpawnEggItem(new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_spawn_egg")).spawnEgg(TestRegistries.TEST_ENTITY.get())));
public static final RegistrySupplier<Item> TEST_SPAWN_EGG_2 = ITEMS.register("test_spawn_egg_2", () ->
new ArchitecturySpawnEggItem(TestRegistries.TEST_ENTITY_2,
new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_spawn_egg_2"))));
new SpawnEggItem(new Item.Properties().arch$tab(TestRegistries.TEST_TAB).setId(id(Registries.ITEM, "test_spawn_egg_2")).spawnEgg(TestRegistries.TEST_ENTITY_2.get())));
public static final RegistrySupplier<Item> TEST_FLUID_BUCKET = ITEMS.register("test_fluid_bucket", () -> {
try {
@@ -161,7 +157,7 @@ public class TestRegistries {
// In example mod the forge class isn't being replaced, this is not required in mods depending on architectury
return (LiquidBlock) Class.forName(!Platform.isForge() ? "dev.architectury.core.block.ArchitecturyLiquidBlock" : "dev.architectury.core.block.forge.imitator.ArchitecturyLiquidBlock")
.getDeclaredConstructor(Supplier.class, BlockBehaviour.Properties.class)
.newInstance(TestRegistries.TEST_FLUID, BlockBehaviour.Properties.ofLegacyCopy(Blocks.WATER).noCollission().strength(100.0F).noLootTable().setId(id(Registries.BLOCK, "test_fluid")));
.newInstance(TestRegistries.TEST_FLUID, BlockBehaviour.Properties.ofLegacyCopy(Blocks.WATER).replaceable().noCollision().strength(100.0F).pushReaction(PushReaction.DESTROY).noLootTable().liquid().sound(SoundType.EMPTY).setId(id(Registries.BLOCK, "test_fluid")));
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
@@ -212,10 +208,10 @@ public class TestRegistries {
public static void initialize() {
TABS.register();
MOB_EFFECTS.register();
ENTITY_TYPES.register();
FLUIDS.register();
BLOCKS.register();
ITEMS.register();
ENTITY_TYPES.register();
RECIPE_TYPES.register();
RECIPE_SERIALIZERS.register();
EntityAttributeRegistry.register(TEST_ENTITY, TestEntity::createAttributes);

View File

@@ -23,16 +23,15 @@ import com.mojang.blaze3d.platform.InputConstants;
import dev.architectury.event.events.client.ClientTickEvent;
import dev.architectury.registry.client.keymappings.KeyMappingRegistry;
import dev.architectury.test.TestMod;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.resources.ResourceLocation;
import org.lwjgl.glfw.GLFW;
public class TestKeybinds {
@Environment(EnvType.CLIENT)
public static void initialize() {
var mapping = new KeyMapping("key.architectury-test.test", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_O, "category.architectury-test");
var category = KeyMapping.Category.register(ResourceLocation.fromNamespaceAndPath("architectury", "architectury-test"));
var mapping = new KeyMapping("key.architectury-test.test", InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_O, category);
KeyMappingRegistry.register(mapping);
ClientTickEvent.CLIENT_POST.register(instance -> {
while (mapping.consumeClick()) {

View File

@@ -44,25 +44,4 @@ public class ItemWithTooltip extends Item {
public record MyTooltipComponent(int count) implements TooltipComponent {
}
@Environment(EnvType.CLIENT)
public record MyClientTooltipComponent(MyTooltipComponent component) implements ClientTooltipComponent {
@Override
public int getHeight(Font font) {
return 100;
}
@Override
public int getWidth(Font font) {
return 100;
}
@Override
public void renderImage(Font font, int x, int y, int w, int h, GuiGraphics graphics) {
graphics.pose().pushMatrix();
graphics.pose().translate(0, 0);
graphics.drawString(font, "Count: " + component.count, x + getWidth(font) / 2, y + (getHeight(font) - font.lineHeight) / 2, 0xFF00FF00);
graphics.pose().popMatrix();
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* 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 dev.architectury.test.registry.objects;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
public record MyClientTooltipComponent(ItemWithTooltip.MyTooltipComponent component) implements ClientTooltipComponent {
@Override
public int getHeight(Font font) {
return 100;
}
@Override
public int getWidth(Font font) {
return 100;
}
@Override
public void renderImage(Font font, int x, int y, int w, int h, GuiGraphics graphics) {
graphics.pose().pushMatrix();
graphics.pose().translate(0, 0);
graphics.drawString(font, "Count: " + component.count(), x + getWidth(font) / 2, y + (getHeight(font) - font.lineHeight) / 2, 0xFF00FF00);
graphics.pose().popMatrix();
}
}