mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Port for 1.21.9
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
name: Build PR snapshot (1.21.6)
|
||||
name: Build PR snapshot (1.21.9)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
- '**.properties'
|
||||
- '**/src/**'
|
||||
branches:
|
||||
- "1.21.7"
|
||||
- "1.21.9"
|
||||
types: [ opened, synchronize, reopened ]
|
||||
jobs:
|
||||
validate-gradle:
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Build and Release (1.21.6)
|
||||
name: Build and Release (1.21.9)
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -8,7 +8,7 @@ on:
|
||||
- '**/src/**'
|
||||
- '.github/**'
|
||||
branches:
|
||||
- "1.21.7"
|
||||
- "1.21.9"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
norelease:
|
||||
@@ -8,7 +8,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||
id "dev.architectury.loom" version "1.10-SNAPSHOT" apply false
|
||||
id "dev.architectury.loom" version "1.11-SNAPSHOT" apply false
|
||||
id "org.cadixdev.licenser" version "0.6.1"
|
||||
id "me.shedaniel.unified-publishing" version "0.1.+" apply false
|
||||
id "maven-publish"
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* 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.core.item;
|
||||
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.dispenser.BlockSource;
|
||||
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
|
||||
import net.minecraft.core.dispenser.DispenseItemBehavior;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.SpawnEggItem;
|
||||
import net.minecraft.world.level.block.DispenserBlock;
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ArchitecturySpawnEggItem extends SpawnEggItem {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ArchitecturySpawnEggItem.class);
|
||||
|
||||
private final RegistrySupplier<? extends EntityType<? extends Mob>> entityType;
|
||||
|
||||
protected static DispenseItemBehavior createDispenseItemBehavior() {
|
||||
return new DefaultDispenseItemBehavior() {
|
||||
@Override
|
||||
public ItemStack execute(BlockSource source, ItemStack stack) {
|
||||
Direction direction = source.state().getValue(DispenserBlock.FACING);
|
||||
EntityType<?> entityType = ((SpawnEggItem) stack.getItem()).getType(source.level().registryAccess(), stack);
|
||||
|
||||
try {
|
||||
entityType.spawn(source.level(), stack, null, source.pos().relative(direction), EntitySpawnReason.DISPENSER, direction != Direction.UP, false);
|
||||
} catch (Exception var6) {
|
||||
LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.pos(), var6);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
stack.shrink(1);
|
||||
source.level().gameEvent(null, GameEvent.ENTITY_PLACE, source.pos());
|
||||
return stack;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ArchitecturySpawnEggItem(RegistrySupplier<? extends EntityType<? extends Mob>> entityType, Properties properties) {
|
||||
this(entityType, properties, createDispenseItemBehavior());
|
||||
}
|
||||
|
||||
public ArchitecturySpawnEggItem(RegistrySupplier<? extends EntityType<? extends Mob>> entityType, Properties properties,
|
||||
@Nullable DispenseItemBehavior dispenseItemBehavior) {
|
||||
super(null, properties);
|
||||
this.entityType = Objects.requireNonNull(entityType, "entityType");
|
||||
SpawnEggItem.BY_ID.remove(null);
|
||||
entityType.listen(type -> {
|
||||
LOGGER.debug("Registering spawn egg {} for {}", toString(),
|
||||
Objects.toString(type.arch$registryName()));
|
||||
SpawnEggItem.BY_ID.put(type, this);
|
||||
this.defaultType = type;
|
||||
|
||||
if (dispenseItemBehavior != null) {
|
||||
DispenserBlock.registerBehavior(this, dispenseItemBehavior);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType<?> getType(HolderLookup.Provider provider, ItemStack itemStack) {
|
||||
EntityType<?> type = super.getType(provider, itemStack);
|
||||
return type == null ? entityType.get() : type;
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,6 @@ package dev.architectury.event;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.utils.Env;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
public final class EventHandler {
|
||||
private EventHandler() {
|
||||
@@ -42,7 +40,6 @@ public final class EventHandler {
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
private static void registerClient() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
@@ -53,7 +50,6 @@ public final class EventHandler {
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.SERVER)
|
||||
private static void registerServer() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@@ -23,13 +23,10 @@ import dev.architectury.event.CompoundEventResult;
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import dev.architectury.event.EventResult;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.chat.ChatType;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientChatEvent {
|
||||
/**
|
||||
* @see Send#send(String, Component)
|
||||
@@ -40,7 +37,6 @@ public interface ClientChatEvent {
|
||||
*/
|
||||
Event<Received> RECEIVED = EventFactory.createCompoundEventResult();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Send {
|
||||
/**
|
||||
* Event to cancel clients sending the chat message.
|
||||
@@ -54,7 +50,6 @@ public interface ClientChatEvent {
|
||||
EventResult send(String message, @Nullable Component component);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Received {
|
||||
/**
|
||||
* Event to intercept the receiving of an chat message.
|
||||
|
||||
@@ -24,8 +24,6 @@ import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import dev.architectury.event.EventResult;
|
||||
import dev.architectury.hooks.client.screen.ScreenAccess;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
@@ -33,7 +31,6 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientGuiEvent {
|
||||
/**
|
||||
* @see RenderHud#renderHud(GuiGraphics, float)
|
||||
@@ -73,7 +70,6 @@ public interface ClientGuiEvent {
|
||||
*/
|
||||
Event<SetScreen> SET_SCREEN = EventFactory.createCompoundEventResult();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface RenderHud {
|
||||
/**
|
||||
* Invoked after the in-game hud has been rendered.
|
||||
@@ -85,7 +81,6 @@ public interface ClientGuiEvent {
|
||||
void renderHud(GuiGraphics graphics, DeltaTracker deltaTracker);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface DebugText {
|
||||
/**
|
||||
* Invoked when the debug text is being gathered for rendering.
|
||||
@@ -97,7 +92,6 @@ public interface ClientGuiEvent {
|
||||
void gatherText(List<String> strings);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ScreenInitPre {
|
||||
/**
|
||||
* Invoked when a screen is being initialized and after the previous widgets have been cleared.
|
||||
@@ -111,7 +105,6 @@ public interface ClientGuiEvent {
|
||||
EventResult init(Screen screen, ScreenAccess access);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ScreenInitPost {
|
||||
/**
|
||||
* Invoked after a screen has been initialized and all the vanilla initialization logic has happened.
|
||||
@@ -123,7 +116,6 @@ public interface ClientGuiEvent {
|
||||
void init(Screen screen, ScreenAccess access);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ScreenRenderPre {
|
||||
/**
|
||||
* Invoked before any screen is rendered.
|
||||
@@ -137,10 +129,9 @@ public interface ClientGuiEvent {
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the vanilla render may be cancelled by the result.
|
||||
*/
|
||||
EventResult render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, DeltaTracker delta);
|
||||
EventResult render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ScreenRenderPost {
|
||||
/**
|
||||
* Invoked after a screen has finished rendering using the vanilla logic.
|
||||
@@ -152,10 +143,9 @@ public interface ClientGuiEvent {
|
||||
* @param mouseY The scaled y-coordinate of the mouse cursor.
|
||||
* @param delta The current tick delta.
|
||||
*/
|
||||
void render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, DeltaTracker delta);
|
||||
void render(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ContainerScreenRenderBackground {
|
||||
/**
|
||||
* Invoked after a container screen's background are rendered.
|
||||
@@ -170,7 +160,6 @@ public interface ClientGuiEvent {
|
||||
void render(AbstractContainerScreen<?> screen, GuiGraphics graphics, int mouseX, int mouseY, float delta);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ContainerScreenRenderForeground {
|
||||
/**
|
||||
* Invoked after a screen has finished rendering most of the foreground, but before any floating widgets are rendered.
|
||||
@@ -185,7 +174,6 @@ public interface ClientGuiEvent {
|
||||
void render(AbstractContainerScreen<?> screen, GuiGraphics graphics, int mouseX, int mouseY, float delta);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface SetScreen {
|
||||
/**
|
||||
* Invoked before a new screen is set to open.
|
||||
|
||||
@@ -22,12 +22,9 @@ package dev.architectury.event.events.client;
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import dev.architectury.event.events.common.LifecycleEvent;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientLifecycleEvent {
|
||||
/**
|
||||
* Invoked when client has been initialised.
|
||||
@@ -55,11 +52,9 @@ public interface ClientLifecycleEvent {
|
||||
*/
|
||||
Event<ClientState> CLIENT_SETUP = EventFactory.createLoop();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ClientState extends LifecycleEvent.InstanceState<Minecraft> {
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ClientLevelState extends LifecycleEvent.LevelState<ClientLevel> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,9 @@ package dev.architectury.event.events.client;
|
||||
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientPlayerEvent {
|
||||
/**
|
||||
* @see ClientPlayerJoin#join(LocalPlayer)
|
||||
@@ -41,7 +38,6 @@ public interface ClientPlayerEvent {
|
||||
*/
|
||||
Event<ClientPlayerRespawn> CLIENT_PLAYER_RESPAWN = EventFactory.createLoop();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ClientPlayerJoin {
|
||||
/**
|
||||
* Invoked whenever a client player joins a level
|
||||
@@ -51,7 +47,6 @@ public interface ClientPlayerEvent {
|
||||
void join(LocalPlayer player);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ClientPlayerQuit {
|
||||
/**
|
||||
* Invoked whenever a client player leaves a level and is cleared on the client side.
|
||||
@@ -61,7 +56,6 @@ public interface ClientPlayerEvent {
|
||||
void quit(@Nullable LocalPlayer player);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ClientPlayerRespawn {
|
||||
/**
|
||||
* Invoked whenever the player respawn packet is received by the client.
|
||||
|
||||
@@ -22,11 +22,10 @@ package dev.architectury.event.events.client;
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import dev.architectury.event.EventResult;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.input.KeyEvent;
|
||||
import net.minecraft.client.input.MouseButtonInfo;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientRawInputEvent {
|
||||
/**
|
||||
* @see MouseScrolled#mouseScrolled(Minecraft, double, double)
|
||||
@@ -38,7 +37,7 @@ public interface ClientRawInputEvent {
|
||||
Event<MouseClicked> MOUSE_CLICKED_PRE = EventFactory.createEventResult();
|
||||
Event<MouseClicked> MOUSE_CLICKED_POST = EventFactory.createEventResult();
|
||||
/**
|
||||
* @see KeyPressed#keyPressed(Minecraft, int, int, int, int)
|
||||
* @see KeyPressed#keyPressed(Minecraft, int, KeyEvent)
|
||||
*/
|
||||
Event<KeyPressed> KEY_PRESSED = EventFactory.createEventResult();
|
||||
|
||||
@@ -47,15 +46,13 @@ public interface ClientRawInputEvent {
|
||||
* Invoked whenever a key input is performed.
|
||||
* Equivalent to Forge's {@code InputEvent.KeyInputEvent} event.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param keyCode The key code.
|
||||
* @param scanCode The raw keyboard scan code.
|
||||
* @param action The action that should be performed.
|
||||
* @param modifiers Additional modifiers.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param keyCode The key code.
|
||||
* @param keyEvent The key event.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla pressing mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult keyPressed(Minecraft client, int keyCode, int scanCode, int action, int modifiers);
|
||||
EventResult keyPressed(Minecraft client, int keyCode, KeyEvent keyEvent);
|
||||
}
|
||||
|
||||
interface MouseScrolled {
|
||||
@@ -77,13 +74,12 @@ public interface ClientRawInputEvent {
|
||||
* Invoked whenever a mouse button is pressed.
|
||||
* There are two variants, either a raw mouse input or the input after it is processed by the game.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param button The pressed mouse button.
|
||||
* @param action The action that should be performed.
|
||||
* @param mods Additional modifiers.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param buttonInfo The pressed mouse button info.
|
||||
* @param action The action that should be performed.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla clicking mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult mouseClicked(Minecraft client, int button, int action, int mods);
|
||||
EventResult mouseClicked(Minecraft client, MouseButtonInfo buttonInfo, int action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@ package dev.architectury.event.events.client;
|
||||
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.protocol.game.ClientboundRecipeBookAddPacket;
|
||||
import net.minecraft.world.item.crafting.RecipeAccess;
|
||||
import net.minecraft.world.item.crafting.display.RecipeDisplayId;
|
||||
@@ -30,7 +28,6 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientRecipeUpdateEvent {
|
||||
/**
|
||||
* @see ClientRecipeUpdateEvent#update(RecipeAccess)
|
||||
|
||||
@@ -22,12 +22,12 @@ package dev.architectury.event.events.client;
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import dev.architectury.event.EventResult;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.input.CharacterEvent;
|
||||
import net.minecraft.client.input.KeyEvent;
|
||||
import net.minecraft.client.input.MouseButtonEvent;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientScreenInputEvent {
|
||||
/**
|
||||
* @see MouseScrolled#mouseScrolled(Minecraft, Screen, double, double, double, double)
|
||||
@@ -50,17 +50,17 @@ public interface ClientScreenInputEvent {
|
||||
Event<MouseDragged> MOUSE_DRAGGED_PRE = EventFactory.createEventResult();
|
||||
Event<MouseDragged> MOUSE_DRAGGED_POST = EventFactory.createEventResult();
|
||||
/**
|
||||
* @see KeyTyped#charTyped(Minecraft, Screen, char, int)
|
||||
* @see KeyTyped#charTyped(Minecraft, Screen, CharacterEvent)
|
||||
*/
|
||||
Event<KeyTyped> CHAR_TYPED_PRE = EventFactory.createEventResult();
|
||||
Event<KeyTyped> CHAR_TYPED_POST = EventFactory.createEventResult();
|
||||
/**
|
||||
* @see KeyPressed#keyPressed(Minecraft, Screen, int, int, int)
|
||||
* @see KeyPressed#keyPressed(Minecraft, Screen, KeyEvent)
|
||||
*/
|
||||
Event<KeyPressed> KEY_PRESSED_PRE = EventFactory.createEventResult();
|
||||
Event<KeyPressed> KEY_PRESSED_POST = EventFactory.createEventResult();
|
||||
/**
|
||||
* @see KeyReleased#keyReleased(Minecraft, Screen, int, int, int)
|
||||
* @see KeyReleased#keyReleased(Minecraft, Screen, KeyEvent)
|
||||
*/
|
||||
Event<KeyReleased> KEY_RELEASED_PRE = EventFactory.createEventResult();
|
||||
Event<KeyReleased> KEY_RELEASED_POST = EventFactory.createEventResult();
|
||||
@@ -73,15 +73,13 @@ public interface ClientScreenInputEvent {
|
||||
* <p> This event is handled in two phases PRE and POST, which are invoked
|
||||
* before and after the keys have been processed by the screen, respectively.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param keyCode The key code.
|
||||
* @param scanCode The raw keyboard scan code.
|
||||
* @param modifiers Additional modifiers.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param keyEvent The key event.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla pressing mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult keyPressed(Minecraft client, Screen screen, int keyCode, int scanCode, int modifiers);
|
||||
EventResult keyPressed(Minecraft client, Screen screen, KeyEvent keyEvent);
|
||||
}
|
||||
|
||||
interface KeyReleased {
|
||||
@@ -92,15 +90,13 @@ public interface ClientScreenInputEvent {
|
||||
* <p> This event is handled in two phases PRE and POST, which are invoked
|
||||
* before and after the keys have been processed by the screen, respectively.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param keyCode The key code.
|
||||
* @param scanCode The raw keyboard scan code.
|
||||
* @param modifiers Additional modifiers.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param keyEvent The key event.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla releasing mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult keyReleased(Minecraft client, Screen screen, int keyCode, int scanCode, int modifiers);
|
||||
EventResult keyReleased(Minecraft client, Screen screen, KeyEvent keyEvent);
|
||||
}
|
||||
|
||||
interface KeyTyped {
|
||||
@@ -111,14 +107,13 @@ public interface ClientScreenInputEvent {
|
||||
* <p> This event is handled in two phases PRE and POST, which are invoked
|
||||
* before and after the keys have been processed by the screen, respectively.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param character The typed character.
|
||||
* @param keyCode The key code.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param characterEvent The character event.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla typing mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult charTyped(Minecraft client, Screen screen, char character, int keyCode);
|
||||
EventResult charTyped(Minecraft client, Screen screen, CharacterEvent characterEvent);
|
||||
}
|
||||
|
||||
interface MouseScrolled {
|
||||
@@ -149,15 +144,13 @@ public interface ClientScreenInputEvent {
|
||||
* <p> This event is handled in two phases PRE and POST, which are invoked
|
||||
* before and after the keys have been processed by the screen, respectively.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param mouseX The scaled x-coordinate of the mouse cursor.
|
||||
* @param mouseY The scaled y-coordinate of the mouse cursor.
|
||||
* @param button The released mouse button.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param buttonEvent The button click event.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla releasing mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult mouseReleased(Minecraft client, Screen screen, double mouseX, double mouseY, int button);
|
||||
EventResult mouseReleased(Minecraft client, Screen screen, MouseButtonEvent buttonEvent);
|
||||
}
|
||||
|
||||
interface MouseDragged {
|
||||
@@ -168,17 +161,15 @@ public interface ClientScreenInputEvent {
|
||||
* <p> This event is handled in two phases PRE and POST, which are invoked
|
||||
* before and after the keys have been processed by the screen, respectively.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param mouseX1 The initial scaled x-coordinate of the mouse cursor.
|
||||
* @param mouseY1 The initial scaled y-coordinate of the mouse cursor.
|
||||
* @param button The dragged mouse button.
|
||||
* @param mouseX2 The final scaled x-coordinate of the mouse cursor.
|
||||
* @param mouseY2 The final scaled y-coordinate of the mouse cursor.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param buttonEvent The mouse event.
|
||||
* @param mouseX2 The final scaled x-delta of the mouse cursor.
|
||||
* @param mouseY2 The final scaled y-delta of the mouse cursor.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla dragging mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult mouseDragged(Minecraft client, Screen screen, double mouseX1, double mouseY1, int button, double mouseX2, double mouseY2);
|
||||
EventResult mouseDragged(Minecraft client, Screen screen, MouseButtonEvent buttonEvent, double mouseX2, double mouseY2);
|
||||
}
|
||||
|
||||
interface MouseClicked {
|
||||
@@ -189,14 +180,13 @@ public interface ClientScreenInputEvent {
|
||||
* <p> This event is handled in two phases PRE and POST, which are invoked
|
||||
* before and after the keys have been processed by the screen, respectively.
|
||||
*
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param mouseX The scaled x-coordinate of the mouse cursor.
|
||||
* @param mouseY The scaled y-coordinate of the mouse cursor.
|
||||
* @param button The clicked mouse button.
|
||||
* @param client The Minecraft instance performing it.
|
||||
* @param screen The screen this keystroke was performed in.
|
||||
* @param buttonEvent The button click event.
|
||||
* @param doubleClick Whether the click is a double click.
|
||||
* @return A {@link EventResult} determining the outcome of the event,
|
||||
* the execution of the vanilla clicking mechanism may be cancelled by the result.
|
||||
*/
|
||||
EventResult mouseClicked(Minecraft client, Screen screen, double mouseX, double mouseY, int button);
|
||||
EventResult mouseClicked(Minecraft client, Screen screen, MouseButtonEvent buttonEvent, boolean doubleClick);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,18 +22,14 @@ package dev.architectury.event.events.client;
|
||||
import dev.architectury.event.CompoundEventResult;
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientSystemMessageEvent {
|
||||
/**
|
||||
* @see Received#process(Component)
|
||||
*/
|
||||
Event<Received> RECEIVED = EventFactory.createCompoundEventResult();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Received {
|
||||
/**
|
||||
* Event to intercept the receiving of a system message.
|
||||
|
||||
@@ -21,11 +21,8 @@ package dev.architectury.event.events.client;
|
||||
|
||||
import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientTickEvent<T> {
|
||||
Event<Client> CLIENT_PRE = EventFactory.createLoop();
|
||||
Event<Client> CLIENT_POST = EventFactory.createLoop();
|
||||
@@ -34,11 +31,9 @@ public interface ClientTickEvent<T> {
|
||||
|
||||
void tick(T instance);
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Client extends ClientTickEvent<Minecraft> {
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface ClientLevel extends ClientTickEvent<net.minecraft.client.multiplayer.ClientLevel> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import dev.architectury.event.Event;
|
||||
import dev.architectury.event.EventFactory;
|
||||
import dev.architectury.event.EventResult;
|
||||
import dev.architectury.impl.TooltipAdditionalContextsImpl;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -35,7 +33,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ClientTooltipEvent {
|
||||
/**
|
||||
* @see Item#append(ItemStack, List, net.minecraft.world.item.Item.TooltipContext, TooltipFlag)
|
||||
@@ -62,7 +59,6 @@ public interface ClientTooltipEvent {
|
||||
void setItem(@Nullable ItemStack stack);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Item {
|
||||
/**
|
||||
* Invoked whenever an item tooltip is rendered.
|
||||
@@ -77,7 +73,6 @@ public interface ClientTooltipEvent {
|
||||
void append(ItemStack stack, List<Component> lines, net.minecraft.world.item.Item.TooltipContext tooltipContext, TooltipFlag flag);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Render {
|
||||
/**
|
||||
* Invoked before the tooltip for a tooltip is rendered.
|
||||
@@ -92,7 +87,6 @@ public interface ClientTooltipEvent {
|
||||
EventResult renderTooltip(GuiGraphics graphics, List<? extends ClientTooltipComponent> texts, int x, int y);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface RenderModifyPosition {
|
||||
/**
|
||||
* Event to manipulate the position of the tooltip.
|
||||
@@ -103,7 +97,6 @@ public interface ClientTooltipEvent {
|
||||
void renderTooltip(GuiGraphics graphics, PositionContext context);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface PositionContext {
|
||||
int getTooltipX();
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.hooks.client.fluid;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ClientFluidStackHooks {
|
||||
private ClientFluidStackHooks() {
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static int getColor(FluidStack stack) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static int getColor(Fluid fluid) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,6 @@
|
||||
package dev.architectury.hooks.client.screen;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.Renderable;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
@@ -30,7 +28,6 @@ import net.minecraft.client.gui.screens.Screen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class ScreenHooks {
|
||||
private ScreenHooks() {
|
||||
}
|
||||
|
||||
@@ -102,66 +102,6 @@ public class FluidStackHooks {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static int getColor(FluidStack stack) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static int getColor(Fluid fluid) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the luminosity of the fluid.
|
||||
*
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class MixinLightningBolt extends Entity {
|
||||
by = 1
|
||||
), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
public void handleLightning(CallbackInfo ci, List<Entity> list) {
|
||||
if (this.isRemoved() || this.level().isClientSide) {
|
||||
if (this.isRemoved() || this.level().isClientSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.networking;
|
||||
|
||||
import dev.architectury.extensions.network.EntitySpawnExtension;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ClientSpawnEntityPacket {
|
||||
public static void register() {
|
||||
NetworkManager.registerReceiver(NetworkManager.s2c(), SpawnEntityPacket.PACKET_TYPE, SpawnEntityPacket.PACKET_CODEC, ClientSpawnEntityPacket::receive);
|
||||
}
|
||||
|
||||
private static void receive(SpawnEntityPacket.PacketPayload payload, NetworkManager.PacketContext context) {
|
||||
context.queue(() -> {
|
||||
if (Minecraft.getInstance().level == null) {
|
||||
throw new IllegalStateException("Client world is null!");
|
||||
}
|
||||
var entity = payload.entityType().create(Minecraft.getInstance().level, EntitySpawnReason.LOAD);
|
||||
if (entity == null) {
|
||||
throw new IllegalStateException("Created entity is null!");
|
||||
}
|
||||
entity.setUUID(payload.uuid());
|
||||
entity.setId(payload.id());
|
||||
entity.syncPacketPositionCodec(payload.x(), payload.y(), payload.z());
|
||||
entity.snapTo(payload.x(), payload.y(), payload.z(), payload.xRot(), payload.yRot());
|
||||
entity.setYHeadRot(payload.yHeadRot());
|
||||
entity.setYBodyRot(payload.yHeadRot());
|
||||
if (entity instanceof EntitySpawnExtension ext) {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(payload.data()), context.registryAccess());
|
||||
ext.loadAdditionalSpawnData(buf);
|
||||
buf.release();
|
||||
}
|
||||
Minecraft.getInstance().level.addEntity(entity);
|
||||
entity.lerpMotion(new Vec3(payload.deltaX(), payload.deltaY(), payload.deltaZ()));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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.networking;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import dev.architectury.networking.NetworkManager.PacketContext;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.utils.Env;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Forge {@code SimpleChannel} like network wrapper of {@link NetworkManager}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final class NetworkChannel {
|
||||
private final ResourceLocation id;
|
||||
private final Map<Class<?>, MessageInfo<?>> encoders = Maps.newHashMap();
|
||||
|
||||
private NetworkChannel(ResourceLocation id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static NetworkChannel create(ResourceLocation id) {
|
||||
return new NetworkChannel(id);
|
||||
}
|
||||
|
||||
public <T> void register(Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
// TODO: this is pretty wasteful; add a way to specify custom or numeric ids
|
||||
var s = UUID.nameUUIDFromBytes(type.getName().getBytes(StandardCharsets.UTF_8)).toString().replace("-", "");
|
||||
var info = new MessageInfo<T>(ResourceLocation.parse(id + "/" + s), encoder, decoder, messageConsumer);
|
||||
encoders.put(type, info);
|
||||
NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver = (buf, context) -> {
|
||||
info.messageConsumer.accept(info.decoder.apply(buf), () -> context);
|
||||
};
|
||||
NetworkManager.registerReceiver(NetworkManager.c2s(), info.packetId, receiver);
|
||||
if (Platform.getEnvironment() == Env.CLIENT) {
|
||||
NetworkManager.registerReceiver(NetworkManager.s2c(), info.packetId, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
public static long hashCodeString(String str) {
|
||||
long h = 0;
|
||||
var length = str.length();
|
||||
for (var i = 0; i < length; i++) {
|
||||
h = 31 * h + str.charAt(i);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
public <T> Packet<?> toPacket(NetworkManager.Side side, T message, RegistryAccess access) {
|
||||
var messageInfo = (MessageInfo<T>) Objects.requireNonNull(encoders.get(message.getClass()), "Unknown message type! " + message);
|
||||
var buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), access);
|
||||
messageInfo.encoder.accept(message, buf);
|
||||
return NetworkManager.toPacket(side, messageInfo.packetId, buf);
|
||||
}
|
||||
|
||||
public <T> void sendToPlayer(ServerPlayer player, T message) {
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(toPacket(NetworkManager.s2c(), message, player.registryAccess()));
|
||||
}
|
||||
|
||||
public <T> void sendToPlayers(Iterable<ServerPlayer> players, T message) {
|
||||
Iterator<ServerPlayer> iterator = players.iterator();
|
||||
if (!iterator.hasNext()) return;
|
||||
var packet = toPacket(NetworkManager.s2c(), message, iterator.next().registryAccess());
|
||||
for (var player : players) {
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public <T> void sendToServer(T message) {
|
||||
ClientPacketListener connection = Minecraft.getInstance().getConnection();
|
||||
if (connection != null) {
|
||||
connection.send(toPacket(NetworkManager.c2s(), message, connection.registryAccess()));
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to send packet to the server while not in game!");
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public <T> boolean canServerReceive(Class<T> type) {
|
||||
return NetworkManager.canServerReceive(encoders.get(type).packetId);
|
||||
}
|
||||
|
||||
public <T> boolean canPlayerReceive(ServerPlayer player, Class<T> type) {
|
||||
return NetworkManager.canPlayerReceive(player, encoders.get(type).packetId);
|
||||
}
|
||||
|
||||
private record MessageInfo<T>(
|
||||
ResourceLocation packetId,
|
||||
BiConsumer<T, FriendlyByteBuf> encoder,
|
||||
Function<FriendlyByteBuf, T> decoder,
|
||||
BiConsumer<T, Supplier<PacketContext>> messageConsumer
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -26,10 +26,7 @@ import dev.architectury.networking.transformers.PacketSink;
|
||||
import dev.architectury.networking.transformers.PacketTransformer;
|
||||
import dev.architectury.networking.transformers.SinglePacketCollector;
|
||||
import dev.architectury.utils.Env;
|
||||
import dev.architectury.utils.GameInstance;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
@@ -147,7 +144,6 @@ public final class NetworkManager {
|
||||
collectPackets(PacketSink.ofPlayers(players), serverToClient(), id, buf);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void sendToServer(ResourceLocation id, RegistryFriendlyByteBuf buf) {
|
||||
collectPackets(PacketSink.client(), clientToServer(), id, buf);
|
||||
@@ -163,14 +159,11 @@ public final class NetworkManager {
|
||||
collectPackets(PacketSink.ofPlayers(players), serverToClient(), payload, iterator.next().registryAccess());
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@ExpectPlatform
|
||||
public static <T extends CustomPacketPayload> void sendToServer(T payload) {
|
||||
ClientPacketListener connection = GameInstance.getClient().getConnection();
|
||||
if (connection == null) return;
|
||||
collectPackets(PacketSink.client(), clientToServer(), payload, connection.registryAccess());
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@ExpectPlatform
|
||||
public static boolean canServerReceive(ResourceLocation id) {
|
||||
throw new AssertionError();
|
||||
@@ -181,7 +174,6 @@ public final class NetworkManager {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static boolean canServerReceive(CustomPacketPayload.Type<?> type) {
|
||||
return canServerReceive(type.id());
|
||||
}
|
||||
|
||||
@@ -22,9 +22,6 @@ package dev.architectury.networking;
|
||||
import dev.architectury.extensions.network.EntitySpawnExtension;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -37,7 +34,6 @@ import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerEntity;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -46,9 +42,9 @@ import java.util.UUID;
|
||||
* @see net.minecraft.network.protocol.game.ClientboundAddEntityPacket
|
||||
*/
|
||||
public class SpawnEntityPacket {
|
||||
private static final ResourceLocation PACKET_ID = ResourceLocation.fromNamespaceAndPath("architectury", "spawn_entity_packet");
|
||||
private static final CustomPacketPayload.Type<PacketPayload> PACKET_TYPE = new CustomPacketPayload.Type<>(PACKET_ID);
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, PacketPayload> PACKET_CODEC = CustomPacketPayload.codec(PacketPayload::write, PacketPayload::new);
|
||||
static final ResourceLocation PACKET_ID = ResourceLocation.fromNamespaceAndPath("architectury", "spawn_entity_packet");
|
||||
static final CustomPacketPayload.Type<PacketPayload> PACKET_TYPE = new CustomPacketPayload.Type<>(PACKET_ID);
|
||||
static final StreamCodec<RegistryFriendlyByteBuf, PacketPayload> PACKET_CODEC = CustomPacketPayload.codec(PacketPayload::write, PacketPayload::new);
|
||||
|
||||
public static Packet<ClientGamePacketListener> create(Entity entity, ServerEntity serverEntity) {
|
||||
if (entity.level().isClientSide()) {
|
||||
@@ -61,42 +57,7 @@ public class SpawnEntityPacket {
|
||||
NetworkManager.registerS2CPayloadType(PACKET_TYPE, PACKET_CODEC);
|
||||
}
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Client {
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static void register() {
|
||||
NetworkManager.registerReceiver(NetworkManager.s2c(), PACKET_TYPE, PACKET_CODEC, Client::receive);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private static void receive(PacketPayload payload, NetworkManager.PacketContext context) {
|
||||
context.queue(() -> {
|
||||
if (Minecraft.getInstance().level == null) {
|
||||
throw new IllegalStateException("Client world is null!");
|
||||
}
|
||||
var entity = payload.entityType().create(Minecraft.getInstance().level, EntitySpawnReason.LOAD);
|
||||
if (entity == null) {
|
||||
throw new IllegalStateException("Created entity is null!");
|
||||
}
|
||||
entity.setUUID(payload.uuid());
|
||||
entity.setId(payload.id());
|
||||
entity.syncPacketPositionCodec(payload.x(), payload.y(), payload.z());
|
||||
entity.snapTo(payload.x(), payload.y(), payload.z(), payload.xRot(), payload.yRot());
|
||||
entity.setYHeadRot(payload.yHeadRot());
|
||||
entity.setYBodyRot(payload.yHeadRot());
|
||||
if (entity instanceof EntitySpawnExtension ext) {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.wrappedBuffer(payload.data()), context.registryAccess());
|
||||
ext.loadAdditionalSpawnData(buf);
|
||||
buf.release();
|
||||
}
|
||||
Minecraft.getInstance().level.addEntity(entity);
|
||||
entity.lerpMotion(payload.deltaX(), payload.deltaY(), payload.deltaZ());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private record PacketPayload(EntityType<?> entityType, UUID uuid, int id, double x, double y, double z, float xRot,
|
||||
record PacketPayload(EntityType<?> entityType, UUID uuid, int id, double x, double y, double z, float xRot,
|
||||
float yRot,
|
||||
float yHeadRot,
|
||||
double deltaX, double deltaY, double deltaZ,
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* 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.networking.simple;
|
||||
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
|
||||
/**
|
||||
* The base class for server -> client messages managed by a {@link SimpleNetworkManager}.
|
||||
*/
|
||||
public abstract class BaseS2CMessage extends Message {
|
||||
private void sendTo(ServerPlayer player, Packet<?> packet) {
|
||||
if (player == null) {
|
||||
throw new NullPointerException("Unable to send packet '" + getType().getId() + "' to a 'null' player!");
|
||||
}
|
||||
|
||||
player.connection.send(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to a player.
|
||||
*
|
||||
* @param player the player
|
||||
*/
|
||||
public final void sendTo(ServerPlayer player) {
|
||||
sendTo(player, toPacket(player.registryAccess()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to multiple players.
|
||||
*
|
||||
* @param players the players
|
||||
*/
|
||||
public final void sendTo(Iterable<ServerPlayer> players) {
|
||||
if (!players.iterator().hasNext()) return;
|
||||
Packet<?> packet = toPacket(players.iterator().next().registryAccess());
|
||||
|
||||
for (ServerPlayer player : players) {
|
||||
sendTo(player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to all players in the server.
|
||||
*
|
||||
* @param server the server
|
||||
*/
|
||||
public final void sendToAll(MinecraftServer server) {
|
||||
sendTo(server.getPlayerList().getPlayers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to all players in a level.
|
||||
*
|
||||
* @param level the level
|
||||
*/
|
||||
public final void sendToLevel(ServerLevel level) {
|
||||
sendTo(level.players());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to all players listening to a chunk.
|
||||
*
|
||||
* @param chunk the listened chunk
|
||||
*/
|
||||
public final void sendToChunkListeners(LevelChunk chunk) {
|
||||
Packet<?> packet = toPacket(chunk.getLevel().registryAccess());
|
||||
((ServerChunkCache) chunk.getLevel().getChunkSource()).chunkMap.getPlayers(chunk.getPos(), false).forEach(e -> sendTo(e, packet));
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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.networking.simple;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
|
||||
/**
|
||||
* The base class for messages managed by a {@link SimpleNetworkManager}.
|
||||
*
|
||||
* @see BaseC2SMessage
|
||||
* @see BaseS2CMessage
|
||||
*/
|
||||
public abstract class Message {
|
||||
Message() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MessageType} of this message
|
||||
*
|
||||
* @return the {@link MessageType} of this message
|
||||
* @see SimpleNetworkManager#registerC2S(String, MessageDecoder)
|
||||
* @see SimpleNetworkManager#registerS2C(String, MessageDecoder)
|
||||
*/
|
||||
public abstract MessageType getType();
|
||||
|
||||
/**
|
||||
* Writes this message to a byte buffer.
|
||||
*
|
||||
* @param buf the byte buffer
|
||||
*/
|
||||
public abstract void write(RegistryFriendlyByteBuf buf);
|
||||
|
||||
/**
|
||||
* Handles this message when it is received.
|
||||
*
|
||||
* @param context the packet context for handling this message
|
||||
*/
|
||||
public abstract void handle(NetworkManager.PacketContext context);
|
||||
|
||||
/**
|
||||
* Converts this message into a corresponding vanilla {@link Packet}.
|
||||
*
|
||||
* @return the converted {@link Packet}
|
||||
*/
|
||||
public final Packet<?> toPacket(RegistryAccess access) {
|
||||
RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), access);
|
||||
write(buf);
|
||||
return NetworkManager.toPacket(getType().getSide(), getType().getId(), buf);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.networking.simple;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
|
||||
/**
|
||||
* Decodes a {@link Message} from a {@link RegistryFriendlyByteBuf}.
|
||||
*
|
||||
* @param <T> the message type handled by this decoder
|
||||
* @author LatvianModder
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface MessageDecoder<T extends Message> {
|
||||
/**
|
||||
* Decodes a {@code T} message from a byte buffer.
|
||||
*
|
||||
* @param buf the byte buffer
|
||||
* @return the decoded instance
|
||||
*/
|
||||
T decode(RegistryFriendlyByteBuf buf);
|
||||
|
||||
/**
|
||||
* Creates a network receiver from this decoder.
|
||||
*
|
||||
* <p>The returned receiver will first {@linkplain #decode(RegistryFriendlyByteBuf) decode a message}
|
||||
* and then call {@link Message#handle(NetworkManager.PacketContext)} on the decoded message.
|
||||
*
|
||||
* @return the created receiver
|
||||
*/
|
||||
default NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> createReceiver() {
|
||||
return (buf, context) -> {
|
||||
Message packet = decode(buf);
|
||||
context.queue(() -> packet.handle(context));
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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.networking.simple;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A unique type for a message in a {@link SimpleNetworkManager}.
|
||||
*/
|
||||
public final class MessageType {
|
||||
private final SimpleNetworkManager manager;
|
||||
private final ResourceLocation id;
|
||||
private final NetworkManager.Side side;
|
||||
|
||||
MessageType(SimpleNetworkManager manager, ResourceLocation id, NetworkManager.Side side) {
|
||||
this.manager = manager;
|
||||
this.id = id;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the network manager that manages this message type
|
||||
*
|
||||
* @return the network manager that manages this message type
|
||||
*/
|
||||
public SimpleNetworkManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of this message type
|
||||
*
|
||||
* @return the ID of this message type
|
||||
*/
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the network side of this message type
|
||||
*
|
||||
* @return the network side of this message type
|
||||
*/
|
||||
public NetworkManager.Side getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id.toString() + ":" + side.name().toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageType messageType = (MessageType) o;
|
||||
return id.equals(messageType.id) && side == messageType.side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, side);
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* 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.networking.simple;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.transformers.PacketTransformer;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.utils.Env;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A simple wrapper for {@link NetworkManager} to make it easier to register messages and send them to clients/servers.
|
||||
*/
|
||||
public class SimpleNetworkManager {
|
||||
/**
|
||||
* Creates a new {@code SimpleNetworkManager}.
|
||||
*
|
||||
* @param namespace a unique namespace for the messages ({@link #namespace})
|
||||
* @return the created network manager
|
||||
*/
|
||||
public static SimpleNetworkManager create(String namespace) {
|
||||
return new SimpleNetworkManager(namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique namespace for the messages managed by this manager.
|
||||
* This will typically be a mod ID.
|
||||
*/
|
||||
public final String namespace;
|
||||
|
||||
private SimpleNetworkManager(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a server -> client message with no packet transformers.
|
||||
*
|
||||
* @param id a unique ID for the message, must be a valid value for {@link ResourceLocation#getPath}
|
||||
* @param decoder the message decoder for the message
|
||||
* @return a {@link MessageType} describing the registered message
|
||||
* @see #registerS2C(String, MessageDecoder, List)
|
||||
*/
|
||||
public MessageType registerS2C(String id, MessageDecoder<BaseS2CMessage> decoder) {
|
||||
return registerS2C(id, decoder, List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a server -> client message using the given packet transformers.
|
||||
*
|
||||
* @param id a unique ID for the message, must be a valid value for {@link ResourceLocation#getPath}
|
||||
* @param decoder the message decoder for the message
|
||||
* @param transformers a list of packet transformers to apply to the message packet
|
||||
* @return a {@link MessageType} describing the registered message
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public MessageType registerS2C(String id, MessageDecoder<BaseS2CMessage> decoder, List<PacketTransformer> transformers) {
|
||||
MessageType messageType = new MessageType(this, ResourceLocation.fromNamespaceAndPath(namespace, id), NetworkManager.s2c());
|
||||
|
||||
if (Platform.getEnvironment() == Env.CLIENT) {
|
||||
NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver = decoder.createReceiver();
|
||||
NetworkManager.registerReceiver(NetworkManager.s2c(), messageType.getId(), transformers, receiver);
|
||||
}
|
||||
|
||||
return messageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a client -> server message with no packet transformers.
|
||||
*
|
||||
* @param id a unique ID for the message, must be a valid value for {@link ResourceLocation#getPath}
|
||||
* @param decoder the message decoder for the message
|
||||
* @return a {@link MessageType} describing the registered message
|
||||
* @see #registerC2S(String, MessageDecoder, List)
|
||||
*/
|
||||
public MessageType registerC2S(String id, MessageDecoder<BaseC2SMessage> decoder) {
|
||||
return registerC2S(id, decoder, List.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a client -> server message using the given packet transformers.
|
||||
*
|
||||
* @param id a unique ID for the message, must be a valid value for {@link ResourceLocation#getPath}
|
||||
* @param decoder the message decoder for the message
|
||||
* @param transformers a list of packet transformers to apply to the message packet
|
||||
* @return a {@link MessageType} describing the registered message
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public MessageType registerC2S(String id, MessageDecoder<BaseC2SMessage> decoder, List<PacketTransformer> transformers) {
|
||||
MessageType messageType = new MessageType(this, ResourceLocation.fromNamespaceAndPath(namespace, id), NetworkManager.c2s());
|
||||
NetworkManager.NetworkReceiver<RegistryFriendlyByteBuf> receiver = decoder.createReceiver();
|
||||
NetworkManager.registerReceiver(NetworkManager.c2s(), messageType.getId(), transformers, receiver);
|
||||
return messageType;
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
package dev.architectury.networking.transformers;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -41,7 +39,6 @@ public interface PacketSink {
|
||||
};
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
static PacketSink client() {
|
||||
return packet -> {
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
|
||||
@@ -19,15 +19,13 @@
|
||||
|
||||
package dev.architectury.networking.transformers;
|
||||
|
||||
import dev.architectury.event.events.client.ClientPlayerEvent;
|
||||
import dev.architectury.event.events.common.PlayerEvent;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.transformers.client.ClientSplitPacketTransformer;
|
||||
import dev.architectury.utils.Env;
|
||||
import dev.architectury.utils.EnvExecutor;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -46,47 +44,17 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
private static final byte END = 0x2;
|
||||
private static final byte ONLY = 0x3;
|
||||
|
||||
private static class PartKey {
|
||||
private final NetworkManager.Side side;
|
||||
@Nullable
|
||||
private final UUID playerUUID;
|
||||
|
||||
public PartKey(NetworkManager.Side side, @Nullable UUID playerUUID) {
|
||||
this.side = side;
|
||||
this.playerUUID = playerUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PartKey)) return false;
|
||||
PartKey key = (PartKey) o;
|
||||
return side == key.side && Objects.equals(playerUUID, key.playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(side, playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PartKey{" +
|
||||
"side=" + side +
|
||||
", playerUUID=" + playerUUID +
|
||||
'}';
|
||||
}
|
||||
@ApiStatus.Internal
|
||||
public record PartKey(NetworkManager.Side side, @Nullable UUID playerUUID) {
|
||||
}
|
||||
|
||||
private static class PartData {
|
||||
private final ResourceLocation id;
|
||||
private final int partsExpected;
|
||||
private final List<RegistryFriendlyByteBuf> parts;
|
||||
|
||||
public PartData(ResourceLocation id, int partsExpected) {
|
||||
this.id = id;
|
||||
this.partsExpected = partsExpected;
|
||||
this.parts = new ArrayList<>();
|
||||
public record PartData(
|
||||
ResourceLocation id,
|
||||
int partsExpected,
|
||||
List<RegistryFriendlyByteBuf> parts
|
||||
) {
|
||||
private PartData(ResourceLocation id, int partsExpected) {
|
||||
this(id, partsExpected, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,16 +64,7 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
PlayerEvent.PLAYER_QUIT.register(player -> {
|
||||
cache.keySet().removeIf(key -> Objects.equals(key.playerUUID, player.getUUID()));
|
||||
});
|
||||
EnvExecutor.runInEnv(Env.CLIENT, () -> new Client()::init);
|
||||
}
|
||||
|
||||
private class Client {
|
||||
@Environment(EnvType.CLIENT)
|
||||
private void init() {
|
||||
ClientPlayerEvent.CLIENT_PLAYER_QUIT.register(player -> {
|
||||
cache.keySet().removeIf(key -> key.side == NetworkManager.Side.S2C);
|
||||
});
|
||||
}
|
||||
EnvExecutor.runInEnv(Env.CLIENT, () -> () -> ClientSplitPacketTransformer.init(cache));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -204,7 +163,7 @@ public class SplitPacketTransformer implements PacketTransformer {
|
||||
buf.skipBytes(next);
|
||||
sink.accept(side, id, packetBuffer);
|
||||
}
|
||||
|
||||
|
||||
buf.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,25 +17,18 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package dev.architectury.networking.simple;
|
||||
package dev.architectury.networking.transformers.client;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import dev.architectury.event.events.client.ClientPlayerEvent;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.transformers.SplitPacketTransformer;
|
||||
|
||||
/**
|
||||
* The base class for client -> server messages managed by a {@link SimpleNetworkManager}.
|
||||
*/
|
||||
public abstract class BaseC2SMessage extends Message {
|
||||
/**
|
||||
* Sends this message to the server.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final void sendToServer() {
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket(Minecraft.getInstance().level.registryAccess()));
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to send packet to the server while not in game!");
|
||||
}
|
||||
import java.util.Map;
|
||||
|
||||
public class ClientSplitPacketTransformer {
|
||||
public static void init(Map<SplitPacketTransformer.PartKey, SplitPacketTransformer.PartData> cache) {
|
||||
ClientPlayerEvent.CLIENT_PLAYER_QUIT.register(player -> {
|
||||
cache.keySet().removeIf(key -> key.side() == NetworkManager.Side.S2C);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,6 @@
|
||||
|
||||
package dev.architectury.platform;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
@@ -80,13 +77,4 @@ public interface Mod {
|
||||
Optional<String> getSources();
|
||||
|
||||
Optional<String> getIssueTracker();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
void registerConfigurationScreen(ConfigurationScreenProvider provider);
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@FunctionalInterface
|
||||
interface ConfigurationScreenProvider {
|
||||
Screen provide(Screen parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,20 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
package dev.architectury.networking.simple;
|
||||
package dev.architectury.platform.client;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import dev.architectury.platform.Mod;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
|
||||
public class ConfigurationScreenRegistry {
|
||||
@ExpectPlatform
|
||||
public static void register(Mod mod, ConfigurationScreenProvider provider) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ConfigurationScreenProvider {
|
||||
Screen provide(Screen parent);
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,6 @@
|
||||
package dev.architectury.registry.client.gui;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
|
||||
import net.minecraft.world.inventory.tooltip.TooltipComponent;
|
||||
|
||||
@@ -30,7 +28,6 @@ import java.util.function.Function;
|
||||
/**
|
||||
* Registry for {@link ClientTooltipComponent} factories
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class ClientTooltipComponentRegistry {
|
||||
private ClientTooltipComponentRegistry() {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.registry.client.gui;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
|
||||
public class MenuScreenRegistry {
|
||||
/**
|
||||
* Registers a Screen Factory on the client to display.
|
||||
*
|
||||
* @param type The {@link MenuType} the screen visualizes
|
||||
* @param factory A functional interface that is used to create new {@link Screen}s
|
||||
* @param <H> The type of {@link AbstractContainerMenu} for the screen
|
||||
* @param <S> The type for the {@link Screen}
|
||||
*/
|
||||
@ExpectPlatform
|
||||
public static <H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> void registerScreenFactory(MenuType<? extends H> type, ScreenFactory<H, S> factory) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new screens.
|
||||
*
|
||||
* @param <H> The type of {@link AbstractContainerMenu} for the screen
|
||||
* @param <S> The type for the {@link Screen}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ScreenFactory<H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> {
|
||||
/**
|
||||
* Creates a new {@link S} that extends {@link Screen}
|
||||
*
|
||||
* @param containerMenu The {@link AbstractContainerMenu} that controls the game logic for the screen
|
||||
* @param inventory The {@link Inventory} for the screen
|
||||
* @param component The {@link Component} for the screen
|
||||
* @return A new {@link S} that extends {@link Screen}
|
||||
*/
|
||||
S create(H containerMenu, Inventory inventory, Component component);
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,8 @@
|
||||
package dev.architectury.registry.client.keymappings;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class KeyMappingRegistry {
|
||||
private KeyMappingRegistry() {
|
||||
}
|
||||
|
||||
@@ -20,14 +20,11 @@
|
||||
package dev.architectury.registry.client.level.entity;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class EntityModelLayerRegistry {
|
||||
@ExpectPlatform
|
||||
public static void register(ModelLayerLocation location, Supplier<LayerDefinition> definition) {
|
||||
|
||||
@@ -20,15 +20,12 @@
|
||||
package dev.architectury.registry.client.level.entity;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class EntityRendererRegistry {
|
||||
private EntityRendererRegistry() {
|
||||
}
|
||||
|
||||
@@ -20,10 +20,7 @@
|
||||
package dev.architectury.registry.client.particle;
|
||||
|
||||
import dev.architectury.event.events.client.ClientLifecycleEvent;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
@@ -44,7 +41,6 @@ import java.util.List;
|
||||
* or use the helper methods {@link #register(RegistrySupplier, ParticleProvider)} and {@link #register(RegistrySupplier, DeferredParticleProvider)},
|
||||
* which will automatically handle the listening for you.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class ParticleProviderRegistry {
|
||||
public interface ExtendedSpriteSet extends SpriteSet {
|
||||
TextureAtlas getAtlas();
|
||||
|
||||
@@ -20,19 +20,17 @@
|
||||
package dev.architectury.registry.client.rendering;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class BlockEntityRendererRegistry {
|
||||
private BlockEntityRendererRegistry() {
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static <T extends BlockEntity> void register(BlockEntityType<T> type, BlockEntityRendererProvider<? super T> provider) {
|
||||
public static <E extends BlockEntity, S extends BlockEntityRenderState> void register(BlockEntityType<E> type, BlockEntityRendererProvider<? super E, ? super S> provider) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,12 @@
|
||||
package dev.architectury.registry.client.rendering;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.color.block.BlockColor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class ColorHandlerRegistry {
|
||||
private ColorHandlerRegistry() {
|
||||
}
|
||||
|
||||
@@ -20,13 +20,10 @@
|
||||
package dev.architectury.registry.client.rendering;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class RenderTypeRegistry {
|
||||
private RenderTypeRegistry() {
|
||||
}
|
||||
|
||||
@@ -20,10 +20,7 @@
|
||||
package dev.architectury.registry.menu;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -38,6 +35,7 @@ import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A utility class to register {@link MenuType}s and {@link Screen}s for containers
|
||||
* @see dev.architectury.registry.client.gui.MenuScreenRegistry
|
||||
*/
|
||||
public final class MenuRegistry {
|
||||
private MenuRegistry() {
|
||||
@@ -117,40 +115,6 @@ public final class MenuRegistry {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a Screen Factory on the client to display.
|
||||
*
|
||||
* @param type The {@link MenuType} the screen visualizes
|
||||
* @param factory A functional interface that is used to create new {@link Screen}s
|
||||
* @param <H> The type of {@link AbstractContainerMenu} for the screen
|
||||
* @param <S> The type for the {@link Screen}
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
@ExpectPlatform
|
||||
public static <H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> void registerScreenFactory(MenuType<? extends H> type, ScreenFactory<H, S> factory) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new screens.
|
||||
*
|
||||
* @param <H> The type of {@link AbstractContainerMenu} for the screen
|
||||
* @param <S> The type for the {@link Screen}
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
@FunctionalInterface
|
||||
public interface ScreenFactory<H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> {
|
||||
/**
|
||||
* Creates a new {@link S} that extends {@link Screen}
|
||||
*
|
||||
* @param containerMenu The {@link AbstractContainerMenu} that controls the game logic for the screen
|
||||
* @param inventory The {@link Inventory} for the screen
|
||||
* @param component The {@link Component} for the screen
|
||||
* @return A new {@link S} that extends {@link Screen}
|
||||
*/
|
||||
S create(H containerMenu, Inventory inventory, Component component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates simple menus.
|
||||
*
|
||||
|
||||
@@ -20,18 +20,10 @@
|
||||
package dev.architectury.utils;
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class GameInstance {
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static Minecraft getClient() {
|
||||
return Minecraft.getInstance();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ExpectPlatform
|
||||
public static MinecraftServer getServer() {
|
||||
|
||||
@@ -120,16 +120,12 @@ transitive-accessible method net/minecraft/client/renderer/RenderType create (Lj
|
||||
transitive-accessible class net/minecraft/client/renderer/RenderType$CompositeState
|
||||
transitive-accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType
|
||||
transitive-accessible class net/minecraft/client/renderer/RenderType$OutlineProperty
|
||||
accessible class net/minecraft/client/resources/model/AtlasSet$AtlasEntry
|
||||
accessible field net/minecraft/world/item/SpawnEggItem BY_ID Ljava/util/Map;
|
||||
accessible field net/minecraft/world/item/SpawnEggItem defaultType Lnet/minecraft/world/entity/EntityType;
|
||||
mutable field net/minecraft/world/item/SpawnEggItem defaultType Lnet/minecraft/world/entity/EntityType;
|
||||
accessible field net/minecraft/client/particle/ParticleEngine textureAtlas Lnet/minecraft/client/renderer/texture/TextureAtlas;
|
||||
accessible class net/minecraft/client/particle/ParticleEngine$MutableSpriteSet
|
||||
accessible field net/minecraft/client/particle/ParticleEngine$MutableSpriteSet sprites Ljava/util/List;
|
||||
accessible class net/minecraft/client/particle/ParticleResources$MutableSpriteSet
|
||||
accessible field net/minecraft/client/particle/ParticleResources$MutableSpriteSet sprites Ljava/util/List;
|
||||
transitive-accessible class net/minecraft/world/item/CreativeModeTab$Output
|
||||
transitive-accessible class net/minecraft/world/item/CreativeModeTab$TabVisibility
|
||||
accessible field net/minecraft/client/multiplayer/MultiPlayerGameMode connection Lnet/minecraft/client/multiplayer/ClientPacketListener;
|
||||
accessible field net/minecraft/client/Minecraft particleResources Lnet/minecraft/client/particle/ParticleResources;
|
||||
|
||||
##############################
|
||||
# This section is generated automatically with Gradle task generateAccessWidener!!!
|
||||
@@ -154,7 +150,7 @@ transitive-accessible method net/minecraft/world/level/block/CakeBlock <init> (L
|
||||
transitive-accessible method net/minecraft/world/level/block/CandleCakeBlock <init> (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/CartographyTableBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/CarvedPumpkinBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/ChestBlock <init> (Ljava/util/function/Supplier;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/ChestBlock <init> (Ljava/util/function/Supplier;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/ChorusFlowerBlock <init> (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/ChorusPlantBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/CoralFanBlock <init> (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
@@ -174,7 +170,6 @@ transitive-accessible method net/minecraft/world/level/block/EndPortalBlock <ini
|
||||
transitive-accessible method net/minecraft/world/level/block/EndRodBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/EnderChestBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/FarmBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/FletchingTableBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/FlowerBedBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/FungusBlock <init> (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/FurnaceBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
@@ -230,9 +225,13 @@ transitive-accessible method net/minecraft/world/level/block/WallSkullBlock <ini
|
||||
transitive-accessible method net/minecraft/world/level/block/WallTorchBlock <init> (Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WaterlilyBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WaterloggedTransparentBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringCopperBarsBlock <init> (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringCopperChainBlock <init> (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringCopperDoorBlock <init> (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringCopperGrateBlock <init> (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringCopperTrapDoorBlock <init> (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringLanternBlock <init> (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeatheringLightningRodBlock <init> (Lnet/minecraft/world/level/block/WeatheringCopper$WeatherState;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WeightedPressurePlateBlock <init> (ILnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WetSpongeBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
transitive-accessible method net/minecraft/world/level/block/WitherSkullBlock <init> (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V
|
||||
@@ -256,8 +255,6 @@ transitive-accessible field net/minecraft/client/renderer/RenderStateShard VIEW_
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard VIEW_OFFSET_Z_LAYERING_FORWARD Lnet/minecraft/client/renderer/RenderStateShard$LayeringStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard MAIN_TARGET Lnet/minecraft/client/renderer/RenderStateShard$OutputStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard OUTLINE_TARGET Lnet/minecraft/client/renderer/RenderStateShard$OutputStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard TRANSLUCENT_TARGET Lnet/minecraft/client/renderer/RenderStateShard$OutputStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard PARTICLES_TARGET Lnet/minecraft/client/renderer/RenderStateShard$OutputStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard WEATHER_TARGET Lnet/minecraft/client/renderer/RenderStateShard$OutputStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard ITEM_ENTITY_TARGET Lnet/minecraft/client/renderer/RenderStateShard$OutputStateShard;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderStateShard DEFAULT_LINE Lnet/minecraft/client/renderer/RenderStateShard$LineStateShard;
|
||||
@@ -304,6 +301,7 @@ transitive-accessible field net/minecraft/client/renderer/RenderPipelines PARTIC
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderPipelines WEATHER_SNIPPET Lcom/mojang/blaze3d/pipeline/RenderPipeline$Snippet;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderPipelines GUI_SNIPPET Lcom/mojang/blaze3d/pipeline/RenderPipeline$Snippet;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderPipelines GUI_TEXTURED_SNIPPET Lcom/mojang/blaze3d/pipeline/RenderPipeline$Snippet;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderPipelines GUI_TEXT_SNIPPET Lcom/mojang/blaze3d/pipeline/RenderPipeline$Snippet;
|
||||
transitive-accessible field net/minecraft/client/renderer/RenderPipelines OUTLINE_SNIPPET Lcom/mojang/blaze3d/pipeline/RenderPipeline$Snippet;
|
||||
|
||||
# CreativeModeTabs fields
|
||||
|
||||
@@ -113,7 +113,7 @@ unifiedPublishing {
|
||||
displayName = "[Fabric $rootProject.supported_version] v$project.version"
|
||||
releaseType = "$rootProject.artifact_type"
|
||||
changelog = releaseChangelog()
|
||||
gameVersions = ["1.21.8"]
|
||||
gameVersions = ["1.21.9"]
|
||||
gameLoaders = ["fabric"]
|
||||
mainPublication renameJarForPublication
|
||||
relations {
|
||||
|
||||
@@ -22,7 +22,7 @@ package dev.architectury.compat.fabric;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import dev.architectury.platform.fabric.PlatformImpl;
|
||||
import dev.architectury.platform.client.fabric.ConfigurationScreenRegistryImpl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ModMenuCompatibility implements ModMenuApi {
|
||||
}
|
||||
|
||||
private void validateMap() {
|
||||
for (var entry : PlatformImpl.CONFIG_SCREENS.entrySet()) {
|
||||
for (var entry : ConfigurationScreenRegistryImpl.CONFIG_SCREENS.entrySet()) {
|
||||
if (!FACTORIES.containsKey(entry.getKey())) {
|
||||
FACTORIES.put(entry.getKey(), entry.getValue()::provide);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
|
||||
import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRenderHandler;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -36,12 +35,10 @@ import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Environment(EnvType.CLIENT)
|
||||
class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, FluidRenderHandler {
|
||||
private final ArchitecturyFluidAttributes attributes;
|
||||
private TextureAtlas atlas = null;
|
||||
private final TextureAtlasSprite[] sprites = new TextureAtlasSprite[2];
|
||||
private final TextureAtlasSprite[] spritesOverlaid = new TextureAtlasSprite[3];
|
||||
private final TextureAtlasSprite[] spritesOther = new TextureAtlasSprite[2];
|
||||
@@ -55,12 +52,11 @@ class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, Flu
|
||||
@Nullable
|
||||
public TextureAtlasSprite[] getSprites(FluidVariant variant) {
|
||||
FluidStack stack = FluidStackHooksFabric.fromFabric(variant, FluidStack.bucketAmount());
|
||||
Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
|
||||
ResourceLocation overlayTexture = attributes.getOverlayTexture(stack);
|
||||
TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.apply(overlayTexture);
|
||||
TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.getSprite(overlayTexture);
|
||||
TextureAtlasSprite[] sprites = overlaySprite == null ? this.sprites : spritesOverlaid;
|
||||
sprites[0] = atlas.apply(attributes.getSourceTexture(stack));
|
||||
sprites[1] = atlas.apply(attributes.getFlowingTexture(stack));
|
||||
sprites[0] = atlas.getSprite(attributes.getSourceTexture(stack));
|
||||
sprites[1] = atlas.getSprite(attributes.getFlowingTexture(stack));
|
||||
if (overlaySprite != null) sprites[2] = overlaySprite;
|
||||
return sprites;
|
||||
}
|
||||
@@ -72,12 +68,11 @@ class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, Flu
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite[] getFluidSprites(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) {
|
||||
Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
|
||||
ResourceLocation overlayTexture = attributes.getOverlayTexture(state, view, pos);
|
||||
TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.apply(overlayTexture);
|
||||
TextureAtlasSprite overlaySprite = overlayTexture == null ? null : atlas.getSprite(overlayTexture);
|
||||
TextureAtlasSprite[] sprites = overlaySprite == null ? this.spritesOther : spritesOtherOverlaid;
|
||||
sprites[0] = atlas.apply(attributes.getSourceTexture(state, view, pos));
|
||||
sprites[1] = atlas.apply(attributes.getFlowingTexture(state, view, pos));
|
||||
sprites[0] = atlas.getSprite(attributes.getSourceTexture(state, view, pos));
|
||||
sprites[1] = atlas.getSprite(attributes.getFlowingTexture(state, view, pos));
|
||||
if (overlaySprite != null) sprites[2] = overlaySprite;
|
||||
return sprites;
|
||||
}
|
||||
@@ -86,4 +81,9 @@ class ArchitecturyFluidRenderingFabric implements FluidVariantRenderHandler, Flu
|
||||
public int getFluidColor(@Nullable BlockAndTintGetter view, @Nullable BlockPos pos, FluidState state) {
|
||||
return attributes.getColor(state, view, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadTextures(TextureAtlas atlas) {
|
||||
this.atlas = atlas;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.hooks.client.fluid.fabric;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.hooks.fluid.fabric.FluidStackHooksFabric;
|
||||
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
|
||||
import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.Nullable;
|
||||
|
||||
public class ClientFluidStackHooksImpl {
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
|
||||
if (handler == null) return null;
|
||||
var sprites = handler.getFluidSprites(level, pos, state);
|
||||
if (sprites == null) return null;
|
||||
return sprites[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
|
||||
return sprites == null ? null : sprites[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
|
||||
return sprites == null ? null : sprites[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
|
||||
if (handler == null) return null;
|
||||
var sprites = handler.getFluidSprites(level, pos, state);
|
||||
if (sprites == null) return null;
|
||||
return sprites[1];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
|
||||
return sprites == null ? null : sprites[1];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
|
||||
return sprites == null ? null : sprites[1];
|
||||
}
|
||||
|
||||
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return -1;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
|
||||
if (handler == null) return -1;
|
||||
return handler.getFluidColor(level, pos, state);
|
||||
}
|
||||
|
||||
public static int getColor(FluidStack stack) {
|
||||
return FluidVariantRendering.getColor(FluidStackHooksFabric.toFabric(stack));
|
||||
}
|
||||
|
||||
public static int getColor(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return -1;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(fluid);
|
||||
if (handler == null) return -1;
|
||||
return handler.getFluidColor(null, null, fluid.defaultFluidState());
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,8 @@ package dev.architectury.hooks.fluid.fabric;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
|
||||
import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
|
||||
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariantAttributes;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
@@ -37,11 +31,8 @@ import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
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.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -84,77 +75,6 @@ public class FluidStackHooksImpl {
|
||||
return 81000;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
|
||||
if (handler == null) return null;
|
||||
var sprites = handler.getFluidSprites(level, pos, state);
|
||||
if (sprites == null) return null;
|
||||
return sprites[0];
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
|
||||
return sprites == null ? null : sprites[0];
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
|
||||
return sprites == null ? null : sprites[0];
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
|
||||
if (handler == null) return null;
|
||||
var sprites = handler.getFluidSprites(level, pos, state);
|
||||
if (sprites == null) return null;
|
||||
return sprites[1];
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidStackHooksFabric.toFabric(stack));
|
||||
return sprites == null ? null : sprites[1];
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
|
||||
var sprites = FluidVariantRendering.getSprites(FluidVariant.of(fluid));
|
||||
return sprites == null ? null : sprites[1];
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return -1;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(state.getType());
|
||||
if (handler == null) return -1;
|
||||
return handler.getFluidColor(level, pos, state);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static int getColor(FluidStack stack) {
|
||||
return FluidVariantRendering.getColor(FluidStackHooksFabric.toFabric(stack));
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static int getColor(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return -1;
|
||||
var handler = FluidRenderHandlerRegistry.INSTANCE.get(fluid);
|
||||
if (handler == null) return -1;
|
||||
return handler.getFluidColor(null, null, fluid.defaultFluidState());
|
||||
}
|
||||
|
||||
public static int getLuminosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
|
||||
return FluidVariantAttributes.getLuminance(FluidStackHooksFabric.toFabric(fluid));
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package dev.architectury.impl.fabric;
|
||||
import dev.architectury.event.events.client.ClientScreenInputEvent;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.input.CharacterEvent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public interface ScreenInputDelegate {
|
||||
@@ -36,12 +37,12 @@ public interface ScreenInputDelegate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char c, int i) {
|
||||
if (ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), parent, c, i).isPresent())
|
||||
public boolean charTyped(CharacterEvent characterEvent) {
|
||||
if (ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), parent, characterEvent).isPresent())
|
||||
return true;
|
||||
if (parent.charTyped(c, i))
|
||||
if (parent.charTyped(characterEvent))
|
||||
return true;
|
||||
return ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), parent, c, i).isPresent();
|
||||
return ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), parent, characterEvent).isPresent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ package dev.architectury.init.fabric;
|
||||
|
||||
import dev.architectury.event.events.client.ClientLifecycleEvent;
|
||||
import dev.architectury.event.events.common.LifecycleEvent;
|
||||
import dev.architectury.networking.SpawnEntityPacket;
|
||||
import dev.architectury.networking.ClientSpawnEntityPacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public class ArchitecturyClient {
|
||||
@@ -29,6 +29,6 @@ public class ArchitecturyClient {
|
||||
LifecycleEvent.SETUP.invoker().run();
|
||||
ClientLifecycleEvent.CLIENT_SETUP.invoker().stateChanged(Minecraft.getInstance());
|
||||
|
||||
SpawnEntityPacket.Client.register();
|
||||
ClientSpawnEntityPacket.register();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public abstract class MixinPhantomSpawner {
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void checkPhantomSpawn(ServerLevel level, boolean bl, boolean bl2, CallbackInfo ci, @Local(ordinal = 1) BlockPos pos, @Local Phantom entity) {
|
||||
private void checkPhantomSpawn(ServerLevel level, boolean bl, CallbackInfo ci, @Local(ordinal = 1) BlockPos pos, @Local Phantom entity) {
|
||||
if (EntityEvent.LIVING_CHECK_SPAWN.invoker().canSpawn(entity, level, pos.getX(), pos.getY(), pos.getZ(), EntitySpawnReason.NATURAL, null).value() == Boolean.FALSE) {
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@@ -24,13 +24,14 @@ import dev.architectury.event.events.common.ExplosionEvent;
|
||||
import dev.architectury.event.events.common.LifecycleEvent;
|
||||
import dev.architectury.hooks.fabric.PersistentEntitySectionManagerHooks;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.ExplosionParticleInfo;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvent;
|
||||
import net.minecraft.util.ProgressListener;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
@@ -61,9 +62,9 @@ public class MixinServerLevel {
|
||||
((PersistentEntitySectionManagerHooks) this.entityManager).architectury_attachLevel((ServerLevel) (Object) this);
|
||||
}
|
||||
|
||||
@Inject(method = "explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/Holder;)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;explode()V"), cancellable = true)
|
||||
private void explodePre(Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionDamageCalculator, double d, double e, double f, float g, boolean bl, Level.ExplosionInteraction explosionInteraction, ParticleOptions particleOptions, ParticleOptions particleOptions2, Holder<SoundEvent> soundEvent, CallbackInfo ci, @Local Explosion.BlockInteraction blockInteraction, @Local ServerExplosion explosion) {
|
||||
@Inject(method = "explode",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;explode()I"), cancellable = true)
|
||||
private void explodePre(Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionDamageCalculator, double d, double e, double f, float g, boolean bl, Level.ExplosionInteraction explosionInteraction, ParticleOptions particleOptions, ParticleOptions particleOptions2, WeightedList<ExplosionParticleInfo> weightedList, Holder<SoundEvent> holder, CallbackInfo ci, @Local ServerExplosion explosion) {
|
||||
if (ExplosionEvent.PRE.invoker().explode((Level) (Object) this, explosion).isFalse()) {
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@@ -20,23 +20,23 @@
|
||||
package dev.architectury.mixin.fabric.client;
|
||||
|
||||
import dev.architectury.event.events.client.ClientGuiEvent;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(DebugScreenOverlay.class)
|
||||
public class MixinDebugScreenOverlay {
|
||||
@Inject(method = "getGameInformation", at = @At("RETURN"))
|
||||
private void getLeftTexts(CallbackInfoReturnable<List<String>> cir) {
|
||||
ClientGuiEvent.DEBUG_TEXT_LEFT.invoker().gatherText(cir.getReturnValue());
|
||||
}
|
||||
|
||||
@Inject(method = "getSystemInformation", at = @At("RETURN"))
|
||||
private void getRightTexts(CallbackInfoReturnable<List<String>> cir) {
|
||||
ClientGuiEvent.DEBUG_TEXT_RIGHT.invoker().gatherText(cir.getReturnValue());
|
||||
@Inject(method = "renderLines", at = @At("RETURN"))
|
||||
private void getLeftTexts(GuiGraphics guiGraphics, List<String> list, boolean bl, CallbackInfo ci) {
|
||||
if (bl) {
|
||||
ClientGuiEvent.DEBUG_TEXT_LEFT.invoker().gatherText(list);
|
||||
} else {
|
||||
ClientGuiEvent.DEBUG_TEXT_RIGHT.invoker().gatherText(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,41 +19,25 @@
|
||||
|
||||
package dev.architectury.mixin.fabric.client;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import dev.architectury.event.events.client.ClientGuiEvent;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(value = GameRenderer.class, priority = 1100)
|
||||
public abstract class MixinGameRenderer {
|
||||
@Shadow
|
||||
@Final
|
||||
private Minecraft minecraft;
|
||||
|
||||
@Shadow
|
||||
public abstract void tick();
|
||||
|
||||
@Inject(method = "render(Lnet/minecraft/client/DeltaTracker;Z)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;renderWithTooltip(Lnet/minecraft/client/gui/GuiGraphics;IIF)V",
|
||||
ordinal = 0), cancellable = true)
|
||||
public void renderScreenPre(DeltaTracker tickDelta, boolean tick, CallbackInfo ci, @Local(ordinal = 0) int mouseX, @Local(ordinal = 1) int mouseY, @Local GuiGraphics graphics) {
|
||||
if (ClientGuiEvent.RENDER_PRE.invoker().render(minecraft.screen, graphics, mouseX, mouseY, tickDelta).isFalse()) {
|
||||
ci.cancel();
|
||||
@WrapOperation(method = "render(Lnet/minecraft/client/DeltaTracker;Z)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;renderWithTooltipAndSubtitles(Lnet/minecraft/client/gui/GuiGraphics;IIF)V",
|
||||
ordinal = 0))
|
||||
public void wrapRenderScreen(Screen screen, GuiGraphics graphics, int mouseX, int mouseY, float delta, Operation<Void> original) {
|
||||
if (ClientGuiEvent.RENDER_PRE.invoker().render(screen, graphics, mouseX, mouseY, delta).isFalse()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "render(Lnet/minecraft/client/DeltaTracker;Z)V",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;renderWithTooltip(Lnet/minecraft/client/gui/GuiGraphics;IIF)V",
|
||||
shift = At.Shift.AFTER, ordinal = 0))
|
||||
public void renderScreenPost(DeltaTracker tickDelta, boolean tick, CallbackInfo ci, @Local(ordinal = 0) int mouseX, @Local(ordinal = 1) int mouseY, @Local GuiGraphics graphics) {
|
||||
ClientGuiEvent.RENDER_POST.invoker().render(minecraft.screen, graphics, mouseX, mouseY, tickDelta);
|
||||
original.call(screen, graphics, mouseX, mouseY, delta);
|
||||
ClientGuiEvent.RENDER_POST.invoker().render(screen, graphics, mouseX, mouseY, delta);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,8 @@ import dev.architectury.impl.fabric.ScreenInputDelegate;
|
||||
import net.minecraft.client.KeyboardHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.input.CharacterEvent;
|
||||
import net.minecraft.client.input.KeyEvent;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -40,40 +42,40 @@ public class MixinKeyboardHandler {
|
||||
@Final
|
||||
private Minecraft minecraft;
|
||||
|
||||
@WrapOperation(method = "charTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;charTyped(CI)Z"))
|
||||
private boolean wrapCharTyped(Screen screen, char chr, int mods, Operation<Boolean> original) {
|
||||
@WrapOperation(method = "charTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;charTyped(Lnet/minecraft/client/input/CharacterEvent;)Z"))
|
||||
private boolean wrapCharTyped(Screen screen, CharacterEvent characterEvent, Operation<Boolean> original) {
|
||||
if (screen instanceof ScreenInputDelegate delegate) {
|
||||
return original.call(delegate.architectury_delegateInputs(), chr, mods);
|
||||
return original.call(delegate.architectury_delegateInputs(), characterEvent);
|
||||
}
|
||||
return original.call(screen, chr, mods);
|
||||
return original.call(screen, characterEvent);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "keyPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;keyPressed(III)Z"))
|
||||
private boolean wrapKeyPressed(Screen screen, int keyCode, int scanCode, int modifiers, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.KEY_PRESSED_PRE.invoker().keyPressed(minecraft, screen, keyCode, scanCode, modifiers);
|
||||
@WrapOperation(method = "keyPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;keyPressed(Lnet/minecraft/client/input/KeyEvent;)Z"))
|
||||
private boolean wrapKeyPressed(Screen screen, KeyEvent keyEvent, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.KEY_PRESSED_PRE.invoker().keyPressed(minecraft, screen, keyEvent);
|
||||
if (result.isPresent())
|
||||
return true;
|
||||
if (original.call(screen, keyCode, scanCode, modifiers))
|
||||
if (original.call(screen, keyEvent))
|
||||
return true;
|
||||
result = ClientScreenInputEvent.KEY_PRESSED_POST.invoker().keyPressed(minecraft, screen, keyCode, scanCode, modifiers);
|
||||
result = ClientScreenInputEvent.KEY_PRESSED_POST.invoker().keyPressed(minecraft, screen, keyEvent);
|
||||
return result.isPresent();
|
||||
}
|
||||
|
||||
@WrapOperation(method = "keyPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;keyReleased(III)Z"))
|
||||
private boolean wrapKeyReleased(Screen screen, int keyCode, int scanCode, int modifiers, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.KEY_RELEASED_PRE.invoker().keyReleased(minecraft, screen, keyCode, scanCode, modifiers);
|
||||
@WrapOperation(method = "keyPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;keyReleased(Lnet/minecraft/client/input/KeyEvent;)Z"))
|
||||
private boolean wrapKeyReleased(Screen screen, KeyEvent keyEvent, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.KEY_RELEASED_PRE.invoker().keyReleased(minecraft, screen, keyEvent);
|
||||
if (result.isPresent())
|
||||
return true;
|
||||
if (original.call(screen, keyCode, scanCode, modifiers))
|
||||
if (original.call(screen, keyEvent))
|
||||
return true;
|
||||
result = ClientScreenInputEvent.KEY_RELEASED_POST.invoker().keyReleased(minecraft, screen, keyCode, scanCode, modifiers);
|
||||
result = ClientScreenInputEvent.KEY_RELEASED_POST.invoker().keyReleased(minecraft, screen, keyEvent);
|
||||
return result.isPresent();
|
||||
}
|
||||
|
||||
@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()) {
|
||||
var result = ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(minecraft, key, scanCode, action, modifiers);
|
||||
public void onRawKey(long handle, int key, KeyEvent keyEvent, CallbackInfo info) {
|
||||
if (handle == this.minecraft.getWindow().handle()) {
|
||||
var result = ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(minecraft, key, keyEvent);
|
||||
if (result.isPresent())
|
||||
info.cancel();
|
||||
}
|
||||
|
||||
@@ -27,13 +27,14 @@ import dev.architectury.event.events.client.ClientScreenInputEvent;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.MouseHandler;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.input.MouseButtonEvent;
|
||||
import net.minecraft.client.input.MouseButtonInfo;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(MouseHandler.class)
|
||||
public class MixinMouseHandler {
|
||||
@@ -41,15 +42,6 @@ public class MixinMouseHandler {
|
||||
@Final
|
||||
private Minecraft minecraft;
|
||||
|
||||
@Shadow
|
||||
private int activeButton;
|
||||
|
||||
@Shadow
|
||||
private double xpos;
|
||||
|
||||
@Shadow
|
||||
private double ypos;
|
||||
|
||||
@WrapOperation(method = "onScroll", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseScrolled(DDDD)Z", ordinal = 0))
|
||||
private boolean onGuiMouseClicked(Screen instance, double mouseX, double mouseY, double amountX, double amountY, Operation<Boolean> original) {
|
||||
var minecraft = Minecraft.getInstance();
|
||||
@@ -66,8 +58,8 @@ public class MixinMouseHandler {
|
||||
|
||||
@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, boolean discreteMouseScroll, double mouseWheelSensitivity, double amountX, double doubleY) {
|
||||
ordinal = 0), cancellable = true)
|
||||
public void onRawMouseScrolled(long handle, double xOffset, double yOffset, CallbackInfo info, @Local(ordinal = 3) double amountX, @Local(ordinal = 4) double doubleY) {
|
||||
if (!info.isCancelled()) {
|
||||
var result = ClientRawInputEvent.MOUSE_SCROLLED.invoker().mouseScrolled(minecraft, amountX, doubleY);
|
||||
if (result.isPresent())
|
||||
@@ -75,68 +67,62 @@ public class MixinMouseHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@WrapOperation(method = "onPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseClicked(DDI)Z", ordinal = 0))
|
||||
private boolean onGuiMouseClicked(Screen instance, double mouseX, double mouseY, int b, Operation<Boolean> original) {
|
||||
var minecraft = Minecraft.getInstance();
|
||||
var result = ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, minecraft.screen, mouseX, mouseY, b);
|
||||
@WrapOperation(method = "onButton", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseClicked(Lnet/minecraft/client/input/MouseButtonEvent;Z)Z"))
|
||||
private boolean wrapMouseClicked(Screen screen, MouseButtonEvent buttonEvent, boolean doubleClick, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, minecraft.screen, buttonEvent, doubleClick);
|
||||
if (result.isPresent()) {
|
||||
return true;
|
||||
}
|
||||
if (original.call(instance, mouseX, mouseY, b)) {
|
||||
if (original.call(screen, buttonEvent, doubleClick)) {
|
||||
return true;
|
||||
}
|
||||
result = ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(minecraft, minecraft.screen, mouseX, mouseY, b);
|
||||
result = ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(minecraft, minecraft.screen, buttonEvent, doubleClick);
|
||||
return result.isPresent();
|
||||
}
|
||||
|
||||
@Inject(method = "onPress", at = @At(value = "INVOKE",
|
||||
@Inject(method = "onButton", at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/Minecraft;getOverlay()Lnet/minecraft/client/gui/screens/Overlay;",
|
||||
ordinal = 0), cancellable = true)
|
||||
public void onRawMouseClicked(long handle, int button, int action, int mods, CallbackInfo info) {
|
||||
public void onRawMouseClicked(long handle, MouseButtonInfo buttonInfo, int action, CallbackInfo info) {
|
||||
if (!info.isCancelled()) {
|
||||
var result = ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, button, action, mods);
|
||||
var result = ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(minecraft, buttonInfo, action);
|
||||
if (result.isPresent())
|
||||
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()) {
|
||||
var result = ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(minecraft, button, action, mods);
|
||||
@Inject(method = "onButton", at = @At("RETURN"), cancellable = true)
|
||||
public void onRawMouseClickedPost(long handle, MouseButtonInfo buttonInfo, int action, CallbackInfo info) {
|
||||
if (handle == this.minecraft.getWindow().handle()) {
|
||||
var result = ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(minecraft, buttonInfo, action);
|
||||
if (result.isPresent())
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@WrapOperation(method = "onPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseReleased(DDI)Z", ordinal = 0))
|
||||
private boolean onGuiMouseReleased(Screen instance, double mouseX, double mouseY, int b, Operation<Boolean> original) {
|
||||
var minecraft = Minecraft.getInstance();
|
||||
var result = ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(minecraft, minecraft.screen, mouseX, mouseY, b);
|
||||
@WrapOperation(method = "onButton", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseReleased(Lnet/minecraft/client/input/MouseButtonEvent;)Z"))
|
||||
private boolean wrapMouseReleased(Screen screen, MouseButtonEvent buttonEvent, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(minecraft, minecraft.screen, buttonEvent);
|
||||
if (result.isPresent()) {
|
||||
return true;
|
||||
}
|
||||
if (original.call(instance, mouseX, mouseY, b)) {
|
||||
if (original.call(screen, buttonEvent)) {
|
||||
return true;
|
||||
}
|
||||
result = ClientScreenInputEvent.MOUSE_RELEASED_POST.invoker().mouseReleased(minecraft, minecraft.screen, mouseX, mouseY, b);
|
||||
result = ClientScreenInputEvent.MOUSE_RELEASED_POST.invoker().mouseReleased(minecraft, minecraft.screen, buttonEvent);
|
||||
return result.isPresent();
|
||||
}
|
||||
|
||||
@Inject(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseDragged(DDIDD)Z", ordinal = 0), cancellable = true)
|
||||
private void onGuiMouseDraggedPre(CallbackInfo ci, @Local(ordinal = 2) double mouseX, @Local(ordinal = 3) double mouseY, @Local(ordinal = 4) double deltaX, @Local(ordinal = 5) double deltaY) {
|
||||
if (ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), Minecraft.getInstance().screen, mouseX, mouseY, this.activeButton, deltaX, deltaY).isPresent()) {
|
||||
ci.cancel();
|
||||
@WrapOperation(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseDragged(Lnet/minecraft/client/input/MouseButtonEvent;DD)Z"))
|
||||
private boolean wrapMouseDragged(Screen screen, MouseButtonEvent event, double deltaX, double deltaY, Operation<Boolean> original) {
|
||||
var result = ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(minecraft, screen, event, deltaX, deltaY);
|
||||
if (result.isPresent()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnresolvedMixinReference", "DefaultAnnotationParam"})
|
||||
@WrapOperation(method = "handleAccumulatedMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseDragged(DDIDD)Z"))
|
||||
private boolean onGuiMouseDraggedPost(Screen screen, double mouseX, double mouseY, int button, double deltaX, double deltaY, Operation<Boolean> original) {
|
||||
if (original.call(screen, mouseX, mouseY, button, deltaX, deltaY)) {
|
||||
if (original.call(screen, event, deltaX, deltaY)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(Minecraft.getInstance(), screen, mouseX, mouseY, button, deltaX, deltaY).isPresent();
|
||||
return ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(Minecraft.getInstance(), screen, event, deltaX, deltaY).isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.networking.client.fabric;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.fabric.NetworkManagerImpl;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ClientNetworkManagerImpl {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static <T extends CustomPacketPayload> void registerS2C(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, NetworkManager.NetworkReceiver<T> receiver) {
|
||||
LOGGER.info("Registering S2C receiver with id {}", type.id());
|
||||
ClientPlayNetworking.registerGlobalReceiver(type, new ClientPlayPayloadHandler<>(receiver));
|
||||
}
|
||||
|
||||
// Lambda methods aren't included in @EnvType, so this inelegant solution is used instead.
|
||||
@Environment(EnvType.CLIENT)
|
||||
static class ClientPlayPayloadHandler<T extends CustomPacketPayload> implements ClientPlayNetworking.PlayPayloadHandler<T> {
|
||||
private final NetworkManager.NetworkReceiver<T> receiver;
|
||||
|
||||
ClientPlayPayloadHandler(NetworkManager.NetworkReceiver<T> receiver) {
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(T payload, ClientPlayNetworking.Context fabricContext) {
|
||||
var context = NetworkManagerImpl.context(fabricContext.player(), fabricContext.client(), true);
|
||||
receiver.receive(payload, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,17 @@ import dev.architectury.impl.NetworkAggregator;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.NetworkManager.NetworkReceiver;
|
||||
import dev.architectury.networking.SpawnEntityPacket;
|
||||
import dev.architectury.networking.client.fabric.ClientNetworkManagerImpl;
|
||||
import dev.architectury.networking.transformers.PacketSink;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.utils.Env;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
@@ -54,33 +59,16 @@ public class NetworkManagerImpl {
|
||||
LOGGER.info("Registering C2S receiver with id {}", type.id());
|
||||
PayloadTypeRegistry.playC2S().register(type, codec);
|
||||
ServerPlayNetworking.registerGlobalReceiver(type, (payload, fabricContext) -> {
|
||||
var context = context(fabricContext.player(), fabricContext.player().getServer(), false);
|
||||
var context = context(fabricContext.player(), fabricContext.server(), false);
|
||||
receiver.receive(payload, context);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public <T extends CustomPacketPayload> void registerS2C(CustomPacketPayload.Type<T> type, StreamCodec<? super RegistryFriendlyByteBuf, T> codec, NetworkReceiver<T> receiver) {
|
||||
LOGGER.info("Registering S2C receiver with id {}", type.id());
|
||||
PayloadTypeRegistry.playS2C().register(type, codec);
|
||||
ClientPlayNetworking.registerGlobalReceiver(type, new ClientPlayPayloadHandler<>(receiver));
|
||||
}
|
||||
|
||||
// Lambda methods aren't included in @EnvType, so this inelegant solution is used instead.
|
||||
@Environment(EnvType.CLIENT)
|
||||
class ClientPlayPayloadHandler<T extends CustomPacketPayload> implements ClientPlayNetworking.PlayPayloadHandler<T> {
|
||||
private final NetworkReceiver<T> receiver;
|
||||
|
||||
ClientPlayPayloadHandler(NetworkReceiver<T> receiver) {
|
||||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(T payload, ClientPlayNetworking.Context fabricContext) {
|
||||
var context = context(fabricContext.player(), fabricContext.client(), true);
|
||||
receiver.receive(payload, context);
|
||||
}
|
||||
if (Platform.getEnvironment() == Env.CLIENT)
|
||||
ClientNetworkManagerImpl.registerS2C(type, codec, receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -100,7 +88,7 @@ public class NetworkManagerImpl {
|
||||
};
|
||||
}
|
||||
|
||||
private static NetworkManager.PacketContext context(Player player, BlockableEventLoop<?> taskQueue, boolean client) {
|
||||
public static NetworkManager.PacketContext context(Player player, BlockableEventLoop<?> taskQueue, boolean client) {
|
||||
return new NetworkManager.PacketContext() {
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
@@ -133,6 +121,12 @@ public class NetworkManagerImpl {
|
||||
return ServerPlayNetworking.canSend(player, id);
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void sendToServer(T payload) {
|
||||
ClientPacketListener connection = Minecraft.getInstance().getConnection();
|
||||
if (connection == null) return;
|
||||
NetworkManager.collectPackets(PacketSink.client(), NetworkManager.clientToServer(), payload, connection.registryAccess());
|
||||
}
|
||||
|
||||
public static Packet<ClientGamePacketListener> createAddEntityPacket(Entity entity, ServerEntity serverEntity) {
|
||||
return SpawnEntityPacket.create(entity, serverEntity);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.platform.client.fabric;
|
||||
|
||||
import dev.architectury.platform.Mod;
|
||||
import dev.architectury.platform.client.ConfigurationScreenRegistry.ConfigurationScreenProvider;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ConfigurationScreenRegistryImpl {
|
||||
public static final Map<String, ConfigurationScreenProvider> CONFIG_SCREENS = new ConcurrentHashMap<>();
|
||||
|
||||
public static void register(Mod mod, ConfigurationScreenProvider provider) {
|
||||
if (CONFIG_SCREENS.containsKey(mod.getModId()))
|
||||
throw new IllegalStateException("Can not register configuration screen for mod '" + mod.getModId() + "' because it was already registered!");
|
||||
CONFIG_SCREENS.put(mod.getModId(), provider);
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PlatformImpl {
|
||||
public static final Map<String, Mod.ConfigurationScreenProvider> CONFIG_SCREENS = new ConcurrentHashMap<>();
|
||||
private static final Map<String, Mod> mods = new ConcurrentHashMap<>();
|
||||
|
||||
public static Path getGameFolder() {
|
||||
@@ -164,12 +163,5 @@ public class PlatformImpl {
|
||||
public Optional<String> getIssueTracker() {
|
||||
return metadata.getContact().get("sources");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerConfigurationScreen(ConfigurationScreenProvider provider) {
|
||||
if (CONFIG_SCREENS.containsKey(getModId()))
|
||||
throw new IllegalStateException("Can not register configuration screen for mod '" + getModId() + "' because it was already registered!");
|
||||
CONFIG_SCREENS.put(getModId(), provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.registry.client.gui.fabric;
|
||||
|
||||
import dev.architectury.registry.client.gui.MenuScreenRegistry.ScreenFactory;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
|
||||
public class MenuScreenRegistryImpl {
|
||||
public static <H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> void registerScreenFactory(MenuType<? extends H> type, ScreenFactory<H, S> factory) {
|
||||
MenuScreens.register(type, factory::create);
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@
|
||||
package dev.architectury.registry.client.particle.fabric;
|
||||
|
||||
import dev.architectury.registry.client.particle.ParticleProviderRegistry;
|
||||
//import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteProvider;
|
||||
//import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||
import net.fabricmc.fabric.api.client.particle.v1.FabricSpriteProvider;
|
||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
@@ -32,7 +32,7 @@ import net.minecraft.util.RandomSource;
|
||||
import java.util.List;
|
||||
|
||||
public class ParticleProviderRegistryImpl {
|
||||
/*public record ExtendedSpriteSetImpl(
|
||||
public record ExtendedSpriteSetImpl(
|
||||
FabricSpriteProvider delegate
|
||||
) implements ParticleProviderRegistry.ExtendedSpriteSet {
|
||||
@Override
|
||||
@@ -54,6 +54,11 @@ public class ParticleProviderRegistryImpl {
|
||||
public TextureAtlasSprite get(RandomSource random) {
|
||||
return delegate.get(random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite first() {
|
||||
return delegate.first();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
|
||||
@@ -63,5 +68,5 @@ public class ParticleProviderRegistryImpl {
|
||||
public static <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProviderRegistry.DeferredParticleProvider<T> provider) {
|
||||
ParticleFactoryRegistry.getInstance().register(type, sprites ->
|
||||
provider.create(new ExtendedSpriteSetImpl(sprites)));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,12 @@ package dev.architectury.registry.client.rendering.fabric;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public class BlockEntityRendererRegistryImpl {
|
||||
public static <T extends BlockEntity> void register(BlockEntityType<T> type, BlockEntityRendererProvider<? super T> provider) {
|
||||
public static <E extends BlockEntity, S extends BlockEntityRenderState> void register(BlockEntityType<E> type, BlockEntityRendererProvider<? super E, ? super S> provider) {
|
||||
BlockEntityRendererRegistry.register(type, provider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,7 @@ import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collection;
|
||||
@@ -59,8 +56,8 @@ public class ReloadListenerRegistryImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> reload(PreparationBarrier preparationBarrier, ResourceManager resourceManager, Executor executor, Executor executor2) {
|
||||
return listener.reload(preparationBarrier, resourceManager, executor, executor2);
|
||||
public CompletableFuture<Void> reload(SharedState sharedState, Executor executor, PreparationBarrier preparationBarrier, Executor executor2) {
|
||||
return listener.reload(sharedState, executor, preparationBarrier, executor2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,18 +21,12 @@ package dev.architectury.registry.menu.fabric;
|
||||
|
||||
import dev.architectury.registry.menu.ExtendedMenuProvider;
|
||||
import dev.architectury.registry.menu.MenuRegistry.ExtendedMenuTypeFactory;
|
||||
import dev.architectury.registry.menu.MenuRegistry.ScreenFactory;
|
||||
import dev.architectury.registry.menu.MenuRegistry.SimpleMenuTypeFactory;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
@@ -83,9 +77,4 @@ public class MenuRegistryImpl {
|
||||
return menu;
|
||||
}, ByteBufCodecs.BYTE_ARRAY.mapStream(Function.identity()));
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static <H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> void registerScreenFactory(MenuType<? extends H> type, ScreenFactory<H, S> factory) {
|
||||
MenuScreens.register(type, factory::create);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,23 @@ org.gradle.daemon=false
|
||||
|
||||
platforms=fabric,neoforge
|
||||
|
||||
minecraft_version=1.21.7
|
||||
supported_version=1.21.7/8
|
||||
minecraft_version=1.21.9
|
||||
supported_version=1.21.9
|
||||
|
||||
artifact_type=release
|
||||
|
||||
archives_base_name=architectury
|
||||
archives_base_name_snapshot=architectury-snapshot
|
||||
base_version=17.0
|
||||
base_version=18.0
|
||||
maven_group=dev.architectury
|
||||
version_suffix=
|
||||
|
||||
fabric_loader_version=0.16.14
|
||||
fabric_api_version=0.128.1+1.21.7
|
||||
fabric_loader_version=0.17.2
|
||||
fabric_api_version=0.133.14+1.21.9
|
||||
mod_menu_version=15.0.0-beta.1
|
||||
|
||||
forge_version=51.0.0
|
||||
neoforge_version=21.7.3-beta
|
||||
neoforge_version=21.9.2-beta
|
||||
|
||||
# Set to empty if not snapshots
|
||||
neoforge_pr=
|
||||
|
||||
@@ -121,7 +121,7 @@ unifiedPublishing {
|
||||
displayName = "[NeoForge $rootProject.supported_version] v$project.version"
|
||||
releaseType = "$rootProject.artifact_type"
|
||||
changelog = releaseChangelog()
|
||||
gameVersions = ["1.21.7", "1.21.8"]
|
||||
gameVersions = ["1.21.9"]
|
||||
gameLoaders = ["neoforge"]
|
||||
mainPublication renameJarForPublication
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ package dev.architectury.core.fluid.forge.imitator;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
|
||||
import dev.architectury.fluid.forge.ArchitecturyFluidAttributesClient;
|
||||
import dev.architectury.hooks.client.forge.ClientExtensionsRegistryImpl;
|
||||
import dev.architectury.hooks.fluid.forge.FluidStackHooksForge;
|
||||
import dev.architectury.platform.Platform;
|
||||
@@ -64,7 +65,7 @@ class ArchitecturyFluidAttributesForge extends FluidType {
|
||||
this.attributes = attributes;
|
||||
this.defaultTranslationKey = Util.makeDescriptionId("fluid", BuiltInRegistries.FLUID.getKey(fluid));
|
||||
if (Platform.getEnvironment() == Env.CLIENT) {
|
||||
this.registerClient();
|
||||
ArchitecturyFluidAttributesClient.registerClient(this, () -> this.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,93 +85,7 @@ class ArchitecturyFluidAttributesForge extends FluidType {
|
||||
return item == null ? super.getBucket(stack) : new ItemStack(item);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void registerClient() {
|
||||
ClientExtensionsRegistryImpl.register(event -> {
|
||||
if (event != null) {
|
||||
event.registerFluidType(initializeClient(), this);
|
||||
} else {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("net.neoforged.neoforge.client.extensions.common.ClientExtensionsManager");
|
||||
Field field = clazz.getDeclaredField("FLUID_TYPE_EXTENSIONS");
|
||||
field.setAccessible(true);
|
||||
Method method = clazz.getDeclaredMethod("register", Object.class, Map.class, Object[].class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(null, initializeClient(), (Map<?, ?>) field.get(null), new Object[]{this});
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public IClientFluidTypeExtensions initializeClient() {
|
||||
return new IClientFluidTypeExtensions() {
|
||||
@Override
|
||||
public int getTintColor() {
|
||||
return attributes.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture() {
|
||||
return attributes.getSourceTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture() {
|
||||
return attributes.getFlowingTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getOverlayTexture() {
|
||||
return attributes.getOverlayTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getSourceTexture(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getFlowingTexture(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getOverlayTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getOverlayTexture(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getColor(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTintColor(FluidStack stack) {
|
||||
return attributes.getColor(convertSafe(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture(FluidStack stack) {
|
||||
return attributes.getSourceTexture(convertSafe(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture(FluidStack stack) {
|
||||
return attributes.getFlowingTexture(convertSafe(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getOverlayTexture(FluidStack stack) {
|
||||
return attributes.getOverlayTexture(convertSafe(stack));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightLevel(FluidStack stack) {
|
||||
|
||||
@@ -27,7 +27,7 @@ import net.minecraft.world.item.BucketItem;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.neoforged.neoforge.fluids.capability.wrappers.FluidBucketWrapper;
|
||||
import net.neoforged.neoforge.transfer.fluid.BucketResourceHandler;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ArchitecturyBucketItem extends BucketItem {
|
||||
EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
bus.<RegisterCapabilitiesEvent>addListener(event -> {
|
||||
if (BuiltInRegistries.ITEM.containsValue(this)) {
|
||||
event.registerItem(Capabilities.FluidHandler.ITEM, (stack, ctx) -> new FluidBucketWrapper(stack), this);
|
||||
event.registerItem(Capabilities.Fluid.ITEM, (stack, access) -> new BucketResourceHandler(access), this);
|
||||
} else {
|
||||
LOGGER.warn("Tried to register a bucket item capability for an item that is not registered: {}", this);
|
||||
}
|
||||
|
||||
@@ -21,17 +21,10 @@ package dev.architectury.event.forge;
|
||||
|
||||
import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
|
||||
public class EventHandlerImpl {
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void registerClient() {
|
||||
NeoForge.EVENT_BUS.register(EventHandlerImplClient.class);
|
||||
EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
bus.register(EventHandlerImplClient.ModBasedEventHandler.class);
|
||||
});
|
||||
}
|
||||
|
||||
public static void registerCommon() {
|
||||
@@ -41,11 +34,6 @@ public class EventHandlerImpl {
|
||||
});
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.DEDICATED_SERVER)
|
||||
public static void registerServer() {
|
||||
// MinecraftForge.EVENT_BUS.register(EventHandlerImplServer.class);
|
||||
// EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
// bus.register(EventHandlerImplServer.ModBasedEventHandler.class);
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ package dev.architectury.event.forge;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import dev.architectury.event.CompoundEventResult;
|
||||
import dev.architectury.event.EventResult;
|
||||
import dev.architectury.event.events.client.ClientChatEvent;
|
||||
import dev.architectury.event.events.client.*;
|
||||
import dev.architectury.event.events.client.ClientChatEvent;
|
||||
import dev.architectury.event.events.common.InteractionEvent;
|
||||
import dev.architectury.impl.ScreenAccessImpl;
|
||||
import dev.architectury.impl.TooltipEventPositionContextImpl;
|
||||
@@ -33,17 +33,17 @@ import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
import net.neoforged.neoforge.client.event.*;
|
||||
import net.neoforged.neoforge.client.event.ClientTickEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.ItemTooltipEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.neoforged.neoforge.event.level.LevelEvent;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@EventBusSubscriber(modid = "architectury", value = Dist.CLIENT)
|
||||
public class EventHandlerImplClient {
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void event(ItemTooltipEvent event) {
|
||||
@@ -140,14 +140,14 @@ public class EventHandlerImplClient {
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventDrawScreenEvent(ScreenEvent.Render.Pre event) {
|
||||
if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaTracker()).isFalse()) {
|
||||
if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventDrawScreenEvent(ScreenEvent.Render.Post event) {
|
||||
ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaTracker());
|
||||
ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getGuiGraphics(), event.getMouseX(), event.getMouseY(), event.getPartialTick());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
@@ -207,74 +207,74 @@ public class EventHandlerImplClient {
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventMouseClickedEvent(ScreenEvent.MouseButtonPressed.Pre event) {
|
||||
if (ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton()).isFalse()) {
|
||||
if (ClientScreenInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent(), event.isDoubleClick()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventMouseClickedEvent(ScreenEvent.MouseButtonPressed.Post event) {
|
||||
ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton());
|
||||
ClientScreenInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent(), event.isDoubleClick());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventMouseDragEvent(ScreenEvent.MouseDragged.Pre event) {
|
||||
if (ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getMouseButton(), event.getDragX(), event.getDragY()).isFalse()) {
|
||||
if (ClientScreenInputEvent.MOUSE_DRAGGED_PRE.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent(), event.getDragX(), event.getDragY()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventMouseDragEvent(ScreenEvent.MouseDragged.Post event) {
|
||||
ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getMouseButton(), event.getDragX(), event.getDragY());
|
||||
ClientScreenInputEvent.MOUSE_DRAGGED_POST.invoker().mouseDragged(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent(), event.getDragX(), event.getDragY());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Pre event) {
|
||||
if (ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton()).isFalse()) {
|
||||
if (ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventMouseReleasedEvent(ScreenEvent.MouseButtonReleased.Post event) {
|
||||
ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseX(), event.getMouseY(), event.getButton());
|
||||
ClientScreenInputEvent.MOUSE_RELEASED_PRE.invoker().mouseReleased(Minecraft.getInstance(), event.getScreen(), event.getMouseButtonEvent());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventKeyboardCharTypedEvent(ScreenEvent.CharacterTyped.Pre event) {
|
||||
if (ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getCodePoint(), event.getModifiers()).isFalse()) {
|
||||
if (ClientScreenInputEvent.CHAR_TYPED_PRE.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getCharacterEvent()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventKeyboardCharTypedEvent(ScreenEvent.CharacterTyped.Post event) {
|
||||
ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getCodePoint(), event.getModifiers());
|
||||
ClientScreenInputEvent.CHAR_TYPED_POST.invoker().charTyped(Minecraft.getInstance(), event.getScreen(), event.getCharacterEvent());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventKeyboardKeyPressedEvent(ScreenEvent.KeyPressed.Pre event) {
|
||||
if (ClientScreenInputEvent.KEY_PRESSED_PRE.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers()).isFalse()) {
|
||||
if (ClientScreenInputEvent.KEY_PRESSED_PRE.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getKeyEvent()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventKeyboardKeyPressedEvent(ScreenEvent.KeyPressed.Post event) {
|
||||
ClientScreenInputEvent.KEY_PRESSED_POST.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers());
|
||||
ClientScreenInputEvent.KEY_PRESSED_POST.invoker().keyPressed(Minecraft.getInstance(), event.getScreen(), event.getKeyEvent());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventKeyboardKeyReleasedEvent(ScreenEvent.KeyReleased.Pre event) {
|
||||
if (ClientScreenInputEvent.KEY_RELEASED_PRE.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers()).isFalse()) {
|
||||
if (ClientScreenInputEvent.KEY_RELEASED_PRE.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getKeyEvent()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventKeyboardKeyReleasedEvent(ScreenEvent.KeyReleased.Post event) {
|
||||
ClientScreenInputEvent.KEY_RELEASED_POST.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getKeyCode(), event.getScanCode(), event.getModifiers());
|
||||
ClientScreenInputEvent.KEY_RELEASED_POST.invoker().keyReleased(Minecraft.getInstance(), event.getScreen(), event.getKeyEvent());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
@@ -286,19 +286,19 @@ public class EventHandlerImplClient {
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventInputEvent(InputEvent.MouseButton.Pre event) {
|
||||
if (ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getButton(), event.getAction(), event.getModifiers()).isFalse()) {
|
||||
if (ClientRawInputEvent.MOUSE_CLICKED_PRE.invoker().mouseClicked(Minecraft.getInstance(), event.getMouseButtonInfo(), event.getAction()).isFalse()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventInputEvent(InputEvent.MouseButton.Post event) {
|
||||
ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getButton(), event.getAction(), event.getModifiers());
|
||||
ClientRawInputEvent.MOUSE_CLICKED_POST.invoker().mouseClicked(Minecraft.getInstance(), event.getMouseButtonInfo(), event.getAction());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
public static void eventInputEvent(InputEvent.Key event) {
|
||||
ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(Minecraft.getInstance(), event.getKey(), event.getScanCode(), event.getAction(), event.getModifiers());
|
||||
ClientRawInputEvent.KEY_PRESSED.invoker().keyPressed(Minecraft.getInstance(), event.getKey(), event.getKeyEvent());
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
@@ -307,7 +307,7 @@ public class EventHandlerImplClient {
|
||||
(CommandDispatcher<?>) event.getDispatcher(), event.getBuildContext());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@EventBusSubscriber(modid = "architectury", value = Dist.CLIENT)
|
||||
public static class ModBasedEventHandler {
|
||||
// @SubscribeEvent(priority = EventPriority.HIGH)
|
||||
// public static void eventTextureStitchEvent(TextureStitchEvent.Post event) {
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
package dev.architectury.event.forge;
|
||||
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
|
||||
@OnlyIn(Dist.DEDICATED_SERVER)
|
||||
@EventBusSubscriber(modid = "architectury", value = Dist.DEDICATED_SERVER)
|
||||
public class EventHandlerImplServer {
|
||||
@OnlyIn(Dist.DEDICATED_SERVER)
|
||||
@EventBusSubscriber(modid = "architectury", value = Dist.DEDICATED_SERVER)
|
||||
public static class ModBasedEventHandler {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.fluid.forge;
|
||||
|
||||
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
|
||||
import dev.architectury.hooks.client.forge.ClientExtensionsRegistryImpl;
|
||||
import dev.architectury.hooks.fluid.forge.FluidStackHooksForge;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.FluidType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ArchitecturyFluidAttributesClient {
|
||||
public static void registerClient(FluidType fluid, Supplier<ArchitecturyFluidAttributes> attributes) {
|
||||
ClientExtensionsRegistryImpl.register(event -> {
|
||||
if (event != null) {
|
||||
event.registerFluidType(initializeClient(attributes.get()), fluid);
|
||||
} else {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("net.neoforged.neoforge.client.extensions.common.ClientExtensionsManager");
|
||||
Field field = clazz.getDeclaredField("FLUID_TYPE_EXTENSIONS");
|
||||
field.setAccessible(true);
|
||||
Method method = clazz.getDeclaredMethod("register", Object.class, Map.class, Object[].class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(null, initializeClient(attributes.get()), (Map<?, ?>) field.get(null), new Object[]{fluid});
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static IClientFluidTypeExtensions initializeClient(ArchitecturyFluidAttributes attributes) {
|
||||
return new IClientFluidTypeExtensions() {
|
||||
@Override
|
||||
public int getTintColor() {
|
||||
return attributes.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture() {
|
||||
return attributes.getSourceTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture() {
|
||||
return attributes.getFlowingTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getOverlayTexture() {
|
||||
return attributes.getOverlayTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getSourceTexture(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getFlowingTexture(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getOverlayTexture(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getOverlayTexture(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
|
||||
return attributes.getColor(state, getter, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTintColor(FluidStack stack) {
|
||||
return attributes.getColor(convertSafe(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStillTexture(FluidStack stack) {
|
||||
return attributes.getSourceTexture(convertSafe(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getFlowingTexture(FluidStack stack) {
|
||||
return attributes.getFlowingTexture(convertSafe(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ResourceLocation getOverlayTexture(FluidStack stack) {
|
||||
return attributes.getOverlayTexture(convertSafe(stack));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidStack stack) {
|
||||
return stack == null ? null : FluidStackHooksForge.fromForge(stack);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static dev.architectury.fluid.FluidStack convertSafe(@Nullable FluidState state) {
|
||||
return state == null ? null : dev.architectury.fluid.FluidStack.create(state.getType(), dev.architectury.fluid.FluidStack.bucketAmount());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.hooks.client.fluid.forge;
|
||||
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import dev.architectury.hooks.fluid.forge.FluidStackHooksForge;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.core.BlockPos;
|
||||
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 net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ClientFluidStackHooksImpl {
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(state).getStillTexture(state, level, pos);
|
||||
return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
|
||||
if (stack.getFluid() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(stack.getFluid()).getStillTexture(FluidStackHooksForge.toForge(stack));
|
||||
return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(fluid).getStillTexture();
|
||||
return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(state).getFlowingTexture(state, level, pos);
|
||||
return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
|
||||
if (stack.getFluid() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(stack.getFluid()).getFlowingTexture(FluidStackHooksForge.toForge(stack));
|
||||
return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(fluid).getFlowingTexture();
|
||||
return Minecraft.getInstance().getAtlasManager().get(new Material(TextureAtlas.LOCATION_BLOCKS, texture));
|
||||
}
|
||||
|
||||
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return -1;
|
||||
return IClientFluidTypeExtensions.of(state).getTintColor(state, level, pos);
|
||||
}
|
||||
|
||||
public static int getColor(FluidStack stack) {
|
||||
if (stack.getFluid() == Fluids.EMPTY) return -1;
|
||||
return IClientFluidTypeExtensions.of(stack.getFluid()).getTintColor(FluidStackHooksForge.toForge(stack));
|
||||
}
|
||||
|
||||
public static int getColor(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return -1;
|
||||
return IClientFluidTypeExtensions.of(fluid).getTintColor();
|
||||
}
|
||||
}
|
||||
@@ -21,26 +21,15 @@ package dev.architectury.hooks.fluid.forge;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import dev.architectury.fluid.FluidStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -82,72 +71,6 @@ public class FluidStackHooksImpl {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(state).getStillTexture(state, level, pos);
|
||||
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(FluidStack stack) {
|
||||
if (stack.getFluid() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(stack.getFluid()).getStillTexture(FluidStackHooksForge.toForge(stack));
|
||||
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getStillTexture(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(fluid).getStillTexture();
|
||||
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(state).getFlowingTexture(state, level, pos);
|
||||
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(FluidStack stack) {
|
||||
if (stack.getFluid() == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(stack.getFluid()).getFlowingTexture(FluidStackHooksForge.toForge(stack));
|
||||
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Nullable
|
||||
public static TextureAtlasSprite getFlowingTexture(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return null;
|
||||
ResourceLocation texture = IClientFluidTypeExtensions.of(fluid).getFlowingTexture();
|
||||
return Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static int getColor(@Nullable BlockAndTintGetter level, @Nullable BlockPos pos, FluidState state) {
|
||||
if (state.getType() == Fluids.EMPTY) return -1;
|
||||
return IClientFluidTypeExtensions.of(state).getTintColor(state, level, pos);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static int getColor(FluidStack stack) {
|
||||
if (stack.getFluid() == Fluids.EMPTY) return -1;
|
||||
return IClientFluidTypeExtensions.of(stack.getFluid()).getTintColor(FluidStackHooksForge.toForge(stack));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static int getColor(Fluid fluid) {
|
||||
if (fluid == Fluids.EMPTY) return -1;
|
||||
return IClientFluidTypeExtensions.of(fluid).getTintColor();
|
||||
}
|
||||
|
||||
public static int getLuminosity(FluidStack fluid, @Nullable Level level, @Nullable BlockPos pos) {
|
||||
return fluid.getFluid().getFluidType().getLightLevel(FluidStackHooksForge.toForge(fluid));
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
package dev.architectury.neoforge;
|
||||
|
||||
import dev.architectury.event.EventHandler;
|
||||
import dev.architectury.networking.ClientSpawnEntityPacket;
|
||||
import dev.architectury.networking.SpawnEntityPacket;
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.registry.level.biome.forge.BiomeModificationsImpl;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import dev.architectury.utils.Env;
|
||||
import dev.architectury.utils.EnvExecutor;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@Mod(ArchitecturyConstants.MOD_ID)
|
||||
@@ -33,7 +34,10 @@ public class ArchitecturyNeoForge {
|
||||
EventHandler.init();
|
||||
BiomeModificationsImpl.init();
|
||||
|
||||
EnvExecutor.runInEnv(Env.CLIENT, () -> SpawnEntityPacket.Client::register);
|
||||
EnvExecutor.runInEnv(Env.SERVER, () -> SpawnEntityPacket::register);
|
||||
if (Platform.getEnvironment() == Env.CLIENT) {
|
||||
ClientSpawnEntityPacket.register();
|
||||
} else {
|
||||
SpawnEntityPacket.register();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ import dev.architectury.impl.NetworkAggregator;
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.NetworkManager.NetworkReceiver;
|
||||
import dev.architectury.networking.SpawnEntityPacket;
|
||||
import dev.architectury.networking.forge.client.ClientNetworkManagerImpl;
|
||||
import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import dev.architectury.utils.Env;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
@@ -42,8 +42,6 @@ import net.minecraft.server.level.ServerEntity;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import org.slf4j.Logger;
|
||||
@@ -120,19 +118,18 @@ public class NetworkManagerImpl {
|
||||
};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static boolean canServerReceive(ResourceLocation id) {
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
return Minecraft.getInstance().getConnection().hasChannel(id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return ClientNetworkManagerImpl.canServerReceive(id);
|
||||
}
|
||||
|
||||
public static boolean canPlayerReceive(ServerPlayer player, ResourceLocation id) {
|
||||
return player.connection.hasChannel(id);
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void sendToServer(T payload) {
|
||||
ClientNetworkManagerImpl.sendToServer(payload);
|
||||
}
|
||||
|
||||
public static Packet<ClientGamePacketListener> createAddEntityPacket(Entity entity, ServerEntity serverEntity) {
|
||||
return SpawnEntityPacket.create(entity, serverEntity);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,32 @@
|
||||
/*
|
||||
* 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.networking.forge.client;
|
||||
|
||||
import dev.architectury.networking.NetworkManager;
|
||||
import dev.architectury.networking.transformers.PacketSink;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
public class ClientNetworkManagerImpl {
|
||||
@@ -23,4 +47,18 @@ public class ClientNetworkManagerImpl {
|
||||
// Fail-safe
|
||||
return RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY);
|
||||
}
|
||||
|
||||
public static boolean canServerReceive(ResourceLocation id) {
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
return Minecraft.getInstance().getConnection().hasChannel(id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends CustomPacketPayload> void sendToServer(T payload) {
|
||||
ClientPacketListener connection = Minecraft.getInstance().getConnection();
|
||||
if (connection == null) return;
|
||||
NetworkManager.collectPackets(PacketSink.client(), NetworkManager.clientToServer(), payload, connection.registryAccess());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.platform.client.forge;
|
||||
|
||||
import dev.architectury.platform.Mod;
|
||||
import dev.architectury.platform.client.ConfigurationScreenRegistry;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||
|
||||
public class ConfigurationScreenRegistryImpl {
|
||||
public static void register(Mod mod, ConfigurationScreenRegistry.ConfigurationScreenProvider provider) {
|
||||
ModList.get().getModContainerById(mod.getModId())
|
||||
.orElseThrow()
|
||||
.registerExtensionPoint(IConfigScreenFactory.class, (container, screen) -> provider.provide(screen));
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,8 @@ import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.fml.ModContainer;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.fml.loading.FMLLoader;
|
||||
import net.neoforged.fml.loading.FMLPaths;
|
||||
import net.neoforged.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
|
||||
import net.neoforged.neoforgespi.language.IModFileInfo;
|
||||
import net.neoforged.neoforgespi.language.IModInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -61,7 +59,7 @@ public class PlatformImpl {
|
||||
}
|
||||
|
||||
public static Dist getEnv() {
|
||||
return FMLEnvironment.dist;
|
||||
return FMLEnvironment.getDist();
|
||||
}
|
||||
|
||||
public static boolean isModLoaded(String id) {
|
||||
@@ -84,7 +82,7 @@ public class PlatformImpl {
|
||||
}
|
||||
|
||||
public static boolean isDevelopmentEnvironment() {
|
||||
return !FMLLoader.isProduction();
|
||||
return !FMLEnvironment.isProduction();
|
||||
}
|
||||
|
||||
private static class ModImpl implements Mod {
|
||||
@@ -135,12 +133,12 @@ public class PlatformImpl {
|
||||
|
||||
@Override
|
||||
public Path getFilePath() {
|
||||
return this.info.getOwningFile().getFile().getSecureJar().getRootPath();
|
||||
return this.info.getOwningFile().getFile().getFilePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Path> findResource(String... path) {
|
||||
return Optional.of(this.info.getOwningFile().getFile().findResource(path)).filter(Files::exists);
|
||||
return Optional.of(this.getFilePath().resolve(String.join("/", path))).filter(Files::exists);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,10 +173,5 @@ public class PlatformImpl {
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerConfigurationScreen(ConfigurationScreenProvider configurationScreenProvider) {
|
||||
container.registerExtensionPoint(IConfigScreenFactory.class, (container, screen) -> configurationScreenProvider.provide(screen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.registry.client.forge;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.client.event.AddClientReloadListenersEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@EventBusSubscriber(modid = "architectury", value = Dist.CLIENT)
|
||||
public class ClientReloadListenerRegistryImpl {
|
||||
private static Map<ResourceLocation, PreparableReloadListener> clientDataReloadListeners = new HashMap<>();
|
||||
private static Map<ResourceLocation, Collection<ResourceLocation>> clientDataReloadListenerDependencies = new HashMap<>();
|
||||
|
||||
public static void register(PreparableReloadListener listener, ResourceLocation listenerId, Collection<ResourceLocation> dependencies) {
|
||||
clientDataReloadListeners.put(listenerId, listener);
|
||||
clientDataReloadListenerDependencies.put(listenerId, dependencies);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void addClientReloadListeners(AddClientReloadListenersEvent event) {
|
||||
clientDataReloadListeners.forEach(event::addListener);
|
||||
clientDataReloadListenerDependencies.forEach((listener, dependencies) -> dependencies.forEach(dependency -> event.addDependency(listener, dependency)));
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,6 @@ import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
|
||||
import net.minecraft.world.inventory.tooltip.TooltipComponent;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -34,7 +32,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@ApiStatus.Internal
|
||||
public class ClientTooltipComponentRegistryImpl {
|
||||
@Nullable
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.registry.client.gui.forge;
|
||||
|
||||
import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.registry.client.gui.MenuScreenRegistry.ScreenFactory;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
|
||||
|
||||
public class MenuScreenRegistryImpl {
|
||||
public static <H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> void registerScreenFactory(MenuType<? extends H> type, ScreenFactory<H, S> factory) {
|
||||
EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
bus.addListener(RegisterMenuScreensEvent.class, event -> event.register(type, factory::create));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -24,13 +24,13 @@ import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.registry.client.particle.ParticleProviderRegistry;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.ParticleEngine;
|
||||
import net.minecraft.client.particle.ParticleProvider;
|
||||
import net.minecraft.client.particle.SpriteSet;
|
||||
import net.minecraft.client.particle.ParticleResources;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.data.AtlasIds;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent;
|
||||
import org.slf4j.Logger;
|
||||
@@ -48,33 +48,30 @@ public class ParticleProviderRegistryImpl {
|
||||
});
|
||||
}
|
||||
|
||||
private static final class ExtendedSpriteSetImpl implements ParticleProviderRegistry.ExtendedSpriteSet {
|
||||
private final ParticleEngine engine;
|
||||
private final SpriteSet delegate;
|
||||
|
||||
private ExtendedSpriteSetImpl(ParticleEngine engine, SpriteSet delegate) {
|
||||
this.engine = engine;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
private record ExtendedSpriteSetImpl(ParticleResources.MutableSpriteSet set) implements ParticleProviderRegistry.ExtendedSpriteSet {
|
||||
@Override
|
||||
public TextureAtlas getAtlas() {
|
||||
return engine.textureAtlas;
|
||||
return Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(AtlasIds.PARTICLES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TextureAtlasSprite> getSprites() {
|
||||
return ((ParticleEngine.MutableSpriteSet) delegate).sprites;
|
||||
return set.sprites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite get(int i, int j) {
|
||||
return delegate.get(i, j);
|
||||
return set.get(i, j);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite get(RandomSource random) {
|
||||
return delegate.get(random);
|
||||
return set.get(random);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite first() {
|
||||
return set.first();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +83,7 @@ public class ParticleProviderRegistryImpl {
|
||||
|
||||
private static <T extends ParticleOptions> void doRegister(ParticleProviderRegistrar registrar, ParticleType<T> type, ParticleProviderRegistry.DeferredParticleProvider<T> provider) {
|
||||
registrar.register(type, sprites ->
|
||||
provider.create(new ExtendedSpriteSetImpl(Minecraft.getInstance().particleEngine, sprites)));
|
||||
provider.create(new ExtendedSpriteSetImpl((ParticleResources.MutableSpriteSet) sprites)));
|
||||
}
|
||||
|
||||
public static <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
|
||||
@@ -122,7 +119,7 @@ public class ParticleProviderRegistryImpl {
|
||||
private interface ParticleProviderRegistrar {
|
||||
<T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider);
|
||||
|
||||
<T extends ParticleOptions> void register(ParticleType<T> type, ParticleEngine.SpriteParticleRegistration<T> registration);
|
||||
<T extends ParticleOptions> void register(ParticleType<T> type, ParticleResources.SpriteParticleRegistration<T> registration);
|
||||
|
||||
static ParticleProviderRegistrar ofForge(RegisterParticleProvidersEvent event) {
|
||||
return new ParticleProviderRegistrar() {
|
||||
@@ -132,7 +129,7 @@ public class ParticleProviderRegistryImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleEngine.SpriteParticleRegistration<T> registration) {
|
||||
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleResources.SpriteParticleRegistration<T> registration) {
|
||||
event.registerSpriteSet(type, registration);
|
||||
}
|
||||
};
|
||||
@@ -142,12 +139,12 @@ public class ParticleProviderRegistryImpl {
|
||||
return new ParticleProviderRegistrar() {
|
||||
@Override
|
||||
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
|
||||
Minecraft.getInstance().particleEngine.register(type, provider);
|
||||
Minecraft.getInstance().particleResources.register(type, provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleEngine.SpriteParticleRegistration<T> registration) {
|
||||
Minecraft.getInstance().particleEngine.register(type, registration);
|
||||
public <T extends ParticleOptions> void register(ParticleType<T> type, ParticleResources.SpriteParticleRegistration<T> registration) {
|
||||
Minecraft.getInstance().particleResources.register(type, registration);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,11 +21,12 @@ package dev.architectury.registry.client.rendering.forge;
|
||||
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public class BlockEntityRendererRegistryImpl {
|
||||
public static <T extends BlockEntity> void register(BlockEntityType<T> type, BlockEntityRendererProvider<? super T> provider) {
|
||||
public static <E extends BlockEntity, S extends BlockEntityRenderState> void register(BlockEntityType<E> type, BlockEntityRendererProvider<? super E, ? super S> provider) {
|
||||
BlockEntityRenderers.register(type, provider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,20 +19,10 @@
|
||||
|
||||
package dev.architectury.registry.forge;
|
||||
|
||||
import dev.architectury.platform.Platform;
|
||||
import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import dev.architectury.utils.Env;
|
||||
import dev.architectury.utils.EnvExecutor;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import dev.architectury.registry.client.forge.ClientReloadListenerRegistryImpl;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.client.event.AddClientReloadListenersEvent;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.event.AddServerReloadListenersEvent;
|
||||
|
||||
@@ -41,19 +31,10 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ReloadListenerRegistryImpl {
|
||||
private static Map<ResourceLocation, PreparableReloadListener> clientDataReloadListeners = new HashMap<>();
|
||||
private static Map<ResourceLocation, Collection<ResourceLocation>> clientDataReloadListenerDependencies = new HashMap<>();
|
||||
|
||||
private static Map<ResourceLocation, PreparableReloadListener> serverDataReloadListeners = new HashMap<>();
|
||||
private static Map<ResourceLocation, Collection<ResourceLocation>> serverDataReloadListenerDependencies = new HashMap<>();
|
||||
|
||||
static {
|
||||
EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
if(Platform.getEnvironment() == Env.CLIENT) {
|
||||
bus.addListener(ReloadListenerRegistryImpl::addClientReloadListeners);
|
||||
}
|
||||
});
|
||||
|
||||
NeoForge.EVENT_BUS.addListener(ReloadListenerRegistryImpl::addServerReloadListeners);
|
||||
}
|
||||
|
||||
@@ -62,17 +43,10 @@ public class ReloadListenerRegistryImpl {
|
||||
serverDataReloadListeners.put(listenerId, listener);
|
||||
serverDataReloadListenerDependencies.put(listenerId, dependencies);
|
||||
} else if (type == PackType.CLIENT_RESOURCES) {
|
||||
clientDataReloadListeners.put(listenerId, listener);
|
||||
clientDataReloadListenerDependencies.put(listenerId, dependencies);
|
||||
ClientReloadListenerRegistryImpl.register(listener, listenerId, dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static void addClientReloadListeners(AddClientReloadListenersEvent event) {
|
||||
clientDataReloadListeners.forEach(event::addListener);
|
||||
clientDataReloadListenerDependencies.forEach((listener, dependencies) -> dependencies.forEach(dependency -> event.addDependency(listener, dependency)));
|
||||
}
|
||||
|
||||
public static void addServerReloadListeners(AddServerReloadListenersEvent event) {
|
||||
serverDataReloadListeners.forEach(event::addListener);
|
||||
serverDataReloadListenerDependencies.forEach((listener, dependencies) -> dependencies.forEach(dependency -> event.addDependency(listener, dependency)));
|
||||
|
||||
@@ -19,23 +19,13 @@
|
||||
|
||||
package dev.architectury.registry.menu.forge;
|
||||
|
||||
import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.registry.menu.ExtendedMenuProvider;
|
||||
import dev.architectury.registry.menu.MenuRegistry.ExtendedMenuTypeFactory;
|
||||
import dev.architectury.registry.menu.MenuRegistry.ScreenFactory;
|
||||
import dev.architectury.registry.menu.MenuRegistry.SimpleMenuTypeFactory;
|
||||
import dev.architectury.utils.ArchitecturyConstants;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.flag.FeatureFlags;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.MenuType;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
|
||||
|
||||
public class MenuRegistryImpl {
|
||||
@@ -51,12 +41,4 @@ public class MenuRegistryImpl {
|
||||
public static <T extends AbstractContainerMenu> MenuType<T> ofExtended(ExtendedMenuTypeFactory<T> factory) {
|
||||
return IMenuTypeExtension.create(factory::create);
|
||||
}
|
||||
|
||||
@SuppressWarnings("CodeBlock2Expr") // It's neater this way
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static <H extends AbstractContainerMenu, S extends Screen & MenuAccess<H>> void registerScreenFactory(MenuType<? extends H> type, ScreenFactory<H, S> factory) {
|
||||
EventBusesHooks.whenAvailable(ArchitecturyConstants.MOD_ID, bus -> {
|
||||
bus.addListener(RegisterMenuScreensEvent.class, event -> event.register(type, factory::create));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
})));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
})));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user