mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Merge remote-tracking branch 'architectury/1.16' into 1.17
# Conflicts: # fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinBlockEntityExtension.java # fabric/src/main/resources/architectury.mixins.json # gradle.properties
This commit is contained in:
@@ -20,26 +20,16 @@ task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
task javadocs(type: Javadoc) {
|
||||
source = sourceSets.main.allJava
|
||||
}
|
||||
|
||||
task javadocsJar(type: Jar, dependsOn: javadocs) {
|
||||
archiveClassifier.set("javadocs")
|
||||
javadocs.failOnError false
|
||||
from javadocs.destinationDir
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenCommon(MavenPublication) {
|
||||
artifactId = rootProject.archivesBaseName
|
||||
artifact(file("${project.buildDir}/libs/${project.archivesBaseName}-${project.version}.jar")) {
|
||||
builtBy build
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
artifact javadocsJar
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
package me.shedaniel.architectury;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -30,5 +32,6 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
public @interface ExpectPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class EventFactory {
|
||||
@Override
|
||||
protected Object handleInvocation(@NotNull Object proxy, @NotNull Method method, Object @NotNull [] args) throws Throwable {
|
||||
for (T listener : listeners) {
|
||||
InteractionResult result = (InteractionResult) method.invoke(listener, args);
|
||||
InteractionResult result = (InteractionResult) Objects.requireNonNull(method.invoke(listener, args));
|
||||
if (result != InteractionResult.PASS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
package me.shedaniel.architectury.event;
|
||||
|
||||
import me.shedaniel.architectury.annotations.ExpectPlatform;
|
||||
import me.shedaniel.architectury.event.events.BlockEvent;
|
||||
import me.shedaniel.architectury.event.events.EntityEvent;
|
||||
import me.shedaniel.architectury.event.events.PlayerEvent;
|
||||
import me.shedaniel.architectury.platform.Platform;
|
||||
import me.shedaniel.architectury.utils.Env;
|
||||
import net.fabricmc.api.EnvType;
|
||||
@@ -38,6 +41,8 @@ public final class EventHandler {
|
||||
registerCommon();
|
||||
if (Platform.getEnvironment() == Env.SERVER)
|
||||
registerServer();
|
||||
|
||||
registerDelegates();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
@@ -56,4 +61,10 @@ public final class EventHandler {
|
||||
private static void registerServer() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void registerDelegates() {
|
||||
BlockEvent.PLACE.register((EntityEvent.PLACE_BLOCK.invoker()::placeBlock));
|
||||
BlockEvent.BREAK.register((PlayerEvent.BREAK_BLOCK.invoker()::breakBlock));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021 shedaniel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package me.shedaniel.architectury.event.events;
|
||||
|
||||
import me.shedaniel.architectury.event.Event;
|
||||
import me.shedaniel.architectury.event.EventFactory;
|
||||
import me.shedaniel.architectury.utils.IntValue;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface BlockEvent {
|
||||
|
||||
// Block interaction events
|
||||
/**
|
||||
* Called when a player breaks a block.
|
||||
*/
|
||||
Event<Break> BREAK = EventFactory.createInteractionResult();
|
||||
/**
|
||||
* Called when a block is placed in the world by an entity.
|
||||
*/
|
||||
Event<Place> PLACE = EventFactory.createInteractionResult();
|
||||
|
||||
/**
|
||||
* Called when a falling block (sand, anvil, etc.) is about to land.
|
||||
* Use fallState#getBlock to get the type of block for more granular control.
|
||||
*/
|
||||
Event<FallingLand> FALLING_LAND = EventFactory.createLoop();
|
||||
|
||||
interface Break {
|
||||
InteractionResult breakBlock(Level world, BlockPos pos, BlockState state, ServerPlayer player, @Nullable IntValue xp);
|
||||
}
|
||||
|
||||
interface Place {
|
||||
InteractionResult placeBlock(Level world, BlockPos pos, BlockState state, @Nullable Entity placer);
|
||||
}
|
||||
|
||||
interface FallingLand {
|
||||
void onLand(Level level, BlockPos pos, BlockState fallState, BlockState landOn, FallingBlockEntity entity);
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface EntityEvent {
|
||||
@@ -43,6 +44,12 @@ public interface EntityEvent {
|
||||
* Invoked before entity is added to a world, equivalent to forge's {@code EntityJoinWorldEvent}.
|
||||
*/
|
||||
Event<Add> ADD = EventFactory.createInteractionResult();
|
||||
|
||||
/**
|
||||
* @deprecated use {@link BlockEvent#PLACE}
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
Event<PlaceBlock> PLACE_BLOCK = EventFactory.createInteractionResult();
|
||||
|
||||
interface LivingDeath {
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.List;
|
||||
|
||||
public interface ExplosionEvent {
|
||||
Event<Pre> PRE = EventFactory.createInteractionResult();
|
||||
Event<Detonate> DETONATE = EventFactory.createInteractionResult();
|
||||
Event<Detonate> DETONATE = EventFactory.createLoop();
|
||||
|
||||
interface Pre {
|
||||
InteractionResult explode(Level world, Explosion explosion);
|
||||
|
||||
@@ -49,7 +49,7 @@ public interface GuiEvent {
|
||||
*/
|
||||
Event<ScreenInitPost> INIT_POST = EventFactory.createLoop();
|
||||
Event<ScreenRenderPre> RENDER_PRE = EventFactory.createInteractionResult();
|
||||
Event<ScreenRenderPost> RENDER_POST = EventFactory.createInteractionResult();
|
||||
Event<ScreenRenderPost> RENDER_POST = EventFactory.createLoop();
|
||||
|
||||
/**
|
||||
* Invoked during Minecraft#setScreen, equivalent to forge's {@code GuiOpenEvent}.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021 shedaniel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package me.shedaniel.architectury.event.events;
|
||||
|
||||
import me.shedaniel.architectury.event.Event;
|
||||
import me.shedaniel.architectury.event.EventFactory;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LightningEvent {
|
||||
|
||||
// TODO Pre - Called before a lightning bolt entity is added to the world. (cancellable)
|
||||
/**
|
||||
* Invoked after the lightning has gathered a list of entities to strike.
|
||||
* Remove entities from the list to stop them from being hit.
|
||||
*/
|
||||
Event<Strike> STRIKE = EventFactory.createLoop();
|
||||
// TODO Post - Called before a lightning bolt entity is removed from the world.
|
||||
|
||||
interface Strike {
|
||||
void onStrike(LightningBolt bolt, Level level, Vec3 pos, List<Entity> toStrike);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface PlayerEvent {
|
||||
@@ -50,6 +51,12 @@ public interface PlayerEvent {
|
||||
Event<DropItem> DROP_ITEM = EventFactory.createLoop();
|
||||
Event<OpenMenu> OPEN_MENU = EventFactory.createLoop();
|
||||
Event<CloseMenu> CLOSE_MENU = EventFactory.createLoop();
|
||||
|
||||
/**
|
||||
* @deprecated use {@link BlockEvent#BREAK}
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
Event<BreakBlock> BREAK_BLOCK = EventFactory.createInteractionResult();
|
||||
|
||||
interface PlayerJoin {
|
||||
|
||||
@@ -44,8 +44,8 @@ public interface TooltipEvent {
|
||||
* Render forge events are only invoked on the forge side.
|
||||
*/
|
||||
Event<RenderForge> RENDER_FORGE_PRE = EventFactory.createInteractionResult();
|
||||
Event<RenderModifyPosition> RENDER_MODIFY_POSITION = EventFactory.createInteractionResult();
|
||||
Event<RenderModifyColor> RENDER_MODIFY_COLOR = EventFactory.createInteractionResult();
|
||||
Event<RenderModifyPosition> RENDER_MODIFY_POSITION = EventFactory.createLoop();
|
||||
Event<RenderModifyColor> RENDER_MODIFY_COLOR = EventFactory.createLoop();
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
interface Item {
|
||||
|
||||
@@ -21,6 +21,8 @@ package me.shedaniel.architectury.hooks;
|
||||
|
||||
import me.shedaniel.architectury.annotations.ExpectPlatform;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class EntityHooks {
|
||||
private EntityHooks() {}
|
||||
@@ -29,4 +31,10 @@ public final class EntityHooks {
|
||||
public static String getEncodeId(Entity entity) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ExpectPlatform
|
||||
public static Entity fromCollision(CollisionContext ctx) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021 shedaniel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package me.shedaniel.architectury.hooks;
|
||||
|
||||
import me.shedaniel.architectury.annotations.ExpectPlatform;
|
||||
import me.shedaniel.architectury.mixin.FluidTagsAccessor;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.*;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class TagHooks {
|
||||
private TagHooks() {}
|
||||
|
||||
@ExpectPlatform
|
||||
public static <T> Tag.Named<T> getOptional(ResourceLocation id, Supplier<TagCollection<T>> collection) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static Tag.Named<Item> getItemOptional(ResourceLocation id) {
|
||||
return getOptional(id, ItemTags::getAllTags);
|
||||
}
|
||||
|
||||
public static Tag.Named<Block> getBlockOptional(ResourceLocation id) {
|
||||
return getOptional(id, BlockTags::getAllTags);
|
||||
}
|
||||
|
||||
public static Tag.Named<Fluid> getFluidOptional(ResourceLocation id) {
|
||||
return getOptional(id, FluidTagsAccessor.getHelper()::getAllTags);
|
||||
}
|
||||
|
||||
public static Tag.Named<EntityType<?>> getEntityTypeOptional(ResourceLocation id) {
|
||||
return getOptional(id, EntityTypeTags::getAllTags);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021 shedaniel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package me.shedaniel.architectury.mixin;
|
||||
|
||||
import me.shedaniel.architectury.event.events.BlockEvent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AnvilBlock;
|
||||
import net.minecraft.world.level.block.ConcretePowderBlock;
|
||||
import net.minecraft.world.level.block.FallingBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin({FallingBlock.class, AnvilBlock.class, ConcretePowderBlock.class})
|
||||
public abstract class BlockLandingInvoker {
|
||||
@Inject(method = "onLand", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
public void handleLand(Level level, BlockPos pos, BlockState fallState, BlockState landOn, FallingBlockEntity entity, CallbackInfo ci) {
|
||||
BlockEvent.FALLING_LAND.invoker().onLand(level, pos, fallState, landOn, entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021 shedaniel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package me.shedaniel.architectury.mixin;
|
||||
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.tags.StaticTagHelper;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(FluidTags.class)
|
||||
public interface FluidTagsAccessor {
|
||||
@Accessor("HELPER")
|
||||
static StaticTagHelper<Fluid> getHelper() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of architectury.
|
||||
* Copyright (C) 2020, 2021 shedaniel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package me.shedaniel.architectury.mixin;
|
||||
|
||||
import me.shedaniel.architectury.event.events.LightningEvent;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.level.Level;
|
||||
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.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(LightningBolt.class)
|
||||
public abstract class MixinLightningBolt extends Entity {
|
||||
|
||||
public MixinLightningBolt(EntityType<?> type, Level level) {
|
||||
super(type, level);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At(
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lnet/minecraft/world/level/Level;getEntities(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;)Ljava/util/List;",
|
||||
ordinal = 0,
|
||||
shift = At.Shift.BY,
|
||||
by = 1
|
||||
), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
public void handleLightning(CallbackInfo ci, double d0, List<Entity> list) {
|
||||
if (this.removed || this.level.isClientSide) {
|
||||
return;
|
||||
}
|
||||
|
||||
LightningEvent.STRIKE.invoker().onStrike((LightningBolt) (Object) this, this.level, this.position(), list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,6 @@
|
||||
package me.shedaniel.architectury.networking;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import me.shedaniel.architectury.networking.NetworkManager.PacketContext;
|
||||
import me.shedaniel.architectury.platform.Platform;
|
||||
@@ -32,11 +31,13 @@ import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -57,26 +58,28 @@ public final class NetworkChannel {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
public <T> void register(NetworkManager.Side side, Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
register(type, encoder, decoder, messageConsumer);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
public <T> void register(Optional<NetworkManager.Side> side, Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
register(type, encoder, decoder, messageConsumer);
|
||||
}
|
||||
|
||||
public <T> void register(Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
String s = StringUtils.leftPad(String.valueOf(hashCodeString(type.toString())), 10, '0');
|
||||
if (s.length() > 10) s = s.substring(0, 10);
|
||||
MessageInfo<T> info = new MessageInfo<>(new ResourceLocation(id + "_" + s), encoder, decoder, messageConsumer);
|
||||
// TODO: this is pretty wasteful; add a way to specify custom or numeric ids
|
||||
String s = UUID.nameUUIDFromBytes(type.getName().getBytes(StandardCharsets.UTF_8)).toString().replace("-", "");
|
||||
MessageInfo<T> info = new MessageInfo<>(new ResourceLocation(id + "/" + s), encoder, decoder, messageConsumer);
|
||||
encoders.put(type, info);
|
||||
NetworkManager.NetworkReceiver receiver = (buf, context) -> {
|
||||
info.messageConsumer.accept(info.decoder.apply(buf), () -> context);
|
||||
};
|
||||
NetworkManager.registerReceiver(NetworkManager.clientToServer(), info.packetId, receiver);
|
||||
NetworkManager.registerReceiver(NetworkManager.c2s(), info.packetId, receiver);
|
||||
if (Platform.getEnvironment() == Env.CLIENT) {
|
||||
NetworkManager.registerReceiver(NetworkManager.serverToClient(), info.packetId, receiver);
|
||||
NetworkManager.registerReceiver(NetworkManager.s2c(), info.packetId, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,46 +93,48 @@ public final class NetworkChannel {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
public <T> void register(int id, Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
register(type, encoder, decoder, messageConsumer);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
public <T> void register(NetworkManager.Side side, int id, Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
register(type, encoder, decoder, messageConsumer);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
|
||||
public <T> void register(Optional<NetworkManager.Side> side, int id, Class<T> type, BiConsumer<T, FriendlyByteBuf> encoder, Function<FriendlyByteBuf, T> decoder, BiConsumer<T, Supplier<PacketContext>> messageConsumer) {
|
||||
register(type, encoder, decoder, messageConsumer);
|
||||
}
|
||||
|
||||
private <T> Pair<MessageInfo<T>, FriendlyByteBuf> encode(T message) {
|
||||
MessageInfo<T> messageInfo = (MessageInfo<T>) Objects.requireNonNull(encoders.get(message.getClass()));
|
||||
public <T> Packet<?> toPacket(NetworkManager.Side side, T message) {
|
||||
MessageInfo<T> messageInfo = (MessageInfo<T>) Objects.requireNonNull(encoders.get(message.getClass()), "Unknown message type! " + message);
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
messageInfo.encoder.accept(message, buf);
|
||||
return new Pair<>(messageInfo, buf);
|
||||
}
|
||||
|
||||
public <T> Packet<?> toPacket(NetworkManager.Side side, T message) {
|
||||
Pair<MessageInfo<T>, FriendlyByteBuf> encoded = encode(message);
|
||||
return NetworkManager.toPacket(side, encoded.getFirst().packetId, encoded.getSecond());
|
||||
return NetworkManager.toPacket(side, messageInfo.packetId, buf);
|
||||
}
|
||||
|
||||
public <T> void sendToPlayer(ServerPlayer player, T message) {
|
||||
player.connection.send(toPacket(NetworkManager.s2c(), message));
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(toPacket(NetworkManager.s2c(), message));
|
||||
}
|
||||
|
||||
public <T> void sendToPlayers(Iterable<ServerPlayer> players, T message) {
|
||||
Packet<?> packet = toPacket(NetworkManager.s2c(), message);
|
||||
for (ServerPlayer player : players) {
|
||||
player.connection.send(packet);
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public <T> void sendToServer(T message) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket(NetworkManager.c2s(), message));
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket(NetworkManager.c2s(), message));
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to send packet to the server while not in game!");
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
|
||||
@@ -30,6 +30,8 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class NetworkManager {
|
||||
@ExpectPlatform
|
||||
public static void registerReceiver(Side side, ResourceLocation id, NetworkReceiver receiver) {
|
||||
@@ -42,19 +44,23 @@ public final class NetworkManager {
|
||||
}
|
||||
|
||||
public static void sendToPlayer(ServerPlayer player, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
player.connection.send(toPacket(serverToClient(), id, buf));
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(toPacket(serverToClient(), id, buf));
|
||||
}
|
||||
|
||||
public static void sendToPlayers(Iterable<ServerPlayer> players, ResourceLocation id, FriendlyByteBuf buf) {
|
||||
Packet<?> packet = toPacket(serverToClient(), id, buf);
|
||||
for (ServerPlayer player : players) {
|
||||
player.connection.send(packet);
|
||||
Objects.requireNonNull(player, "Unable to send packet to a 'null' player!").connection.send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static void sendToServer(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket(clientToServer(), id, buf));
|
||||
if (Minecraft.getInstance().getConnection() != null) {
|
||||
Minecraft.getInstance().getConnection().send(toPacket(clientToServer(), id, buf));
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to send packet to the server while not in game!");
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@@ -77,7 +83,7 @@ public final class NetworkManager {
|
||||
Player getPlayer();
|
||||
|
||||
void queue(Runnable runnable);
|
||||
|
||||
|
||||
Env getEnvironment();
|
||||
|
||||
default EnvType getEnv() {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.shedaniel.architectury.registry.entity;
|
||||
|
||||
import me.shedaniel.architectury.annotations.ExpectPlatform;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public final class EntityRenderers {
|
||||
private EntityRenderers() {}
|
||||
|
||||
@ExpectPlatform
|
||||
public static <T extends Entity> void register(EntityType<T> type, Function<EntityRenderDispatcher, EntityRenderer<T>> factory) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
13
common/src/main/resources/architectury-common.mixins.json
Normal file
13
common/src/main/resources/architectury-common.mixins.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "me.shedaniel.architectury.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"minVersion": "0.7.11",
|
||||
"client": [
|
||||
],
|
||||
"mixins": ["BlockLandingInvoker", "FluidTagsAccessor", "MixinLightningBolt"],
|
||||
"injectors": {
|
||||
"maxShiftBy": 5,
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user