diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java index 5a6c3ac87af..8ebe54b6ffc 100644 --- a/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java @@ -66,7 +66,7 @@ public void callItemDestroyedEvent( public CriticalHitResult callCriticalHitEvent( final Player player, final Entity targetEntity, final boolean isCriticalAttack, final float v ) { - final CriticalHitEvent hitResult = ForgeHooks.getCriticalHit(player, targetEntity, isCriticalAttack, v); + final CriticalHitEvent hitResult = ForgeHooks.getCriticalHit(player, targetEntity, isCriticalAttack, v + 1.0F); if (hitResult != null) { return new CriticalHitResult(true, hitResult.getDamageModifier() - 1.0F); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntity_Mixin.java b/src/accessors/java/org/spongepowered/common/accessor/network/Connection_PacketHolderAccessor.java similarity index 65% rename from src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntity_Mixin.java rename to src/accessors/java/org/spongepowered/common/accessor/network/Connection_PacketHolderAccessor.java index 9b0bab09eb0..9286033e7dd 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntity_Mixin.java +++ b/src/accessors/java/org/spongepowered/common/accessor/network/Connection_PacketHolderAccessor.java @@ -22,22 +22,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.core.world.level.block.entity; +package org.spongepowered.common.accessor.network; -import net.minecraft.commands.CommandSourceStack; -import org.spongepowered.api.event.Cause; +import net.minecraft.network.PacketSendListener; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.common.bridge.commands.CommandSourceProviderBridge; - -@Mixin(targets = "net.minecraft.world.level.block.entity.CommandBlockEntity$1") -public abstract class CommandBlockEntity_Mixin implements CommandSourceProviderBridge { - - @Shadow public abstract CommandSourceStack shadow$createCommandSourceStack(); - - @Override - public CommandSourceStack bridge$getCommandSource(final Cause cause) { - return this.shadow$createCommandSourceStack(); - } +import org.spongepowered.asm.mixin.gen.Accessor; +@Mixin(targets = "net/minecraft/network/Connection$PacketHolder") +public interface Connection_PacketHolderAccessor { + @Accessor("listener") PacketSendListener accessor$listener(); } diff --git a/src/accessors/resources/mixins.sponge.accessors.json b/src/accessors/resources/mixins.sponge.accessors.json index 96a26714538..3266ea7eeb8 100644 --- a/src/accessors/resources/mixins.sponge.accessors.json +++ b/src/accessors/resources/mixins.sponge.accessors.json @@ -20,6 +20,7 @@ "commands.arguments.selector.options.EntitySelectorOptions_OptionAccessor", "commands.arguments.selector.options.EntitySelectorOptionsAccessor", "entity.passive.AbstractChestedHorseEntityAccessor", + "network.Connection_PacketHolderAccessor", "network.ConnectionAccessor", "network.chat.HoverEvent_ItemStackInfoAccessor", "network.chat.StyleAccessor", diff --git a/src/main/java/org/spongepowered/common/data/persistence/NBTTranslator.java b/src/main/java/org/spongepowered/common/data/persistence/NBTTranslator.java index 9bb0f65152c..9d63933562d 100644 --- a/src/main/java/org/spongepowered/common/data/persistence/NBTTranslator.java +++ b/src/main/java/org/spongepowered/common/data/persistence/NBTTranslator.java @@ -181,7 +181,7 @@ private static void setInternal(Tag base, byte type, DataView view, String key) checkNotNull(view); checkNotNull(key); checkArgument(!key.isEmpty()); - checkArgument(type > Constants.NBT.TAG_END && type <= Constants.NBT.TAG_INT_ARRAY); + checkArgument(type > Constants.NBT.TAG_END && type <= Constants.NBT.TAG_LONG_ARRAY); switch (type) { case Constants.NBT.TAG_BYTE: if (key.contains(NBTTranslator.BOOLEAN_IDENTIFIER)) { diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/ItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/ItemStackData.java index a490667397a..e2758d00a86 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/ItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/ItemStackData.java @@ -40,6 +40,7 @@ import net.minecraft.world.item.PickaxeItem; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.block.BlockType; import org.spongepowered.api.data.Keys; import org.spongepowered.api.effect.potion.PotionEffect; @@ -122,10 +123,7 @@ public static void register(final DataProviderRegistrator registrator) { tag.putInt(Constants.Item.CUSTOM_MODEL_DATA, v); }) .delete(h -> { - final CompoundTag tag = h.getTag(); - if (tag != null) { - tag.remove(Constants.Item.CUSTOM_MODEL_DATA); - } + h.removeTagKey(Constants.Item.CUSTOM_MODEL_DATA); }) .create(Keys.CUSTOM_NAME) .get(h -> { @@ -211,18 +209,21 @@ private static void setIsUnbrekable(final ItemStack stack, final Boolean value) if (value == null || (!value && !stack.hasTag())) { return; } - final CompoundTag tag = stack.getOrCreateTag(); if (value) { + final CompoundTag tag = stack.getOrCreateTag(); tag.putBoolean(Constants.Item.ITEM_UNBREAKABLE, true); } else { - tag.remove(Constants.Item.ITEM_UNBREAKABLE); + stack.removeTagKey(Constants.Item.ITEM_UNBREAKABLE); } } private static void deleteLore(final ItemStack stack) { - final CompoundTag tag = stack.getTag(); - if (tag != null && tag.contains(Constants.Item.ITEM_DISPLAY)) { - tag.getCompound(Constants.Item.ITEM_DISPLAY).remove(Constants.Item.ITEM_LORE); + final @Nullable CompoundTag tag = stack.getTagElement(Constants.Item.ITEM_DISPLAY); + if (tag != null) { + tag.remove(Constants.Item.ITEM_LORE); + if (tag.isEmpty()) { + stack.removeTagKey(Constants.Item.ITEM_DISPLAY); + } } } } diff --git a/src/main/java/org/spongepowered/common/world/level/chunk/SpongeOfflineChunk.java b/src/main/java/org/spongepowered/common/world/level/chunk/SpongeOfflineChunk.java new file mode 100644 index 00000000000..d5a720b3142 --- /dev/null +++ b/src/main/java/org/spongepowered/common/world/level/chunk/SpongeOfflineChunk.java @@ -0,0 +1,81 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.common.world.level.chunk; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.storage.RegionFile; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.world.chunk.OfflineChunk; +import org.spongepowered.common.data.persistence.NBTTranslator; +import org.spongepowered.math.vector.Vector3i; + +import java.io.DataInputStream; +import java.io.IOException; + +public final class SpongeOfflineChunk implements OfflineChunk { + + private final CompoundTag nbt; + private final Vector3i chunkPos; + + public SpongeOfflineChunk(final CompoundTag nbt, final int cx, final int cz) { + this.nbt = nbt; + this.chunkPos = new Vector3i(cx, 0, cz); + } + + @Nullable + public static OfflineChunk of(final RegionFile regionFile, final ChunkPos pos) { + CompoundTag chunkNbt; + try (DataInputStream $$2 = regionFile.getChunkDataInputStream(pos)) { + if ($$2 == null) { + return null; + } + + chunkNbt = NbtIo.read($$2); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return new SpongeOfflineChunk(chunkNbt, pos.x, pos.z); + } + + @Override + public org.spongepowered.math.vector.Vector3i chunkPosition() { + return this.chunkPos; + } + + @Override + public int contentVersion() { + return 2; // TODO get from actual data?, assuming compression type is 2 + } + + @Override + public DataContainer toContainer() { + return NBTTranslator.INSTANCE.translate(this.nbt); + } + +} diff --git a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java index 4921360bc07..0c266bf8d65 100644 --- a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java +++ b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java @@ -425,6 +425,7 @@ public CompletableFuture> loadProperties(final R ((PrimaryLevelDataBridge) levelData).bridge$populateFromLevelStem(scratch); } + ((ResourceKeyBridge) levelData).bridge$setKey(key); return CompletableFuture.completedFuture(Optional.of((ServerWorldProperties) levelData)); }); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerLevelMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerLevelMixin_API.java index b14b8d59abd..49ae2c606e3 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerLevelMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerLevelMixin_API.java @@ -35,9 +35,11 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.raid.Raid; import net.minecraft.world.entity.raid.Raids; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.CollisionGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.storage.RegionFile; import net.minecraft.world.level.entity.PersistentEntitySectionManager; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.storage.LevelResource; @@ -56,6 +58,7 @@ import org.spongepowered.api.world.BlockChangeFlag; import org.spongepowered.api.world.SerializationBehavior; import org.spongepowered.api.world.border.WorldBorder; +import org.spongepowered.api.world.chunk.OfflineChunk; import org.spongepowered.api.world.chunk.WorldChunk; import org.spongepowered.api.world.generation.ChunkGenerator; import org.spongepowered.api.world.server.ChunkManager; @@ -66,6 +69,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.accessor.world.entity.raid.RaidsAccessor; import org.spongepowered.common.bridge.server.level.ServerLevelBridge; import org.spongepowered.common.bridge.world.level.border.WorldBorderBridge; @@ -73,11 +77,15 @@ import org.spongepowered.common.data.holder.SpongeServerLocationBaseDataHolder; import org.spongepowered.common.mixin.api.minecraft.world.level.LevelMixin_API; import org.spongepowered.common.util.VecHelper; +import org.spongepowered.common.world.level.chunk.SpongeOfflineChunk; import org.spongepowered.common.world.storage.SpongeChunkLayout; import org.spongepowered.math.vector.Vector3d; import org.spongepowered.math.vector.Vector3i; +import org.spongepowered.math.vector.Vector4i; import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Collection; import java.util.Collections; @@ -85,7 +93,11 @@ import java.util.Objects; import java.util.Optional; import java.util.UUID; +import java.util.function.BiFunction; +import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; import java.util.stream.StreamSupport; import javax.annotation.Nonnull; @@ -182,7 +194,7 @@ public BlockSnapshot createSnapshot(final int x, final int y, final int z) { @Override public boolean restoreSnapshot(final BlockSnapshot snapshot, final boolean force, final BlockChangeFlag flag) { - return snapshot.restore(force, Objects.requireNonNull(flag, "flag")); + return Objects.requireNonNull(snapshot, "snapshot").withLocation(this.location(snapshot.position())).restore(force, Objects.requireNonNull(flag, "flag")); } @Override @@ -319,4 +331,68 @@ public ChunkManager chunkManager() { return (ChunkManager) this.shadow$getChunkSource().chunkMap; } + public Stream api$chunkPosStream(BiFunction, Stream> mapper) { + final Path dimensionPath = ((ServerLevelBridge) this).bridge$getLevelSave().getDimensionPath(this.shadow$dimension()); + final Path regionPath = dimensionPath.resolve("region"); + + return Stream + .generate(() -> { + try { + // open directory stream over all region files of this world + return Stream.of(Files.newDirectoryStream(regionPath, "*.mca")); + } catch (IOException ex) { + SpongeCommon.logger().error("Could not find region files", ex); + return Stream.>empty(); + } + }) + .limit(1) + .flatMap(Function.identity()) + .flatMap(stream -> StreamSupport.stream(stream.spliterator(), false) + .flatMap(path -> { + try { // For every region file + RegionFile regionFile = new RegionFile(path, regionPath, true); + final Vector4i regionBound = this.api$pathToRegionPos(path); + // Find all chunks in bounds + final Stream chunkPosStream = IntStream.range(regionBound.x(), regionBound.z()) + .mapToObj(x -> IntStream.range(regionBound.y(), regionBound.w()). + mapToObj(z -> new ChunkPos(x, z))) + .flatMap(Function.identity()); + return mapper.apply(regionFile, chunkPosStream).onClose(() -> this.api$close(regionFile)); + } catch (IOException ignored) { + return Stream.empty(); + } + }) + .onClose(() -> this.api$close(stream))); + } + + @Override + public Stream chunkPositions() { + return this.api$chunkPosStream((regionFile, stream) -> + stream.filter(regionFile::doesChunkExist) // filter out non-existent chunks + .map(cp -> new Vector3i(cp.x, 0, cp.z)) // map to API type + ); + } + + @Override + public Stream offlineChunks() { + return this.api$chunkPosStream((regionFile, stream) -> + stream.map(cp -> SpongeOfflineChunk.of(regionFile, cp)) // map to API type + .filter(Objects::nonNull)); // filter out non-existent chunks + } + + private void api$close(final AutoCloseable closeable) { + try { + closeable.close(); + } catch (Exception ignored) { + } + } + + private Vector4i api$pathToRegionPos(Path regionPath) { + final String[] split = regionPath.getFileName().toString().split("\\."); + final int rx = Integer.parseInt(split[1]); + final int ry = Integer.parseInt(split[2]); + final ChunkPos min = ChunkPos.minFromRegion(rx, ry); + final ChunkPos max = ChunkPos.maxFromRegion(rx, ry); + return new Vector4i(min.x, min.z, max.x, max.z); + } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/EntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/EntityMixin_API.java index 0193137c41a..707f37af96b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/EntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/EntityMixin_API.java @@ -395,4 +395,9 @@ public HoverEvent asHoverEvent(final UnaryOperator attribute(final AttributeType type) { Preconditions.checkNotNull(type, "AttributeType cannot be null"); diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartCommandBlockMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartCommandBlockMixin_API.java index d570a2ec8cb..a53afd2da02 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartCommandBlockMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/entity/vehicle/MinecartCommandBlockMixin_API.java @@ -38,12 +38,12 @@ public abstract class MinecartCommandBlockMixin_API extends AbstractMinecartMixin_API implements CommandBlockMinecart { // @formatter:off - @Shadow public abstract BaseCommandBlock getCommandBlock(); + @Shadow public abstract BaseCommandBlock shadow$getCommandBlock(); // @formatter:on @Override public String identifier() { - return this.getCommandBlock().getName().getString(); + return this.shadow$getCommandBlock().getName().getString(); } @Override diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/CommandBlockEntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/CommandBlockEntityMixin_API.java index b5e3c4becc5..119aece2369 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/CommandBlockEntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/CommandBlockEntityMixin_API.java @@ -24,9 +24,13 @@ */ package org.spongepowered.common.mixin.api.minecraft.world.level.block.entity; +import net.kyori.adventure.audience.MessageType; +import net.kyori.adventure.identity.Identity; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.world.level.BaseCommandBlock; import net.minecraft.world.level.block.entity.CommandBlockEntity; +import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.api.block.entity.CommandBlock; import org.spongepowered.api.data.persistence.DataContainer; import org.spongepowered.api.data.value.Value; @@ -84,4 +88,9 @@ public DataContainer toContainer() { public String identifier() { return this.shadow$getCommandBlock().getName().getString(); } + + @Override + public void sendMessage(final @NonNull Identity identity, final @NonNull Component message, final @NonNull MessageType type) { + this.shadow$getCommandBlock().sendSystemMessage(SpongeAdventure.asVanilla(message)); + } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/network/ConnectionMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/network/ConnectionMixin.java index 4bd5e58faa7..bc003c24de2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/network/ConnectionMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/network/ConnectionMixin.java @@ -38,7 +38,6 @@ import org.spongepowered.api.MinecraftVersion; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.network.EngineConnection; -import org.spongepowered.api.resource.pack.PackStatus; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerPlayerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerPlayerMixin.java index ee95f7f3aac..8de3ee34d9e 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerPlayerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerPlayerMixin.java @@ -123,6 +123,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.accessor.network.ConnectionAccessor; +import org.spongepowered.common.accessor.server.level.ChunkMapAccessor; +import org.spongepowered.common.accessor.server.level.ChunkMap_TrackedEntityAccessor; import org.spongepowered.common.accessor.server.network.ServerCommonPacketListenerImplAccessor; import org.spongepowered.common.accessor.server.level.ChunkMapAccessor; import org.spongepowered.common.accessor.server.level.ChunkMap_TrackedEntityAccessor; @@ -722,6 +724,9 @@ public void die(final DamageSource cause) { DataUtil.syncTagToData(this); } + this.impl$language = ((ServerPlayerBridge) oldPlayer).bridge$getLanguage(); + this.impl$viewDistance = ((ServerPlayerBridge) oldPlayer).bridge$getViewDistance(); + // Update boss bars SpongeAdventure.forEachBossBar(bar -> ((BossEventBridge) bar).bridge$replacePlayer(oldPlayer, (net.minecraft.server.level.ServerPlayer) (Object) this)); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlock_MinecartCommandBaseMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java similarity index 67% rename from src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlock_MinecartCommandBaseMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java index 2d399b32d19..da95a861ee5 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlock_MinecartCommandBaseMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java @@ -22,20 +22,27 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.core.world.entity.vehicle; +package org.spongepowered.common.mixin.core.world; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.audience.MessageType; +import net.kyori.adventure.identity.Identity; +import net.kyori.adventure.text.Component; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.world.entity.vehicle.MinecartCommandBlock; +import net.minecraft.world.level.BaseCommandBlock; +import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.api.event.Cause; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.commands.CommandSourceProviderBridge; -@Mixin(MinecartCommandBlock.MinecartCommandBase.class) -public abstract class MinecartCommandBlock_MinecartCommandBaseMixin implements CommandSourceProviderBridge { +@Mixin(BaseCommandBlock.class) +public abstract class BaseCommandBlockMixin implements CommandSourceProviderBridge, Audience { // @formatter:off @Shadow public abstract CommandSourceStack shadow$createCommandSourceStack(); + @Shadow public abstract void shadow$sendSystemMessage(net.minecraft.network.chat.Component $$0); // @formatter:on @Override @@ -43,4 +50,8 @@ public abstract class MinecartCommandBlock_MinecartCommandBaseMixin implements C return this.shadow$createCommandSourceStack(); } + @Override + public void sendMessage(final @NonNull Identity identity, final @NonNull Component message, final @NonNull MessageType type) { + this.shadow$sendSystemMessage(SpongeAdventure.asVanilla(message)); + } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/EntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/EntityMixin.java index 9ad7bd763ce..d2ce9cf6518 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/EntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/EntityMixin.java @@ -34,7 +34,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; -import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; @@ -1174,10 +1173,10 @@ public void stopRiding() { //If the event is cancelled, well, don't change the underlying value. return; } - this.remainingFireTicks = valueChange.endResult().successfulValue(Keys.FIRE_TICKS) + valueChange.endResult().successfulValue(Keys.FIRE_TICKS) .map(Value::get) .map(t -> (int) t.ticks()) - .orElse(0); + .ifPresent(t -> this.remainingFireTicks = t); } return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin_Attack_Impl.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin_Attack_Impl.java index dd71d28c066..7ea13205d78 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin_Attack_Impl.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin_Attack_Impl.java @@ -191,7 +191,7 @@ public void attack(final Entity targetEntity) { isCriticalAttack = isStrongAttack && this.fallDistance > 0.0F && !this.shadow$onGround() && !this.shadow$onClimbable() && !this.shadow$isInWater() && !this.shadow$hasEffect( MobEffects.BLINDNESS) && !this.shadow$isPassenger() && targetEntity instanceof LivingEntity; isCriticalAttack = isCriticalAttack && !this.shadow$isSprinting(); - final EventHooks.CriticalHitResult criticalResult = PlatformHooks.INSTANCE.getEventHooks().callCriticalHitEvent((net.minecraft.world.entity.player.Player) (Object) this, targetEntity, isCriticalAttack, isCriticalAttack ? 1.5F : 1.0F); + final EventHooks.CriticalHitResult criticalResult = PlatformHooks.INSTANCE.getEventHooks().callCriticalHitEvent((net.minecraft.world.entity.player.Player) (Object) this, targetEntity, isCriticalAttack, isCriticalAttack ? 0.5F : 0.0F); isCriticalAttack = criticalResult.criticalHit; if (isCriticalAttack) { // Sponge Start - add critical attack tuple diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/food/FoodDataMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/food/FoodDataMixin.java index aa563a12939..23508dcd0a9 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/food/FoodDataMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/food/FoodDataMixin.java @@ -119,6 +119,6 @@ public abstract class FoodDataMixin implements FoodDataBridge { return event.endResult().successfulValue(key) .map(Value::get) - .orElse(value); + .orElse(currentValue); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PrimaryLevelDataMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PrimaryLevelDataMixin.java index 4f6b0c78257..c9f868d6a67 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PrimaryLevelDataMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PrimaryLevelDataMixin.java @@ -398,6 +398,7 @@ public ServerLevelData overworldData() { final ListTag playerIdList = new ListTag(); data.put(Constants.Sponge.SPONGE_PLAYER_UUID_TABLE, playerIdList); + this.impl$playerUniqueIdMap.values().forEach(uuid -> playerIdList.add(new IntArrayTag(UUIDUtil.uuidToIntArray(uuid)))); this.impl$pendingUniqueIds.forEach(uuid -> playerIdList.add(new IntArrayTag(UUIDUtil.uuidToIntArray(uuid)))); this.impl$pendingUniqueIds.clear(); diff --git a/src/mixins/resources/mixins.sponge.core.json b/src/mixins/resources/mixins.sponge.core.json index 0aff975cfd2..4525b2bf3aa 100644 --- a/src/mixins/resources/mixins.sponge.core.json +++ b/src/mixins/resources/mixins.sponge.core.json @@ -95,6 +95,7 @@ "service.permission.SubjectMixin", "util.ClassInstanceMultiMapMixin", "util.datafix.schemas.V1125Mixin", + "world.BaseCommandBlockMixin", "world.BossEventMixin", "world.damagesource.DamageSourceMixin", "world.damagesource.DamageSourcesMixin", @@ -164,7 +165,6 @@ "world.entity.vehicle.AbstractMinecartContainerMixin", "world.entity.vehicle.AbstractMinecartMixin", "world.entity.vehicle.BoatMixin", - "world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin", "world.entity.vehicle.MinecartCommandBlockMixin", "world.entity.vehicle.MinecartFurnaceMixin", "world.entity.vehicle.MinecartTNTMixin", @@ -206,7 +206,6 @@ "world.level.block.entity.BlockEntityMixin", "world.level.block.entity.BrewingStandBlockEntityMixin", "world.level.block.entity.CampfireBlockEntityMixin", - "world.level.block.entity.CommandBlockEntity_Mixin", "world.level.block.entity.CommandBlockEntityMixin", "world.level.block.entity.EnchantmentTableBlockEntityMixin", "world.level.block.entity.LecternBlockEntityMixin",