Update to 1.19.3

This commit is contained in:
IzzelAliz 2022-12-10 15:47:33 +08:00
parent 0550c6cd96
commit 7590e2b5d7
No known key found for this signature in database
GPG Key ID: EE50E123A11D8338
107 changed files with 904 additions and 894 deletions

View File

@ -5,8 +5,9 @@ A Bukkit server implementation utilizing Mixin.
![Actions](https://img.shields.io/github/workflow/status/IzzelAliz/Arclight/Java%20CI%20with%20Gradle?style=flat-square) ![GitHub](https://img.shields.io/github/license/IzzelAliz/Arclight?style=flat-square) ![Actions](https://img.shields.io/github/workflow/status/IzzelAliz/Arclight/Java%20CI%20with%20Gradle?style=flat-square) ![GitHub](https://img.shields.io/github/license/IzzelAliz/Arclight?style=flat-square)
| Release | Forge | Status | Build | | Release | Forge | Status | Build |
|:-------------:|:-------:|:------:|:------------------------------------------------------------------------------------------------------------------------------------------------------:| |:-------------------:|:-------:|:------:|:------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Horn (1.19.x) | 43.2.0 | ACTIVE | [![1.19 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-19?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-19) | | Great Horn (1.19.3) | 44.0.1 | ACTIVE | [![1.19 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-19?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-19) |
| Horn (1.19-1.19.2) | 43.2.0 | LTS | [![1.19 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-19?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-19) |
| 1.18.x | 40.1.80 | LTS | [![1.18 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-18?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-18) | | 1.18.x | 40.1.80 | LTS | [![1.18 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-18?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-18) |
| 1.16.x | 36.2.39 | LTS | [![1.16 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-16?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-16) | | 1.16.x | 36.2.39 | LTS | [![1.16 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-16?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-16) |

View File

@ -24,7 +24,7 @@ apply plugin: 'io.izzel.arclight'
arclight { arclight {
mcVersion = minecraftVersion mcVersion = minecraftVersion
forgeVersion = project.ext.forgeVersion forgeVersion = project.ext.forgeVersion
bukkitVersion = 'v1_19_R1' bukkitVersion = 'v1_19_R2'
wipeVersion = true wipeVersion = true
reobfVersion = true reobfVersion = true
accessTransformer = project.file('bukkit.at') accessTransformer = project.file('bukkit.at')

View File

@ -1,17 +1,12 @@
package io.izzel.arclight.common.bridge.core.entity; package io.izzel.arclight.common.bridge.core.entity;
import org.bukkit.event.entity.CreatureSpawnEvent;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.player.Player; import org.bukkit.event.entity.CreatureSpawnEvent;
public interface EntityTypeBridge<T extends Entity> { public interface EntityTypeBridge<T extends Entity> {
T bridge$spawnCreature(ServerLevel worldIn, @Nullable CompoundTag compound, @Nullable Component customName, @Nullable Player playerIn, BlockPos pos, MobSpawnType reason, boolean flag, boolean flag1, CreatureSpawnEvent.SpawnReason spawnReason); T bridge$spawnCreature(ServerLevel worldIn, BlockPos pos, MobSpawnType mobSpawnType, CreatureSpawnEvent.SpawnReason spawnReason);
} }

View File

@ -1,8 +1,11 @@
package io.izzel.arclight.common.bridge.core.network.datasync; package io.izzel.arclight.common.bridge.core.network.datasync;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.server.level.ServerPlayer;
public interface EntityDataManagerBridge { public interface SynchedEntityDataBridge {
<T> void bridge$markDirty(EntityDataAccessor<T> key); <T> void bridge$markDirty(EntityDataAccessor<T> key);
void bridge$refresh(ServerPlayer player);
} }

View File

@ -4,7 +4,6 @@ import com.mojang.authlib.GameProfile;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerLoginPacketListenerImpl; import net.minecraft.server.network.ServerLoginPacketListenerImpl;
import net.minecraft.world.entity.player.ProfilePublicKey;
import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.CraftServer;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -18,7 +17,7 @@ public interface PlayerListBridge {
CraftServer bridge$getCraftServer(); CraftServer bridge$getCraftServer();
ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler, ProfilePublicKey profilePublicKey); ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler);
void bridge$sendMessage(Component[] components); void bridge$sendMessage(Component[] components);
} }

View File

@ -1,17 +0,0 @@
package io.izzel.arclight.common.mixin.bukkit;
import net.minecraft.world.item.CreativeModeTab;
import org.bukkit.craftbukkit.v.inventory.CraftCreativeCategory;
import org.bukkit.inventory.CreativeCategory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Map;
@Mixin(CraftCreativeCategory.class)
public class CraftCreativeCategoryMixin {
@Shadow @Final @Mutable private static Map<CreativeModeTab, CreativeCategory> NMS_TO_BUKKIT;
}

View File

@ -41,7 +41,7 @@ public interface CraftRecipeMixin {
throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit); throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
} }
stack.dissolve(); stack.getItems();
if (stack.isVanilla() && requireNotEmpty && stack.getItems().length == 0) { if (stack.isVanilla() && requireNotEmpty && stack.getItems().length == 0) {
throw new IllegalArgumentException("Recipe requires at least one non-air choice!"); throw new IllegalArgumentException("Recipe requires at least one non-air choice!");
} else { } else {
@ -55,7 +55,7 @@ public interface CraftRecipeMixin {
*/ */
@Overwrite @Overwrite
static RecipeChoice toBukkit(Ingredient list) { static RecipeChoice toBukkit(Ingredient list) {
list.dissolve(); list.getItems();
if (!list.isVanilla()) { if (!list.isVanilla()) {
return new ArclightSpecialIngredient(list); return new ArclightSpecialIngredient(list);
} }

View File

@ -50,19 +50,19 @@ import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@Mixin(CraftServer.class) @Mixin(value = CraftServer.class, remap = false)
public abstract class CraftServerMixin implements CraftServerBridge { public abstract class CraftServerMixin implements CraftServerBridge {
// @formatter:off // @formatter:off
@Shadow(remap = false) @Final private CraftCommandMap commandMap; @Shadow @Final private CraftCommandMap commandMap;
@Shadow(remap = false) @Final private SimplePluginManager pluginManager; @Shadow @Final private SimplePluginManager pluginManager;
@Shadow(remap = false) @Final private SimpleHelpMap helpMap; @Shadow @Final private SimpleHelpMap helpMap;
@Shadow(remap = false) protected abstract void enablePlugin(Plugin plugin); @Shadow protected abstract void enablePlugin(Plugin plugin);
@Shadow(remap = false) protected abstract void loadCustomPermissions(); @Shadow protected abstract void loadCustomPermissions();
@Shadow(remap = false) @Final protected DedicatedServer console; @Shadow @Final protected DedicatedServer console;
@Shadow(remap = false) @Final @Mutable private String serverName; @Shadow @Final @Mutable private String serverName;
@Shadow(remap = false) @Final @Mutable protected DedicatedPlayerList playerList; @Shadow @Final @Mutable protected DedicatedPlayerList playerList;
@Shadow(remap = false) @Final private Map<String, World> worlds; @Shadow @Final private Map<String, World> worlds;
@Shadow public int reloadCount; @Shadow public int reloadCount;
@Shadow private YamlConfiguration configuration; @Shadow private YamlConfiguration configuration;
@Shadow protected abstract File getConfigFile(); @Shadow protected abstract File getConfigFile();
@ -77,7 +77,7 @@ public abstract class CraftServerMixin implements CraftServerBridge {
@Shadow public abstract void loadPlugins(); @Shadow public abstract void loadPlugins();
@Shadow public abstract void enablePlugins(PluginLoadOrder type); @Shadow public abstract void enablePlugins(PluginLoadOrder type);
@Shadow public abstract PluginManager getPluginManager(); @Shadow public abstract PluginManager getPluginManager();
@Accessor(value = "logger", remap = false) @Mutable public abstract void setLogger(Logger logger); @Accessor("logger") @Mutable public abstract void setLogger(Logger logger);
// @formatter:on // @formatter:on
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))

View File

@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map; import java.util.Map;
import java.util.function.Predicate; import java.util.function.Predicate;
@Mixin(Registry.SimpleRegistry.class) @Mixin(value = Registry.SimpleRegistry.class, remap = false)
public class Registry_SimpleRegistryMixin<T extends Enum<T> & Keyed> implements SimpleRegistryBridge { public class Registry_SimpleRegistryMixin<T extends Enum<T> & Keyed> implements SimpleRegistryBridge {
@Shadow @Final @Mutable private Map<NamespacedKey, T> map; @Shadow @Final @Mutable private Map<NamespacedKey, T> map;

View File

@ -5,7 +5,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FlowingFluid; import net.minecraft.world.level.material.FlowingFluid;
import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluid;
@ -33,7 +32,7 @@ public abstract class FlowingFluidMixin {
// @formatter:on // @formatter:on
@Inject(method = "spread", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FlowingFluid;spreadTo(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/world/level/material/FluidState;)V")) @Inject(method = "spread", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FlowingFluid;spreadTo(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/world/level/material/FluidState;)V"))
public void arclight$flowInto(LevelAccessor worldIn, BlockPos pos, FluidState stateIn, CallbackInfo ci) { public void arclight$flowInto(Level worldIn, BlockPos pos, FluidState stateIn, CallbackInfo ci) {
if (!DistValidate.isValid(worldIn)) return; if (!DistValidate.isValid(worldIn)) return;
Block source = CraftBlock.at(worldIn, pos); Block source = CraftBlock.at(worldIn, pos);
BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN); BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN);

View File

@ -21,8 +21,6 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerLoginPacketListenerImpl; import net.minecraft.server.network.ServerLoginPacketListenerImpl;
import net.minecraft.util.Crypt; import net.minecraft.util.Crypt;
import net.minecraft.util.CryptException; import net.minecraft.util.CryptException;
import net.minecraft.util.SignatureValidator;
import net.minecraft.world.entity.player.ProfilePublicKey;
import net.minecraftforge.fml.util.thread.SidedThreadGroups; import net.minecraftforge.fml.util.thread.SidedThreadGroups;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -55,7 +53,6 @@ public abstract class ServerLoginNetHandlerMixin {
// @formatter:off // @formatter:off
@Shadow private ServerLoginPacketListenerImpl.State state; @Shadow private ServerLoginPacketListenerImpl.State state;
@Shadow @Final private MinecraftServer server; @Shadow @Final private MinecraftServer server;
@Shadow @Final private byte[] nonce;
@Shadow @Final public Connection connection; @Shadow @Final public Connection connection;
@Shadow @Final private static AtomicInteger UNIQUE_THREAD_ID; @Shadow @Final private static AtomicInteger UNIQUE_THREAD_ID;
@Shadow private GameProfile gameProfile; @Shadow private GameProfile gameProfile;
@ -64,8 +61,7 @@ public abstract class ServerLoginNetHandlerMixin {
@Shadow public abstract void disconnect(Component reason); @Shadow public abstract void disconnect(Component reason);
@Shadow public abstract String getUserName(); @Shadow public abstract String getUserName();
@Shadow private ServerPlayer delayedAcceptPlayer; @Shadow private ServerPlayer delayedAcceptPlayer;
@Shadow @Nullable private ProfilePublicKey.Data profilePublicKeyData; @Shadow @Final private byte[] challenge;
@Shadow @Nullable private static ProfilePublicKey validatePublicKey(@org.jetbrains.annotations.Nullable ProfilePublicKey.Data p_240244_, UUID p_240245_, SignatureValidator p_240246_, boolean p_240247_) throws ProfilePublicKey.ValidationException { return null; }
// @formatter:on // @formatter:on
public void disconnect(final String s) { public void disconnect(final String s) {
@ -83,26 +79,13 @@ public abstract class ServerLoginNetHandlerMixin {
this.loginGameProfile = this.getOfflineProfile(this.loginGameProfile); this.loginGameProfile = this.getOfflineProfile(this.loginGameProfile);
} }
*/ */
ProfilePublicKey profilePublicKey = null;
if (!this.server.usesAuthentication()) { if (!this.server.usesAuthentication()) {
// this.gameProfile = this.createFakeProfile(this.gameProfile); // Spigot - Moved to initUUID // this.gameProfile = this.createFakeProfile(this.gameProfile); // Spigot - Moved to initUUID
// Spigot end // Spigot end
} else {
try {
SignatureValidator signaturevalidator = this.server.getServiceSignatureValidator();
profilePublicKey = validatePublicKey(this.profilePublicKeyData, this.gameProfile.getId(), signaturevalidator, this.server.enforceSecureProfile());
} catch (ProfilePublicKey.ValidationException e) {
LOGGER.error("Failed to validate profile key: {}", e.getMessage());
if (!this.connection.isMemoryConnection()) {
this.disconnect(e.getComponent());
return;
}
}
} }
ServerPlayer entity = ((PlayerListBridge) this.server.getPlayerList()).bridge$canPlayerLogin(this.connection.getRemoteAddress(), this.gameProfile, (ServerLoginPacketListenerImpl) (Object) this, profilePublicKey); ServerPlayer entity = ((PlayerListBridge) this.server.getPlayerList()).bridge$canPlayerLogin(this.connection.getRemoteAddress(), this.gameProfile, (ServerLoginPacketListenerImpl) (Object) this);
if (entity == null) { if (entity == null) {
// this.disconnect(itextcomponent); // this.disconnect(itextcomponent);
} else { } else {
@ -141,7 +124,6 @@ public abstract class ServerLoginNetHandlerMixin {
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet"); Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet");
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet"); Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet");
Validate.validState(isValidUsername(packetIn.name()), "Invalid characters in username"); Validate.validState(isValidUsername(packetIn.name()), "Invalid characters in username");
this.profilePublicKeyData = packetIn.publicKey().orElse(null);
GameProfile gameprofile = this.server.getSingleplayerProfile(); GameProfile gameprofile = this.server.getSingleplayerProfile();
if (gameprofile != null && packetIn.name().equalsIgnoreCase(gameprofile.getName())) { if (gameprofile != null && packetIn.name().equalsIgnoreCase(gameprofile.getName())) {
this.gameProfile = gameprofile; this.gameProfile = gameprofile;
@ -150,7 +132,7 @@ public abstract class ServerLoginNetHandlerMixin {
this.gameProfile = new GameProfile(null, packetIn.name()); this.gameProfile = new GameProfile(null, packetIn.name());
if (this.server.usesAuthentication() && !this.connection.isMemoryConnection()) { if (this.server.usesAuthentication() && !this.connection.isMemoryConnection()) {
this.state = ServerLoginPacketListenerImpl.State.KEY; this.state = ServerLoginPacketListenerImpl.State.KEY;
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.nonce)); this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge));
} else { } else {
class Handler extends Thread { class Handler extends Thread {
@ -202,12 +184,7 @@ public abstract class ServerLoginNetHandlerMixin {
final String s; final String s;
try { try {
PrivateKey privatekey = this.server.getKeyPair().getPrivate(); PrivateKey privatekey = this.server.getKeyPair().getPrivate();
if (this.profilePublicKeyData != null) { if (!packetIn.isChallengeValid(this.challenge, privatekey)) {
ProfilePublicKey profilepublickey = new ProfilePublicKey(this.profilePublicKeyData);
if (!packetIn.isChallengeSignatureValid(this.nonce, profilepublickey)) {
throw new IllegalStateException("Protocol error");
}
} else if (!packetIn.isNonceValid(this.nonce, privatekey)) {
throw new IllegalStateException("Protocol error"); throw new IllegalStateException("Protocol error");
} }

View File

@ -5,6 +5,7 @@ import com.mojang.datafixers.util.Pair;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.core.inventory.container.ContainerBridge; import io.izzel.arclight.common.bridge.core.inventory.container.ContainerBridge;
import io.izzel.arclight.common.bridge.core.network.datasync.SynchedEntityDataBridge;
import io.izzel.arclight.common.bridge.core.network.play.ServerPlayNetHandlerBridge; import io.izzel.arclight.common.bridge.core.network.play.ServerPlayNetHandlerBridge;
import io.izzel.arclight.common.bridge.core.network.play.TimestampedPacket; import io.izzel.arclight.common.bridge.core.network.play.TimestampedPacket;
import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge;
@ -25,14 +26,13 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
import net.minecraft.network.Connection; import net.minecraft.network.Connection;
import net.minecraft.network.PacketSendListener; import net.minecraft.network.PacketSendListener;
import net.minecraft.network.chat.ChatDecorator;
import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FilterMask;
import net.minecraft.network.chat.LastSeenMessages; import net.minecraft.network.chat.LastSeenMessages;
import net.minecraft.network.chat.OutgoingPlayerChatMessage; import net.minecraft.network.chat.OutgoingChatMessage;
import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.network.chat.PlayerChatMessage;
import net.minecraft.network.chat.PreviewableCommand; import net.minecraft.network.chat.SignableCommand;
import net.minecraft.network.chat.SignedMessageChain;
import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketUtils; import net.minecraft.network.protocol.PacketUtils;
import net.minecraft.network.protocol.game.*; import net.minecraft.network.protocol.game.*;
@ -104,7 +104,6 @@ import org.bukkit.event.inventory.InventoryCreativeEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.SmithItemEvent; import org.bukkit.event.inventory.SmithItemEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.AsyncPlayerChatPreviewEvent;
import org.bukkit.event.player.PlayerAnimationEvent; import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerAnimationType; import org.bukkit.event.player.PlayerAnimationType;
import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.PlayerChatEvent;
@ -146,6 +145,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -198,13 +198,13 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
@Shadow protected abstract void updateBookPages(List<FilteredText> p_143635_, UnaryOperator<String> p_143636_, ItemStack p_143637_); @Shadow protected abstract void updateBookPages(List<FilteredText> p_143635_, UnaryOperator<String> p_143636_, ItemStack p_143637_);
@Shadow public abstract void ackBlockChangesUpTo(int p_215202_); @Shadow public abstract void ackBlockChangesUpTo(int p_215202_);
@Shadow private static boolean isChatMessageIllegal(String p_215215_) { return false; } @Shadow private static boolean isChatMessageIllegal(String p_215215_) { return false; }
@Shadow protected abstract boolean tryHandleChat(String p_242372_, Instant p_242311_, LastSeenMessages.Update p_242217_);
@Shadow protected abstract PlayerChatMessage getSignedMessage(ServerboundChatPacket p_242875_);
@Shadow protected abstract boolean verifyChatMessage(PlayerChatMessage p_242942_);
@Shadow protected abstract CompletableFuture<FilteredText> filterTextPacket(String p_243213_); @Shadow protected abstract CompletableFuture<FilteredText> filterTextPacket(String p_243213_);
@Shadow protected abstract ParseResults<CommandSourceStack> parseCommand(String p_242938_); @Shadow protected abstract ParseResults<CommandSourceStack> parseCommand(String p_242938_);
@Shadow protected abstract Map<String, PlayerChatMessage> collectSignedArguments(ServerboundChatCommandPacket p_242876_, PreviewableCommand<?> p_242848_);
@Shadow protected abstract void detectRateSpam(); @Shadow protected abstract void detectRateSpam();
@Shadow protected abstract Optional<LastSeenMessages> tryHandleChat(String p_251364_, Instant p_248959_, LastSeenMessages.Update p_249613_);
@Shadow protected abstract PlayerChatMessage getSignedMessage(ServerboundChatPacket p_251061_, LastSeenMessages p_250566_) throws SignedMessageChain.DecodeException;
@Shadow protected abstract void handleMessageDecodeFailure(SignedMessageChain.DecodeException p_252068_);
@Shadow protected abstract Map<String, PlayerChatMessage> collectSignedArguments(ServerboundChatCommandPacket p_249441_, SignableCommand<?> p_250039_, LastSeenMessages p_249207_) throws SignedMessageChain.DecodeException;
// @formatter:on // @formatter:on
private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6; private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6;
@ -638,6 +638,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
this.player.absMoveTo(d0, d1, d2, f, f1); this.player.absMoveTo(d0, d1, d2, f, f1);
if (!this.player.noPhysics && !this.player.isSleeping() && (flag1 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew((LevelReader) worldserver, axisalignedbb))) { if (!this.player.noPhysics && !this.player.isSleeping() && (flag1 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew((LevelReader) worldserver, axisalignedbb))) {
this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet(), false); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. this.internalTeleport(d3, d4, d5, f, f1, Collections.emptySet(), false); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
this.player.doCheckFallDamage(this.player.getY() - d6, packetplayinflying.isOnGround());
} else { } else {
this.player.absMoveTo(prevX, prevY, prevZ, prevYaw, prevPitch); this.player.absMoveTo(prevX, prevY, prevZ, prevYaw, prevPitch);
CraftPlayer player = this.getCraftPlayer(); CraftPlayer player = this.getCraftPlayer();
@ -790,10 +791,11 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
} }
} }
@Inject(method = "handleUseItemOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayerGameMode;useItemOn(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;")) // So, what is SPIGOT-4706 exactly?
private void arclight$checkDistance(ServerboundUseItemOnPacket packetIn, CallbackInfo ci) { // @Inject(method = "handleUseItemOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayerGameMode;useItemOn(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)Lnet/minecraft/world/InteractionResult;"))
this.player.stopUsingItem(); // private void arclight$checkDistance(ServerboundUseItemOnPacket packetIn, CallbackInfo ci) {
} // this.player.stopUsingItem();
// }
private int limitedPackets; private int limitedPackets;
private long lastLimitedPacket = -1; private long lastLimitedPacket = -1;
@ -830,7 +832,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
InteractionHand enumhand = packet.getHand(); InteractionHand enumhand = packet.getHand();
ItemStack itemstack = this.player.getItemInHand(enumhand); ItemStack itemstack = this.player.getItemInHand(enumhand);
this.player.resetLastActionTime(); this.player.resetLastActionTime();
if (!itemstack.isEmpty()) { if (!itemstack.isEmpty() && itemstack.isItemEnabled(worldserver.enabledFeatures())) {
float f1 = this.player.getXRot(); float f1 = this.player.getXRot();
float f2 = this.player.getYRot(); float f2 = this.player.getYRot();
double d0 = this.player.getX(); double d0 = this.player.getX();
@ -957,17 +959,23 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
if (isChatMessageIllegal(packet.message())) { if (isChatMessageIllegal(packet.message())) {
this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters")); this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"));
} else { } else {
if (this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages())) { var optional = this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages());
PlayerChatMessage playerchatmessage = this.getSignedMessage(packet); if (optional.isPresent()) {
PlayerChatMessage playerchatmessage;
if (this.verifyChatMessage(playerchatmessage)) { try {
this.chatMessageChain.append(() -> { playerchatmessage = this.getSignedMessage(packet, optional.get());
CompletableFuture<FilteredText> completablefuture = this.filterTextPacket(playerchatmessage.signedContent().plain()); } catch (SignedMessageChain.DecodeException e) {
CompletableFuture<PlayerChatMessage> completablefuture1 = ForgeHooks.getServerChatSubmittedDecorator().decorate(this.player, playerchatmessage); this.handleMessageDecodeFailure(e);
return;
}
CompletableFuture<FilteredText> completablefuture = this.filterTextPacket(playerchatmessage.signedContent());
CompletableFuture<Component> completablefuture1 = this.server.getChatDecorator().decorate(this.player, playerchatmessage.decoratedContent());
this.chatMessageChain.append((executor) -> {
return CompletableFuture.allOf(completablefuture, completablefuture1).thenAcceptAsync((ovoid) -> { return CompletableFuture.allOf(completablefuture, completablefuture1).thenAcceptAsync((ovoid) -> {
FilterMask filtermask = completablefuture.join().mask(); PlayerChatMessage playerchatmessage1 = playerchatmessage.withUnsignedContent(completablefuture1.join()).filter(completablefuture.join().mask());
PlayerChatMessage playerchatmessage1 = completablefuture1.join().filter(filtermask);
this.broadcastChatMessage(playerchatmessage1); this.broadcastChatMessage(playerchatmessage1);
}, ArclightServer.getChatExecutor()); // CraftBukkit - async chat }, ArclightServer.getChatExecutor()); // CraftBukkit - async chat
@ -975,33 +983,13 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
} }
} }
} }
}
@Redirect(method = "queryChatPreview", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/common/ForgeHooks;getServerChatPreviewDecorator()Lnet/minecraft/network/chat/ChatDecorator;"))
private ChatDecorator arclight$asyncChatPreview() {
return (player, component) -> ForgeHooks.getServerChatPreviewDecorator().decorate(player, component)
.thenApplyAsync(forgeComponent -> {
if (player == null) {
return forgeComponent;
}
AsyncPlayerChatPreviewEvent event = new AsyncPlayerChatPreviewEvent(true, ((ServerPlayerEntityBridge) player).bridge$getBukkitEntity(), CraftChatMessage.fromComponent(forgeComponent), new LazyPlayerSet(server));
String originalFormat = event.getFormat(), originalMessage = event.getMessage();
this.cserver.getPluginManager().callEvent(event);
if (originalFormat.equals(event.getFormat()) && originalMessage.equals(event.getMessage()) && event.getPlayer().getName().equalsIgnoreCase(event.getPlayer().getDisplayName())) {
return forgeComponent;
}
return CraftChatMessage.fromStringOrNull(String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()));
}, ArclightServer.getChatExecutor());
}
/** /**
* @author IzzelAliz * @author IzzelAliz
* @reason * @reason
*/ */
@Overwrite @Overwrite
private void performChatCommand(ServerboundChatCommandPacket packet) { private void performChatCommand(ServerboundChatCommandPacket packet, LastSeenMessages lastseenmessages) {
String command = "/" + packet.command(); String command = "/" + packet.command();
LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command); LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command);
@ -1014,18 +1002,19 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
command = event.getMessage().substring(1); command = event.getMessage().substring(1);
ParseResults<CommandSourceStack> parseresults = this.parseCommand(command); ParseResults<CommandSourceStack> parseresults = this.parseCommand(command);
Map<String, PlayerChatMessage> map = (packet.command().equals(command)) ? this.collectSignedArguments(packet, PreviewableCommand.of(parseresults)) : Collections.emptyMap();
for (PlayerChatMessage playerchatmessage : map.values()) { Map<String, PlayerChatMessage> map;
if (!this.verifyChatMessage(playerchatmessage)) {
try {
map = (packet.command().equals(command)) ? this.collectSignedArguments(packet, SignableCommand.of(parseresults), lastseenmessages) : Collections.emptyMap(); // CraftBukkit
} catch (SignedMessageChain.DecodeException e) {
this.handleMessageDecodeFailure(e);
return; return;
} }
}
CommandSigningContext commandsigningcontext = new CommandSigningContext.SignedArguments(map); CommandSigningContext.SignedArguments arguments = new CommandSigningContext.SignedArguments(map);
parseresults = Commands.mapSource(parseresults, (p_242749_) -> {
return p_242749_.withSigningContext(commandsigningcontext); parseresults = Commands.mapSource(parseresults, (stack) -> stack.withSigningContext(arguments));
});
this.server.getCommands().performCommand(parseresults, command); this.server.getCommands().performCommand(parseresults, command);
} }
@ -1043,7 +1032,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
return; return;
} }
ServerGamePacketListenerImpl handler = (ServerGamePacketListenerImpl) (Object) this; ServerGamePacketListenerImpl handler = (ServerGamePacketListenerImpl) (Object) this;
OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(original); var outgoing = OutgoingChatMessage.create(original);
if (!async && s.startsWith("/")) { if (!async && s.startsWith("/")) {
this.handleCommand(s); this.handleCommand(s);
} else if (this.player.getChatVisibility() != ChatVisiblity.SYSTEM) { } else if (this.player.getChatVisibility() != ChatVisiblity.SYSTEM) {
@ -1054,15 +1043,12 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) {
PlayerChatEvent queueEvent = new PlayerChatEvent(thisPlayer, event.getMessage(), event.getFormat(), event.getRecipients()); PlayerChatEvent queueEvent = new PlayerChatEvent(thisPlayer, event.getMessage(), event.getFormat(), event.getRecipients());
queueEvent.setCancelled(event.isCancelled()); queueEvent.setCancelled(event.isCancelled());
class SyncChat extends Waitable { class SyncChat extends Waitable<Object> {
@Override @Override
protected Object evaluate() { protected Object evaluate() {
Bukkit.getPluginManager().callEvent(queueEvent); Bukkit.getPluginManager().callEvent(queueEvent);
if (queueEvent.isCancelled()) { if (queueEvent.isCancelled()) {
if (outgoing != null) {
outgoing.sendHeadersToRemainingPlayers(server.getPlayerList());
}
return null; return null;
} }
String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage()); String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage());
@ -1070,7 +1056,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
if (!org.spigotmc.SpigotConfig.bungee && originalFormat.equals(queueEvent.getFormat()) && originalMessage.equals(queueEvent.getMessage()) && queueEvent.getPlayer().getName().equalsIgnoreCase(queueEvent.getPlayer().getDisplayName())) { // Spigot if (!org.spigotmc.SpigotConfig.bungee && originalFormat.equals(queueEvent.getFormat()) && originalMessage.equals(queueEvent.getMessage()) && queueEvent.getPlayer().getName().equalsIgnoreCase(queueEvent.getPlayer().getDisplayName())) { // Spigot
server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.CHAT, player)); server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.CHAT, player));
return null; return null;
} else if (!org.spigotmc.SpigotConfig.bungee && CraftChatMessage.fromComponent(original.serverContent()).equals(message)) { // Spigot } else if (!org.spigotmc.SpigotConfig.bungee && CraftChatMessage.fromComponent(original.decoratedContent()).equals(message)) { // Spigot
// TODO server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.RAW, player)); // TODO server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.RAW, player));
return null; return null;
} }
@ -1083,9 +1069,6 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
} }
} }
Bukkit.getConsoleSender().sendMessage(message); Bukkit.getConsoleSender().sendMessage(message);
if (outgoing != null) {
outgoing.sendHeadersToRemainingPlayers(server.getPlayerList());
}
return null; return null;
} }
} }
@ -1106,9 +1089,6 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
} }
} }
if (event.isCancelled()) { if (event.isCancelled()) {
if (outgoing != null) {
outgoing.sendHeadersToRemainingPlayers(server.getPlayerList());
}
return; return;
} }
@ -1117,7 +1097,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
if (!org.spigotmc.SpigotConfig.bungee && originalFormat.equals(event.getFormat()) && originalMessage.equals(event.getMessage()) && event.getPlayer().getName().equalsIgnoreCase(event.getPlayer().getDisplayName())) { // Spigot if (!org.spigotmc.SpigotConfig.bungee && originalFormat.equals(event.getFormat()) && originalMessage.equals(event.getMessage()) && event.getPlayer().getName().equalsIgnoreCase(event.getPlayer().getDisplayName())) { // Spigot
server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.CHAT, player)); server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.CHAT, player));
return; return;
} else if (!org.spigotmc.SpigotConfig.bungee && CraftChatMessage.fromComponent(original.serverContent()).equals(s)) { // Spigot } else if (!org.spigotmc.SpigotConfig.bungee && CraftChatMessage.fromComponent(original.decoratedContent()).equals(s)) { // Spigot
// TODO server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.RAW, player)); // TODO server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.RAW, player));
return; return;
} }
@ -1131,10 +1111,6 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
} }
} }
Bukkit.getConsoleSender().sendMessage(s); Bukkit.getConsoleSender().sendMessage(s);
if (outgoing != null) {
outgoing.sendHeadersToRemainingPlayers(server.getPlayerList());
}
} }
} }
@ -1162,12 +1138,10 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
*/ */
@Overwrite @Overwrite
private void broadcastChatMessage(PlayerChatMessage playerchatmessage) { private void broadcastChatMessage(PlayerChatMessage playerchatmessage) {
String s = playerchatmessage.signedContent().plain(); String s = playerchatmessage.signedContent();
if (s.isEmpty()) { if (s.isEmpty()) {
LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message"); LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message");
} else if (getCraftPlayer().isConversing()) { } else if (getCraftPlayer().isConversing()) {
OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(playerchatmessage);
outgoing.sendHeadersToRemainingPlayers(this.server.getPlayerList());
final String conversationInput = s; final String conversationInput = s;
((MinecraftServerBridge) this.server).bridge$queuedProcess(() -> getCraftPlayer().acceptConversationInput(conversationInput)); ((MinecraftServerBridge) this.server).bridge$queuedProcess(() -> getCraftPlayer().acceptConversationInput(conversationInput));
} else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Re-add "Command Only" flag check } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Re-add "Command Only" flag check
@ -1264,7 +1238,10 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
private void performInteraction(InteractionHand hand, ServerGamePacketListenerImpl.EntityInteraction interaction, PlayerInteractEntityEvent event) { // CraftBukkit private void performInteraction(InteractionHand hand, ServerGamePacketListenerImpl.EntityInteraction interaction, PlayerInteractEntityEvent event) { // CraftBukkit
if (!player.canInteractWith(entity, 1.5D)) if (!player.canInteractWith(entity, 1.5D))
return; //Forge: If the entity cannot be reached, do nothing. Original check was dist < 6, range is 4.5, so vanilla used padding=1.5 return; //Forge: If the entity cannot be reached, do nothing. Original check was dist < 6, range is 4.5, so vanilla used padding=1.5
ItemStack itemstack = player.getItemInHand(hand).copy(); var stack = player.getItemInHand(hand);
if (!stack.isItemEnabled(world.enabledFeatures()))
return;
ItemStack itemstack = stack.copy();
// CraftBukkit start // CraftBukkit start
ItemStack itemInHand = player.getItemInHand(hand); ItemStack itemInHand = player.getItemInHand(hand);
boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob; boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof Mob;
@ -1285,7 +1262,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
if (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem) { if (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem) {
// Refresh the current entity metadata // Refresh the current entity metadata
send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true)); ((SynchedEntityDataBridge) entity.getEntityData()).bridge$refresh(player);
if (entity instanceof Allay) { if (entity instanceof Allay) {
send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList()))); send(new ClientboundSetEquipmentPacket(entity.getId(), Arrays.stream(net.minecraft.world.entity.EquipmentSlot.values()).map((slot) -> Pair.of(slot, ((LivingEntity) entity).getItemBySlot(slot).copy())).collect(Collectors.toList())));
player.containerMenu.sendAllDataToRemote(); player.containerMenu.sendAllDataToRemote();
@ -1336,6 +1313,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
public void onAttack() { public void onAttack() {
if (!(entity instanceof ItemEntity) && !(entity instanceof ExperienceOrb) && !(entity instanceof AbstractArrow) && (entity != player || player.isSpectator())) { if (!(entity instanceof ItemEntity) && !(entity instanceof ExperienceOrb) && !(entity instanceof AbstractArrow) && (entity != player || player.isSpectator())) {
ItemStack itemInHand = player.getMainHandItem(); ItemStack itemInHand = player.getMainHandItem();
if (!itemInHand.isItemEnabled(world.enabledFeatures())) return;
if (player.canHit(entity, 3)) { //Forge: Perform attack range check. Original check was dist < 6, range is 3, so vanilla used padding=3 if (player.canHit(entity, 3)) { //Forge: Perform attack range check. Original check was dist < 6, range is 3, so vanilla used padding=3
player.attack(entity); player.attack(entity);
} }

View File

@ -54,7 +54,6 @@ public class ServerStatusNetHandlerMixin {
playerSample.setSample(profiles.toArray(new GameProfile[0])); playerSample.setSample(profiles.toArray(new GameProfile[0]));
} }
ServerStatus ping = new ServerStatus(); ServerStatus ping = new ServerStatus();
ping.setPreviewsChat(event.shouldSendChatPreviews());
ping.setFavicon(event.icon.value); ping.setFavicon(event.icon.value);
ping.setDescription(CraftChatMessage.fromString(event.getMotd(), true)[0]); ping.setDescription(CraftChatMessage.fromString(event.getMotd(), true)[0]);
ping.setPlayers(playerSample); ping.setPlayers(playerSample);

View File

@ -1,9 +1,11 @@
package io.izzel.arclight.common.mixin.core.network; package io.izzel.arclight.common.mixin.core.network;
import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.core.network.datasync.EntityDataManagerBridge; import io.izzel.arclight.common.bridge.core.network.datasync.SynchedEntityDataBridge;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import org.bukkit.craftbukkit.v.entity.CraftPlayer; import org.bukkit.craftbukkit.v.entity.CraftPlayer;
@ -14,13 +16,18 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import javax.annotation.Nullable;
import java.util.List;
@Mixin(SynchedEntityData.class) @Mixin(SynchedEntityData.class)
public abstract class SynchedEntityDataMixin implements EntityDataManagerBridge { public abstract class SynchedEntityDataMixin implements SynchedEntityDataBridge {
// @formatter:off // @formatter:off
@Shadow protected abstract <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> key); @Shadow protected abstract <T> SynchedEntityData.DataItem<T> getItem(EntityDataAccessor<T> key);
@Shadow private boolean isDirty; @Shadow private boolean isDirty;
@Shadow @Final private Entity entity; @Shadow @Final private Entity entity;
@Shadow @Nullable public abstract List<SynchedEntityData.DataValue<?>> getNonDefaultValues();
@Shadow public abstract boolean isEmpty();
// @formatter:on // @formatter:on
@Inject(method = "set", at = @At("HEAD")) @Inject(method = "set", at = @At("HEAD"))
@ -42,4 +49,18 @@ public abstract class SynchedEntityDataMixin implements EntityDataManagerBridge
public <T> void bridge$markDirty(EntityDataAccessor<T> key) { public <T> void bridge$markDirty(EntityDataAccessor<T> key) {
this.markDirty(key); this.markDirty(key);
} }
public void refresh(ServerPlayer player) {
if (!this.isEmpty()) {
var list = this.getNonDefaultValues();
if (list != null) {
player.connection.send(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
}
}
}
@Override
public void bridge$refresh(ServerPlayer player) {
refresh(player);
}
} }

View File

@ -3,7 +3,7 @@ package io.izzel.arclight.common.mixin.core.network.protocol.game;
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.minecraft.commands.synchronization.ArgumentTypeInfo; import net.minecraft.commands.synchronization.ArgumentTypeInfo;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import org.spigotmc.SpigotConfig; import org.spigotmc.SpigotConfig;
@ -30,7 +30,7 @@ public class ClientboundCommandsPacket_ArgumentNodeStubMixin {
ci.cancel(); ci.cancel();
buf.writeVarInt(ARCLIGHT_WRAP_INDEX); buf.writeVarInt(ARCLIGHT_WRAP_INDEX);
//noinspection deprecation //noinspection deprecation
buf.writeVarInt(Registry.COMMAND_ARGUMENT_TYPE.getId(type)); buf.writeVarInt(BuiltInRegistries.COMMAND_ARGUMENT_TYPE.getId(type));
var payload = new FriendlyByteBuf(Unpooled.buffer()); var payload = new FriendlyByteBuf(Unpooled.buffer());
type.serializeToNetwork((T) node, payload); type.serializeToNetwork((T) node, payload);
buf.writeVarInt(payload.readableBytes()); buf.writeVarInt(payload.readableBytes());

View File

@ -1,8 +1,6 @@
package io.izzel.arclight.common.mixin.core.server; package io.izzel.arclight.common.mixin.core.server;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixer;
import com.mojang.serialization.DynamicOps;
import io.izzel.arclight.api.ArclightVersion; import io.izzel.arclight.api.ArclightVersion;
import io.izzel.arclight.common.bridge.core.command.ICommandSourceBridge; import io.izzel.arclight.common.bridge.core.command.ICommandSourceBridge;
import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge;
@ -22,30 +20,26 @@ import net.minecraft.Util;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands; import net.minecraft.commands.Commands;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.LayeredRegistryAccess;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistryAccess;
import net.minecraft.nbt.NbtOps; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.status.ServerStatus; import net.minecraft.network.protocol.status.ServerStatus;
import net.minecraft.obfuscate.DontObfuscate; import net.minecraft.obfuscate.DontObfuscate;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ReloadableServerResources; import net.minecraft.server.RegistryLayer;
import net.minecraft.server.ServerFunctionManager; import net.minecraft.server.ServerFunctionManager;
import net.minecraft.server.Services; import net.minecraft.server.Services;
import net.minecraft.server.TickTask; import net.minecraft.server.TickTask;
import net.minecraft.server.WorldLoader;
import net.minecraft.server.WorldStem; import net.minecraft.server.WorldStem;
import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.TicketType; import net.minecraft.server.level.TicketType;
import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.server.level.progress.ChunkProgressListenerFactory; import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.repository.Pack;
import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.server.packs.resources.CloseableResourceManager;
import net.minecraft.server.packs.resources.MultiPackResourceManager;
import net.minecraft.server.players.PlayerList; import net.minecraft.server.players.PlayerList;
import net.minecraft.util.Unit; import net.minecraft.util.Unit;
import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.util.profiling.ProfilerFiller;
@ -56,7 +50,7 @@ import net.minecraft.world.level.DataPackConfig;
import net.minecraft.world.level.ForcedChunksSavedData; import net.minecraft.world.level.ForcedChunksSavedData;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldOptions;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.ServerLevelData;
@ -94,10 +88,7 @@ import java.io.IOException;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.net.Proxy; import java.net.Proxy;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
@ -149,19 +140,20 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
@Shadow private static DataPackConfig getSelectedPacks(PackRepository p_129818_) { return null; } @Shadow private static DataPackConfig getSelectedPacks(PackRepository p_129818_) { return null; }
@Shadow public abstract PlayerList getPlayerList(); @Shadow public abstract PlayerList getPlayerList();
@Shadow @Final private ServerFunctionManager functionManager; @Shadow @Final private ServerFunctionManager functionManager;
@Shadow public abstract boolean previewsChat();
@Shadow public abstract boolean enforceSecureProfile(); @Shadow public abstract boolean enforceSecureProfile();
@Shadow @Final protected Services services; @Shadow @Final protected Services services;
@Shadow private static CrashReport constructOrExtractCrashReport(Throwable p_206569_) { return null; } @Shadow private static CrashReport constructOrExtractCrashReport(Throwable p_206569_) { return null; }
@Shadow @Final private StructureTemplateManager structureTemplateManager; @Shadow @Final private StructureTemplateManager structureTemplateManager;
@Shadow private boolean debugCommandProfilerDelayStart;
@Shadow @Nullable private MinecraftServer.TimeProfiler debugCommandProfiler;
@Shadow public abstract LayeredRegistryAccess<RegistryLayer> registries();
// @formatter:on // @formatter:on
public MinecraftServerMixin(String name) { public MinecraftServerMixin(String name) {
super(name); super(name);
} }
public DataPackConfig datapackconfiguration; public WorldLoader.DataLoadContext worldLoader;
public DynamicOps<Tag> registryreadops;
private boolean forceTicks; private boolean forceTicks;
public CraftServer server; public CraftServer server;
public OptionSet options; public OptionSet options;
@ -199,9 +191,8 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
this.datapackconfiguration = ArclightCaptures.getDatapackConfig();
this.registryreadops = RegistryOps.create(NbtOps.INSTANCE, worldStem.registryAccess());
this.vanillaCommandDispatcher = worldStem.dataPackResources().getCommands(); this.vanillaCommandDispatcher = worldStem.dataPackResources().getCommands();
this.worldLoader = ArclightCaptures.getDataLoadContext();
} }
/** /**
@ -218,7 +209,6 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
this.nextTickTime = Util.getMillis(); this.nextTickTime = Util.getMillis();
this.status.setDescription(Component.literal(this.motd)); this.status.setDescription(Component.literal(this.motd));
this.status.setVersion(new ServerStatus.Version(SharedConstants.getCurrentVersion().getName(), SharedConstants.getCurrentVersion().getProtocolVersion())); this.status.setVersion(new ServerStatus.Version(SharedConstants.getCurrentVersion().getName(), SharedConstants.getCurrentVersion().getProtocolVersion()));
this.status.setPreviewsChat(this.previewsChat());
this.status.setEnforcesSecureChat(this.enforceSecureProfile()); this.status.setEnforcesSecureChat(this.enforceSecureProfile());
this.updateStatusIcon(this.status); this.updateStatusIcon(this.status);
@ -248,6 +238,11 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
currentTick = (int) (System.currentTimeMillis() / 50); currentTick = (int) (System.currentTimeMillis() / 50);
if (this.debugCommandProfilerDelayStart) {
this.debugCommandProfilerDelayStart = false;
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
}
this.nextTickTime += 50L; this.nextTickTime += 50L;
this.startMetricsRecordingTick(); this.startMetricsRecordingTick();
this.profiler.push("tick"); this.profiler.push("tick");
@ -343,7 +338,7 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
@Inject(method = "createLevels", at = @At(value = "NEW", ordinal = 0, target = "net/minecraft/server/level/ServerLevel")) @Inject(method = "createLevels", at = @At(value = "NEW", ordinal = 0, target = "net/minecraft/server/level/ServerLevel"))
private void arclight$registerEnv(ChunkProgressListener p_240787_1_, CallbackInfo ci) { private void arclight$registerEnv(ChunkProgressListener p_240787_1_, CallbackInfo ci) {
BukkitRegistry.registerEnvironments(this.worldData.worldGenSettings().dimensions()); BukkitRegistry.registerEnvironments(this.registryAccess().registryOrThrow(Registries.LEVEL_STEM));
} }
@Redirect(method = "createLevels", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")) @Redirect(method = "createLevels", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
@ -409,8 +404,8 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
} }
// bukkit methods // bukkit methods
public void initWorld(ServerLevel serverWorld, ServerLevelData worldInfo, WorldData saveData, WorldGenSettings generatorSettings) { public void initWorld(ServerLevel serverWorld, ServerLevelData worldInfo, WorldData saveData, WorldOptions worldOptions) {
boolean flag = generatorSettings.isDebug(); boolean flag = saveData.isDebugWorld();
if (((WorldBridge) serverWorld).bridge$getGenerator() != null) { if (((WorldBridge) serverWorld).bridge$getGenerator() != null) {
((WorldBridge) serverWorld).bridge$getWorld().getPopulators().addAll( ((WorldBridge) serverWorld).bridge$getWorld().getPopulators().addAll(
((WorldBridge) serverWorld).bridge$getGenerator().getDefaultPopulators( ((WorldBridge) serverWorld).bridge$getGenerator().getDefaultPopulators(
@ -420,7 +415,7 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
worldborder.applySettings(worldInfo.getWorldBorder()); worldborder.applySettings(worldInfo.getWorldBorder());
if (!worldInfo.isInitialized()) { if (!worldInfo.isInitialized()) {
try { try {
setInitialSpawn(serverWorld, worldInfo, generatorSettings.generateBonusChest(), flag); setInitialSpawn(serverWorld, worldInfo, worldOptions.generateBonusChest(), flag);
worldInfo.setInitialized(true); worldInfo.setInitialized(true);
if (flag) { if (flag) {
this.setupDebugLevel(this.worldData); this.setupDebugLevel(this.worldData);
@ -499,47 +494,13 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop<T
} }
@Inject(method = "saveAllChunks", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;")) @Inject(method = "saveAllChunks", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;"))
private void arclight$skipSave(boolean suppressLog, boolean flush, boolean forced, CallbackInfoReturnable<Boolean> cir, boolean flag) { private void arclight$skipSave(boolean suppressLog, boolean flush, boolean forced, CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(flag); cir.setReturnValue(!this.levels.isEmpty());
} }
/** @Inject(method = "desc=/V$/", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/repository/PackRepository;setSelected(Ljava/util/Collection;)V"))
* @author IzzelAliz private void arclight$syncCommand(CallbackInfo ci) {
* @reason
*/
@Overwrite
public CompletableFuture<Void> reloadResources(Collection<String> p_129862_) {
RegistryAccess.Frozen registryaccess$frozen = this.registryAccess();
CompletableFuture<Void> completablefuture = CompletableFuture.supplyAsync(() -> {
return p_129862_.stream().map(this.packRepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList());
}, this).thenCompose((p_212913_) -> {
CloseableResourceManager closeableresourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, p_212913_);
return ReloadableServerResources.loadResources(closeableresourcemanager, registryaccess$frozen, this.isDedicatedServer() ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED, this.getFunctionCompilationLevel(), this.executor, this).whenComplete((p_212907_, p_212908_) -> {
if (p_212908_ != null) {
closeableresourcemanager.close();
}
}).thenApply((p_212904_) -> {
return new MinecraftServer.ReloadableResources(closeableresourcemanager, p_212904_);
});
}).thenAcceptAsync((p_212919_) -> {
this.resources.close();
this.resources = p_212919_;
this.server.syncCommands(); this.server.syncCommands();
this.packRepository.setSelected(p_129862_);
this.worldData.setDataPackConfig(getSelectedPacks(this.packRepository));
this.resources.managers().updateRegistryTags(this.registryAccess());
this.getPlayerList().saveAll();
this.getPlayerList().reloadResources();
this.functionManager.replaceLibrary(this.resources.managers().getFunctionLibrary());
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager());
this.getPlayerList().getPlayers().forEach(this.getPlayerList()::sendPlayerPermissionLevel); //Forge: Fix newly added/modified commands not being sent to the client when commands reload.
}, this);
if (this.isSameThread()) {
this.managedBlock(completablefuture::isDone);
}
return completablefuture;
} }
/** /**

View File

@ -0,0 +1,17 @@
package io.izzel.arclight.common.mixin.core.server;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import net.minecraft.server.WorldLoader;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(WorldLoader.class)
public class WorldLoaderMixin {
@ModifyArg(method = "load", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/WorldLoader$WorldDataSupplier;get(Lnet/minecraft/server/WorldLoader$DataLoadContext;)Lnet/minecraft/server/WorldLoader$DataLoadOutput;"))
private static WorldLoader.DataLoadContext arclight$captureContext(WorldLoader.DataLoadContext context) {
ArclightCaptures.captureDataLoadContext(context);
return context;
}
}

View File

@ -1,21 +0,0 @@
package io.izzel.arclight.common.mixin.core.server;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldLoader;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.world.level.DataPackConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(WorldLoader.PackConfig.class)
public class WorldLoader_PackConfigMixin {
@Redirect(method = "createResourceManager", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;configurePackRepository(Lnet/minecraft/server/packs/repository/PackRepository;Lnet/minecraft/world/level/DataPackConfig;Z)Lnet/minecraft/world/level/DataPackConfig;"))
private DataPackConfig arclight$capturePack(PackRepository s, DataPackConfig s1, boolean pack) {
var dataPackConfig = MinecraftServer.configurePackRepository(s, s1, pack);
ArclightCaptures.captureDatapackConfig(dataPackConfig);
return dataPackConfig;
}
}

View File

@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.server.commands;
import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge; import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.Holder;
import net.minecraft.server.commands.EffectCommands; import net.minecraft.server.commands.EffectCommands;
import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -18,7 +19,7 @@ import java.util.Collection;
public class EffectCommandMixin { public class EffectCommandMixin {
@Inject(method = "giveEffect", at = @At("HEAD")) @Inject(method = "giveEffect", at = @At("HEAD"))
private static void arclight$addReason(CommandSourceStack source, Collection<? extends Entity> targets, MobEffect effect, Integer seconds, int amplifier, boolean showParticles, CallbackInfoReturnable<Integer> cir) { private static void arclight$addReason(CommandSourceStack p_250553_, Collection<? extends Entity> targets, Holder<MobEffect> p_249495_, Integer p_249652_, int p_251498_, boolean p_249944_, CallbackInfoReturnable<Integer> cir) {
for (Entity entity : targets) { for (Entity entity : targets) {
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity) {
((LivingEntityBridge) entity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.COMMAND); ((LivingEntityBridge) entity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.COMMAND);
@ -36,7 +37,7 @@ public class EffectCommandMixin {
} }
@Inject(method = "clearEffect", at = @At("HEAD")) @Inject(method = "clearEffect", at = @At("HEAD"))
private static void arclight$removeReason(CommandSourceStack source, Collection<? extends Entity> targets, MobEffect effect, CallbackInfoReturnable<Integer> cir) { private static void arclight$removeReason(CommandSourceStack p_250069_, Collection<? extends Entity> targets, Holder<MobEffect> p_249198_, CallbackInfoReturnable<Integer> cir) {
for (Entity entity : targets) { for (Entity entity : targets) {
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity) {
((LivingEntityBridge) entity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.COMMAND); ((LivingEntityBridge) entity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.COMMAND);

View File

@ -2,9 +2,10 @@ package io.izzel.arclight.common.mixin.core.server.commands;
import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge; import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.Holder;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.commands.SummonCommand; import net.minecraft.server.commands.SummonCommand;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -16,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public class SummonCommandMixin { public class SummonCommandMixin {
@Inject(method = "spawnEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;tryAddFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)Z")) @Inject(method = "spawnEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;tryAddFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)Z"))
private static void arclight$summonReason(CommandSourceStack source, ResourceLocation type, Vec3 pos, CompoundTag nbt, boolean randomizeProperties, CallbackInfoReturnable<Integer> cir) { private static void arclight$summonReason(CommandSourceStack source, Holder.Reference<EntityType<?>> p_251948_, Vec3 p_251429_, CompoundTag p_250568_, boolean p_250229_, CallbackInfoReturnable<Integer> cir) {
((ServerWorldBridge) source.getLevel()).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.COMMAND); ((ServerWorldBridge) source.getLevel()).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.COMMAND);
} }
} }

View File

@ -4,7 +4,7 @@ import com.mojang.datafixers.DataFixer;
import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import io.izzel.arclight.common.bridge.core.world.server.ChunkMapBridge; import io.izzel.arclight.common.bridge.core.world.server.ChunkMapBridge;
import io.izzel.arclight.common.mod.util.ArclightCallbackExecutor; import io.izzel.arclight.common.mod.util.ArclightCallbackExecutor;
import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ChunkMap;
@ -45,7 +45,7 @@ public abstract class ChunkMapMixin implements ChunkMapBridge {
@Shadow protected abstract void tick(); @Shadow protected abstract void tick();
@Shadow @Mutable public ChunkGenerator generator; @Shadow @Mutable public ChunkGenerator generator;
@Shadow @Final public ServerLevel level; @Shadow @Final public ServerLevel level;
@Shadow private RandomState randomState; @Shadow @Final @Mutable private RandomState randomState;
@Invoker("tick") public abstract void bridge$tick(BooleanSupplier hasMoreTime); @Invoker("tick") public abstract void bridge$tick(BooleanSupplier hasMoreTime);
@Invoker("setViewDistance") public abstract void bridge$setViewDistance(int i); @Invoker("setViewDistance") public abstract void bridge$setViewDistance(int i);
// @formatter:on // @formatter:on
@ -89,9 +89,9 @@ public abstract class ChunkMapMixin implements ChunkMapBridge {
generator = custom.getDelegate(); generator = custom.getDelegate();
} }
if (generator instanceof NoiseBasedChunkGenerator noisebasedchunkgenerator) { if (generator instanceof NoiseBasedChunkGenerator noisebasedchunkgenerator) {
this.randomState = RandomState.create(noisebasedchunkgenerator.generatorSettings().value(), this.level.registryAccess().registryOrThrow(Registry.NOISE_REGISTRY), this.level.getSeed()); this.randomState = RandomState.create(noisebasedchunkgenerator.generatorSettings().value(), this.level.registryAccess().lookupOrThrow(Registries.NOISE), this.level.getSeed());
} else { } else {
this.randomState = RandomState.create(NoiseGeneratorSettings.dummy(), this.level.registryAccess().registryOrThrow(Registry.NOISE_REGISTRY), this.level.getSeed()); this.randomState = RandomState.create(NoiseGeneratorSettings.dummy(), this.level.registryAccess().lookupOrThrow(Registries.NOISE), this.level.getSeed());
} }
} }
} }

View File

@ -33,7 +33,7 @@ public abstract class DistanceManagerMixin implements TicketManagerBridge {
@Shadow private static int getTicketLevelAt(SortedArraySet<Ticket<?>> p_229844_0_) { return 0; } @Shadow private static int getTicketLevelAt(SortedArraySet<Ticket<?>> p_229844_0_) { return 0; }
@Shadow @Final public Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets; @Shadow @Final public Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets;
@Shadow abstract TickingTracker tickingTracker(); @Shadow abstract TickingTracker tickingTracker();
@Shadow @Final private Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> forcedTickets; @Shadow(remap = false) @Final private Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> forcedTickets;
@Invoker("purgeStaleTickets") public abstract void bridge$tick(); @Invoker("purgeStaleTickets") public abstract void bridge$tick();
// @formatter:on // @formatter:on

View File

@ -49,6 +49,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@ -77,6 +78,7 @@ public abstract class ServerEntityMixin implements ServerEntityBridge {
@Shadow private Vec3 ap; @Shadow private Vec3 ap;
@Shadow private int yHeadRotp; @Shadow private int yHeadRotp;
@Shadow protected abstract void broadcastAndSend(Packet<?> packet); @Shadow protected abstract void broadcastAndSend(Packet<?> packet);
@Shadow @Nullable private List<SynchedEntityData.DataValue<?>> trackedDataValues;
// @formatter:on // @formatter:on
private Set<ServerPlayerConnection> trackedPlayers; private Set<ServerPlayerConnection> trackedPlayers;
@ -259,8 +261,8 @@ public abstract class ServerEntityMixin implements ServerEntityBridge {
Packet<?> packet = this.entity.getAddEntityPacket(); Packet<?> packet = this.entity.getAddEntityPacket();
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f); this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
consumer.accept(packet); consumer.accept(packet);
if (!this.entity.getEntityData().isEmpty()) { if (this.trackedDataValues != null) {
consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.entity.getEntityData(), true)); consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.trackedDataValues));
} }
boolean flag = this.trackDelta; boolean flag = this.trackDelta;
if (this.entity instanceof LivingEntity livingEntity) { if (this.entity instanceof LivingEntity livingEntity) {
@ -310,7 +312,7 @@ public abstract class ServerEntityMixin implements ServerEntityBridge {
} }
@Inject(method = "sendDirtyEntityData", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerEntity;broadcastAndSend(Lnet/minecraft/network/protocol/Packet;)V")) @Inject(method = "sendDirtyEntityData", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerEntity;broadcastAndSend(Lnet/minecraft/network/protocol/Packet;)V"))
private void arclight$sendScaledHealth(CallbackInfo ci, SynchedEntityData entitydatamanager, Set<AttributeInstance> set) { private void arclight$sendScaledHealth(CallbackInfo ci, SynchedEntityData entitydatamanager, List<SynchedEntityData.DataValue<?>> list, Set<AttributeInstance> set) {
if (this.entity instanceof ServerPlayerEntityBridge player) { if (this.entity instanceof ServerPlayerEntityBridge player) {
player.bridge$getBukkitEntity().injectScaledMaxHealth(set, false); player.bridge$getBukkitEntity().injectScaledMaxHealth(set, false);
} }

View File

@ -21,8 +21,9 @@ import io.izzel.arclight.common.mod.util.DelegateWorldInfo;
import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.common.mod.util.DistValidate;
import io.izzel.arclight.i18n.ArclightConfig; import io.izzel.arclight.i18n.ArclightConfig;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket; import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
@ -148,13 +149,13 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld
if (typeKey != null) { if (typeKey != null) {
this.typeKey = typeKey; this.typeKey = typeKey;
} else { } else {
var dimensions = shadow$getServer().getWorldData().worldGenSettings().dimensions(); var dimensions = shadow$getServer().registryAccess().registryOrThrow(Registries.LEVEL_STEM);
var key = dimensions.getKey(levelStem); var key = dimensions.getResourceKey(levelStem);
if (key != null) { if (key.isPresent()) {
this.typeKey = ResourceKey.create(Registry.LEVEL_STEM_REGISTRY, key); this.typeKey = key.get();
} else { } else {
ArclightMod.LOGGER.warn("Assign {} to unknown level stem {}", dimension.location(), levelStem); ArclightMod.LOGGER.warn("Assign {} to unknown level stem {}", dimension.location(), levelStem);
this.typeKey = ResourceKey.create(Registry.LEVEL_STEM_REGISTRY, dimension.location()); this.typeKey = ResourceKey.create(Registries.LEVEL_STEM, dimension.location());
} }
} }
if (worldInfo instanceof PrimaryLevelData) { if (worldInfo instanceof PrimaryLevelData) {
@ -185,7 +186,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld
private void arclight$gameEventEvent(GameEvent gameEvent, Vec3 pos, GameEvent.Context context, CallbackInfo ci) { private void arclight$gameEventEvent(GameEvent gameEvent, Vec3 pos, GameEvent.Context context, CallbackInfo ci) {
var entity = context.sourceEntity(); var entity = context.sourceEntity();
var i = gameEvent.getNotificationRadius(); var i = gameEvent.getNotificationRadius();
GenericGameEvent event = new GenericGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameEvent))), new Location(this.getWorld(), pos.x(), pos.y(), pos.z()), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), i, !Bukkit.isPrimaryThread()); GenericGameEvent event = new GenericGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(gameEvent))), new Location(this.getWorld(), pos.x(), pos.y(), pos.z()), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), i, !Bukkit.isPrimaryThread());
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
ci.cancel(); ci.cancel();
@ -269,7 +270,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld
if (this.serverLevelData instanceof PrimaryLevelData worldInfo) { if (this.serverLevelData instanceof PrimaryLevelData worldInfo) {
worldInfo.setWorldBorder(this.getWorldBorder().createSettings()); worldInfo.setWorldBorder(this.getWorldBorder().createSettings());
worldInfo.setCustomBossEvents(this.shadow$getServer().getCustomBossEvents().save()); worldInfo.setCustomBossEvents(this.shadow$getServer().getCustomBossEvents().save());
this.convertable.saveDataTag(this.shadow$getServer().registryHolder, worldInfo, this.shadow$getServer().getPlayerList().getSingleplayerData()); this.convertable.saveDataTag(this.shadow$getServer().registryAccess(), worldInfo, this.shadow$getServer().getPlayerList().getSingleplayerData());
} }
} }
@ -377,11 +378,10 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld
return tryAddFreshEntityWithPassengers(entity, reason); return tryAddFreshEntityWithPassengers(entity, reason);
} }
@Inject(method = "explode", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, @Inject(method = "explode", cancellable = true, at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/level/Explosion;finalizeExplosion(Z)V"), locals = LocalCapture.CAPTURE_FAILHARD) target = "Lnet/minecraft/world/level/Explosion;interactsWithBlocks()Z"), locals = LocalCapture.CAPTURE_FAILHARD)
public void arclight$doExplosion(Entity entityIn, DamageSource damageSourceIn, @Nullable ExplosionDamageCalculator context, double xIn, double yIn, double zIn, private void arclight$doExplosion(Entity p_256039_, DamageSource p_255778_, ExplosionDamageCalculator p_256002_, double p_256067_, double p_256370_, double p_256153_, float p_256045_, boolean p_255686_, Level.ExplosionInteraction p_255827_,
float explosionRadius, boolean causesFire, Explosion.BlockInteraction modeIn, CallbackInfoReturnable<Explosion> cir, CallbackInfoReturnable<Explosion> cir, Explosion explosion) {
Explosion explosion) {
if (((ExplosionBridge) explosion).bridge$wasCancelled()) { if (((ExplosionBridge) explosion).bridge$wasCancelled()) {
cir.setReturnValue(explosion); cir.setReturnValue(explosion);
} }

View File

@ -14,7 +14,7 @@ import io.izzel.arclight.common.mod.server.ArclightServer;
import io.izzel.arclight.common.mod.util.ArclightCaptures; import io.izzel.arclight.common.mod.util.ArclightCaptures;
import io.izzel.arclight.mixin.Eject; import io.izzel.arclight.mixin.Eject;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess; import net.minecraft.core.LayeredRegistryAccess;
import net.minecraft.core.UUIDUtil; import net.minecraft.core.UUIDUtil;
import net.minecraft.network.Connection; import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -31,6 +31,7 @@ import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.RegistryLayer;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@ -48,7 +49,6 @@ import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.ProfilePublicKey;
import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.BiomeManager; import net.minecraft.world.level.biome.BiomeManager;
@ -130,7 +130,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
} }
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
private void arclight$loadServer(MinecraftServer minecraftServer, RegistryAccess.Frozen p_i231425_2_, PlayerDataStorage p_i231425_3_, int p_i231425_4_, CallbackInfo ci) { private void arclight$loadServer(MinecraftServer minecraftServer, LayeredRegistryAccess<RegistryLayer> p_251844_, PlayerDataStorage p_203844_, int p_203845_, CallbackInfo ci) {
cserver = ArclightServer.createOrLoad((DedicatedServer) minecraftServer, (PlayerList) (Object) this); cserver = ArclightServer.createOrLoad((DedicatedServer) minecraftServer, (PlayerList) (Object) this);
} }
@ -209,7 +209,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
} }
@Override @Override
public ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler, ProfilePublicKey profilePublicKey) { public ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler) {
UUID uuid = UUIDUtil.getOrCreatePlayerUUID(gameProfile); UUID uuid = UUIDUtil.getOrCreatePlayerUUID(gameProfile);
List<ServerPlayer> list = Lists.newArrayList(); List<ServerPlayer> list = Lists.newArrayList();
for (ServerPlayer entityplayer : this.players) { for (ServerPlayer entityplayer : this.players) {
@ -221,7 +221,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
this.save(entityplayer); this.save(entityplayer);
entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login")); entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login"));
} }
ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, profilePublicKey); ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile);
Player player = ((ServerPlayerEntityBridge) entity).bridge$getBukkitEntity(); Player player = ((ServerPlayerEntityBridge) entity).bridge$getBukkitEntity();
String hostname = handler == null ? "" : ((NetworkManagerBridge) handler.connection).bridge$getHostname(); String hostname = handler == null ? "" : ((NetworkManagerBridge) handler.connection).bridge$getHostname();
@ -332,7 +332,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
playerIn.setPos(playerIn.getX(), playerIn.getY() + 1.0, playerIn.getZ()); playerIn.setPos(playerIn.getX(), playerIn.getY() + 1.0, playerIn.getZ());
} }
LevelData worlddata = serverWorld.getLevelData(); LevelData worlddata = serverWorld.getLevelData();
playerIn.connection.send(new ClientboundRespawnPacket(serverWorld.dimensionTypeId(), serverWorld.dimension(), BiomeManager.obfuscateSeed(serverWorld.getSeed()), playerIn.gameMode.getGameModeForPlayer(), playerIn.gameMode.getPreviousGameModeForPlayer(), serverWorld.isDebug(), serverWorld.isFlat(), flag, playerIn.getLastDeathLocation())); playerIn.connection.send(new ClientboundRespawnPacket(serverWorld.dimensionTypeId(), serverWorld.dimension(), BiomeManager.obfuscateSeed(serverWorld.getSeed()), playerIn.gameMode.getGameModeForPlayer(), playerIn.gameMode.getPreviousGameModeForPlayer(), serverWorld.isDebug(), serverWorld.isFlat(), (byte) (flag ? 1 : 0), playerIn.getLastDeathLocation()));
playerIn.connection.send(new ClientboundSetChunkCacheRadiusPacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); playerIn.connection.send(new ClientboundSetChunkCacheRadiusPacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance));
playerIn.connection.send(new ClientboundSetSimulationDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().simulationDistance)); playerIn.connection.send(new ClientboundSetSimulationDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().simulationDistance));
playerIn.setLevel(serverWorld); playerIn.setLevel(serverWorld);
@ -446,7 +446,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
ServerLevel serverWorld = ((CraftWorld) location.getWorld()).getHandle(); ServerLevel serverWorld = ((CraftWorld) location.getWorld()).getHandle();
ServerPlayer serverplayerentity = new ServerPlayer(this.server, serverWorld, playerIn.getGameProfile(), playerIn.getProfilePublicKey()); ServerPlayer serverplayerentity = new ServerPlayer(this.server, serverWorld, playerIn.getGameProfile());
// Forward to new player instance // Forward to new player instance
((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity); ((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity);
@ -478,7 +478,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
} }
LevelData iworldinfo = serverplayerentity.level.getLevelData(); LevelData iworldinfo = serverplayerentity.level.getLevelData();
serverplayerentity.connection.send(new ClientboundRespawnPacket(serverplayerentity.level.dimensionTypeId(), serverplayerentity.level.dimension(), BiomeManager.obfuscateSeed(serverplayerentity.getLevel().getSeed()), serverplayerentity.gameMode.getGameModeForPlayer(), serverplayerentity.gameMode.getPreviousGameModeForPlayer(), serverplayerentity.getLevel().isDebug(), serverplayerentity.getLevel().isFlat(), conqueredEnd, serverplayerentity.getLastDeathLocation())); serverplayerentity.connection.send(new ClientboundRespawnPacket(serverplayerentity.level.dimensionTypeId(), serverplayerentity.level.dimension(), BiomeManager.obfuscateSeed(serverplayerentity.getLevel().getSeed()), serverplayerentity.gameMode.getGameModeForPlayer(), serverplayerentity.gameMode.getPreviousGameModeForPlayer(), serverplayerentity.getLevel().isDebug(), serverplayerentity.getLevel().isFlat(), (byte) (conqueredEnd ? 1 : 0), serverplayerentity.getLastDeathLocation()));
serverplayerentity.connection.send(new ClientboundSetChunkCacheRadiusPacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); serverplayerentity.connection.send(new ClientboundSetChunkCacheRadiusPacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance));
serverplayerentity.connection.send(new ClientboundSetSimulationDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().simulationDistance)); serverplayerentity.connection.send(new ClientboundSetSimulationDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().simulationDistance));
serverplayerentity.setLevel(serverWorld); serverplayerentity.setLevel(serverWorld);

View File

@ -212,12 +212,12 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana
} }
} }
@Inject(method = "destroyBlock", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/common/ForgeHooks;onBlockBreakEvent(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/GameType;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/core/BlockPos;)I")) @Inject(method = "destroyBlock", remap = true, at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/common/ForgeHooks;onBlockBreakEvent(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/GameType;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/core/BlockPos;)I"))
public void arclight$beforePrimaryEventFired(BlockPos pos, CallbackInfoReturnable<Boolean> cir) { public void arclight$beforePrimaryEventFired(BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
ArclightCaptures.captureNextBlockBreakEventAsPrimaryEvent(); ArclightCaptures.captureNextBlockBreakEventAsPrimaryEvent();
} }
@Inject(method = "destroyBlock", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraftforge/common/ForgeHooks;onBlockBreakEvent(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/GameType;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/core/BlockPos;)I")) @Inject(method = "destroyBlock", remap = true, at = @At(value = "INVOKE_ASSIGN", remap = false, target = "Lnet/minecraftforge/common/ForgeHooks;onBlockBreakEvent(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/GameType;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/core/BlockPos;)I"))
public void arclight$handleSecondaryBlockBreakEvents(BlockPos pos, CallbackInfoReturnable<Boolean> cir) { public void arclight$handleSecondaryBlockBreakEvents(BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
ArclightCaptures.BlockBreakEventContext breakEventContext = ArclightCaptures.popSecondaryBlockBreakEvent(); ArclightCaptures.BlockBreakEventContext breakEventContext = ArclightCaptures.popSecondaryBlockBreakEvent();
while (breakEventContext != null) { while (breakEventContext != null) {
@ -284,7 +284,9 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana
BlockState blockstate = worldIn.getBlockState(blockpos); BlockState blockstate = worldIn.getBlockState(blockpos);
InteractionResult resultType = InteractionResult.PASS; InteractionResult resultType = InteractionResult.PASS;
boolean cancelledBlock = false; boolean cancelledBlock = false;
if (this.gameModeForPlayer == GameType.SPECTATOR) { if (!blockstate.getBlock().isEnabled(worldIn.enabledFeatures())) {
return InteractionResult.FAIL;
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
MenuProvider provider = blockstate.getMenuProvider(worldIn, blockpos); MenuProvider provider = blockstate.getMenuProvider(worldIn, blockpos);
cancelledBlock = !(provider instanceof MenuProvider); cancelledBlock = !(provider instanceof MenuProvider);
} }

View File

@ -79,10 +79,10 @@ public abstract class ExplosionMixin implements ExplosionBridge {
@Shadow @Final private RandomSource random; @Shadow @Final private RandomSource random;
@Shadow private static void addBlockDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> dropPositionArray, ItemStack stack, BlockPos pos) { } @Shadow private static void addBlockDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> dropPositionArray, ItemStack stack, BlockPos pos) { }
@Shadow @Final private ExplosionDamageCalculator damageCalculator; @Shadow @Final private ExplosionDamageCalculator damageCalculator;
@Shadow @Nullable public abstract LivingEntity getSourceMob(); @Shadow public abstract boolean interactsWithBlocks();
@Shadow @Nullable public abstract LivingEntity getIndirectSourceEntity();
// @formatter:on // @formatter:on
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;)V", @Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;)V",
at = @At("RETURN")) at = @At("RETURN"))
public void arclight$adjustSize(Level worldIn, Entity exploderIn, double xIn, double yIn, double zIn, float sizeIn, boolean causesFireIn, Explosion.BlockInteraction modeIn, CallbackInfo ci) { public void arclight$adjustSize(Level worldIn, Entity exploderIn, double xIn, double yIn, double zIn, float sizeIn, boolean causesFireIn, Explosion.BlockInteraction modeIn, CallbackInfo ci) {
@ -236,7 +236,7 @@ public abstract class ExplosionMixin implements ExplosionBridge {
this.level.playLocalSound(this.x, this.y, this.z, SoundEvents.GENERIC_EXPLODE, SoundSource.BLOCKS, 4.0F, (1.0F + (this.level.random.nextFloat() - this.level.random.nextFloat()) * 0.2F) * 0.7F, false); this.level.playLocalSound(this.x, this.y, this.z, SoundEvents.GENERIC_EXPLODE, SoundSource.BLOCKS, 4.0F, (1.0F + (this.level.random.nextFloat() - this.level.random.nextFloat()) * 0.2F) * 0.7F, false);
} }
boolean flag = this.blockInteraction != Explosion.BlockInteraction.NONE; boolean flag = this.interactsWithBlocks();
if (spawnParticles) { if (spawnParticles) {
if (!(this.radius < 2.0F) && flag) { if (!(this.radius < 2.0F) && flag) {
this.level.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D); this.level.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
@ -247,7 +247,7 @@ public abstract class ExplosionMixin implements ExplosionBridge {
if (flag) { if (flag) {
ObjectArrayList<Pair<ItemStack, BlockPos>> objectarraylist = new ObjectArrayList<>(); ObjectArrayList<Pair<ItemStack, BlockPos>> objectarraylist = new ObjectArrayList<>();
boolean flag2 = this.getSourceMob() instanceof Player; boolean flag2 = this.getIndirectSourceEntity() instanceof Player;
Util.shuffle(this.toBlow, this.level.random); Util.shuffle(this.toBlow, this.level.random);
float yield = this.callBlockExplodeEvent(); float yield = this.callBlockExplodeEvent();
@ -266,7 +266,7 @@ public abstract class ExplosionMixin implements ExplosionBridge {
if (blockstate.canDropFromExplosion(this.level, blockpos, (Explosion) (Object) this) && this.level instanceof ServerLevel serverLevel) { if (blockstate.canDropFromExplosion(this.level, blockpos, (Explosion) (Object) this) && this.level instanceof ServerLevel serverLevel) {
BlockEntity tileentity = blockstate.hasBlockEntity() ? this.level.getBlockEntity(blockpos) : null; BlockEntity tileentity = blockstate.hasBlockEntity() ? this.level.getBlockEntity(blockpos) : null;
LootContext.Builder lootcontext$builder = new LootContext.Builder(serverLevel).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source); LootContext.Builder lootcontext$builder = new LootContext.Builder(serverLevel).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source);
if (this.blockInteraction == Explosion.BlockInteraction.DESTROY || yield < 1.0F) { if (this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY || yield < 1.0F) {
lootcontext$builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / yield); lootcontext$builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / yield);
} }

View File

@ -1,22 +1,15 @@
package io.izzel.arclight.common.mixin.core.world.damagesource; package io.izzel.arclight.common.mixin.core.world.damagesource;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import io.izzel.arclight.common.bridge.core.util.IndirectEntityDamageSourceBridge; import io.izzel.arclight.common.bridge.core.util.IndirectEntityDamageSourceBridge;
import net.minecraft.world.damagesource.IndirectEntityDamageSource; import net.minecraft.world.damagesource.IndirectEntityDamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Mixin;
@Mixin(IndirectEntityDamageSource.class) @Mixin(IndirectEntityDamageSource.class)
public class IndirectEntityDamageSourceMixin extends DamageSourceMixin implements IndirectEntityDamageSourceBridge { public class IndirectEntityDamageSourceMixin extends DamageSourceMixin implements IndirectEntityDamageSourceBridge {
// @formatter:off
@Shadow @Final private Entity owner;
// @formatter:on
public Entity getProximateDamageSource() { public Entity getProximateDamageSource() {
Entity trueSource = super.getEntity(); return getEntity();
return trueSource == null ? this.owner : trueSource;
} }
@Override @Override

View File

@ -3,7 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.entity;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import io.izzel.arclight.common.bridge.core.entity.AreaEffectCloudEntityBridge; import io.izzel.arclight.common.bridge.core.entity.AreaEffectCloudEntityBridge;
import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge; import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
@ -208,11 +208,11 @@ public abstract class AreaEffectCloudEntityMixin extends EntityMixin implements
} }
public String getPotionType() { public String getPotionType() {
return Registry.POTION.getKey(this.potion).toString(); return BuiltInRegistries.POTION.getKey(this.potion).toString();
} }
public void setPotionType(final String string) { public void setPotionType(final String string) {
this.setPotion(Registry.POTION.get(new ResourceLocation(string))); this.setPotion(BuiltInRegistries.POTION.get(new ResourceLocation(string)));
} }
@Override @Override

View File

@ -8,7 +8,7 @@ import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import io.izzel.arclight.common.bridge.core.entity.InternalEntityBridge; import io.izzel.arclight.common.bridge.core.entity.InternalEntityBridge;
import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge; import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.core.network.datasync.EntityDataManagerBridge; import io.izzel.arclight.common.bridge.core.network.datasync.SynchedEntityDataBridge;
import io.izzel.arclight.common.bridge.core.world.TeleporterBridge; import io.izzel.arclight.common.bridge.core.world.TeleporterBridge;
import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import io.izzel.arclight.common.mod.util.ArclightCaptures; import io.izzel.arclight.common.mod.util.ArclightCaptures;
@ -789,7 +789,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
if (event.isCancelled() && this.getAirSupply() != -1) { if (event.isCancelled() && this.getAirSupply() != -1) {
ci.cancel(); ci.cancel();
((EntityDataManagerBridge) this.getEntityData()).bridge$markDirty(DATA_AIR_SUPPLY_ID); ((SynchedEntityDataBridge) this.getEntityData()).bridge$markDirty(DATA_AIR_SUPPLY_ID);
return; return;
} }
this.entityData.set(DATA_AIR_SUPPLY_ID, event.getAmount()); this.entityData.set(DATA_AIR_SUPPLY_ID, event.getAmount());
@ -967,7 +967,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
ArclightCaptures.captureCraftPortalEvent(event); ArclightCaptures.captureCraftPortalEvent(event);
return PortalShape.createPortalInfo(worldFinal, result, direction$axis, vector3d, this.getDimensions(this.getPose()), this.getDeltaMovement(), this.getYRot(), this.getXRot()); return PortalShape.createPortalInfo(worldFinal, result, direction$axis, vector3d, (Entity) (Object) this, this.getDeltaMovement(), this.getYRot(), this.getXRot());
}).orElse(null); }).orElse(null);
} }
} else { } else {

View File

@ -4,12 +4,12 @@ import io.izzel.arclight.common.bridge.core.entity.EntityTypeBridge;
import io.izzel.arclight.common.bridge.core.world.IWorldWriterBridge; import io.izzel.arclight.common.bridge.core.world.IWorldWriterBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -20,46 +20,51 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.function.Consumer;
@Mixin(EntityType.class) @Mixin(EntityType.class)
public abstract class EntityTypeMixin<T extends Entity> implements EntityTypeBridge<T> { public abstract class EntityTypeMixin<T extends Entity> implements EntityTypeBridge<T> {
// @formatter:off // @formatter:off
@Shadow @Nullable public abstract T create(ServerLevel worldIn, @Nullable CompoundTag compound, @Nullable Component customName, @Nullable Player playerIn, BlockPos pos, MobSpawnType reason, boolean p_220349_7_, boolean p_220349_8_); @Shadow @Nullable public abstract T create(ServerLevel p_262637_, @org.jetbrains.annotations.Nullable CompoundTag p_262687_, @org.jetbrains.annotations.Nullable Consumer<T> p_262629_, BlockPos p_262595_, MobSpawnType p_262666_, boolean p_262685_, boolean p_262588_);
// @formatter:on // @formatter:on
@Inject(method = "spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;", @Inject(method = "spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;",
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")) at = @At(value = "HEAD"))
private void arclight$spawnReason(ServerLevel worldIn, CompoundTag compound, Component customName, Player playerIn, BlockPos pos, MobSpawnType reason, boolean p_220342_7_, boolean p_220342_8_, CallbackInfoReturnable<T> cir) { private void arclight$spawnReason(ServerLevel worldIn, ItemStack p_20594_, Player p_20595_, BlockPos p_20596_, MobSpawnType p_20597_, boolean p_20598_, boolean p_20599_, CallbackInfoReturnable<T> cir) {
CreatureSpawnEvent.SpawnReason spawnReason = ((IWorldWriterBridge) worldIn).bridge$getAddEntityReason(); CreatureSpawnEvent.SpawnReason spawnReason = ((IWorldWriterBridge) worldIn).bridge$getAddEntityReason();
if (spawnReason == null) { if (spawnReason == null) {
((IWorldWriterBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); ((IWorldWriterBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.SPAWNER_EGG);
} }
} }
@Inject(method = "spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;", @Inject(method = "spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Ljava/util/function/Consumer;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;",
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At("RETURN"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At("RETURN"),
slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"))) slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")))
private void arclight$returnIfSuccess(ServerLevel worldIn, CompoundTag compound, Component customName, Player playerIn, BlockPos pos, MobSpawnType reason, boolean p_220342_7_, boolean p_220342_8_, CallbackInfoReturnable<T> cir, T t) { private void arclight$returnIfSuccess(ServerLevel p_262704_, CompoundTag p_262603_, Consumer<T> p_262621_, BlockPos p_262672_, MobSpawnType p_262644_, boolean p_262690_, boolean p_262590_, CallbackInfoReturnable<T> cir, T t) {
if (t != null) { if (t != null) {
cir.setReturnValue(t.isRemoved() ? null : t); cir.setReturnValue(t.isRemoved() ? null : t);
} }
} }
public T spawn(ServerLevel worldIn, @Nullable CompoundTag compound, @Nullable Component customName, @Nullable Player playerIn, BlockPos pos, MobSpawnType reason, boolean p_220342_7_, boolean p_220342_8_, CreatureSpawnEvent.SpawnReason spawnReason) { public T spawn(ServerLevel p_262634_, BlockPos p_262707_, MobSpawnType p_262597_, CreatureSpawnEvent.SpawnReason spawnReason) {
T t = this.create(worldIn, compound, customName, playerIn, pos, reason, p_220342_7_, p_220342_8_); return this.spawn(p_262634_, null, null, p_262707_, p_262597_, false, false, spawnReason);
}
public T spawn(ServerLevel p_262704_, @Nullable CompoundTag p_262603_, @Nullable Consumer<T> p_262621_, BlockPos p_262672_, MobSpawnType p_262644_, boolean p_262690_, boolean p_262590_, CreatureSpawnEvent.SpawnReason spawnReason) {
T t = this.create(p_262704_, p_262603_, p_262621_, p_262672_, p_262644_, p_262690_, p_262590_);
if (t != null) { if (t != null) {
if (t instanceof net.minecraft.world.entity.Mob && net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn((net.minecraft.world.entity.Mob) t, worldIn, pos.getX(), pos.getY(), pos.getZ(), null, reason)) if (t instanceof net.minecraft.world.entity.Mob && net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn((net.minecraft.world.entity.Mob) t, p_262704_, p_262672_.getX(), p_262672_.getY(), p_262672_.getZ(), null, p_262644_))
return null; return null;
((IWorldWriterBridge) worldIn).bridge$pushAddEntityReason(spawnReason); ((IWorldWriterBridge) p_262704_).bridge$pushAddEntityReason(spawnReason);
worldIn.addFreshEntityWithPassengers(t); p_262704_.addFreshEntityWithPassengers(t);
return t.isRemoved() ? null : t; return t.isRemoved() ? null : t;
} }
return null; return null;
} }
@Override @Override
public T bridge$spawnCreature(ServerLevel worldIn, @Nullable CompoundTag compound, @Nullable Component customName, @Nullable Player playerIn, BlockPos pos, MobSpawnType reason, boolean flag, boolean flag1, CreatureSpawnEvent.SpawnReason spawnReason) { public T bridge$spawnCreature(ServerLevel worldIn, BlockPos pos, MobSpawnType mobSpawnType, CreatureSpawnEvent.SpawnReason spawnReason) {
return spawn(worldIn, compound, customName, playerIn, pos, reason, flag, flag1, spawnReason); return spawn(worldIn, pos, mobSpawnType, spawnReason);
} }
} }

View File

@ -523,15 +523,9 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
this.noActionTime = 0; this.noActionTime = 0;
float f = amount; float f = amount;
if (false && (source == DamageSource.ANVIL || source == DamageSource.FALLING_BLOCK) && !this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
this.getItemBySlot(EquipmentSlot.HEAD).hurtAndBreak((int) (amount * 4.0F + this.random.nextFloat() * amount * 2.0F), (LivingEntity) (Object) this, (p_213341_0_) -> {
p_213341_0_.broadcastBreakEvent(EquipmentSlot.HEAD);
});
amount *= 0.75F;
}
boolean flag = f > 0.0F && this.isDamageSourceBlocked(source); // Copied from below boolean flag = f > 0.0F && this.isDamageSourceBlocked(source); // Copied from below
float f1 = 0.0F; float f1 = 0.0F;
// ShieldBlockEvent implemented in damageEntity0
if (false && amount > 0.0F && this.isDamageSourceBlocked(source)) { if (false && amount > 0.0F && this.isDamageSourceBlocked(source)) {
this.hurtCurrentlyUsedShield(amount); this.hurtCurrentlyUsedShield(amount);
@ -623,7 +617,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
this.markHurt(); this.markHurt();
} }
if (entity1 != null) { if (entity1 != null && !source.isExplosion()) {
double d1 = entity1.getX() - this.getX(); double d1 = entity1.getX() - this.getX();
double d0; double d0;
@ -638,7 +632,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
} }
if (this.getHealth() <= 0.0F) { if (this.isDeadOrDying()) {
if (!this.checkTotemDeathProtection(source)) { if (!this.checkTotemDeathProtection(source)) {
SoundEvent soundevent = this.getDeathSound(); SoundEvent soundevent = this.getDeathSound();
if (flag1 && soundevent != null) { if (flag1 && soundevent != null) {
@ -687,7 +681,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
float originalDamage = f; float originalDamage = f;
Function<Double, Double> hardHat = f12 -> { Function<Double, Double> hardHat = f12 -> {
if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && !this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) { if (damagesource.isDamageHelmet() && !this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
return -(f12 - (f12 * 0.75F)); return -(f12 - (f12 * 0.75F));
} }
return -0.0; return -0.0;
@ -953,7 +947,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
@Inject(method = "createWitherRose", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) @Inject(method = "createWitherRose", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private void arclight$witherRoseDrop(LivingEntity livingEntity, CallbackInfo ci, boolean flag, ItemEntity itemEntity) { private void arclight$witherRoseDrop(LivingEntity livingEntity, CallbackInfo ci, boolean flag, ItemEntity
itemEntity) {
org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) (((EntityBridge) itemEntity).bridge$getBukkitEntity())); org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) (((EntityBridge) itemEntity).bridge$getBukkitEntity()));
CraftEventFactory.callEvent(event); CraftEventFactory.callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
@ -1023,7 +1018,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
@Eject(method = "completeUsingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;finishUsingItem(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/LivingEntity;)Lnet/minecraft/world/item/ItemStack;")) @Eject(method = "completeUsingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;finishUsingItem(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/LivingEntity;)Lnet/minecraft/world/item/ItemStack;"))
private ItemStack arclight$itemConsume(ItemStack itemStack, Level worldIn, LivingEntity entityLiving, CallbackInfo ci) { private ItemStack arclight$itemConsume(ItemStack itemStack, Level worldIn, LivingEntity
entityLiving, CallbackInfo ci) {
if (this instanceof ServerPlayerEntityBridge) { if (this instanceof ServerPlayerEntityBridge) {
final org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(itemStack); final org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(itemStack);
final PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, CraftEquipmentSlot.getHand(this.getUsedItemHand())); final PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, CraftEquipmentSlot.getHand(this.getUsedItemHand()));
@ -1041,7 +1037,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
@Eject(method = "randomTeleport", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/entity/LivingEntity;teleportTo(DDD)V")) @Eject(method = "randomTeleport", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/entity/LivingEntity;teleportTo(DDD)V"))
private void arclight$entityTeleport(LivingEntity entity, double x, double y, double z, CallbackInfoReturnable<Boolean> cir) { private void arclight$entityTeleport(LivingEntity entity, double x, double y, double z, CallbackInfoReturnable<
Boolean> cir) {
EntityTeleportEvent event = new EntityTeleportEvent(getBukkitEntity(), new Location(((WorldBridge) this.level).bridge$getWorld(), this.getX(), this.getY(), this.getZ()), EntityTeleportEvent event = new EntityTeleportEvent(getBukkitEntity(), new Location(((WorldBridge) this.level).bridge$getWorld(), this.getX(), this.getY(), this.getZ()),
new Location(((WorldBridge) this.level).bridge$getWorld(), x, y, z)); new Location(((WorldBridge) this.level).bridge$getWorld(), x, y, z));
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -1054,7 +1051,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
@Redirect(method = "dropAllDeathLoot", at = @At(value = "INVOKE", ordinal = 0, remap = false, target = "Lnet/minecraft/world/entity/LivingEntity;captureDrops(Ljava/util/Collection;)Ljava/util/Collection;")) @Redirect(method = "dropAllDeathLoot", at = @At(value = "INVOKE", ordinal = 0, remap = false, target = "Lnet/minecraft/world/entity/LivingEntity;captureDrops(Ljava/util/Collection;)Ljava/util/Collection;"))
private Collection<ItemEntity> arclight$captureIfNeed(LivingEntity livingEntity, Collection<ItemEntity> value) { private Collection<ItemEntity> arclight$captureIfNeed(LivingEntity
livingEntity, Collection<ItemEntity> value) {
Collection<ItemEntity> drops = livingEntity.captureDrops(); Collection<ItemEntity> drops = livingEntity.captureDrops();
// todo this instanceof ArmorStandEntity // todo this instanceof ArmorStandEntity
return drops == null ? livingEntity.captureDrops(value) : drops; return drops == null ? livingEntity.captureDrops(value) : drops;
@ -1071,7 +1069,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
@Inject(method = "addEatEffect", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z")) @Inject(method = "addEatEffect", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z"))
public void arclight$foodEffectCause(ItemStack p_213349_1_, Level p_213349_2_, LivingEntity livingEntity, CallbackInfo ci) { public void arclight$foodEffectCause(ItemStack p_213349_1_, Level p_213349_2_, LivingEntity
livingEntity, CallbackInfo ci) {
((LivingEntityBridge) livingEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.FOOD); ((LivingEntityBridge) livingEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.FOOD);
} }
@ -1134,7 +1133,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
protected void equipEventAndSound(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem, boolean silent) { protected void equipEventAndSound(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem, boolean silent) {
boolean flag = oldItem.isEmpty() && newItem.isEmpty(); boolean flag = oldItem.isEmpty() && newItem.isEmpty();
if (!flag && !ItemStack.isSameIgnoreDurability(oldItem, newItem) && !this.firstTick) { if (!flag && !ItemStack.isSame(oldItem, newItem) && !this.firstTick) {
if (slot.getType() == EquipmentSlot.Type.ARMOR && !silent) { if (slot.getType() == EquipmentSlot.Type.ARMOR && !silent) {
this.playEquipSound(newItem); this.playEquipSound(newItem);
} }

View File

@ -44,8 +44,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static net.minecraft.world.entity.LivingEntity.getEquipmentSlotForItem;
@Mixin(Mob.class) @Mixin(Mob.class)
public abstract class MobMixin extends LivingEntityMixin implements MobEntityBridge { public abstract class MobMixin extends LivingEntityMixin implements MobEntityBridge {
@ -69,6 +67,7 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
@Shadow protected abstract void setItemSlotAndDropWhenKilled(EquipmentSlot p_233657_1_, ItemStack p_233657_2_); @Shadow protected abstract void setItemSlotAndDropWhenKilled(EquipmentSlot p_233657_1_, ItemStack p_233657_2_);
@Shadow @Nullable public abstract <T extends Mob> T convertTo(EntityType<T> p_233656_1_, boolean p_233656_2_); @Shadow @Nullable public abstract <T extends Mob> T convertTo(EntityType<T> p_233656_1_, boolean p_233656_2_);
@Shadow @Nullable protected abstract SoundEvent getAmbientSound(); @Shadow @Nullable protected abstract SoundEvent getAmbientSound();
@Shadow protected abstract EquipmentSlot getEquipmentSlotForItemStack(ItemStack p_256113_);
// @formatter:on // @formatter:on
public boolean aware; public boolean aware;
@ -221,10 +220,10 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
* @reason * @reason
*/ */
@Overwrite @Overwrite
public boolean equipItemIfPossible(ItemStack stack) { public ItemStack equipItemIfPossible(ItemStack stack) {
ItemEntity itemEntity = arclight$item; ItemEntity itemEntity = arclight$item;
arclight$item = null; arclight$item = null;
EquipmentSlot equipmentslottype = getEquipmentSlotForItem(stack); EquipmentSlot equipmentslottype = this.getEquipmentSlotForItemStack(stack);
ItemStack itemstack = this.getItemBySlot(equipmentslottype); ItemStack itemstack = this.getItemBySlot(equipmentslottype);
boolean flag = this.canReplaceCurrentItem(stack, itemstack); boolean flag = this.canReplaceCurrentItem(stack, itemstack);
boolean canPickup = flag && this.canHoldItem(stack); boolean canPickup = flag && this.canHoldItem(stack);
@ -239,10 +238,16 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
forceDrops = false; forceDrops = false;
} }
this.setItemSlotAndDropWhenKilled(equipmentslottype, stack); if (equipmentslottype.isArmor() && stack.getCount() > 1) {
return true; ItemStack itemstack1 = stack.copyWithCount(1);
this.setItemSlotAndDropWhenKilled(equipmentslottype, itemstack1);
return itemstack1;
} else { } else {
return false; this.setItemSlotAndDropWhenKilled(equipmentslottype, stack);
return stack;
}
} else {
return ItemStack.EMPTY;
} }
} }

View File

@ -1,51 +1,24 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior; package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.core.GlobalPos;
import net.minecraft.core.Registry;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.behavior.AssignProfessionFromJobSite; import net.minecraft.world.entity.ai.behavior.AssignProfessionFromJobSite;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.npc.Villager; import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.npc.VillagerData; import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.world.entity.npc.VillagerProfession;
import org.bukkit.craftbukkit.v.entity.CraftVillager; import org.bukkit.craftbukkit.v.entity.CraftVillager;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.VillagerCareerChangeEvent; import org.bukkit.event.entity.VillagerCareerChangeEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Optional;
@Mixin(AssignProfessionFromJobSite.class) @Mixin(AssignProfessionFromJobSite.class)
public class AssignProfessionFromJobSiteMixin { public class AssignProfessionFromJobSiteMixin {
/** @Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;setVillagerData(Lnet/minecraft/world/entity/npc/VillagerData;)V"))
* @author IzzelAliz private static void arclight$jobChange(Villager instance, VillagerData villagerData) {
* @reason VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(instance, CraftVillager.nmsToBukkitProfession(villagerData.getProfession()), VillagerCareerChangeEvent.ChangeReason.EMPLOYED);
*/
@Overwrite
protected void start(ServerLevel worldIn, Villager entityIn, long gameTimeIn) {
GlobalPos globalpos = entityIn.getBrain().getMemory(MemoryModuleType.POTENTIAL_JOB_SITE).get();
entityIn.getBrain().eraseMemory(MemoryModuleType.POTENTIAL_JOB_SITE);
entityIn.getBrain().setMemory(MemoryModuleType.JOB_SITE, globalpos);
worldIn.broadcastEntityEvent(entityIn, (byte) 14);
if (entityIn.getVillagerData().getProfession() == VillagerProfession.NONE) {
MinecraftServer minecraftserver = worldIn.getServer();
Optional.ofNullable(minecraftserver.getLevel(globalpos.dimension())).flatMap((world) -> {
return world.getPoiManager().getType(globalpos.pos());
}).flatMap((poiType) -> {
return Registry.VILLAGER_PROFESSION.stream().filter((profession) -> {
return profession.heldJobSite().test(poiType);
}).findFirst();
}).ifPresent((profession) -> {
VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityIn, CraftVillager.nmsToBukkitProfession(profession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED);
if (!event.isCancelled()) { if (!event.isCancelled()) {
VillagerData newData = entityIn.getVillagerData().setProfession(CraftVillager.bukkitToNmsProfession(event.getProfession())); VillagerData newData = villagerData.setProfession(CraftVillager.bukkitToNmsProfession(event.getProfession()));
entityIn.setVillagerData(newData); instance.setVillagerData(newData);
entityIn.refreshBrain(worldIn);
}
});
} }
} }
} }

View File

@ -1,45 +1,61 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior; package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.util.valueproviders.UniformInt;
import net.minecraft.world.entity.AgeableMob; import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.BabyFollowAdult; import net.minecraft.world.entity.ai.behavior.BabyFollowAdult;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils; import net.minecraft.world.entity.ai.behavior.EntityTracker;
import net.minecraft.world.entity.ai.behavior.OneShot;
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity; import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent;
import org.spongepowered.asm.mixin.Final; import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.function.Function; import java.util.function.Function;
@Mixin(BabyFollowAdult.class) @Mixin(BabyFollowAdult.class)
public abstract class BabyFollowAdultMixin<E extends AgeableMob> { public abstract class BabyFollowAdultMixin {
// @formatter:off
@Shadow protected abstract AgeableMob getNearestAdult(E p_147430_);
@Shadow @Final private Function<LivingEntity, Float> speedModifier;
@Shadow @Final private UniformInt followRange;
// @formatter:on
/** /**
* @author IzzelAliz * @author IzzelAliz
* @reason * @reason
*/ */
@Overwrite @Overwrite
protected void start(ServerLevel p_147426_, E entity, long p_147428_) { public static OneShot<AgeableMob> create(UniformInt p_259321_, Function<LivingEntity, Float> p_259190_) {
var event = CraftEventFactory.callEntityTargetLivingEvent(entity, this.getNearestAdult(entity), EntityTargetEvent.TargetReason.FOLLOW_LEADER); return BehaviorBuilder.create((p_258331_) -> {
if (event.isCancelled()) { return p_258331_.group(p_258331_.present(MemoryModuleType.NEAREST_VISIBLE_ADULT), p_258331_.registered(MemoryModuleType.LOOK_TARGET), p_258331_.absent(MemoryModuleType.WALK_TARGET)).apply(p_258331_, (p_258317_, p_258318_, p_258319_) -> {
return; return (p_258326_, p_258327_, p_258328_) -> {
} if (!p_258327_.isBaby()) {
if (event.getTarget() != null) { return false;
BehaviorUtils.setWalkAndLookTargetMemories(entity, ((CraftLivingEntity) event.getTarget()).getHandle(), this.speedModifier.apply(entity), this.followRange.getMinValue() - 1);
} else { } else {
entity.getBrain().eraseMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT); LivingEntity ageablemob = p_258331_.get(p_258317_);
if (p_258327_.closerThan(ageablemob, (double) (p_259321_.getMaxValue() + 1)) && !p_258327_.closerThan(ageablemob, (double) p_259321_.getMinValue())) {
// CraftBukkit start
EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(p_258327_, ageablemob, EntityTargetEvent.TargetReason.FOLLOW_LEADER);
if (event.isCancelled()) {
return false;
}
if (event.getTarget() == null) {
p_258317_.erase();
return true;
}
ageablemob = ((CraftLivingEntity) event.getTarget()).getHandle();
// CraftBukkit end
WalkTarget walktarget = new WalkTarget(new EntityTracker(ageablemob, false), p_259190_.apply(p_258327_), p_259321_.getMinValue() - 1);
p_258318_.set(new EntityTracker(ageablemob, true));
p_258319_.set(walktarget);
return true;
} else {
return false;
} }
} }
};
});
});
}
} }

View File

@ -1,51 +1,62 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior; package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.server.level.ServerLevel; import com.mojang.datafixers.kinds.K1;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils; import net.minecraft.world.entity.ai.behavior.BehaviorControl;
import net.minecraft.world.entity.ai.behavior.EntityTracker;
import net.minecraft.world.entity.ai.behavior.GoToWantedItem; import net.minecraft.world.entity.ai.behavior.GoToWantedItem;
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.behavior.declarative.MemoryAccessor;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.animal.allay.Allay; import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
import org.bukkit.craftbukkit.v.entity.CraftEntity; import org.bukkit.craftbukkit.v.entity.CraftEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional; import java.util.function.Predicate;
@Mixin(GoToWantedItem.class) @Mixin(GoToWantedItem.class)
public abstract class GoToWantedItemMixin<E extends LivingEntity> { public abstract class GoToWantedItemMixin<E extends LivingEntity> {
// @formatter:off /**
@Shadow protected abstract ItemEntity getClosestLovedItem(E p_23156_); * @author IzzelAliz
@Shadow @Final private float speedModifier; * @reason
// @formatter:on */
@Overwrite
@Inject(method = "start", cancellable = true, at = @At("HEAD")) public static <E extends LivingEntity> BehaviorControl<E> create(Predicate<E> p_259490_, float p_260346_, boolean p_259637_, int p_259054_) {
private void arclight$entityTarget(ServerLevel level, E entity, long p_23154_, CallbackInfo ci) { return BehaviorBuilder.create((p_258371_) -> {
if (entity instanceof Allay) { BehaviorBuilder<E, ? extends MemoryAccessor<? extends K1, WalkTarget>> behaviorbuilder = p_259637_ ? p_258371_.registered(MemoryModuleType.WALK_TARGET) : p_258371_.absent(MemoryModuleType.WALK_TARGET);
Entity target = this.getClosestLovedItem(entity); return p_258371_.group(p_258371_.registered(MemoryModuleType.LOOK_TARGET), behaviorbuilder, p_258371_.present(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM), p_258371_.registered(MemoryModuleType.ITEM_PICKUP_COOLDOWN_TICKS)).apply(p_258371_, (p_258387_, p_258388_, p_258389_, p_258390_) -> {
var event = CraftEventFactory.callEntityTargetEvent(entity, target, EntityTargetEvent.TargetReason.CLOSEST_ENTITY); return (p_258380_, p_258381_, p_258382_) -> {
ItemEntity itementity = p_258371_.get(p_258389_);
if (p_258371_.tryGet(p_258390_).isEmpty() && p_259490_.test(p_258381_) && itementity.closerThan(p_258381_, (double) p_259054_) && p_258381_.level.getWorldBorder().isWithinBounds(itementity.blockPosition())) {
// CraftBukkit start
if (p_258381_ instanceof net.minecraft.world.entity.animal.allay.Allay) {
var event = CraftEventFactory.callEntityTargetEvent(p_258381_, itementity, EntityTargetEvent.TargetReason.CLOSEST_ENTITY);
if (event.isCancelled()) { if (event.isCancelled()) {
ci.cancel(); return false;
}
if (!(event.getTarget() instanceof ItemEntity)) {
p_258389_.erase();
} }
target = (event.getTarget() == null) ? null : ((CraftEntity) event.getTarget()).getHandle(); itementity = (ItemEntity) ((CraftEntity) event.getTarget()).getHandle();
if (target instanceof ItemEntity item) { }
entity.getBrain().setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, Optional.of(item)); // CraftBukkit end
BehaviorUtils.setWalkAndLookTargetMemories(entity, target, this.speedModifier, 0);
WalkTarget walktarget = new WalkTarget(new EntityTracker(itementity, false), p_260346_, 0);
p_258387_.set(new EntityTracker(itementity, true));
p_258388_.set(walktarget);
return true;
} else { } else {
entity.getBrain().eraseMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM); return false;
}
ci.cancel();
} }
};
});
});
} }
} }

View File

@ -1,75 +1,31 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior; package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.InteractWithDoor; import net.minecraft.world.entity.ai.behavior.InteractWithDoor;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.pathfinder.Node;
import net.minecraft.world.level.pathfinder.Path;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.entity.EntityInteractEvent; import org.bukkit.event.entity.EntityInteractEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import javax.annotation.Nullable;
@Mixin(InteractWithDoor.class) @Mixin(InteractWithDoor.class)
public abstract class InteractWithDoorMixin { public abstract class InteractWithDoorMixin {
// @formatter:off @Eject(method = "desc=/B$/", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/DoorBlock;setOpen(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Z)V"))
@Shadow @Nullable private Node lastCheckedNode; private static void arclight$openDoor1(DoorBlock instance, Entity entity, Level p_153167_, BlockState p_153168_, BlockPos pos, boolean p_153170_, CallbackInfoReturnable<Boolean> cir) {
@Shadow protected abstract void rememberDoorToClose(ServerLevel p_242301_1_, LivingEntity p_242301_2_, BlockPos p_242301_3_); var event = new EntityInteractEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(entity.getLevel(), pos));
@Shadow public static void closeDoorsThatIHaveOpenedOrPassedThrough(ServerLevel p_242294_0_, LivingEntity p_242294_1_, @org.jetbrains.annotations.Nullable Node p_242294_2_, @org.jetbrains.annotations.Nullable Node p_242294_3_) { }
// @formatter:on
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
protected void start(ServerLevel worldIn, LivingEntity entityIn, long gameTimeIn) {
Path path = entityIn.getBrain().getMemory(MemoryModuleType.PATH).get();
this.lastCheckedNode = path.getNextNode();
Node pathpoint = path.getPreviousNode();
Node pathpoint1 = path.getNextNode();
BlockPos blockpos = pathpoint.asBlockPos();
BlockState blockstate = worldIn.getBlockState(blockpos);
if (blockstate.is(BlockTags.WOODEN_DOORS)) {
DoorBlock doorblock = (DoorBlock) blockstate.getBlock();
if (!doorblock.isOpen(blockstate)) {
EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(((EntityBridge) entityIn).bridge$getBukkitEntity(), CraftBlock.at(entityIn.level, blockpos));
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
cir.setReturnValue(false);
return; return;
} }
doorblock.setOpen(entityIn, worldIn, blockstate, blockpos, true); instance.setOpen(entity, p_153167_, p_153168_, pos, p_153170_);
}
this.rememberDoorToClose(worldIn, entityIn, blockpos);
}
BlockPos blockpos1 = pathpoint1.asBlockPos();
BlockState blockstate1 = worldIn.getBlockState(blockpos1);
if (blockstate1.is(BlockTags.WOODEN_DOORS)) {
DoorBlock doorblock1 = (DoorBlock) blockstate1.getBlock();
if (!doorblock1.isOpen(blockstate1)) {
EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(((EntityBridge) entityIn).bridge$getBukkitEntity(), CraftBlock.at(entityIn.level, blockpos));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
doorblock1.setOpen(entityIn, worldIn, blockstate1, blockpos1, true);
this.rememberDoorToClose(worldIn, entityIn, blockpos1);
}
}
closeDoorsThatIHaveOpenedOrPassedThrough(worldIn, entityIn, pathpoint, pathpoint1);
} }
} }

View File

@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ResetProfession.class) @Mixin(ResetProfession.class)
public class ResetProfessionMixin { public class ResetProfessionMixin {
@Redirect(method = "start(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/npc/Villager;J)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;setVillagerData(Lnet/minecraft/world/entity/npc/VillagerData;)V")) @Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;setVillagerData(Lnet/minecraft/world/entity/npc/VillagerData;)V"))
private void arclight$careerChangeHook(Villager villagerEntity, VillagerData villagerData) { private void arclight$careerChangeHook(Villager villagerEntity, VillagerData villagerData) {
VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(villagerEntity, VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(villagerEntity,
CraftVillager.nmsToBukkitProfession(VillagerProfession.NONE), CraftVillager.nmsToBukkitProfession(VillagerProfession.NONE),

View File

@ -3,7 +3,9 @@ package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.behavior.BehaviorControl;
import net.minecraft.world.entity.ai.behavior.StartAttacking; import net.minecraft.world.entity.ai.behavior.StartAttacking;
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.event.entity.living.LivingChangeTargetEvent; import net.minecraftforge.event.entity.living.LivingChangeTargetEvent;
@ -13,28 +15,56 @@ import org.bukkit.event.entity.EntityTargetEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
@Mixin(StartAttacking.class) @Mixin(StartAttacking.class)
public class StartAttackingMixin<E extends Mob> { public class StartAttackingMixin {
/** /**
* @author IzzelAliz * @author IzzelAliz
* @reason * @reason
*/ */
@Overwrite @Overwrite
public static <E extends Mob> void setAttackTarget(E mob, LivingEntity livingEntity) { public static <E extends Mob> BehaviorControl<E> create(Predicate<E> p_259618_, Function<E, Optional<? extends LivingEntity>> p_259435_) {
EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(mob, livingEntity, (livingEntity instanceof ServerPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY); return BehaviorBuilder.create((p_258782_) -> {
return p_258782_.group(p_258782_.absent(MemoryModuleType.ATTACK_TARGET), p_258782_.registered(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)).apply(p_258782_, (p_258778_, p_258779_) -> {
return (p_258773_, p_258774_, p_258775_) -> {
if (!p_259618_.test(p_258774_)) {
return false;
} else {
Optional<? extends LivingEntity> optional = p_259435_.apply(p_258774_);
if (optional.isEmpty()) {
return false;
} else {
LivingEntity livingentity = optional.get();
if (!p_258774_.canAttack(livingentity)) {
return false;
} else {
LivingChangeTargetEvent changeTargetEvent = ForgeHooks.onLivingChangeTarget(p_258774_, livingentity, LivingChangeTargetEvent.LivingTargetType.BEHAVIOR_TARGET);
if (changeTargetEvent.isCanceled())
return false;
// CraftBukkit start
EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(p_258774_, livingentity, (livingentity instanceof ServerPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return false;
} }
livingEntity = ((event.getTarget() != null) ? ((CraftLivingEntity) event.getTarget()).getHandle() : null); if (event.getTarget() == null) {
var changeTargetEvent = ForgeHooks.onLivingChangeTarget(mob, livingEntity, LivingChangeTargetEvent.LivingTargetType.BEHAVIOR_TARGET); p_258778_.erase();
if (changeTargetEvent.isCanceled()) { return true;
return;
} }
livingEntity = changeTargetEvent.getNewTarget(); livingentity = ((CraftLivingEntity) event.getTarget()).getHandle();
mob.getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, livingEntity); // CraftBukkit end
mob.getBrain().eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); p_258778_.set(changeTargetEvent.getNewTarget());
// noinspection removal p_258779_.erase();
ForgeHooks.onLivingSetAttackTarget(mob, livingEntity, LivingChangeTargetEvent.LivingTargetType.BEHAVIOR_TARGET); // TODO: Remove in 1.20 ForgeHooks.onLivingSetAttackTarget(p_258774_, changeTargetEvent.getNewTarget(), LivingChangeTargetEvent.LivingTargetType.BEHAVIOR_TARGET); // TODO: Remove in 1.20
return true;
}
}
}
};
});
});
} }
} }

View File

@ -2,30 +2,59 @@ package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.behavior.BehaviorControl;
import net.minecraft.world.entity.ai.behavior.StopAttackingIfTargetInvalid; import net.minecraft.world.entity.ai.behavior.StopAttackingIfTargetInvalid;
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity; import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
@Mixin(StopAttackingIfTargetInvalid.class) @Mixin(StopAttackingIfTargetInvalid.class)
public class StopAttackingIfTargetInvalidMixin<E extends Mob> { public abstract class StopAttackingIfTargetInvalidMixin {
@Inject(method = "clearAttackTarget", cancellable = true, at = @At("HEAD")) // @formatter:off
private void arclight$attackEvent(E mob, CallbackInfo ci) { @Shadow private static boolean isTiredOfTryingToReachTarget(LivingEntity p_259416_, Optional<Long> p_259377_) { return false; }
LivingEntity old = mob.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null); // @formatter:on
EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(mob, old, (old != null && !old.isAlive()) ? EntityTargetEvent.TargetReason.TARGET_DIED : EntityTargetEvent.TargetReason.FORGOT_TARGET);
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public static <E extends Mob> BehaviorControl<E> create(Predicate<LivingEntity> p_260357_, BiConsumer<E, LivingEntity> p_259568_, boolean p_260319_) {
return BehaviorBuilder.create((p_258801_) -> {
return p_258801_.group(p_258801_.present(MemoryModuleType.ATTACK_TARGET), p_258801_.registered(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)).apply(p_258801_, (p_258787_, p_258788_) -> {
return (p_258795_, p_258796_, p_258797_) -> {
LivingEntity livingentity = p_258801_.get(p_258787_);
if (p_258796_.canAttack(livingentity) && (!p_260319_ || !isTiredOfTryingToReachTarget(p_258796_, p_258801_.tryGet(p_258788_))) && livingentity.isAlive() && livingentity.level == p_258796_.level && !p_260357_.test(livingentity)) {
return true;
} else {
// CraftBukkit start
LivingEntity old = p_258796_.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).orElse(null);
EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(p_258796_, null, (old != null && !old.isAlive()) ? EntityTargetEvent.TargetReason.TARGET_DIED : EntityTargetEvent.TargetReason.FORGOT_TARGET);
if (event.isCancelled()) { if (event.isCancelled()) {
ci.cancel(); return false;
return;
}
if (event.getTarget() != null) {
mob.getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, ((CraftLivingEntity)event.getTarget()).getHandle());
ci.cancel();
} }
if (event.getTarget() == null) {
p_258787_.erase();
return true;
}
livingentity = ((CraftLivingEntity) event.getTarget()).getHandle();
// CraftBukkit end
p_259568_.accept(p_258796_, livingentity);
p_258787_.erase();
return true;
}
};
});
});
} }
} }

View File

@ -1,8 +1,8 @@
package io.izzel.arclight.common.mixin.core.world.entity.animal; package io.izzel.arclight.common.mixin.core.world.entity.animal;
import io.izzel.arclight.common.bridge.core.network.datasync.SynchedEntityDataBridge;
import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
@ -42,7 +42,7 @@ public interface BucketableMixin {
if (event.isCancelled()) { if (event.isCancelled()) {
player.containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket player.containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket
((ServerPlayer) player).connection.send(new ClientboundAddEntityPacket(entity)); // We need to play out these packets as the client assumes the fish is gone ((ServerPlayer) player).connection.send(new ClientboundAddEntityPacket(entity)); // We need to play out these packets as the client assumes the fish is gone
((ServerPlayer) player).connection.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true)); // Need to send data such as the display name to client ((SynchedEntityDataBridge) livingEntity.getEntityData()).bridge$refresh((ServerPlayer) player); // Need to send data such as the display name to client
return Optional.of(InteractionResult.FAIL); return Optional.of(InteractionResult.FAIL);
} }
entity.playSound(entity.getPickupSound(), 1.0F, 1.0F); entity.playSound(entity.getPickupSound(), 1.0F, 1.0F);

View File

@ -0,0 +1,30 @@
package io.izzel.arclight.common.mixin.core.world.entity.animal;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.animal.Cat;
import net.minecraft.world.level.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Item;
import org.bukkit.event.entity.EntityDropItemEvent;
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.Redirect;
@Mixin(targets = "net.minecraft.world.entity.animal.Cat$CatRelaxOnOwnerGoal")
public class Cat_CatRelaxOnOwnerGoalMixin {
@Shadow @Final private Cat cat;
@Redirect(method = "giveMorningGift", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private boolean arclight$dropItem(Level instance, Entity entity) {
var event = new EntityDropItemEvent(((EntityBridge) this.cat).bridge$getBukkitEntity(), (Item) ((EntityBridge) entity).bridge$getBukkitEntity());
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
return instance.addFreshEntity(entity);
}
return false;
}
}

View File

@ -5,6 +5,7 @@ import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.boss.enderdragon.EndCrystal; import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.ExplosionDamageCalculator;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
@ -33,15 +34,15 @@ public abstract class EnderCrystalMixin extends EntityMixin {
} }
} }
@Redirect(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;DDDFLnet/minecraft/world/level/Explosion$BlockInteraction;)Lnet/minecraft/world/level/Explosion;")) @Redirect(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;)Lnet/minecraft/world/level/Explosion;"))
private Explosion arclight$blockPrime(Level world, Entity entityIn, double xIn, double yIn, double zIn, float explosionRadius, Explosion.BlockInteraction modeIn) { private Explosion arclight$blockPrime(Level world, Entity entityIn, DamageSource damageSource, ExplosionDamageCalculator calculator, double xIn, double yIn, double zIn, float explosionRadius, boolean fire, Level.ExplosionInteraction interaction) {
ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), explosionRadius, false); ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), explosionRadius, fire);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
this.unsetRemoved(); this.unsetRemoved();
return null; return null;
} else { } else {
return world.explode(entityIn, xIn, yIn, zIn, event.getRadius(), event.getFire(), modeIn); return world.explode(entityIn, damageSource, calculator, xIn, yIn, zIn, event.getRadius(), event.getFire(), interaction);
} }
} }
} }

View File

@ -8,7 +8,7 @@ import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.targeting.TargetingConditions; import net.minecraft.world.entity.ai.targeting.TargetingConditions;
import net.minecraft.world.entity.boss.wither.WitherBoss; import net.minecraft.world.entity.boss.wither.WitherBoss;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.ForgeEventFactory;
@ -51,11 +51,10 @@ public abstract class WitherBossMixin extends PathfinderMobMixin {
int k1 = this.getInvulnerableTicks() - 1; int k1 = this.getInvulnerableTicks() - 1;
this.bossEvent.setProgress(1.0F - (float) k1 / 220.0F); this.bossEvent.setProgress(1.0F - (float) k1 / 220.0F);
if (k1 <= 0) { if (k1 <= 0) {
Explosion.BlockInteraction explosion$blockinteraction = ForgeEventFactory.getMobGriefingEvent(this.level, (WitherBoss) (Object) this) ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.NONE;
ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false); ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
this.level.explode((WitherBoss) (Object) this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), explosion$blockinteraction); this.level.explode((WitherBoss) (Object) this, this.getX(), this.getEyeY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
} }
if (!this.isSilent()) { if (!this.isSilent()) {
this.level.globalLevelEvent(1023, this.blockPosition(), 0); this.level.globalLevelEvent(1023, this.blockPosition(), 0);

View File

@ -4,7 +4,7 @@ import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge;
import io.izzel.arclight.common.bridge.core.entity.player.PlayerInventoryBridge; import io.izzel.arclight.common.bridge.core.entity.player.PlayerInventoryBridge;
import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.core.network.datasync.EntityDataManagerBridge; import io.izzel.arclight.common.bridge.core.network.datasync.SynchedEntityDataBridge;
import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import io.izzel.arclight.common.mixin.core.world.entity.EntityMixin; import io.izzel.arclight.common.mixin.core.world.entity.EntityMixin;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
@ -127,7 +127,7 @@ public abstract class ItemEntityMixin extends EntityMixin {
@Inject(method = "setItem", at = @At("RETURN")) @Inject(method = "setItem", at = @At("RETURN"))
private void arclight$markDirty(ItemStack stack, CallbackInfo ci) { private void arclight$markDirty(ItemStack stack, CallbackInfo ci) {
((EntityDataManagerBridge) this.getEntityData()).bridge$markDirty(DATA_ITEM); ((SynchedEntityDataBridge) this.getEntityData()).bridge$markDirty(DATA_ITEM);
} }
@Redirect(method = "merge(Lnet/minecraft/world/entity/item/ItemEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/item/ItemEntity;setItem(Lnet/minecraft/world/item/ItemStack;)V")) @Redirect(method = "merge(Lnet/minecraft/world/entity/item/ItemEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/item/ItemEntity;setItem(Lnet/minecraft/world/item/ItemStack;)V"))

View File

@ -6,7 +6,6 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.item.PrimedTnt; import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Explosive; import org.bukkit.entity.Explosive;
@ -83,7 +82,7 @@ public abstract class PrimedTntMixin extends EntityMixin {
ExplosionPrimeEvent event = new ExplosionPrimeEvent((Explosive) this.getBukkitEntity()); ExplosionPrimeEvent event = new ExplosionPrimeEvent((Explosive) this.getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
this.level.explode((PrimedTnt) (Object) this, this.getX(), this.getY(0.0625), this.getZ(), event.getRadius(), event.getFire(), Explosion.BlockInteraction.BREAK); this.level.explode((PrimedTnt) (Object) this, this.getX(), this.getY(0.0625), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.TNT);
} }
} }
} }

View File

@ -9,8 +9,7 @@ import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.AreaEffectCloud; import net.minecraft.world.entity.AreaEffectCloud;
import net.minecraft.world.entity.LightningBolt; import net.minecraft.world.entity.LightningBolt;
import net.minecraft.world.entity.monster.Creeper; import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Level;
import net.minecraftforge.event.ForgeEventFactory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
@ -35,6 +34,7 @@ public abstract class CreeperMixin extends PathfinderMobMixin implements Creeper
@Shadow public int explosionRadius; @Shadow public int explosionRadius;
@Shadow protected abstract void spawnLingeringCloud(); @Shadow protected abstract void spawnLingeringCloud();
@Shadow private int swell; @Shadow private int swell;
@Shadow public abstract boolean isPowered();
// @formatter:on // @formatter:on
@Inject(method = "thunderHit", cancellable = true, at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/monster/Creeper;entityData:Lnet/minecraft/network/syncher/SynchedEntityData;")) @Inject(method = "thunderHit", cancellable = true, at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/monster/Creeper;entityData:Lnet/minecraft/network/syncher/SynchedEntityData;"))
@ -51,13 +51,12 @@ public abstract class CreeperMixin extends PathfinderMobMixin implements Creeper
@Overwrite @Overwrite
public void explodeCreeper() { public void explodeCreeper() {
if (!this.level.isClientSide) { if (!this.level.isClientSide) {
Explosion.BlockInteraction explosion_effect = ForgeEventFactory.getMobGriefingEvent(this.level, (Creeper) (Object) this) ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.NONE; final float f = this.isPowered() ? 2.0f : 1.0f;
final float f = this.entityData.get(DATA_IS_POWERED) ? 2.0f : 1.0f;
final ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.explosionRadius * f, false); final ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.explosionRadius * f, false);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
this.dead = true; this.dead = true;
this.level.explode((Creeper) (Object) this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), explosion_effect); this.level.explode((Creeper) (Object) this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB);
this.discard(); this.discard();
this.spawnLingeringCloud(); this.spawnLingeringCloud();
} else { } else {

View File

@ -55,6 +55,7 @@ public abstract class SlimeMixin extends MobMixin {
float f1 = ((float) (l % 2) - 0.5F) * f; float f1 = ((float) (l % 2) - 0.5F) * f;
float f2 = ((float) (l / 2) - 0.5F) * f; float f2 = ((float) (l / 2) - 0.5F) * f;
net.minecraft.world.entity.monster.Slime slimeentity = this.getType().create(this.level); net.minecraft.world.entity.monster.Slime slimeentity = this.getType().create(this.level);
if (slimeentity == null) continue;
if (this.isPersistenceRequired()) { if (this.isPersistenceRequired()) {
slimeentity.setPersistenceRequired(); slimeentity.setPersistenceRequired();
} }

View File

@ -91,7 +91,7 @@ public abstract class ZombieMixin extends PathfinderMobMixin {
if (zombieVillager != null) { if (zombieVillager != null) {
zombieVillager.finalizeSpawn(level, level.getCurrentDifficultyAt(zombieVillager.blockPosition()), MobSpawnType.CONVERSION, new net.minecraft.world.entity.monster.Zombie.ZombieGroupData(false, true), null); zombieVillager.finalizeSpawn(level, level.getCurrentDifficultyAt(zombieVillager.blockPosition()), MobSpawnType.CONVERSION, new net.minecraft.world.entity.monster.Zombie.ZombieGroupData(false, true), null);
zombieVillager.setVillagerData(villager.getVillagerData()); zombieVillager.setVillagerData(villager.getVillagerData());
zombieVillager.setGossips(villager.getGossips().store(NbtOps.INSTANCE).getValue()); zombieVillager.setGossips(villager.getGossips().store(NbtOps.INSTANCE));
zombieVillager.setTradeOffers(villager.getOffers().createTag()); zombieVillager.setTradeOffers(villager.getOffers().createTag());
zombieVillager.setVillagerXp(villager.getVillagerXp()); zombieVillager.setVillagerXp(villager.getVillagerXp());
net.minecraftforge.event.ForgeEventFactory.onLivingConvert(villager, zombieVillager); net.minecraftforge.event.ForgeEventFactory.onLivingConvert(villager, zombieVillager);

View File

@ -67,7 +67,7 @@ public abstract class PiglinAiMixin {
eat(piglinEntity); eat(piglinEntity);
} else { } else {
((MobEntityBridge) piglinEntity).bridge$captureItemDrop(itemEntity); ((MobEntityBridge) piglinEntity).bridge$captureItemDrop(itemEntity);
boolean flag = piglinEntity.equipItemIfPossible(itemstack); boolean flag = !piglinEntity.equipItemIfPossible(itemstack).equals(ItemStack.EMPTY);
if (!flag) { if (!flag) {
putInInventory(piglinEntity, itemstack); putInInventory(piglinEntity, itemstack);
} }

View File

@ -2,7 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.monster.piglin;
import io.izzel.arclight.common.bridge.core.entity.monster.piglin.PiglinBridge; import io.izzel.arclight.common.bridge.core.entity.monster.piglin.PiglinBridge;
import io.izzel.arclight.common.mixin.core.world.entity.PathfinderMobMixin; import io.izzel.arclight.common.mixin.core.world.entity.PathfinderMobMixin;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag; import net.minecraft.nbt.StringTag;
@ -41,17 +41,17 @@ public abstract class PiglinMixin extends PathfinderMobMixin implements PiglinBr
@Inject(method = "addAdditionalSaveData", at = @At("RETURN")) @Inject(method = "addAdditionalSaveData", at = @At("RETURN"))
private void arclight$writeAdditional(CompoundTag compound, CallbackInfo ci) { private void arclight$writeAdditional(CompoundTag compound, CallbackInfo ci) {
ListTag barterList = new ListTag(); ListTag barterList = new ListTag();
allowedBarterItems.stream().map(Registry.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(barterList::add); allowedBarterItems.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(barterList::add);
compound.put("Bukkit.BarterList", barterList); compound.put("Bukkit.BarterList", barterList);
ListTag interestList = new ListTag(); ListTag interestList = new ListTag();
interestItems.stream().map(Registry.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(interestList::add); interestItems.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).map(StringTag::valueOf).forEach(interestList::add);
compound.put("Bukkit.InterestList", interestList); compound.put("Bukkit.InterestList", interestList);
} }
@Inject(method = "readAdditionalSaveData", at = @At("RETURN")) @Inject(method = "readAdditionalSaveData", at = @At("RETURN"))
private void arclight$readAdditional(CompoundTag compound, CallbackInfo ci) { private void arclight$readAdditional(CompoundTag compound, CallbackInfo ci) {
this.allowedBarterItems = compound.getList("Bukkit.BarterList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(Registry.ITEM::get).collect(Collectors.toCollection(HashSet::new)); this.allowedBarterItems = compound.getList("Bukkit.BarterList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(BuiltInRegistries.ITEM::get).collect(Collectors.toCollection(HashSet::new));
this.interestItems = compound.getList("Bukkit.InterestList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(Registry.ITEM::get).collect(Collectors.toCollection(HashSet::new)); this.interestItems = compound.getList("Bukkit.InterestList", 8).stream().map(Tag::getAsString).map(ResourceLocation::tryParse).map(BuiltInRegistries.ITEM::get).collect(Collectors.toCollection(HashSet::new));
} }
@Redirect(method = "holdInOffHand", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/item/ItemStack;isPiglinCurrency()Z")) @Redirect(method = "holdInOffHand", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/item/ItemStack;isPiglinCurrency()Z"))

View File

@ -39,19 +39,16 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobType; import net.minecraft.world.entity.MobType;
import net.minecraft.world.entity.TamableAnimal; import net.minecraft.world.entity.TamableAnimal;
import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.boss.EnderDragonPart;
import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Abilities; import net.minecraft.world.entity.player.Abilities;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.ProfilePublicKey;
import net.minecraft.world.food.FoodData; import net.minecraft.world.food.FoodData;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.inventory.PlayerEnderChestContainer; import net.minecraft.world.inventory.PlayerEnderChestContainer;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.Scoreboard; import net.minecraft.world.scores.Scoreboard;
import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.ForgeHooks;
@ -139,7 +136,7 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt
public int oldLevel; public int oldLevel;
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
private void arclight$init(Level p_219727_, BlockPos p_219728_, float p_219729_, GameProfile p_219730_, ProfilePublicKey p_219731_, CallbackInfo ci) { private void arclight$init(CallbackInfo ci) {
oldLevel = -1; oldLevel = -1;
((FoodStatsBridge) this.foodData).bridge$setEntityHuman((net.minecraft.world.entity.player.Player) (Object) this); ((FoodStatsBridge) this.foodData).bridge$setEntityHuman((net.minecraft.world.entity.player.Player) (Object) this);
((IInventoryBridge) this.enderChestInventory).setOwner(this.getBukkitEntity()); ((IInventoryBridge) this.enderChestInventory).setOwner(this.getBukkitEntity());

View File

@ -493,7 +493,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
} }
ServerLevel[] exitWorld = new ServerLevel[]{server}; ServerLevel[] exitWorld = new ServerLevel[]{server};
LevelData iworldinfo = server.getLevelData(); LevelData iworldinfo = server.getLevelData();
this.connection.send(new ClientboundRespawnPacket(server.dimensionTypeId(), server.dimension(), BiomeManager.obfuscateSeed(server.getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), server.isDebug(), server.isFlat(), true, this.getLastDeathLocation())); this.connection.send(new ClientboundRespawnPacket(server.dimensionTypeId(), server.dimension(), BiomeManager.obfuscateSeed(server.getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), server.isDebug(), server.isFlat(), (byte) 3, this.getLastDeathLocation()));
this.connection.send(new ClientboundChangeDifficultyPacket(iworldinfo.getDifficulty(), iworldinfo.isDifficultyLocked())); this.connection.send(new ClientboundChangeDifficultyPacket(iworldinfo.getDifficulty(), iworldinfo.isDifficultyLocked()));
PlayerList playerlist = this.server.getPlayerList(); PlayerList playerlist = this.server.getPlayerList();
playerlist.sendPlayerPermissionLevel((ServerPlayer) (Object) this); playerlist.sendPlayerPermissionLevel((ServerPlayer) (Object) this);
@ -527,7 +527,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
if (newWorld != exitWorld[0]) { if (newWorld != exitWorld[0]) {
exitWorld[0] = newWorld; exitWorld[0] = newWorld;
LevelData newWorldInfo = exitWorld[0].getLevelData(); LevelData newWorldInfo = exitWorld[0].getLevelData();
this.connection.send(new ClientboundRespawnPacket(exitWorld[0].dimensionTypeId(), exitWorld[0].dimension(), BiomeManager.obfuscateSeed(exitWorld[0].getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), exitWorld[0].isDebug(), exitWorld[0].isFlat(), true, this.getLastDeathLocation())); this.connection.send(new ClientboundRespawnPacket(exitWorld[0].dimensionTypeId(), exitWorld[0].dimension(), BiomeManager.obfuscateSeed(exitWorld[0].getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), exitWorld[0].isDebug(), exitWorld[0].isFlat(), (byte) 3, this.getLastDeathLocation()));
this.connection.send(new ClientboundChangeDifficultyPacket(newWorldInfo.getDifficulty(), newWorldInfo.isDifficultyLocked())); this.connection.send(new ClientboundChangeDifficultyPacket(newWorldInfo.getDifficulty(), newWorldInfo.isDifficultyLocked()));
} }
@ -787,7 +787,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
this.clientViewDistance = packetIn.viewDistance(); this.clientViewDistance = packetIn.viewDistance();
} }
@Inject(method = "setCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;teleportTo(DDD)V")) @Inject(method = "setCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;teleport(DDDFF)V"))
private void arclight$spectatorReason(Entity entityToSpectate, CallbackInfo ci) { private void arclight$spectatorReason(Entity entityToSpectate, CallbackInfo ci) {
this.bridge$pushChangeDimensionCause(PlayerTeleportEvent.TeleportCause.SPECTATE); this.bridge$pushChangeDimensionCause(PlayerTeleportEvent.TeleportCause.SPECTATE);
} }

View File

@ -2,7 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.projectile;
import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge; import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.core.entity.projectile.ArrowEntityBridge; import io.izzel.arclight.common.bridge.core.entity.projectile.ArrowEntityBridge;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
@ -45,11 +45,11 @@ public abstract class ArrowEntityMixin extends AbstractArrowMixin implements Arr
} }
public String getPotionType() { public String getPotionType() {
return Registry.POTION.getKey(this.potion).toString(); return BuiltInRegistries.POTION.getKey(this.potion).toString();
} }
public void setPotionType(final String string) { public void setPotionType(final String string) {
this.potion = Registry.POTION.get(new ResourceLocation(string)); this.potion = BuiltInRegistries.POTION.get(new ResourceLocation(string));
this.getEntityData().set(ID_EFFECT_COLOR, PotionUtils.getColor(PotionUtils.getAllEffects(this.potion, this.effects))); this.getEntityData().set(ID_EFFECT_COLOR, PotionUtils.getColor(PotionUtils.getAllEffects(this.potion, this.effects)));
} }

View File

@ -29,15 +29,15 @@ public abstract class LargeFireballMixin extends AbstractHurtingProjectileMixin
this.isIncendiary = level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); this.isIncendiary = level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
} }
@Redirect(method = "onHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;)Lnet/minecraft/world/level/Explosion;")) @Redirect(method = "onHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;)Lnet/minecraft/world/level/Explosion;"))
private Explosion arclight$explodePrime(Level world, Entity entityIn, double xIn, double yIn, double zIn, float explosionRadius, boolean causesFire, Explosion.BlockInteraction modeIn) { private Explosion arclight$explodePrime(Level world, Entity entityIn, double xIn, double yIn, double zIn, float explosionRadius, boolean causesFire, Level.ExplosionInteraction interaction) {
ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity()); ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
event.setRadius(explosionRadius); event.setRadius(explosionRadius);
event.setFire(causesFire); event.setFire(causesFire);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
return this.level.explode((LargeFireball) (Object) this, xIn, yIn, zIn, event.getRadius(), event.getFire(), modeIn); return this.level.explode((LargeFireball) (Object) this, xIn, yIn, zIn, event.getRadius(), event.getFire(), interaction);
} else { } else {
return null; return null;
} }

View File

@ -47,6 +47,7 @@ public abstract class ThrownEggMixin extends ThrowableProjectileMixin {
if (hatching) { if (hatching) {
for (int i = 0; i < b0; ++i) { for (int i = 0; i < b0; ++i) {
Entity entity = ((WorldBridge) this.level).bridge$getWorld().createEntity(new Location(((WorldBridge) this.level).bridge$getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0f), hatchingType.getEntityClass()); Entity entity = ((WorldBridge) this.level).bridge$getWorld().createEntity(new Location(((WorldBridge) this.level).bridge$getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0f), hatchingType.getEntityClass());
if (entity != null) {
if (((EntityBridge) entity).bridge$getBukkitEntity() instanceof Ageable) { if (((EntityBridge) entity).bridge$getBukkitEntity() instanceof Ageable) {
((Ageable) ((EntityBridge) entity).bridge$getBukkitEntity()).setBaby(); ((Ageable) ((EntityBridge) entity).bridge$getBukkitEntity()).setBaby();
} }
@ -54,6 +55,7 @@ public abstract class ThrownEggMixin extends ThrowableProjectileMixin {
this.level.addFreshEntity(entity); this.level.addFreshEntity(entity);
} }
} }
}
this.level.broadcastEntityEvent((ThrownEgg) (Object) this, (byte) 3); this.level.broadcastEntityEvent((ThrownEgg) (Object) this, (byte) 3);
this.discard(); this.discard();
} }

View File

@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.projectile;
import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import net.minecraft.world.entity.projectile.ThrownEnderpearl; import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -16,4 +17,14 @@ public abstract class ThrownEnderpearlMixin extends ThrowableProjectileMixin {
private void arclight$spawnEndermite(HitResult result, CallbackInfo ci) { private void arclight$spawnEndermite(HitResult result, CallbackInfo ci) {
((WorldBridge) this.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.ENDER_PEARL); ((WorldBridge) this.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
} }
@Inject(method = "onHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
private void arclight$entityDamage(CallbackInfo ci) {
CraftEventFactory.entityDamage = (ThrownEnderpearl) (Object) this;
}
@Inject(method = "onHit", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))
private void arclight$entityDamageReset(CallbackInfo ci) {
CraftEventFactory.entityDamage = null;
}
} }

View File

@ -29,12 +29,12 @@ public abstract class WitherSkullMixin extends AbstractHurtingProjectileMixin {
((LivingEntityBridge) result.getEntity()).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ATTACK); ((LivingEntityBridge) result.getEntity()).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ATTACK);
} }
@Redirect(method = "onHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;)Lnet/minecraft/world/level/Explosion;")) @Redirect(method = "onHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;)Lnet/minecraft/world/level/Explosion;"))
private Explosion arclight$explode(Level world, Entity entityIn, double xIn, double yIn, double zIn, float explosionRadius, boolean causesFire, Explosion.BlockInteraction modeIn) { private Explosion arclight$explode(Level world, Entity entityIn, double xIn, double yIn, double zIn, float explosionRadius, boolean causesFire, Level.ExplosionInteraction interaction) {
ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), explosionRadius, causesFire); ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), explosionRadius, causesFire);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
return this.level.explode((WitherSkull) (Object) this, xIn, yIn, zIn, event.getRadius(), event.getFire(), modeIn); return this.level.explode((WitherSkull) (Object) this, xIn, yIn, zIn, event.getRadius(), event.getFire(), interaction);
} }
return null; return null;
} }

View File

@ -1,9 +1,11 @@
package io.izzel.arclight.common.mixin.core.world.entity.vehicle; package io.izzel.arclight.common.mixin.core.world.entity.vehicle;
import io.izzel.arclight.mixin.Eject; import io.izzel.arclight.mixin.Eject;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.vehicle.MinecartTNT; import net.minecraft.world.entity.vehicle.MinecartTNT;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.ExplosionDamageCalculator;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.entity.ExplosionPrimeEvent; import org.bukkit.event.entity.ExplosionPrimeEvent;
@ -17,9 +19,9 @@ public abstract class MinecartTNTMixin extends AbstractMinecartMixin {
@Shadow private int fuse; @Shadow private int fuse;
@Eject(method = "explode", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;DDDFLnet/minecraft/world/level/Explosion$BlockInteraction;)Lnet/minecraft/world/level/Explosion;")) @Eject(method = "explode(Lnet/minecraft/world/damagesource/DamageSource;D)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;)Lnet/minecraft/world/level/Explosion;"))
private Explosion arclight$explode(Level level, Entity entity, double x, double y, double z, float radius, Explosion.BlockInteraction interaction, CallbackInfo ci) { private Explosion arclight$explode(Level level, Entity entity, DamageSource source, ExplosionDamageCalculator calculator, double x, double y, double z, float radius, boolean fire, Level.ExplosionInteraction interaction, CallbackInfo ci) {
var event = new ExplosionPrimeEvent(this.getBukkitEntity(), radius, false); var event = new ExplosionPrimeEvent(this.getBukkitEntity(), radius, fire);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
this.fuse = -1; this.fuse = -1;

View File

@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.inventory;
import io.izzel.arclight.common.bridge.core.inventory.container.LecternContainerBridge; import io.izzel.arclight.common.bridge.core.inventory.container.LecternContainerBridge;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.LecternMenu; import net.minecraft.world.inventory.LecternMenu;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
@ -11,12 +12,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(MenuType.class) @Mixin(MenuType.class)
public class ContainerTypeMixin<T extends AbstractContainerMenu> { public class ContainerTypeMixin {
@Inject(method = "register", cancellable = true, at = @At("HEAD")) @Inject(method = "register", cancellable = true, at = @At("HEAD"))
private static <T extends AbstractContainerMenu> void arclight$replaceLectern(String key, MenuType.MenuSupplier<T> factory, CallbackInfoReturnable<MenuType<T>> cir) { private static <T extends AbstractContainerMenu> void arclight$replaceLectern(String key, MenuType.MenuSupplier<T> factory, CallbackInfoReturnable<MenuType<T>> cir) {
if (key.equals("lectern")) { if (key.equals("lectern")) {
cir.setReturnValue(Registry.register(Registry.MENU, key, new MenuType<>((i, inv) -> { cir.setReturnValue(Registry.register(BuiltInRegistries.MENU, key, new MenuType<>((i, inv) -> {
LecternMenu container = new LecternMenu(i); LecternMenu container = new LecternMenu(i);
((LecternContainerBridge) container).bridge$setPlayerInventory(inv); ((LecternContainerBridge) container).bridge$setPlayerInventory(inv);
return (T) container; return (T) container;

View File

@ -63,7 +63,7 @@ public abstract class CraftingMenuMixin extends AbstractContainerMenuMixin imple
return optional.isPresent(); return optional.isPresent();
} }
@ModifyVariable(method = "slotChangedCraftingGrid", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/ResultContainer;setItem(ILnet/minecraft/world/item/ItemStack;)V")) @ModifyVariable(method = "slotChangedCraftingGrid", ordinal = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/ResultContainer;setItem(ILnet/minecraft/world/item/ItemStack;)V"))
private static ItemStack arclight$preCraft(ItemStack stack, AbstractContainerMenu container, Level level, Player player, CraftingContainer craftingContainer, ResultContainer resultContainer) { private static ItemStack arclight$preCraft(ItemStack stack, AbstractContainerMenu container, Level level, Player player, CraftingContainer craftingContainer, ResultContainer resultContainer) {
return CraftEventFactory.callPreCraftEvent(craftingContainer, resultContainer, stack, ((ContainerBridge) container).bridge$getBukkitView(), arclight$isRepair); return CraftEventFactory.callPreCraftEvent(craftingContainer, resultContainer, stack, ((ContainerBridge) container).bridge$getBukkitView(), arclight$isRepair);
} }

View File

@ -6,7 +6,7 @@ import io.izzel.arclight.common.bridge.core.inventory.container.PosContainerBrid
import io.izzel.arclight.common.bridge.core.util.IWorldPosCallableBridge; import io.izzel.arclight.common.bridge.core.util.IWorldPosCallableBridge;
import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
@ -112,7 +112,7 @@ public abstract class EnchantmentContainerMixin extends AbstractContainerMenuMix
List<EnchantmentInstance> list = this.getEnchantmentList(itemstack, j1, this.costs[j1]); List<EnchantmentInstance> list = this.getEnchantmentList(itemstack, j1, this.costs[j1]);
if (list != null && !list.isEmpty()) { if (list != null && !list.isEmpty()) {
EnchantmentInstance enchantmentdata = list.get(this.random.nextInt(list.size())); EnchantmentInstance enchantmentdata = list.get(this.random.nextInt(list.size()));
this.enchantClue[j1] = Registry.ENCHANTMENT.getId(enchantmentdata.enchantment); this.enchantClue[j1] = BuiltInRegistries.ENCHANTMENT.getId(enchantmentdata.enchantment);
this.levelClue[j1] = enchantmentdata.level; this.levelClue[j1] = enchantmentdata.level;
} }
} }
@ -122,7 +122,7 @@ public abstract class EnchantmentContainerMixin extends AbstractContainerMenuMix
CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); CraftItemStack item = CraftItemStack.asCraftMirror(itemstack);
org.bukkit.enchantments.EnchantmentOffer[] offers = new EnchantmentOffer[3]; org.bukkit.enchantments.EnchantmentOffer[] offers = new EnchantmentOffer[3];
for (int j = 0; j < 3; ++j) { for (int j = 0; j < 3; ++j) {
org.bukkit.enchantments.Enchantment enchantment = (this.enchantClue[j] >= 0) ? org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(ForgeRegistries.ENCHANTMENTS.getKey(Registry.ENCHANTMENT.byId(this.enchantClue[j])))) : null; org.bukkit.enchantments.Enchantment enchantment = (this.enchantClue[j] >= 0) ? org.bukkit.enchantments.Enchantment.getByKey(CraftNamespacedKey.fromMinecraft(ForgeRegistries.ENCHANTMENTS.getKey(BuiltInRegistries.ENCHANTMENT.byId(this.enchantClue[j])))) : null;
offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.levelClue[j], this.costs[j]) : null; offers[j] = (enchantment != null) ? new EnchantmentOffer(enchantment, this.levelClue[j], this.costs[j]) : null;
} }
@ -143,7 +143,7 @@ public abstract class EnchantmentContainerMixin extends AbstractContainerMenuMix
EnchantmentOffer offer = event.getOffers()[j]; EnchantmentOffer offer = event.getOffers()[j];
if (offer != null) { if (offer != null) {
this.costs[j] = offer.getCost(); this.costs[j] = offer.getCost();
this.enchantClue[j] = Registry.ENCHANTMENT.getId(ForgeRegistries.ENCHANTMENTS.getValue(CraftNamespacedKey.toMinecraft(offer.getEnchantment().getKey()))); this.enchantClue[j] = BuiltInRegistries.ENCHANTMENT.getId(ForgeRegistries.ENCHANTMENTS.getValue(CraftNamespacedKey.toMinecraft(offer.getEnchantment().getKey())));
this.levelClue[j] = offer.getEnchantmentLevel(); this.levelClue[j] = offer.getEnchantmentLevel();
} else { } else {
this.costs[j] = 0; this.costs[j] = 0;

View File

@ -77,7 +77,7 @@ public abstract class BoatItemMixin extends Item {
} }
Boat boatentity = this.getBoat(worldIn, result); Boat boatentity = this.getBoat(worldIn, result);
boatentity.setType(this.type); boatentity.setVariant(this.type);
boatentity.setYRot(playerIn.getYRot()); boatentity.setYRot(playerIn.getYRot());
if (!worldIn.noCollision(boatentity, boatentity.getBoundingBox().inflate(-0.1D))) { if (!worldIn.noCollision(boatentity, boatentity.getBoundingBox().inflate(-0.1D))) {
return new InteractionResultHolder<>(InteractionResult.FAIL, itemstack); return new InteractionResultHolder<>(InteractionResult.FAIL, itemstack);

View File

@ -5,6 +5,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.AbstractCookingRecipe; import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.BlastingRecipe; import net.minecraft.world.item.crafting.BlastingRecipe;
import net.minecraft.world.item.crafting.CookingBookCategory;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import org.bukkit.craftbukkit.v.inventory.CraftBlastingRecipe; import org.bukkit.craftbukkit.v.inventory.CraftBlastingRecipe;
@ -17,8 +18,8 @@ import org.spongepowered.asm.mixin.Mixin;
@Mixin(BlastingRecipe.class) @Mixin(BlastingRecipe.class)
public abstract class BlastingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge { public abstract class BlastingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge {
public BlastingRecipeMixin(RecipeType<?> typeIn, ResourceLocation idIn, String groupIn, Ingredient ingredientIn, ItemStack resultIn, float experienceIn, int cookTimeIn) { public BlastingRecipeMixin(RecipeType<?> p_250197_, ResourceLocation p_249379_, String p_249518_, CookingBookCategory p_250891_, Ingredient p_251354_, ItemStack p_252185_, float p_252165_, int p_250256_) {
super(typeIn, idIn, groupIn, ingredientIn, resultIn, experienceIn, cookTimeIn); super(p_250197_, p_249379_, p_249518_, p_250891_, p_251354_, p_252185_, p_252165_, p_250256_);
} }
@Override @Override
@ -26,6 +27,7 @@ public abstract class BlastingRecipeMixin extends AbstractCookingRecipe implemen
CraftItemStack result = CraftItemStack.asCraftMirror(this.result); CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
CraftBlastingRecipe recipe = new CraftBlastingRecipe(CraftNamespacedKey.fromMinecraft(this.getId()), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); CraftBlastingRecipe recipe = new CraftBlastingRecipe(CraftNamespacedKey.fromMinecraft(this.getId()), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime);
recipe.setGroup(this.group); recipe.setGroup(this.group);
recipe.setCategory(CraftRecipe.getCategory(this.category()));
return recipe; return recipe;
} }
} }

View File

@ -5,6 +5,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.AbstractCookingRecipe; import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.CampfireCookingRecipe; import net.minecraft.world.item.crafting.CampfireCookingRecipe;
import net.minecraft.world.item.crafting.CookingBookCategory;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import org.bukkit.craftbukkit.v.inventory.CraftCampfireRecipe; import org.bukkit.craftbukkit.v.inventory.CraftCampfireRecipe;
@ -17,8 +18,8 @@ import org.spongepowered.asm.mixin.Mixin;
@Mixin(CampfireCookingRecipe.class) @Mixin(CampfireCookingRecipe.class)
public abstract class CampfireCookingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge { public abstract class CampfireCookingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge {
public CampfireCookingRecipeMixin(RecipeType<?> typeIn, ResourceLocation idIn, String groupIn, Ingredient ingredientIn, ItemStack resultIn, float experienceIn, int cookTimeIn) { public CampfireCookingRecipeMixin(RecipeType<?> p_250197_, ResourceLocation p_249379_, String p_249518_, CookingBookCategory p_250891_, Ingredient p_251354_, ItemStack p_252185_, float p_252165_, int p_250256_) {
super(typeIn, idIn, groupIn, ingredientIn, resultIn, experienceIn, cookTimeIn); super(p_250197_, p_249379_, p_249518_, p_250891_, p_251354_, p_252185_, p_252165_, p_250256_);
} }
@Override @Override
@ -26,6 +27,7 @@ public abstract class CampfireCookingRecipeMixin extends AbstractCookingRecipe i
CraftItemStack result = CraftItemStack.asCraftMirror(this.result); CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
CraftCampfireRecipe recipe = new CraftCampfireRecipe(CraftNamespacedKey.fromMinecraft(this.getId()), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); CraftCampfireRecipe recipe = new CraftCampfireRecipe(CraftNamespacedKey.fromMinecraft(this.getId()), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime);
recipe.setGroup(this.group); recipe.setGroup(this.group);
recipe.setCategory(CraftRecipe.getCategory(this.category()));
return recipe; return recipe;
} }
} }

View File

@ -1,20 +1,20 @@
package io.izzel.arclight.common.mixin.core.world.item.crafting; package io.izzel.arclight.common.mixin.core.world.item.crafting;
import io.izzel.arclight.common.bridge.core.item.crafting.IngredientBridge; import io.izzel.arclight.common.bridge.core.item.crafting.IngredientBridge;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
@Mixin(Ingredient.class) @Mixin(Ingredient.class)
public abstract class IngredientMixin implements IngredientBridge { public abstract class IngredientMixin implements IngredientBridge {
// @formatter:off // @formatter:off
@Shadow public abstract void dissolve(); @Shadow public abstract boolean isEmpty();
@Shadow public ItemStack[] itemStacks; @Shadow public abstract ItemStack[] getItems();
// @formatter:on // @formatter:on
public boolean exact; public boolean exact;
@ -24,22 +24,23 @@ public abstract class IngredientMixin implements IngredientBridge {
* @reason * @reason
*/ */
@Overwrite @Overwrite
public boolean test(@Nullable ItemStack stack) { public boolean test(@Nullable ItemStack itemstack) {
if (stack == null) { if (itemstack == null) {
return false; return false;
} else if (this.isEmpty()) {
return itemstack.isEmpty();
} else { } else {
this.dissolve(); ItemStack[] items = this.getItems();
if (this.itemStacks.length == 0) { for (ItemStack stack : items) {
return stack.isEmpty(); // CraftBukkit start
} else {
for (ItemStack itemstack : this.itemStacks) {
if (exact) { if (exact) {
if (itemstack.getItem() == stack.getItem() && ItemStack.isSame(itemstack, stack)) { if (stack.getItem() == itemstack.getItem() && ItemStack.tagMatches(itemstack, stack)) {
return true; return true;
} }
continue; continue;
} }
if (itemstack.getItem() == stack.getItem()) { // CraftBukkit end
if (stack.is(itemstack.getItem())) {
return true; return true;
} }
} }
@ -47,7 +48,6 @@ public abstract class IngredientMixin implements IngredientBridge {
return false; return false;
} }
} }
}
@Override @Override
public void bridge$setExact(boolean exact) { public void bridge$setExact(boolean exact) {

View File

@ -8,7 +8,7 @@ import com.google.gson.JsonParseException;
import io.izzel.arclight.common.bridge.core.inventory.IInventoryBridge; import io.izzel.arclight.common.bridge.core.inventory.IInventoryBridge;
import io.izzel.arclight.common.bridge.core.item.crafting.RecipeManagerBridge; import io.izzel.arclight.common.bridge.core.item.crafting.RecipeManagerBridge;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.GsonHelper; import net.minecraft.util.GsonHelper;
@ -53,7 +53,7 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge {
this.hasErrors = false; this.hasErrors = false;
Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, Recipe<?>>> map = Maps.newHashMap(); Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, Recipe<?>>> map = Maps.newHashMap();
for (RecipeType<?> type : Registry.RECIPE_TYPE) { for (RecipeType<?> type : BuiltInRegistries.RECIPE_TYPE) {
map.put(type, new Object2ObjectLinkedOpenHashMap<>()); map.put(type, new Object2ObjectLinkedOpenHashMap<>());
} }
@ -139,7 +139,7 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge {
public void clearRecipes() { public void clearRecipes() {
this.recipes = new HashMap<>(); this.recipes = new HashMap<>();
for (RecipeType<?> type : Registry.RECIPE_TYPE) { for (RecipeType<?> type : BuiltInRegistries.RECIPE_TYPE) {
this.recipes.put(type, new Object2ObjectLinkedOpenHashMap<>()); this.recipes.put(type, new Object2ObjectLinkedOpenHashMap<>());
} }
this.byName = new HashMap<>(); this.byName = new HashMap<>();

View File

@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.core.item.crafting.IRecipeBridge;
import io.izzel.arclight.common.mod.util.ArclightSpecialRecipe; import io.izzel.arclight.common.mod.util.ArclightSpecialRecipe;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.ShapedRecipe;
import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
@ -24,6 +25,7 @@ public abstract class ShapedRecipeMixin implements IRecipeBridge {
@Shadow @Final NonNullList<Ingredient> recipeItems; @Shadow @Final NonNullList<Ingredient> recipeItems;
@Shadow public abstract int getHeight(); @Shadow public abstract int getHeight();
@Shadow public abstract int getWidth(); @Shadow public abstract int getWidth();
@Shadow public abstract CraftingBookCategory category();
// @formatter:on // @formatter:on
@Override @Override
@ -34,6 +36,7 @@ public abstract class ShapedRecipeMixin implements IRecipeBridge {
CraftItemStack result = CraftItemStack.asCraftMirror(this.result); CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
CraftShapedRecipe recipe = new CraftShapedRecipe(result, (ShapedRecipe) (Object) this); CraftShapedRecipe recipe = new CraftShapedRecipe(result, (ShapedRecipe) (Object) this);
recipe.setGroup(this.group); recipe.setGroup(this.group);
recipe.setCategory(CraftRecipe.getCategory(this.category()));
switch (this.getHeight()) { switch (this.getHeight()) {
case 1: case 1:

View File

@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.item.crafting;
import io.izzel.arclight.common.bridge.core.item.crafting.IRecipeBridge; import io.izzel.arclight.common.bridge.core.item.crafting.IRecipeBridge;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapelessRecipe; import net.minecraft.world.item.crafting.ShapelessRecipe;
import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
@ -14,12 +15,13 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(ShapelessRecipe.class) @Mixin(ShapelessRecipe.class)
public class ShapelessRecipeMixin implements IRecipeBridge { public abstract class ShapelessRecipeMixin implements IRecipeBridge {
// @formatter:off // @formatter:off
@Shadow @Final ItemStack result; @Shadow @Final ItemStack result;
@Shadow @Final String group; @Shadow @Final String group;
@Shadow @Final NonNullList<Ingredient> ingredients; @Shadow @Final NonNullList<Ingredient> ingredients;
@Shadow public abstract CraftingBookCategory category();
// @formatter:off // @formatter:off
@Override @Override
@ -27,6 +29,7 @@ public class ShapelessRecipeMixin implements IRecipeBridge {
CraftItemStack result = CraftItemStack.asCraftMirror(this.result); CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
CraftShapelessRecipe recipe = new CraftShapelessRecipe(result, (ShapelessRecipe)(Object) this); CraftShapelessRecipe recipe = new CraftShapelessRecipe(result, (ShapelessRecipe)(Object) this);
recipe.setGroup(this.group); recipe.setGroup(this.group);
recipe.setCategory(CraftRecipe.getCategory(this.category()));
for (Ingredient list : this.ingredients) { for (Ingredient list : this.ingredients) {
recipe.addIngredient(CraftRecipe.toBukkit(list)); recipe.addIngredient(CraftRecipe.toBukkit(list));
} }

View File

@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.core.item.crafting.IRecipeBridge;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.AbstractCookingRecipe; import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.CookingBookCategory;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.SmeltingRecipe; import net.minecraft.world.item.crafting.SmeltingRecipe;
@ -15,10 +16,10 @@ import org.bukkit.inventory.Recipe;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@Mixin(SmeltingRecipe.class) @Mixin(SmeltingRecipe.class)
public abstract class FurnaceRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge { public abstract class SmeltingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge {
public FurnaceRecipeMixin(RecipeType<?> typeIn, ResourceLocation idIn, String groupIn, Ingredient ingredientIn, ItemStack resultIn, float experienceIn, int cookTimeIn) { public SmeltingRecipeMixin(RecipeType<?> p_250197_, ResourceLocation p_249379_, String p_249518_, CookingBookCategory p_250891_, Ingredient p_251354_, ItemStack p_252185_, float p_252165_, int p_250256_) {
super(typeIn, idIn, groupIn, ingredientIn, resultIn, experienceIn, cookTimeIn); super(p_250197_, p_249379_, p_249518_, p_250891_, p_251354_, p_252185_, p_252165_, p_250256_);
} }
@Override @Override
@ -27,6 +28,7 @@ public abstract class FurnaceRecipeMixin extends AbstractCookingRecipe implement
CraftFurnaceRecipe recipe = new CraftFurnaceRecipe(CraftNamespacedKey.fromMinecraft(this.id), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); CraftFurnaceRecipe recipe = new CraftFurnaceRecipe(CraftNamespacedKey.fromMinecraft(this.id), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime);
recipe.setGroup(this.group); recipe.setGroup(this.group);
recipe.setCategory(CraftRecipe.getCategory(this.category()));
return recipe; return recipe;
} }

View File

@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.core.item.crafting.IRecipeBridge;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.AbstractCookingRecipe; import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.CookingBookCategory;
import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.SmokingRecipe; import net.minecraft.world.item.crafting.SmokingRecipe;
@ -17,8 +18,8 @@ import org.spongepowered.asm.mixin.Mixin;
@Mixin(SmokingRecipe.class) @Mixin(SmokingRecipe.class)
public abstract class SmokingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge { public abstract class SmokingRecipeMixin extends AbstractCookingRecipe implements IRecipeBridge {
public SmokingRecipeMixin(RecipeType<?> typeIn, ResourceLocation idIn, String groupIn, Ingredient ingredientIn, ItemStack resultIn, float experienceIn, int cookTimeIn) { public SmokingRecipeMixin(RecipeType<?> p_250197_, ResourceLocation p_249379_, String p_249518_, CookingBookCategory p_250891_, Ingredient p_251354_, ItemStack p_252185_, float p_252165_, int p_250256_) {
super(typeIn, idIn, groupIn, ingredientIn, resultIn, experienceIn, cookTimeIn); super(p_250197_, p_249379_, p_249518_, p_250891_, p_251354_, p_252185_, p_252165_, p_250256_);
} }
@Override @Override
@ -26,6 +27,7 @@ public abstract class SmokingRecipeMixin extends AbstractCookingRecipe implement
CraftItemStack result = CraftItemStack.asCraftMirror(this.result); CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
CraftSmokingRecipe recipe = new CraftSmokingRecipe(CraftNamespacedKey.fromMinecraft(this.getId()), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); CraftSmokingRecipe recipe = new CraftSmokingRecipe(CraftNamespacedKey.fromMinecraft(this.getId()), result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime);
recipe.setGroup(this.group); recipe.setGroup(this.group);
recipe.setCategory(CraftRecipe.getCategory(this.category()));
return recipe; return recipe;
} }
} }

View File

@ -11,7 +11,7 @@ import io.izzel.arclight.common.mod.util.ArclightCaptures;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
@ -204,7 +204,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter {
} }
var generator = serverWorld.getChunkSource().getGenerator(); var generator = serverWorld.getChunkSource().getGenerator();
if (biomeProvider != null) { if (biomeProvider != null) {
BiomeSource biomeSource = new CustomWorldChunkManager(worldInfo, biomeProvider, serverWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)); BiomeSource biomeSource = new CustomWorldChunkManager(worldInfo, biomeProvider, serverWorld.registryAccess().registryOrThrow(Registries.BIOME));
((ChunkGeneratorBridge) generator).bridge$setBiomeSource(biomeSource); ((ChunkGeneratorBridge) generator).bridge$setBiomeSource(biomeSource);
} }
CustomChunkGenerator gen = new CustomChunkGenerator(serverWorld, generator, this.generator); CustomChunkGenerator gen = new CustomChunkGenerator(serverWorld, generator, this.generator);

View File

@ -3,7 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource; import net.minecraft.util.RandomSource;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BambooBlock; import net.minecraft.world.level.block.BambooStalkBlock;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BambooLeaves; import net.minecraft.world.level.block.state.properties.BambooLeaves;
@ -18,8 +18,8 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(BambooBlock.class) @Mixin(BambooStalkBlock.class)
public abstract class BambooBlockMixin extends BlockMixin { public abstract class BambooStalkBlockMixin extends BlockMixin {
@Shadow @Final public static EnumProperty<BambooLeaves> LEAVES; @Shadow @Final public static EnumProperty<BambooLeaves> LEAVES;
@Shadow @Final public static IntegerProperty AGE; @Shadow @Final public static IntegerProperty AGE;

View File

@ -6,7 +6,6 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BedBlock; import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -14,6 +13,7 @@ import net.minecraft.world.level.block.state.properties.BedPart;
import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty; import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
@ -74,7 +74,8 @@ public abstract class BedBlockMixin {
level.removeBlock(blockpos, false); level.removeBlock(blockpos, false);
} }
level.explode(null, DamageSource.badRespawnPointExplosion(), null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, 5.0F, true, Explosion.BlockInteraction.DESTROY); Vec3 vec3d = pos.getCenter();
level.explode(null, DamageSource.badRespawnPointExplosion(vec3d), null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK);
} else if (p_49477_.getMessage() != null) { } else if (p_49477_.getMessage() != null) {
p_49518_.displayClientMessage(p_49477_.getMessage(), true); p_49518_.displayClientMessage(p_49477_.getMessage(), true);
} }

View File

@ -2,11 +2,9 @@ package io.izzel.arclight.common.mixin.core.world.level.block;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.ButtonBlock; import net.minecraft.world.level.block.ButtonBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -26,8 +24,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.List;
@Mixin(ButtonBlock.class) @Mixin(ButtonBlock.class)
public class ButtonBlockMixin { public class ButtonBlockMixin {
@ -38,25 +34,14 @@ public class ButtonBlockMixin {
@Inject(method = "checkPressed", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, @Inject(method = "checkPressed", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;")) at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;"))
public void arclight$entityInteract(BlockState state, Level worldIn, BlockPos pos, CallbackInfo ci, public void arclight$entityInteract(BlockState state, Level worldIn, BlockPos pos, CallbackInfo ci,
List<? extends Entity> list, boolean flag) { AbstractArrow abstractarrow, boolean flag) {
boolean flag1 = state.getValue(ButtonBlock.POWERED); boolean flag1 = state.getValue(ButtonBlock.POWERED);
if (flag1 != flag && flag) { if (flag1 != flag && flag) {
Block block = CraftBlock.at(worldIn, pos); Block block = CraftBlock.at(worldIn, pos);
boolean allowed = false; EntityInteractEvent event = new EntityInteractEvent(((EntityBridge) abstractarrow).bridge$getBukkitEntity(), block);
for (Object object : list) {
if (object != null) {
EntityInteractEvent event = new EntityInteractEvent(((EntityBridge) object).bridge$getBukkitEntity(), block);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (event.isCancelled()) {
allowed = true;
break;
}
}
}
if (!allowed) {
ci.cancel(); ci.cancel();
} }
} }
@ -65,7 +50,7 @@ public class ButtonBlockMixin {
@Inject(method = "checkPressed", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, @Inject(method = "checkPressed", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
public void arclight$blockRedstone3(BlockState state, Level worldIn, BlockPos pos, CallbackInfo ci, public void arclight$blockRedstone3(BlockState state, Level worldIn, BlockPos pos, CallbackInfo ci,
List<? extends Entity> list, boolean flag, boolean flag1) { AbstractArrow abstractarrow, boolean flag, boolean flag1) {
Block block = CraftBlock.at(worldIn, pos); Block block = CraftBlock.at(worldIn, pos);
int old = (flag1) ? 15 : 0; int old = (flag1) ? 15 : 0;
int current = (!flag1) ? 15 : 0; int current = (!flag1) ? 15 : 0;
@ -94,16 +79,4 @@ public class ButtonBlockMixin {
} }
} }
} }
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
private void arclight$blockRedstone2(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource rand, CallbackInfo ci) {
Block block = CraftBlock.at(worldIn, pos);
BlockRedstoneEvent event = new BlockRedstoneEvent(block, 15, 0);
Bukkit.getPluginManager().callEvent(event);
if (event.getNewCurrent() > 0) {
ci.cancel();
}
}
} }

View File

@ -1,15 +1,10 @@
package io.izzel.arclight.common.mixin.core.world.level.block; package io.izzel.arclight.common.mixin.core.world.level.block;
import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.CarvedPumpkinBlock; import net.minecraft.world.level.block.CarvedPumpkinBlock;
import net.minecraft.world.level.block.LevelEvent; import net.minecraft.world.level.block.state.pattern.BlockPattern;
import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
@ -19,47 +14,16 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(CarvedPumpkinBlock.class) @Mixin(CarvedPumpkinBlock.class)
public class CarvedPumpkinBlockMixin { public class CarvedPumpkinBlockMixin {
private transient BlockStateListPopulator arclight$populator; @Redirect(method = "spawnGolemInWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/CarvedPumpkinBlock;clearPatternBlocks(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/pattern/BlockPattern$BlockPatternMatch;)V"))
private transient boolean arclight$success = false; private static void arclight$clearLater(Level level, BlockPattern.BlockPatternMatch match) {
@Redirect(method = "trySpawnGolem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
public boolean arclight$storeUpdate1(Level world, BlockPos pos, BlockState newState, int flags) {
if (arclight$populator == null) {
arclight$populator = new BlockStateListPopulator(world);
}
return arclight$populator.setBlock(pos, newState, flags);
} }
@Redirect(method = "trySpawnGolem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;levelEvent(ILnet/minecraft/core/BlockPos;I)V")) @Inject(method = "spawnGolemInWorld", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
public void arclight$storeUpdate2(Level world, int type, BlockPos pos, int data) { private static void arclight$clearPattern(Level p_249110_, BlockPattern.BlockPatternMatch p_251293_, Entity entity, BlockPos p_251189_, CallbackInfo ci) {
// do nothing if (!entity.isAddedToWorld()) {
}
@Inject(method = "trySpawnGolem", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
public void arclight$returnIfFail(Level world, BlockPos blockPos, CallbackInfo ci) {
if (arclight$success) {
if (arclight$populator != null) {
for (BlockPos pos : arclight$populator.getBlocks()) {
world.levelEvent(LevelEvent.PARTICLES_DESTROY_BLOCK, pos, Block.getId(world.getBlockState(pos)));
}
arclight$populator.updateList();
}
} else {
ci.cancel(); ci.cancel();
} } else {
arclight$populator = null; CarvedPumpkinBlock.clearPatternBlocks(p_249110_, p_251293_);
arclight$success = false; }
}
@Redirect(method = "trySpawnGolem", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
public boolean arclight$spawnSnow(Level world, Entity entityIn) {
((WorldBridge) world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BUILD_SNOWMAN);
return arclight$success = world.addFreshEntity(entityIn);
}
@Redirect(method = "trySpawnGolem", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
public boolean arclight$spawnIron(Level world, Entity entityIn) {
((WorldBridge) world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BUILD_IRONGOLEM);
return arclight$success = world.addFreshEntity(entityIn);
} }
} }

View File

@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.DoorBlock;
@ -12,6 +13,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.event.block.BlockRedstoneEvent;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
@ -24,7 +26,7 @@ public abstract class DoorBlockMixin {
@Shadow @Final public static EnumProperty<DoubleBlockHalf> HALF; @Shadow @Final public static EnumProperty<DoubleBlockHalf> HALF;
@Shadow @Final public static BooleanProperty POWERED; @Shadow @Final public static BooleanProperty POWERED;
@Shadow @Final public static BooleanProperty OPEN; @Shadow @Final public static BooleanProperty OPEN;
@Shadow protected abstract void playSound(Level worldIn, BlockPos pos, boolean isOpening); @Shadow protected abstract void playSound(@Nullable Entity p_251616_, Level p_249656_, BlockPos p_249439_, boolean p_251628_);
// @formatter:on // @formatter:on
/** /**
@ -49,7 +51,7 @@ public abstract class DoorBlockMixin {
boolean flag = event.getNewCurrent() > 0; boolean flag = event.getNewCurrent() > 0;
if (flag != state.getValue(OPEN)) { if (flag != state.getValue(OPEN)) {
this.playSound(worldIn, pos, flag); this.playSound(null, worldIn, pos, flag);
} }
worldIn.setBlock(pos, state.setValue(POWERED, flag).setValue(OPEN, flag), 2); worldIn.setBlock(pos, state.setValue(POWERED, flag).setValue(OPEN, flag), 2);

View File

@ -36,7 +36,7 @@ public class DragonEggBlockMixin {
private transient BlockPos arclight$toBlock; private transient BlockPos arclight$toBlock;
@ModifyVariable(method = "teleport", index = 6, name = "blockpos", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 2)) @ModifyVariable(method = "teleport", ordinal = 1, name = "blockpos", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 2))
public BlockPos arclight$setPos(BlockPos pos) { public BlockPos arclight$setPos(BlockPos pos) {
return arclight$toBlock; return arclight$toBlock;
} }

View File

@ -4,13 +4,10 @@ import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import io.izzel.arclight.common.bridge.core.entity.EntityTypeBridge; import io.izzel.arclight.common.bridge.core.entity.EntityTypeBridge;
import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.NetherPortalBlock; import net.minecraft.world.level.block.NetherPortalBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -27,9 +24,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NetherPortalBlock.class) @Mixin(NetherPortalBlock.class)
public class NetherPortalBlockMixin { public class NetherPortalBlockMixin {
@Redirect(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;")) @Redirect(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;)Lnet/minecraft/world/entity/Entity;"))
public Entity arclight$spawn(EntityType<?> entityType, ServerLevel worldIn, CompoundTag compound, Component customName, Player playerIn, BlockPos pos, MobSpawnType reason, boolean flag, boolean flag1) { public Entity arclight$spawn(EntityType<?> instance, ServerLevel p_262634_, BlockPos p_262707_, MobSpawnType p_262597_) {
return ((EntityTypeBridge<?>) entityType).bridge$spawnCreature(worldIn, compound, customName, playerIn, pos, reason, flag, flag1, CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); return ((EntityTypeBridge<?>) instance).bridge$spawnCreature(p_262634_, p_262707_, p_262597_, CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
} }
@Inject(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;handleInsidePortal(Lnet/minecraft/core/BlockPos;)V")) @Inject(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;handleInsidePortal(Lnet/minecraft/core/BlockPos;)V"))

View File

@ -8,45 +8,16 @@ import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.block.NotePlayEvent; import org.bukkit.event.block.NotePlayEvent;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NoteBlock.class) @Mixin(NoteBlock.class)
public abstract class NoteBlockMixin { public abstract class NoteBlockMixin {
// @formatter:off
@Shadow protected abstract void playNote(Entity entity, Level worldIn, BlockPos pos);
// @formatter:on
@Redirect(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V"))
public void arclight$callNote2(NoteBlock noteBlock, Entity entity, Level worldIn, BlockPos pos, BlockState blockState) {
this.playNote(entity, worldIn, pos, blockState);
}
@Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V"))
public void arclight$callNote1(NoteBlock noteBlock, Entity entity, Level worldIn, BlockPos pos, BlockState blockState) {
this.playNote(entity, worldIn, pos, blockState);
}
@Redirect(method = "attack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V"))
public void arclight$callNote3(NoteBlock noteBlock, Entity entity, Level worldIn, BlockPos pos, BlockState blockState) {
this.playNote(entity, worldIn, pos, blockState);
}
private transient BlockState arclight$state;
private void playNote(Entity entity, Level worldIn, BlockPos pos, BlockState state) {
arclight$state = state;
this.playNote(entity, worldIn, pos);
arclight$state = null;
}
@Inject(method = "playNote", cancellable = true, require = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;blockEvent(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;II)V")) @Inject(method = "playNote", cancellable = true, require = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;blockEvent(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;II)V"))
private void arclight$notePlay(Entity entity, Level worldIn, BlockPos pos, CallbackInfo ci) { private void arclight$notePlay(Entity entity, BlockState state, Level worldIn, BlockPos pos, CallbackInfo ci) {
NotePlayEvent event = CraftEventFactory.callNotePlayEvent(worldIn, pos, arclight$state.getValue(NoteBlock.INSTRUMENT), arclight$state.getValue(NoteBlock.NOTE)); NotePlayEvent event = CraftEventFactory.callNotePlayEvent(worldIn, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE));
if (event.isCancelled()) { if (event.isCancelled()) {
ci.cancel(); ci.cancel();
} }

View File

@ -9,7 +9,7 @@ import net.minecraft.BlockUtil;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
@ -49,7 +49,7 @@ public abstract class PortalShapeMixin implements PortalSizeBridge {
@Shadow private int height; @Shadow private int height;
@Shadow @Final private Direction rightDir; @Shadow @Final private Direction rightDir;
@Shadow @Final private int width; @Shadow @Final private int width;
@Shadow public static PortalInfo createPortalInfo(ServerLevel world, BlockUtil.FoundRectangle result, Direction.Axis axis, Vec3 offsetVector, EntityDimensions size, Vec3 motion, float rotationYaw, float rotationPitch) { return null; } @Shadow public static PortalInfo createPortalInfo(ServerLevel p_259301_, BlockUtil.FoundRectangle p_259931_, Direction.Axis p_259901_, Vec3 p_259630_, Entity p_259166_, Vec3 p_260043_, float p_259853_, float p_259667_) { return null; }
// @formatter:on // @formatter:on
List<BlockState> blocks = new ArrayList<>(); List<BlockState> blocks = new ArrayList<>();
@ -101,8 +101,8 @@ public abstract class PortalShapeMixin implements PortalSizeBridge {
return portalInfo; return portalInfo;
} }
private static PortalInfo createPortalInfo(ServerLevel world, BlockUtil.FoundRectangle result, Direction.Axis axis, Vec3 offsetVector, EntityDimensions size, Vec3 motion, float rotationYaw, float rotationPitch, CraftPortalEvent event) { private static PortalInfo createPortalInfo(ServerLevel world, BlockUtil.FoundRectangle result, Direction.Axis axis, Vec3 offsetVector, Entity entity, Vec3 motion, float rotationYaw, float rotationPitch, CraftPortalEvent event) {
ArclightCaptures.captureCraftPortalEvent(event); ArclightCaptures.captureCraftPortalEvent(event);
return createPortalInfo(world, result, axis, offsetVector, size, motion, rotationYaw, rotationPitch); return createPortalInfo(world, result, axis, offsetVector, entity, motion, rotationYaw, rotationPitch);
} }
} }

View File

@ -3,58 +3,41 @@ package io.izzel.arclight.common.mixin.core.world.level.block;
import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.boss.wither.WitherBoss;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.CarvedPumpkinBlock;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.WitherSkullBlock; import net.minecraft.world.level.block.WitherSkullBlock;
import net.minecraft.world.level.block.entity.SkullBlockEntity; import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator; import net.minecraft.world.level.block.state.pattern.BlockPattern;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(WitherSkullBlock.class) @Mixin(WitherSkullBlock.class)
public class WitherSkullBlockMixin { public class WitherSkullBlockMixin {
private static transient BlockStateListPopulator arclight$populator; @Redirect(method = "checkSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/CarvedPumpkinBlock;clearPatternBlocks(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/pattern/BlockPattern$BlockPatternMatch;)V"))
private static transient boolean arclight$success = false; private static void arclight$clearLater(Level p_249604_, BlockPattern.BlockPatternMatch p_251190_) {
@Redirect(method = "checkSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
private static boolean arclight$storeUpdate1(Level world, BlockPos pos, BlockState newState, int flags) {
if (arclight$populator == null) {
arclight$populator = new BlockStateListPopulator(world);
}
return arclight$populator.setBlock(pos, newState, flags);
} }
@Redirect(method = "checkSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;levelEvent(ILnet/minecraft/core/BlockPos;I)V")) @Inject(method = "checkSpawn", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/boss/wither/WitherBoss;makeInvulnerable()V"))
private static void arclight$storeUpdate2(Level world, int type, BlockPos pos, int data) { private static void arclight$addEntity(Level level, BlockPos pos, SkullBlockEntity p_58258_, CallbackInfo ci,
// do nothing BlockState state, boolean flag, BlockPattern.BlockPatternMatch patternMatch, WitherBoss witherBoss) {
} ((WorldBridge) level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BUILD_WITHER);
if (!level.addFreshEntity(witherBoss)) {
@Inject(method = "checkSpawn", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private static void arclight$returnIfFail(Level worldIn, BlockPos blockPos, SkullBlockEntity tileEntity, CallbackInfo ci) {
if (arclight$success) {
if (arclight$populator != null) {
for (BlockPos pos : arclight$populator.getBlocks()) {
worldIn.levelEvent(LevelEvent.PARTICLES_DESTROY_BLOCK, pos, Block.getId(worldIn.getBlockState(pos)));
}
arclight$populator.updateList();
}
} else {
ci.cancel(); ci.cancel();
} else {
CarvedPumpkinBlock.clearPatternBlocks(level, patternMatch);
} }
arclight$populator = null;
arclight$success = false;
} }
@Redirect(method = "checkSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) @Redirect(method = "checkSpawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private static boolean arclight$spawnWither(Level world, Entity entityIn) { private static boolean arclight$muteSpawn(Level instance, Entity entity) {
((WorldBridge) world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.BUILD_WITHER); return true;
return arclight$success = world.addFreshEntity(entityIn);
} }
} }

View File

@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(CampfireBlockEntity.class) @Mixin(CampfireBlockEntity.class)
public abstract class CampfireTileEntityMixin extends BlockEntityMixin { public abstract class CampfireBlockEntityMixin extends BlockEntityMixin {
@Shadow @Final private RecipeManager.CachedCheck<Container, CampfireCookingRecipe> quickCheck; @Shadow @Final private RecipeManager.CachedCheck<Container, CampfireCookingRecipe> quickCheck;
@ -40,9 +40,11 @@ public abstract class CampfireTileEntityMixin extends BlockEntityMixin {
entity.cookingProgress[i]++; entity.cookingProgress[i]++;
if (entity.cookingProgress[i] >= entity.cookingTime[i]) { if (entity.cookingProgress[i] >= entity.cookingTime[i]) {
Container container = new SimpleContainer(itemstack); Container container = new SimpleContainer(itemstack);
ItemStack itemstack1 = ((CampfireTileEntityMixin) (Object) entity).quickCheck.getRecipeFor(container, level).map((p_155305_) -> { ItemStack itemstack1 = ((CampfireBlockEntityMixin) (Object) entity).quickCheck.getRecipeFor(container, level).map((p_155305_) -> {
return p_155305_.assemble(container); return p_155305_.assemble(container);
}).orElse(itemstack); }).orElse(itemstack);
if (!itemstack1.isItemEnabled(level.enabledFeatures())) continue;
CraftItemStack source = CraftItemStack.asCraftMirror(itemstack); CraftItemStack source = CraftItemStack.asCraftMirror(itemstack);
org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1); org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack1);

View File

@ -0,0 +1,68 @@
package io.izzel.arclight.common.mixin.core.world.level.block.entity;
import io.izzel.arclight.common.bridge.core.inventory.IInventoryBridge;
import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import io.izzel.arclight.common.mod.util.DistValidate;
import net.minecraft.core.NonNullList;
import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.InventoryHolder;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.ArrayList;
import java.util.List;
@Mixin(ChiseledBookShelfBlockEntity.class)
public abstract class ChiseledBookShelfBlockEntityMixin extends BlockEntityMixin implements IInventoryBridge, Container {
@Shadow @Final private NonNullList<ItemStack> items;
public List<HumanEntity> transaction = new ArrayList<>();
private int maxStack = 1;
@Override
public List<ItemStack> getContents() {
return this.items;
}
@Override
public void onOpen(CraftHumanEntity who) {
transaction.add(who);
}
@Override
public void onClose(CraftHumanEntity who) {
transaction.remove(who);
}
@Override
public List<HumanEntity> getViewers() {
return transaction;
}
@Override
public void setOwner(InventoryHolder owner) {
}
@Override
public void setMaxStackSize(int size) {
maxStack = size;
}
@Override
public int getMaxStackSize() {
return maxStack;
}
@Override
public Location getLocation() {
if (!DistValidate.isValid(level)) return null;
return new org.bukkit.Location(((WorldBridge) level).bridge$getWorld(), worldPosition.getX(), worldPosition.getY(), worldPosition.getZ());
}
}

View File

@ -0,0 +1,49 @@
package io.izzel.arclight.common.mixin.core.world.level.gameevent;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.GameEventDispatcher;
import net.minecraft.world.phys.Vec3;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v.util.CraftNamespacedKey;
import org.bukkit.event.world.GenericGameEvent;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
@Mixin(GameEventDispatcher.class)
public class GameEventDispatcherMixin {
@Shadow @Final private ServerLevel level;
private transient int arclight$newRadius;
@Inject(method = "post", cancellable = true, at = @At("HEAD"))
private void arclight$gameEvent(GameEvent gameEvent, Vec3 vec3, GameEvent.Context context, CallbackInfo ci) {
var entity = context.sourceEntity();
var i = gameEvent.getNotificationRadius();
GenericGameEvent event = new GenericGameEvent(Objects.requireNonNull(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(gameEvent)))),
new Location(((WorldBridge) this.level).bridge$getWorld(), vec3.x(), vec3.y(), vec3.z()), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), i, !Bukkit.isPrimaryThread());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
ci.cancel();
} else {
arclight$newRadius = event.getRadius();
}
}
@Redirect(method = "post", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/gameevent/GameEvent;getNotificationRadius()I"))
private int arclight$applyRadius(GameEvent instance) {
return arclight$newRadius;
}
}

View File

@ -2,12 +2,13 @@ package io.izzel.arclight.common.mixin.core.world.level.gameevent.vibrations;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.PositionSource; import net.minecraft.world.level.gameevent.PositionSource;
import net.minecraft.world.level.gameevent.vibrations.VibrationInfo;
import net.minecraft.world.level.gameevent.vibrations.VibrationListener; import net.minecraft.world.level.gameevent.vibrations.VibrationListener;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -26,11 +27,11 @@ import java.util.Optional;
public abstract class VibrationListenerMixin { public abstract class VibrationListenerMixin {
// @formatter:off // @formatter:off
@Shadow @Nullable protected VibrationListener.ReceivingEvent receivingEvent;
@Shadow @Final protected VibrationListener.VibrationListenerConfig config; @Shadow @Final protected VibrationListener.VibrationListenerConfig config;
@Shadow @Final protected PositionSource listenerSource; @Shadow @Final protected PositionSource listenerSource;
@Shadow private static boolean isOccluded(Level p_223776_, Vec3 p_223777_, Vec3 p_223778_) { return false; } @Shadow private static boolean isOccluded(Level p_223776_, Vec3 p_223777_, Vec3 p_223778_) { return false; }
@Shadow protected abstract void scheduleSignal(ServerLevel p_223770_, GameEvent p_223771_, GameEvent.Context p_223772_, Vec3 p_223773_, Vec3 p_223774_); @Shadow @Nullable protected VibrationInfo currentVibration;
@Shadow public abstract void scheduleVibration(ServerLevel p_250210_, GameEvent p_251063_, GameEvent.Context p_249354_, Vec3 p_250310_, Vec3 p_249553_);
// @formatter:on // @formatter:on
/** /**
@ -38,36 +39,35 @@ public abstract class VibrationListenerMixin {
* @reason * @reason
*/ */
@Overwrite @Overwrite
public boolean handleGameEvent(ServerLevel level, GameEvent.Message p_223768_) { public boolean handleGameEvent(ServerLevel worldserver, GameEvent gameevent, GameEvent.Context gameevent_a, Vec3 vec3d) {
if (this.receivingEvent != null) { if (this.currentVibration != null) {
return false;
} else if (!this.config.isValidVibration(gameevent, gameevent_a)) {
return false; return false;
} else { } else {
GameEvent gameevent = p_223768_.gameEvent(); Optional<Vec3> optional = this.listenerSource.getPosition(worldserver);
GameEvent.Context gameevent$context = p_223768_.context();
if (!this.config.isValidVibration(gameevent, gameevent$context)) {
return false;
} else {
Optional<Vec3> optional = this.listenerSource.getPosition(level);
if (optional.isEmpty()) { if (optional.isEmpty()) {
return false; return false;
} else { } else {
Vec3 vec3 = p_223768_.source(); Vec3 vec3d1 = optional.get();
Vec3 vec31 = optional.get();
boolean cancelled = !this.config.shouldListen(level, (VibrationListener) (Object) this, new BlockPos(vec3), gameevent, gameevent$context); // CraftBukkit start
Entity entity = gameevent$context.sourceEntity(); boolean defaultCancel = !this.config.shouldListen(worldserver, (VibrationListener) (Object) this, new BlockPos(vec3d), gameevent, gameevent_a);
var event = new BlockReceiveGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameevent))), CraftBlock.at(level, new BlockPos(vec31)), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity()); Entity entity = gameevent_a.sourceEntity();
event.setCancelled(cancelled); BlockReceiveGameEvent event = new BlockReceiveGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(gameevent))), CraftBlock.at(worldserver, new BlockPos(vec3d1)), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity());
event.setCancelled(defaultCancel);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
// CraftBukkit end
return false; return false;
} else if (isOccluded(level, vec3, vec31)) { } else if (isOccluded(worldserver, vec3d, vec3d1)) {
return false; return false;
} else { } else {
this.scheduleSignal(level, gameevent, gameevent$context, vec3, vec31); this.scheduleVibration(worldserver, gameevent, gameevent_a, vec3d, vec3d1);
return true; return true;
} }
} }
} }
} }
} }
}

View File

@ -1,6 +1,8 @@
package io.izzel.arclight.common.mixin.core.world.level.levelgen.structure.templatesystem; package io.izzel.arclight.common.mixin.core.world.level.levelgen.structure.templatesystem;
import net.minecraft.core.HolderGetter;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer; import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer;
import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataTypeRegistry; import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataTypeRegistry;
@ -24,7 +26,7 @@ public class StructureTemplateMixin {
} }
@Inject(method = "load", at = @At("RETURN")) @Inject(method = "load", at = @At("RETURN"))
private void arclight$loadPdc(CompoundTag tag, CallbackInfo ci) { private void arclight$loadPdc(HolderGetter<Block> reg, CompoundTag tag, CallbackInfo ci) {
var base = tag.get("BukkitValues"); var base = tag.get("BukkitValues");
if (base instanceof CompoundTag compoundTag) { if (base instanceof CompoundTag compoundTag) {
this.persistentDataContainer.putAll(compoundTag); this.persistentDataContainer.putAll(compoundTag);

View File

@ -5,7 +5,7 @@ import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory; import net.minecraft.CrashReportCategory;
import net.minecraft.ReportedException; import net.minecraft.ReportedException;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -47,9 +47,9 @@ public interface NeighborUpdaterMixin {
CrashReportCategory crashreportcategory = crashreport.addCategory("Block being updated"); CrashReportCategory crashreportcategory = crashreport.addCategory("Block being updated");
crashreportcategory.setDetail("Source block type", () -> { crashreportcategory.setDetail("Source block type", () -> {
try { try {
return String.format(Locale.ROOT, "ID #%s (%s // %s)", Registry.BLOCK.getKey(block), block.getDescriptionId(), block.getClass().getCanonicalName()); return String.format(Locale.ROOT, "ID #%s (%s // %s)", BuiltInRegistries.BLOCK.getKey(block), block.getDescriptionId(), block.getClass().getCanonicalName());
} catch (Throwable throwable1) { } catch (Throwable throwable1) {
return "ID #" + Registry.BLOCK.getKey(block); return "ID #" + BuiltInRegistries.BLOCK.getKey(block);
} }
}); });
CrashReportCategory.populateBlockDetails(crashreportcategory, level, pos, state); CrashReportCategory.populateBlockDetails(crashreportcategory, level, pos, state);

View File

@ -7,6 +7,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.util.random.SimpleWeightedRandomList; import net.minecraft.util.random.SimpleWeightedRandomList;
import net.minecraft.world.Difficulty; import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -24,6 +25,7 @@ import net.minecraft.world.phys.AABB;
import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.ForgeEventFactory;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -40,15 +42,15 @@ public abstract class BaseSpawnerMixin {
@Shadow public SimpleWeightedRandomList<SpawnData> spawnPotentials; @Shadow public SimpleWeightedRandomList<SpawnData> spawnPotentials;
@Shadow public int spawnDelay; @Shadow public int spawnDelay;
@Shadow public int spawnCount; @Shadow public int spawnCount;
@Shadow public SpawnData nextSpawnData;
@Shadow public int spawnRange; @Shadow public int spawnRange;
@Shadow public int maxNearbyEntities; @Shadow public int maxNearbyEntities;
@Shadow protected abstract boolean isNearPlayer(Level p_151344_, BlockPos p_151345_); @Shadow protected abstract boolean isNearPlayer(Level p_151344_, BlockPos p_151345_);
@Shadow protected abstract void delay(Level p_151351_, BlockPos p_151352_); @Shadow protected abstract void delay(Level p_151351_, BlockPos p_151352_);
@Shadow protected abstract SpawnData getOrCreateNextSpawnData(@Nullable Level p_254503_, RandomSource p_253892_, BlockPos p_254487_);
// @formatter:on // @formatter:on
@Inject(method = "setEntityId", at = @At("RETURN")) @Inject(method = "setEntityId", at = @At("RETURN"))
public void arclight$clearMobs(EntityType<?> type, CallbackInfo ci) { public void arclight$clearMobs(CallbackInfo ci) {
this.spawnPotentials = SimpleWeightedRandomList.empty(); this.spawnPotentials = SimpleWeightedRandomList.empty();
} }
@ -67,9 +69,11 @@ public abstract class BaseSpawnerMixin {
--this.spawnDelay; --this.spawnDelay;
} else { } else {
boolean flag = false; boolean flag = false;
RandomSource randomsource = level.getRandom();
SpawnData spawnData = this.getOrCreateNextSpawnData(level, randomsource, pos);
for (int i = 0; i < this.spawnCount; ++i) { for (int i = 0; i < this.spawnCount; ++i) {
CompoundTag compoundtag = this.nextSpawnData.getEntityToSpawn(); CompoundTag compoundtag = spawnData.getEntityToSpawn();
Optional<EntityType<?>> optional = EntityType.by(compoundtag); Optional<EntityType<?>> optional = EntityType.by(compoundtag);
if (optional.isEmpty()) { if (optional.isEmpty()) {
this.delay(level, pos); this.delay(level, pos);
@ -83,12 +87,12 @@ public abstract class BaseSpawnerMixin {
double d2 = j >= 3 ? listtag.getDouble(2) : (double) pos.getZ() + (level.random.nextDouble() - level.random.nextDouble()) * (double) this.spawnRange + 0.5D; double d2 = j >= 3 ? listtag.getDouble(2) : (double) pos.getZ() + (level.random.nextDouble() - level.random.nextDouble()) * (double) this.spawnRange + 0.5D;
if (level.noCollision(optional.get().getAABB(d0, d1, d2))) { if (level.noCollision(optional.get().getAABB(d0, d1, d2))) {
BlockPos blockpos = new BlockPos(d0, d1, d2); BlockPos blockpos = new BlockPos(d0, d1, d2);
if (this.nextSpawnData.getCustomSpawnRules().isPresent()) { if (spawnData.getCustomSpawnRules().isPresent()) {
if (!optional.get().getCategory().isFriendly() && level.getDifficulty() == Difficulty.PEACEFUL) { if (!optional.get().getCategory().isFriendly() && level.getDifficulty() == Difficulty.PEACEFUL) {
continue; continue;
} }
SpawnData.CustomSpawnRules spawndata$customspawnrules = this.nextSpawnData.getCustomSpawnRules().get(); SpawnData.CustomSpawnRules spawndata$customspawnrules = spawnData.getCustomSpawnRules().get();
if (!spawndata$customspawnrules.blockLightLimit().isValueInRange(level.getBrightness(LightLayer.BLOCK, blockpos)) || !spawndata$customspawnrules.skyLightLimit().isValueInRange(level.getBrightness(LightLayer.SKY, blockpos))) { if (!spawndata$customspawnrules.blockLightLimit().isValueInRange(level.getBrightness(LightLayer.BLOCK, blockpos)) || !spawndata$customspawnrules.skyLightLimit().isValueInRange(level.getBrightness(LightLayer.SKY, blockpos))) {
continue; continue;
} }
@ -116,12 +120,12 @@ public abstract class BaseSpawnerMixin {
var res = ForgeEventFactory.canEntitySpawn(mob, level, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this, MobSpawnType.SPAWNER); var res = ForgeEventFactory.canEntitySpawn(mob, level, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this, MobSpawnType.SPAWNER);
if (res == net.minecraftforge.eventbus.api.Event.Result.DENY) continue; if (res == net.minecraftforge.eventbus.api.Event.Result.DENY) continue;
if (res == net.minecraftforge.eventbus.api.Event.Result.DEFAULT) { if (res == net.minecraftforge.eventbus.api.Event.Result.DEFAULT) {
if (this.nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(level, MobSpawnType.SPAWNER) || !mob.checkSpawnObstruction(level)) { if (spawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(level, MobSpawnType.SPAWNER) || !mob.checkSpawnObstruction(level)) {
continue; continue;
} }
} }
if (this.nextSpawnData.getEntityToSpawn().size() == 1 && this.nextSpawnData.getEntityToSpawn().contains("id", 8)) { if (spawnData.getEntityToSpawn().size() == 1 && spawnData.getEntityToSpawn().contains("id", 8)) {
if (!ForgeEventFactory.doSpecialSpawn(mob, (LevelAccessor) level, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this, MobSpawnType.SPAWNER)) if (!ForgeEventFactory.doSpecialSpawn(mob, (LevelAccessor) level, (float) entity.getX(), (float) entity.getY(), (float) entity.getZ(), (BaseSpawner) (Object) this, MobSpawnType.SPAWNER))
((Mob) entity).finalizeSpawn(level, level.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null, null); ((Mob) entity).finalizeSpawn(level, level.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null, null);
} }

View File

@ -14,12 +14,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(WanderingTraderSpawner.class) @Mixin(WanderingTraderSpawner.class)
public class WanderingTraderSpawnerMixin { public class WanderingTraderSpawnerMixin {
@Inject(method = "spawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;")) @Inject(method = "spawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;)Lnet/minecraft/world/entity/Entity;"))
public void arclight$spawnReason1(ServerLevel serverWorld, CallbackInfoReturnable<Boolean> cir) { public void arclight$spawnReason1(ServerLevel serverWorld, CallbackInfoReturnable<Boolean> cir) {
((WorldBridge) serverWorld).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL); ((WorldBridge) serverWorld).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL);
} }
@Inject(method = "tryToSpawnLlamaFor", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/nbt/CompoundTag;Lnet/minecraft/network/chat/Component;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;ZZ)Lnet/minecraft/world/entity/Entity;")) @Inject(method = "tryToSpawnLlamaFor", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;spawn(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/MobSpawnType;)Lnet/minecraft/world/entity/Entity;"))
public void arclight$spawnReason2(ServerLevel serverWorld, WanderingTrader p_242373_2_, int p_242373_3_, CallbackInfo ci) { public void arclight$spawnReason2(ServerLevel serverWorld, WanderingTrader p_242373_2_, int p_242373_3_, CallbackInfo ci) {
((WorldBridge) serverWorld).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL); ((WorldBridge) serverWorld).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL);
} }

View File

@ -28,7 +28,7 @@ public abstract class PrimaryLevelDataMixin implements WorldInfoBridge {
@Shadow private boolean thundering; @Shadow private boolean thundering;
@Shadow private boolean raining; @Shadow private boolean raining;
@Shadow public abstract boolean isDifficultyLocked(); @Shadow public abstract boolean isDifficultyLocked();
@Shadow private LevelSettings settings; @Shadow public LevelSettings settings;
@Shadow @Final private Lifecycle worldGenSettingsLifecycle; @Shadow @Final private Lifecycle worldGenSettingsLifecycle;
// @formatter:on // @formatter:on

View File

@ -1,24 +0,0 @@
package io.izzel.arclight.common.mixin.optimization.general;
import net.minecraft.resources.ResourceKey;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Mixin(ResourceKey.class)
public class ResourceKeyMixin_Optimize {
@Redirect(method = "<clinit>", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Collections;synchronizedMap(Ljava/util/Map;)Ljava/util/Map;"))
private static <K, V> Map<K, V> arclight$useHashMap(Map<K, V> m) {
return new ConcurrentHashMap<>();
}
@Redirect(method = "create(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/resources/ResourceKey;",
at = @At(value = "INVOKE", remap = false, target = "Ljava/lang/String;intern()Ljava/lang/String;"))
private static String arclight$dropIntern(String instance) {
return instance;
}
}

View File

@ -19,6 +19,8 @@ import io.izzel.arclight.i18n.ArclightConfig;
import io.izzel.arclight.i18n.conf.EntityPropertySpec; import io.izzel.arclight.i18n.conf.EntityPropertySpec;
import io.izzel.arclight.i18n.conf.MaterialPropertySpec; import io.izzel.arclight.i18n.conf.MaterialPropertySpec;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
@ -29,10 +31,10 @@ import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase; import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase;
import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potions; import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.item.crafting.CookingBookCategory;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.LevelStem;
@ -48,7 +50,7 @@ import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v.CraftCrashReport; import org.bukkit.craftbukkit.v.CraftCrashReport;
import org.bukkit.craftbukkit.v.CraftStatistic; import org.bukkit.craftbukkit.v.CraftStatistic;
import org.bukkit.craftbukkit.v.inventory.CraftCreativeCategory; import org.bukkit.craftbukkit.v.inventory.CraftRecipe;
import org.bukkit.craftbukkit.v.potion.CraftPotionUtil; import org.bukkit.craftbukkit.v.potion.CraftPotionUtil;
import org.bukkit.craftbukkit.v.util.CraftMagicNumbers; import org.bukkit.craftbukkit.v.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v.util.CraftNamespacedKey; import org.bukkit.craftbukkit.v.util.CraftNamespacedKey;
@ -59,7 +61,6 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.SpawnCategory; import org.bukkit.entity.SpawnCategory;
import org.bukkit.entity.Villager; import org.bukkit.entity.Villager;
import org.bukkit.inventory.CreativeCategory;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType; import org.bukkit.potion.PotionType;
@ -67,12 +68,10 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
@SuppressWarnings({"ConstantConditions", "deprecation"}) @SuppressWarnings({"ConstantConditions", "deprecation"})
public class BukkitRegistry { public class BukkitRegistry {
@ -108,9 +107,9 @@ public class BukkitRegistry {
loadBiomes(console); loadBiomes(console);
loadArts(); loadArts();
loadStats(); loadStats();
loadCreativeTab();
loadSpawnCategory(); loadSpawnCategory();
loadEndDragonPhase(); loadEndDragonPhase();
loadCookingBookCategory();
try { try {
for (var field : org.bukkit.Registry.class.getFields()) { for (var field : org.bukkit.Registry.class.getFields()) {
if (Modifier.isStatic(field.getModifiers()) && field.get(null) instanceof org.bukkit.Registry.SimpleRegistry<?> registry) { if (Modifier.isStatic(field.getModifiers()) && field.get(null) instanceof org.bukkit.Registry.SimpleRegistry<?> registry) {
@ -121,6 +120,22 @@ public class BukkitRegistry {
} }
} }
private static void loadCookingBookCategory() {
var id = CookingBookCategory.values().length;
var newTypes = new ArrayList<org.bukkit.inventory.recipe.CookingBookCategory>();
for (CookingBookCategory category : CookingBookCategory.values()) {
try {
CraftRecipe.getCategory(category);
} catch (Exception e) {
var name = category.name();
var bukkit = EnumHelper.makeEnum(org.bukkit.inventory.recipe.CookingBookCategory.class, name, id++, List.of(), List.of());
newTypes.add(bukkit);
ArclightMod.LOGGER.debug("Registered {} as cooking category {}", name, bukkit);
}
}
EnumHelper.addEnums(org.bukkit.inventory.recipe.CookingBookCategory.class, newTypes);
}
private static void loadEndDragonPhase() { private static void loadEndDragonPhase() {
var max = EnderDragonPhase.getCount(); var max = EnderDragonPhase.getCount();
var newTypes = new ArrayList<EnderDragon.Phase>(); var newTypes = new ArrayList<EnderDragon.Phase>();
@ -149,30 +164,6 @@ public class BukkitRegistry {
EnumHelper.addEnums(SpawnCategory.class, newTypes); EnumHelper.addEnums(SpawnCategory.class, newTypes);
} }
private static void loadCreativeTab() {
var id = new AtomicInteger(CreativeCategory.values().length);
var newTypes = new ArrayList<CreativeCategory>();
var tabs = CreativeModeTab.TABS;
var map = new HashMap<CreativeModeTab, CreativeCategory>(Unsafe.getStatic(CraftCreativeCategory.class, "NMS_TO_BUKKIT"));
for (var tab : tabs) {
map.computeIfAbsent(tab, k -> {
var name = "MOD_" + k.getId();
var newTab = EnumHelper.makeEnum(CreativeCategory.class, name, id.getAndIncrement(), List.of(), List.of());
newTypes.add(newTab);
ArclightMod.LOGGER.debug("Registered {} as creative tab {}", k, newTab);
return newTab;
});
}
EnumHelper.addEnums(CreativeCategory.class, newTypes);
try {
var field = CraftCreativeCategory.class.getDeclaredField("NMS_TO_BUKKIT");
field.setAccessible(true);
field.set(null, map);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void loadStats() { private static void loadStats() {
int i = Statistic.values().length; int i = Statistic.values().length;
List<Statistic> newTypes = new ArrayList<>(); List<Statistic> newTypes = new ArrayList<>();
@ -185,11 +176,11 @@ public class BukkitRegistry {
if (statistic == null) { if (statistic == null) {
String standardName = ResourceLocationUtil.standardize(location); String standardName = ResourceLocationUtil.standardize(location);
Statistic.Type type; Statistic.Type type;
if (statType.getRegistry() == Registry.ENTITY_TYPE) { if (statType.getRegistry() == BuiltInRegistries.ENTITY_TYPE) {
type = Statistic.Type.ENTITY; type = Statistic.Type.ENTITY;
} else if (statType.getRegistry() == Registry.BLOCK) { } else if (statType.getRegistry() == BuiltInRegistries.BLOCK) {
type = Statistic.Type.BLOCK; type = Statistic.Type.BLOCK;
} else if (statType.getRegistry() == Registry.ITEM) { } else if (statType.getRegistry() == BuiltInRegistries.ITEM) {
type = Statistic.Type.ITEM; type = Statistic.Type.ITEM;
} else { } else {
type = Statistic.Type.UNTYPED; type = Statistic.Type.UNTYPED;
@ -202,7 +193,7 @@ public class BukkitRegistry {
i++; i++;
} }
} }
for (ResourceLocation location : Registry.CUSTOM_STAT) { for (ResourceLocation location : BuiltInRegistries.CUSTOM_STAT) {
Statistic statistic = STATS.get(location); Statistic statistic = STATS.get(location);
if (statistic == null) { if (statistic == null) {
String standardName = ResourceLocationUtil.standardize(location); String standardName = ResourceLocationUtil.standardize(location);
@ -246,7 +237,7 @@ public class BukkitRegistry {
List<Biome> newTypes = new ArrayList<>(); List<Biome> newTypes = new ArrayList<>();
Field key = Arrays.stream(Biome.class.getDeclaredFields()).filter(it -> it.getName().equals("key")).findAny().orElse(null); Field key = Arrays.stream(Biome.class.getDeclaredFields()).filter(it -> it.getName().equals("key")).findAny().orElse(null);
long keyOffset = Unsafe.objectFieldOffset(key); long keyOffset = Unsafe.objectFieldOffset(key);
var registry = console.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); var registry = console.registryAccess().registryOrThrow(Registries.BIOME);
for (net.minecraft.world.level.biome.Biome biome : registry) { for (net.minecraft.world.level.biome.Biome biome : registry) {
var location = registry.getKey(biome); var location = registry.getKey(biome);
String name = ResourceLocationUtil.standardize(location); String name = ResourceLocationUtil.standardize(location);

View File

@ -3,13 +3,13 @@ package io.izzel.arclight.common.mod.util;
import io.izzel.arclight.common.mod.ArclightConstants; import io.izzel.arclight.common.mod.ArclightConstants;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.server.WorldLoader;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.DataPackConfig;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import org.bukkit.TreeType; import org.bukkit.TreeType;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
@ -19,6 +19,7 @@ import org.bukkit.event.entity.EntityPotionEffectEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Stack; import java.util.Stack;
public class ArclightCaptures { public class ArclightCaptures {
@ -252,17 +253,17 @@ public class ArclightCaptures {
} }
} }
private static transient DataPackConfig datapackCodec; private static transient WorldLoader.DataLoadContext dataLoadContext;
public static void captureDatapackConfig(DataPackConfig codec) { public static void captureDataLoadContext(WorldLoader.DataLoadContext context) {
datapackCodec = codec; dataLoadContext = context;
} }
public static DataPackConfig getDatapackConfig() { public static WorldLoader.DataLoadContext getDataLoadContext() {
try { try {
return datapackCodec; return Objects.requireNonNull(dataLoadContext, "dataLoadContext");
} finally { } finally {
datapackCodec = null; dataLoadContext = null;
} }
} }

View File

@ -23,7 +23,7 @@ public class ArclightPingEvent extends ServerListPingEvent {
private final Object[] players; private final Object[] players;
public ArclightPingEvent(Connection networkManager, MinecraftServer server) { public ArclightPingEvent(Connection networkManager, MinecraftServer server) {
super(((NetworkManagerBridge) networkManager).bridge$getHostname(), ((InetSocketAddress) networkManager.getRemoteAddress()).getAddress(), server.getMotd(), server.previewsChat(), server.getPlayerList().getMaxPlayers()); super(((NetworkManagerBridge) networkManager).bridge$getHostname(), ((InetSocketAddress) networkManager.getRemoteAddress()).getAddress(), server.getMotd(), server.getPlayerList().getMaxPlayers());
this.icon = ((CraftServer) Bukkit.getServer()).getServerIcon(); this.icon = ((CraftServer) Bukkit.getServer()).getServerIcon();
this.players = server.getPlayerList().players.toArray(); this.players = server.getPlayerList().players.toArray();
} }

View File

@ -10,7 +10,7 @@ import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.GameType; import net.minecraft.world.level.GameType;
import net.minecraft.world.level.LevelSettings; import net.minecraft.world.level.LevelSettings;
import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldOptions;
import net.minecraft.world.level.storage.DerivedLevelData; import net.minecraft.world.level.storage.DerivedLevelData;
import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.PrimaryLevelData;
import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.ServerLevelData;
@ -23,9 +23,9 @@ public class DelegateWorldInfo extends PrimaryLevelData {
private final DerivedLevelData derivedWorldInfo; private final DerivedLevelData derivedWorldInfo;
public DelegateWorldInfo(LevelSettings worldSettings, WorldGenSettings generatorSettings, Lifecycle lifecycle, DerivedLevelData derivedWorldInfo) { public DelegateWorldInfo(LevelSettings p_251081_, WorldOptions p_251666_, SpecialWorldProperty p_252268_, Lifecycle p_251714_, DerivedLevelData derivedLevelData) {
super(worldSettings, generatorSettings, lifecycle); super(p_251081_, p_251666_, p_252268_, p_251714_);
this.derivedWorldInfo = derivedWorldInfo; this.derivedWorldInfo = derivedLevelData;
} }
@Override @Override
@ -234,7 +234,7 @@ public class DelegateWorldInfo extends PrimaryLevelData {
} }
public static DelegateWorldInfo wrap(DerivedLevelData worldInfo) { public static DelegateWorldInfo wrap(DerivedLevelData worldInfo) {
return new DelegateWorldInfo(worldSettings(worldInfo), generatorSettings(worldInfo), lifecycle(worldInfo), worldInfo); return new DelegateWorldInfo(worldSettings(worldInfo), generatorSettings(worldInfo), specialWorldProperty(worldInfo), lifecycle(worldInfo), worldInfo);
} }
private static LevelSettings worldSettings(ServerLevelData worldInfo) { private static LevelSettings worldSettings(ServerLevelData worldInfo) {
@ -245,14 +245,25 @@ public class DelegateWorldInfo extends PrimaryLevelData {
} }
} }
private static WorldGenSettings generatorSettings(ServerLevelData worldInfo) { private static WorldOptions generatorSettings(ServerLevelData worldInfo) {
if (worldInfo instanceof PrimaryLevelData) { if (worldInfo instanceof PrimaryLevelData) {
return ((PrimaryLevelData) worldInfo).worldGenSettings(); return ((PrimaryLevelData) worldInfo).worldGenOptions();
} else { } else {
return generatorSettings(((DerivedWorldInfoBridge) worldInfo).bridge$getDelegate()); return generatorSettings(((DerivedWorldInfoBridge) worldInfo).bridge$getDelegate());
} }
} }
private static SpecialWorldProperty specialWorldProperty(ServerLevelData serverLevelData) {
if (serverLevelData instanceof PrimaryLevelData) {
return ((PrimaryLevelData) serverLevelData).isFlatWorld() ?
SpecialWorldProperty.FLAT : (
((PrimaryLevelData) serverLevelData).isDebugWorld() ? SpecialWorldProperty.DEBUG : SpecialWorldProperty.NONE
);
} else {
return specialWorldProperty(((DerivedWorldInfoBridge) serverLevelData).bridge$getDelegate());
}
}
private static Lifecycle lifecycle(ServerLevelData worldInfo) { private static Lifecycle lifecycle(ServerLevelData worldInfo) {
if (worldInfo instanceof PrimaryLevelData) { if (worldInfo instanceof PrimaryLevelData) {
return ((WorldInfoBridge) worldInfo).bridge$getLifecycle(); return ((WorldInfoBridge) worldInfo).bridge$getLifecycle();

View File

@ -1,3 +1,5 @@
# Arclight 1.19.3
public net.minecraft.server.MinecraftServer$TimeProfiler <init>(JI)V # TimeProfiler
# Arclight 1.18.2 # Arclight 1.18.2
public-f net.minecraft.server.ReloadableServerResources f_206847_ # commands public-f net.minecraft.server.ReloadableServerResources f_206847_ # commands
public net.minecraft.world.level.chunk.ChunkGenerator f_212255_ public net.minecraft.world.level.chunk.ChunkGenerator f_212255_
@ -538,3 +540,21 @@ public net.minecraft.world.entity.animal.allay.Allay m_239811_()V # resetDuplica
public net.minecraft.world.entity.animal.allay.Allay m_218324_()Z # canDuplicate public net.minecraft.world.entity.animal.allay.Allay m_218324_()Z # canDuplicate
public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37022_ # life public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37022_ # life
public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37024_ # attachedToEntity public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37024_ # attachedToEntity
# Bukkit 1.19.3
public net.minecraft.server.MinecraftServer$ReloadableResources
public net.minecraft.server.dedicated.DedicatedServerProperties$WorldDimensionData
public net.minecraft.server.level.ServerLevel m_261178_(Lnet/minecraft/world/level/entity/EntityTypeTest;Ljava/util/function/Predicate;Ljava/util/List;I)V
public net.minecraft.server.Main m_195488_(Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lcom/mojang/datafixers/DataFixer;ZLjava/util/function/BooleanSupplier;Lnet/minecraft/core/Registry;)V
public net.minecraft.server.WorldLoader m_245736_(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/core/LayeredRegistryAccess;Lnet/minecraft/server/RegistryLayer;Ljava/util/List;)Lnet/minecraft/core/LayeredRegistryAccess;
public net.minecraft.util.datafix.fixes.BlockStateData m_14942_(ILjava/lang/String;[Ljava/lang/String;)V
public net.minecraft.world.entity.animal.TropicalFish m_30042_()I
public net.minecraft.world.entity.animal.TropicalFish m_30056_(I)V
public net.minecraft.world.entity.decoration.ItemFrame f_31757_
public net.minecraft.world.entity.decoration.ItemFrame f_31758_
public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37024_
public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37022_
public net.minecraft.world.item.context.UseOnContext <init>(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/phys/BlockHitResult;)V
public net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity f_262317_
public net.minecraft.world.level.chunk.ChunkGenerator f_223021_
public-f net.minecraft.world.level.saveddata.maps.MapItemSavedData f_256718_
public-f net.minecraft.world.level.saveddata.maps.MapItemSavedData f_256789_

View File

@ -1,5 +1,5 @@
modLoader="javafml" modLoader="javafml"
loaderVersion="[24,]" loaderVersion="[44,]"
license="GNU GENERAL PUBLIC LICENSE Version 3" license="GNU GENERAL PUBLIC LICENSE Version 3"
[[mods]] [[mods]]

View File

@ -16,7 +16,6 @@
"CraftBlockMixin", "CraftBlockMixin",
"CraftBlockStateMixin", "CraftBlockStateMixin",
"CraftConsoleCommandSenderMixin", "CraftConsoleCommandSenderMixin",
"CraftCreativeCategoryMixin",
"CraftEntityMixin", "CraftEntityMixin",
"CraftEventFactoryMixin", "CraftEventFactoryMixin",
"CraftHumanEntityMixin", "CraftHumanEntityMixin",

View File

@ -52,7 +52,7 @@
"server.PlayerAdvancementsMixin", "server.PlayerAdvancementsMixin",
"server.ServerFunctionManagerMixin", "server.ServerFunctionManagerMixin",
"server.ServerScoreboardMixin", "server.ServerScoreboardMixin",
"server.WorldLoader_PackConfigMixin", "server.WorldLoaderMixin",
"server.commands.EffectCommandMixin", "server.commands.EffectCommandMixin",
"server.commands.GameRuleCommandMixin", "server.commands.GameRuleCommandMixin",
"server.commands.ReloadCommandMixin", "server.commands.ReloadCommandMixin",
@ -133,6 +133,7 @@
"world.entity.animal.Bee_HurtByOtherGoalMixin", "world.entity.animal.Bee_HurtByOtherGoalMixin",
"world.entity.animal.BeeMixin", "world.entity.animal.BeeMixin",
"world.entity.animal.BucketableMixin", "world.entity.animal.BucketableMixin",
"world.entity.animal.Cat_CatRelaxOnOwnerGoalMixin",
"world.entity.animal.ChickenMixin", "world.entity.animal.ChickenMixin",
"world.entity.animal.CowMixin", "world.entity.animal.CowMixin",
"world.entity.animal.DolphinEntity_SwimWithPlayerGoalMixin", "world.entity.animal.DolphinEntity_SwimWithPlayerGoalMixin",
@ -312,7 +313,7 @@
"world.item.crafting.BlastingRecipeMixin", "world.item.crafting.BlastingRecipeMixin",
"world.item.crafting.CampfireCookingRecipeMixin", "world.item.crafting.CampfireCookingRecipeMixin",
"world.item.crafting.CustomRecipeMixin", "world.item.crafting.CustomRecipeMixin",
"world.item.crafting.FurnaceRecipeMixin", "world.item.crafting.SmeltingRecipeMixin",
"world.item.crafting.IngredientMixin", "world.item.crafting.IngredientMixin",
"world.item.crafting.RecipeManagerMixin", "world.item.crafting.RecipeManagerMixin",
"world.item.crafting.RecipeMixin", "world.item.crafting.RecipeMixin",
@ -325,8 +326,8 @@
"world.item.enchantment.DamageEnchantmentMixin", "world.item.enchantment.DamageEnchantmentMixin",
"world.item.enchantment.FrostWalkerEnchantmentMixin", "world.item.enchantment.FrostWalkerEnchantmentMixin",
"world.level.LevelMixin", "world.level.LevelMixin",
"world.level.block.BambooBlockMixin",
"world.level.block.BambooSaplingBlockMixin", "world.level.block.BambooSaplingBlockMixin",
"world.level.block.BambooStalkBlockMixin",
"world.level.block.BaseFireBlockMixin", "world.level.block.BaseFireBlockMixin",
"world.level.block.BasePressurePlateBlockMixin", "world.level.block.BasePressurePlateBlockMixin",
"world.level.block.BedBlockMixin", "world.level.block.BedBlockMixin",
@ -434,8 +435,9 @@
"world.level.block.entity.BeehiveBlockEntityMixin", "world.level.block.entity.BeehiveBlockEntityMixin",
"world.level.block.entity.BlockEntityMixin", "world.level.block.entity.BlockEntityMixin",
"world.level.block.entity.BrewingStandBlockEntityMixin", "world.level.block.entity.BrewingStandBlockEntityMixin",
"world.level.block.entity.CampfireTileEntityMixin", "world.level.block.entity.CampfireBlockEntityMixin",
"world.level.block.entity.ChestBlockEntityMixin", "world.level.block.entity.ChestBlockEntityMixin",
"world.level.block.entity.ChiseledBookShelfBlockEntityMixin",
"world.level.block.entity.CommandBlockLogicMixin", "world.level.block.entity.CommandBlockLogicMixin",
"world.level.block.entity.CommandBlockTileEntity1Mixin", "world.level.block.entity.CommandBlockTileEntity1Mixin",
"world.level.block.entity.ConduitBlockEntityMixin", "world.level.block.entity.ConduitBlockEntityMixin",
@ -461,6 +463,7 @@
"world.level.chunk.storage.ChunkSerializerMixin", "world.level.chunk.storage.ChunkSerializerMixin",
"world.level.chunk.storage.RegionFileCacheMixin", "world.level.chunk.storage.RegionFileCacheMixin",
"world.level.entity.PersistentEntitySectionManagerMixin", "world.level.entity.PersistentEntitySectionManagerMixin",
"world.level.gameevent.GameEventDispatcherMixin",
"world.level.gameevent.vibrations.VibrationListenerMixin", "world.level.gameevent.vibrations.VibrationListenerMixin",
"world.level.levelgen.structure.templatesystem.StructureTemplateMixin", "world.level.levelgen.structure.templatesystem.StructureTemplateMixin",
"world.level.portal.PortalForcerMixin", "world.level.portal.PortalForcerMixin",

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